Files
arr-suite-template-bootstrap/tasks/security_setup.yml
openhands 24f2cd64e9 Initial template repository
🎬 ARR Suite Template Bootstrap - Complete Media Automation Stack

Features:
- 16 production services (Prowlarr, Sonarr, Radarr, Plex, etc.)
- One-command Ansible deployment
- VPN-protected downloads via Gluetun
- Tailscale secure access
- Production-ready security (UFW, Fail2Ban)
- Automated backups and monitoring
- Comprehensive documentation

Ready for customization and deployment to any VPS.

Co-authored-by: openhands <openhands@all-hands.dev>
2025-11-28 04:26:12 +00:00

185 lines
5.4 KiB
YAML

---
# Security and firewall configuration tasks
- name: Configure SSH security
lineinfile:
path: /etc/ssh/sshd_config
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
backup: yes
loop:
- { regexp: '^#?PermitRootLogin', line: 'PermitRootLogin yes' }
- { regexp: '^#?PasswordAuthentication', line: 'PasswordAuthentication {{ "yes" if not ssh_key_based_auth else "no" }}' }
- { regexp: '^#?PubkeyAuthentication', line: 'PubkeyAuthentication yes' }
- { regexp: '^#?Port', line: 'Port {{ ssh_port }}' }
- { regexp: '^#?MaxAuthTries', line: 'MaxAuthTries 3' }
- { regexp: '^#?ClientAliveInterval', line: 'ClientAliveInterval 300' }
- { regexp: '^#?ClientAliveCountMax', line: 'ClientAliveCountMax 2' }
notify: restart sshd
tags: ['ssh_security']
- name: Configure fail2ban for SSH
template:
src: jail.local.j2
dest: /etc/fail2ban/jail.local
backup: yes
notify: restart fail2ban
tags: ['fail2ban']
- name: Configure fail2ban filter for Plex
template:
src: plex-fail2ban-filter.j2
dest: /etc/fail2ban/filter.d/plex.conf
backup: yes
when: plex_public_access | default(false)
notify: restart fail2ban
tags: ['fail2ban', 'plex']
- name: Start and enable fail2ban
systemd:
name: fail2ban
state: started
enabled: yes
tags: ['fail2ban']
- name: Reset UFW to defaults
ufw:
state: reset
when: ufw_enabled
tags: ['firewall']
- name: Configure UFW default policies
ufw:
direction: "{{ item.direction }}"
policy: "{{ item.policy }}"
loop:
- { direction: 'incoming', policy: "{{ ufw_default_policy_incoming }}" }
- { direction: 'outgoing', policy: "{{ ufw_default_policy_outgoing }}" }
when: ufw_enabled
tags: ['firewall']
- name: Allow SSH through UFW
ufw:
rule: allow
port: "{{ ssh_port }}"
proto: tcp
when: ufw_enabled
tags: ['firewall']
- name: Check if Tailscale is installed
command: which tailscale
register: tailscale_check
failed_when: false
changed_when: false
when: tailscale_enabled
tags: ['tailscale']
- name: Install Tailscale
shell: |
curl -fsSL https://tailscale.com/install.sh | sh
when: tailscale_enabled and tailscale_check.rc != 0
tags: ['tailscale']
- name: Get Tailscale interface information
shell: ip addr show {{ tailscale_interface }} | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1
register: tailscale_ip
failed_when: false
changed_when: false
when: tailscale_enabled
tags: ['tailscale']
- name: Allow Tailscale interface through UFW
ufw:
rule: allow
interface: "{{ tailscale_interface }}"
direction: in
when: ufw_enabled and tailscale_enabled
tags: ['firewall', 'tailscale']
- name: Allow Arrs services from Tailscale network
ufw:
rule: allow
port: "{{ item.value }}"
proto: tcp
src: "{{ tailscale_ip.stdout | regex_replace('\\.[0-9]+$', '.0/24') }}"
loop: "{{ ports | dict2items }}"
when: ufw_enabled and tailscale_enabled and tailscale_ip.stdout != ""
tags: ['firewall', 'tailscale']
- name: Allow Docker bridge network communication
ufw:
rule: allow
from_ip: "{{ docker_network_subnet }}"
to_ip: "{{ docker_network_subnet }}"
when: ufw_enabled
tags: ['firewall', 'docker']
- name: Allow Plex Media Server through UFW (public access)
ufw:
rule: allow
port: "{{ item.port }}"
proto: "{{ item.proto }}"
comment: "{{ item.comment }}"
loop:
- { port: "32400", proto: "tcp", comment: "Plex Media Server" }
- { port: "3005", proto: "tcp", comment: "Plex Home Theater via Plex Companion" }
- { port: "8324", proto: "tcp", comment: "Plex for Roku via Plex Companion" }
- { port: "32469", proto: "tcp", comment: "Plex DLNA Server" }
- { port: "1900", proto: "udp", comment: "Plex DLNA Server" }
- { port: "32410", proto: "udp", comment: "Plex GDM network discovery" }
- { port: "32412", proto: "udp", comment: "Plex GDM network discovery" }
- { port: "32413", proto: "udp", comment: "Plex GDM network discovery" }
- { port: "32414", proto: "udp", comment: "Plex GDM network discovery" }
when: ufw_enabled and plex_public_access | default(false)
tags: ['firewall', 'plex']
- name: Enable UFW
ufw:
state: enabled
when: ufw_enabled
tags: ['firewall']
- name: Configure Docker security options
template:
src: docker-security.json.j2
dest: /etc/docker/seccomp-profile.json
mode: '0644'
notify: restart docker
tags: ['docker_security']
- name: Create AppArmor profile for Docker containers
template:
src: docker-apparmor.j2
dest: /etc/apparmor.d/docker-arrs
mode: '0644'
notify: reload apparmor
tags: ['apparmor']
- name: Set secure file permissions
file:
path: "{{ item.path }}"
mode: "{{ item.mode }}"
owner: "{{ item.owner | default('root') }}"
group: "{{ item.group | default('root') }}"
loop:
- { path: '/etc/ssh/sshd_config', mode: '0600' }
- { path: '/etc/fail2ban/jail.local', mode: '0644' }
- { path: '/etc/docker', mode: '0755' }
tags: ['file_permissions']
- name: Configure log monitoring
template:
src: rsyslog-docker.conf.j2
dest: /etc/rsyslog.d/30-docker.conf
mode: '0644'
notify: restart rsyslog
tags: ['logging']
- name: Create security audit script
template:
src: security-audit.sh.j2
dest: "{{ docker_root }}/scripts/security-audit.sh"
owner: "{{ docker_user }}"
group: "{{ docker_group }}"
mode: '0755'
tags: ['security_audit']