installed firewalld and selinux permissions

This commit is contained in:
2026-09-13 13:33:53 -06:00
parent cce172b9fe
commit bfcdc47e46
5 changed files with 76 additions and 3 deletions

View File

@@ -1,10 +1,10 @@
{
"sessionID": "ses_f63e23ebcffe7Q6sJKCl9W8sFt",
"updatedAt": "2026-09-13T19:25:59.636Z",
"updatedAt": "2026-09-13T19:33:29.129Z",
"sources": {
"background-task": {
"state": "idle",
"updatedAt": "2026-09-13T19:25:59.636Z"
"updatedAt": "2026-09-13T19:33:29.129Z"
}
}
}

View File

@@ -56,11 +56,12 @@ Ansible automation that **hardens a Fedora 44 server**, installs **rootless Podm
| Stage | Actions |
|---|---|
| **System** | `dnf update` all packages; install `git`, `curl`, `openssl` |
| **Firewall** | firewalld default-deny; allow `ssh`, `http`, `https`, `7881/tcp`, `50000-50100/udp` (LiveKit voice) |
| **Firewall** | installs + starts firewalld (native/minimal Fedora may not ship it); default-deny; allow `ssh`, `http`, `https`, `7881/tcp`, `50000-50100/udp` (LiveKit voice) |
| **Fail2Ban** | `sshd` jail (3 retries → 1 h ban, incremental for repeat offenders) |
| **Auto-updates** | `dnf5-plugin-automatic`, security-only, `apply_updates = yes`, started timer |
| **Logs** | logrotate rule for fail2ban logs (daily, 7 rotations, compressed) |
| **Podman** | rootless engine + `podman-compose` + `podman-docker`; `net.ipv4.ip_unprivileged_port_start=80` so Caddy can bind 80/443; dedicated `stoat` service user with lingering enabled |
| **SELinux** | keeps mode enforcing; installs `container-selinux` (container policy) + `policycoreutils-python-utils` / `setools-console` (`semanage`, `audit2why`) |
| **Stoat** | clone `stoatchat/self-hosted` to `/opt/stoat/self-hosted`; run `generate_config.sh <domain>` (answers: built-in Caddy, video enabled); start stack under `podman-compose-stoat.service` |
---
@@ -87,6 +88,7 @@ Ansible automation that **hardens a Fedora 44 server**, installs **rootless Podm
| `stoat_video` | `true` | enable camera/screen sharing (LiveKit) |
| `stoat_service_user` | `stoat` | unprivileged user running rootless podman |
| `podman_unprivileged_port_start` | `80` | lowest port rootless containers may bind |
| `selinux_mode` | `enforcing` | SELinux mode the role enforces (config + setenforce) |
| `fail2ban_port` / `fail2ban_maxretry` / `fail2ban_bantime` | `22` / `3` / `3600` | sshd jail tuning |
| `firewall_services` / `firewall_ports` | ssh,http,https / 7881, UDP range | firewalld allow rules |
@@ -138,6 +140,32 @@ sudo firewall-cmd --list-all
---
## SELinux notes
Fedora 44 ships SELinux **enforcing**; the role pins that mode. The stack runs in **rootless** podman, where containers run in the user's own SELinux domain and can read/write the `stoat` user's files — bind mounts under `/opt/stoat/self-hosted/data` generally need no relabeling or `:Z` flags.
If a service misbehaves, check for denials before anything else:
```bash
sudo ausearch -m avc -ts recent | grep -i stoat # recent denials
# or find the exact rule suggestion:
sudo grep "denied" /var/log/audit/audit.log | tail -20 | audit2why
```
Common knobs if a denial shows up (only set what the denial actually requires):
```bash
# containers connecting to non-default ports on the host
sudo setsebool -P container_connect_any 1
# container needs to manage cgroups (systemd inside a container)
sudo setsebool -P container_manage_cgroup 1
# give a specific bind-mounted volume its container context (last resort,
# only if audit2why points at file labeling):
sudo chcon -R -t container_file_t /opt/stoat/self-hosted/data
```
---
## Caveats & notes
- **First start pulls ~2 GB of images** and initializes MongoDB — allow a few minutes; the systemd unit tolerates up to 15 min (`TimeoutStartSec=900`).

View File

@@ -67,6 +67,14 @@ sshd_password_authentication: yes
# out. Leave false unless you know what you are doing.
sshd_mfa_required: false
# ------------------------------------------------------------
# Hardening - SELinux
# ------------------------------------------------------------
# Native Fedora 44 ships SELinux enforcing; the role keeps it in
# this mode and installs container-selinux + policycoreutils
# (semanage / audit2why) for diagnosing container denials.
selinux_mode: enforcing
# ------------------------------------------------------------
# Hardening - firewall (firewalld, default deny)
# ------------------------------------------------------------

View File

@@ -1,7 +1,14 @@
---
# ------------------------------------------------------------
# Firewall (firewalld) - default deny, allow only what is needed
# Native/minimal Fedora installs may not ship firewalld, so
# install it explicitly before starting it.
# ------------------------------------------------------------
- name: Install firewalld
ansible.builtin.dnf:
name: firewalld
state: present
- name: Start and enable firewalld
ansible.builtin.systemd:
name: firewalld

View File

@@ -30,4 +30,34 @@
# on boot without an interactive login.
- name: Enable lingering for the service user
ansible.builtin.command: "loginctl enable-linger {{ stoat_service_user }}"
changed_when: false
# ------------------------------------------------------------
# SELinux - keep enforcing, ensure the container policy and
# diagnostic tools are present for resolving any denials.
# ------------------------------------------------------------
- name: Install SELinux container policy and diagnostics tools
ansible.builtin.dnf:
name:
- container-selinux
- policycoreutils-python-utils
- setools-console
state: present
- name: Check current SELinux mode
ansible.builtin.command: getenforce
register: selinux_current_mode
changed_when: false
- name: Configure SELinux mode in /etc/selinux/config
ansible.builtin.lineinfile:
path: /etc/selinux/config
regexp: '^SELINUX='
line: 'SELINUX={{ selinux_mode }}'
- name: Apply SELinux mode now
ansible.builtin.command: "setenforce {{ selinux_mode }}"
when:
- selinux_mode | lower == "enforcing"
- selinux_current_mode.stdout | lower != "enforcing"
changed_when: false