Skip to content

Commit

Permalink
Use the selinux role from the cockpit role
Browse files Browse the repository at this point in the history
- Introduce cockpit_manage_selinux to use the selinux role to
  manage the ports in the cockpit service.
  Assign websm_port_t to the cockpit service ports.
  Default to false - means the selinux role is not used.

- Add a test playbook tests_port2.yml to check port 443 when
  cockpit_manage_firewall and cockpit_manage_selinux are yes.
  • Loading branch information
nhosoi committed Oct 3, 2022
1 parent 6db7522 commit 0852ffe
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 51 deletions.
32 changes: 20 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ Installs and configures the Cockpit Web Console for distributions that support i
- RHEL/CentOS 7.x depend on the Extras repository being enabled.
- Recommended to use [`linux-system-roles.firewall`](https://github.com/linux-system-roles/firewall/) to make the Web Console available remotely.

- The role requires the `firewall` role from the `fedora.linux_system_roles`
collection, if `cockpit_manage_firewall` is set to `yes`.
Please see also `cockpit_manage_firewall` in [`Role Variables`](#role-variables).
- The role requires the `firewall` role and the `selinux` role from the
`fedora.linux_system_roles` collection, if `cockpit_manage_firewall`
and `cockpit_manage_selinux` is set to yes, respectively.
Please see also `cockpit_manage_firewall` and `cockpit_manage_selinux`
in [`Role Variables`](#role-variables).

If `cockpit` is a role from the `fedora.linux_system_roles` collection
or from the Fedora RPM package, the requirement is already satisfied.
Expand Down Expand Up @@ -106,17 +108,23 @@ role directly.
NOTE: This functionality is supported only when the managed host's `os_family`
is `RedHat`.

Note that the default SELinux policy does not allow Cockpit to listen to anything else than port 9090, so you need to allow that first, with e.g.

semanage port -m -t websm_port_t -p tcp 443

for ports that are already defined in the SELinux policy, such as 443, or

semanage port -a -t websm_port_t -p tcp 9999
cockpit_manage_selinux: no
Boolean flag allowing to configure selinux using the selinux role.
The default SELinux policy does not allow Cockpit to listen to anything else
than port 9090. If you change the port, enable this to use the selinux role
to set the correct port permissions (websm_port_t).
If the variable is set to no, the `cockpit` role does not manage the
SELinux permissions of the cockpit port.

NOTE: `cockpit_manage_selinux` is limited to *adding* policy.
It cannot be used for *removing* policy.
If you want to remove policy, you will need to use the selinux system
role directly.

otherwise.
NOTE: This functionality is supported only when the managed host's `os_family`
is `RedHat`.

See the [Cockpit guide](https://cockpit-project.org/guide/latest/listen.html#listen-systemd) for details.
See also the [Cockpit guide](https://cockpit-project.org/guide/latest/listen.html#listen-systemd) for details.

## Certificate setup

Expand Down
3 changes: 3 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ cockpit_port: null

# If yes, manage the cockpit ports using the firewall role.
cockpit_manage_firewall: no

# If yes, manage the cockpit ports using the selinux role.
cockpit_manage_selinux: no
2 changes: 1 addition & 1 deletion tasks/firewall.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
include_role:
name: fedora.linux_system_roles.firewall
vars:
_cockpit_port: "{{ cockpit_port if cockpit_port is defined else 9090 }}"
_cockpit_port: "{{ cockpit_port if cockpit_port is not none else 9090 }}"
_cockpit_port_proto: "{{ _cockpit_port }}/tcp"
firewall: "{{ [{'service': 'cockpit', 'state': 'enabled'}]
if (_cockpit_port | int) == 9090 else
Expand Down
3 changes: 3 additions & 0 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
- name: Configure firewall
include_tasks: firewall.yml

- name: Configure selinux
include_tasks: selinux.yml

- name: Create custom port configuration file directory
file:
path: /etc/systemd/system/cockpit.socket.d/
Expand Down
13 changes: 13 additions & 0 deletions tasks/selinux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# SPDX-License-Identifier: MIT
---
- name: Ensure the service and the ports status with the selinux role
include_role:
name: fedora.linux_system_roles.selinux
vars:
selinux_ports: "{{ [{'ports': cockpit_port, 'proto': 'tcp',
'setype': 'websm_port_t',
'state': 'present', 'local': 'true'}] }}"
when:
- cockpit_manage_selinux | bool
- ansible_facts['os_family'] == 'RedHat'
- cockpit_port is not none
17 changes: 14 additions & 3 deletions tests/tasks/check_port.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
---
- block:
- block:
- name: Check firewall port status when cockpit_manage_firewall is true
- name: Check firewall port status when cockpit_manage_firewall is yes
command: firewall-cmd --list-service
register: _result
failed_when: "'cockpit' not in _result.stdout"
changed_when: false
when:
- _cockpit_port | int == 9090

- name: Check firewall port status when cockpit_manage_firewall is true
- name: Check firewall port status when cockpit_manage_firewall is yes
command: firewall-cmd --list-port
register: _result
failed_when: "'{{ _cockpit_port }}/tcp' not in _result.stdout"
Expand All @@ -19,7 +19,18 @@
- _cockpit_port | int != 9090
when:
- cockpit_manage_firewall | bool

- block:
- name: Install SELinux tools
include_tasks: install_selinux_tools.yml

- name: Check associated selinux ports when cockpit_manage_selinux is yes
shell: |-
set -euo pipefail
semanage port --list | egrep "websm_port_t *tcp" | grep "{{ _cockpit_port }}"
changed_when: false
when: cockpit_manage_selinux | bool
vars:
_cockpit_port: "{{ cockpit_port if cockpit_port is defined else 9090 }}"
_cockpit_port: "{{ cockpit_port if cockpit_port is not none else 9090 }}"
when:
- ansible_facts['os_family'] == 'RedHat'
28 changes: 28 additions & 0 deletions tests/tasks/install_selinux_tools.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# SPDX-License-Identifier: MIT
---
- name: Install SELinux python2 tools
package:
name:
- libselinux-python
- policycoreutils-python
state: present
when: ( ansible_python_version is version('3', '<') and
ansible_distribution in ["Fedora", "CentOS", "RedHat", "Rocky"] )

- name: Install SELinux python3 tools
package:
name:
- libselinux-python3
- policycoreutils-python3
state: present
when: ( ansible_python_version is version('3', '>=') and
ansible_distribution in ["Fedora", "CentOS", "RedHat", "Rocky"] )

- name: Install SELinux tool semanage
package:
name:
- policycoreutils-python-utils
state: present
when: ansible_distribution == "Fedora" or
( ansible_distribution_major_version | int > 7 and
ansible_distribution in ["CentOS", "RedHat", "Rocky"] )
5 changes: 3 additions & 2 deletions tests/tests_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
LoginTitle: "hello world"
Session:
IdleTimeout: 60
cockpit_manage_firewall: false
cockpit_manage_firewall: no
cockpit_manage_selinux: yes
public: true

tasks:
Expand Down Expand Up @@ -60,7 +61,7 @@
command: diff -u /run/cockpit.conf.expected /etc/cockpit/cockpit.conf
changed_when: false

- name: test - ensure cockpit_port is configured for firewall
- name: test - ensure cockpit_port is configured for firewall and selinux
include_tasks: tasks/check_port.yml

always:
Expand Down
5 changes: 3 additions & 2 deletions tests/tests_packages_full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
public: true
vars:
cockpit_packages: full
cockpit_manage_firewall: true
cockpit_manage_firewall: yes
cockpit_manage_selinux: no

- meta: flush_handlers

Expand Down Expand Up @@ -39,7 +40,7 @@
msg: cockpit-doc is not installed
when: "'cockpit-doc' not in ansible_facts.packages"

- name: test - ensure cockpit_port is configured for firewall
- name: test - ensure cockpit_port is configured for firewall and selinux
include_tasks: tasks/check_port.yml

always:
Expand Down
33 changes: 2 additions & 31 deletions tests/tests_port.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,16 @@
tasks:
- name: tests
block:
- name: Install SELinux python2 tools
package:
name:
- libselinux-python
- policycoreutils-python
state: present
when: ( ansible_python_version is version('3', '<') and
ansible_distribution in ["Fedora", "CentOS", "RedHat", "Rocky"] )

- name: Install SELinux python3 tools
package:
name:
- libselinux-python3
- policycoreutils-python3
state: present
when: ( ansible_python_version is version('3', '>=') and
ansible_distribution in ["Fedora", "CentOS", "RedHat", "Rocky"] )

- name: Install SELinux tool semanage
package:
name:
- policycoreutils-python-utils
state: present
when: ansible_distribution == "Fedora" or
( ansible_distribution_major_version | int > 7 and
ansible_distribution in ["CentOS", "RedHat", "Rocky"] )
- name: Install SELinux tools
include_tasks: tasks/install_selinux_tools.yml

- name: Allow cockpit to own customized port in SELinux
shell: if selinuxenabled; then semanage port -m -t websm_port_t -p tcp 443; fi

- name: Run cockpit role
include_role:
name: linux-system-roles.cockpit
public: true
vars:
cockpit_manage_firewall: true
cockpit_packages: minimal
cockpit_port: 443

Expand All @@ -63,9 +37,6 @@
register: result
failed_when: result is succeeded

- name: test - ensure cockpit_port is configured for firewall
include_tasks: tasks/check_port.yml

- name: test - clean up output file
file:
path: /run/out
Expand Down
46 changes: 46 additions & 0 deletions tests/tests_port2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
- name: Test cockpit_* role options
hosts: all
gather_facts: true
tasks:
- name: tests
block:
- name: Run cockpit role
include_role:
name: linux-system-roles.cockpit
public: true
vars:
cockpit_manage_firewall: yes
cockpit_manage_selinux: yes
cockpit_packages: minimal
cockpit_port: 443

- meta: flush_handlers

- name: test - cockpit works on customized port
get_url:
dest: /run/out
url: https://localhost
validate_certs: no

- name: test - HTTP response is something sensible
command: grep 'id="login-user-input"' /run/out

- name: test - cockpit does not listen on port 9090
get_url:
dest: /run/out
url: https://localhost:9090
validate_certs: no
register: result
failed_when: result is succeeded

- name: test - ensure cockpit_port is configured for firewall
include_tasks: tasks/check_port.yml

- name: test - clean up output file
file:
path: /run/out
state: absent

always:
- include_tasks: tasks/cleanup.yml

0 comments on commit 0852ffe

Please sign in to comment.