firewall role: add UFW mail server firewall configuration

- Add comprehensive UFW firewall rules for mail server
- Opens essential ports: SSH (22), HTTPS (443), HTTP (80)
- Opens mail ports: SMTP (25), Submission (587), SMTPS (465), IMAPS (993)
- Blocks plaintext ports: POP3 (110), IMAP (143), POP3S (995)
- Allows LMTP (24) from private networks only
- Provides verification output with visual status display
- Default deny all incoming, allow all outgoing
- Security warnings included in output

Features:
- Idempotent UFW configuration
- Configurable via variables
- Clean visual output of all rules
- SSH added first to prevent lockout
- Documentation in defaults/main.yml

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Haitao Pan 2025-11-10 20:48:31 +08:00
parent be98544f02
commit 136b205e01
3 changed files with 131 additions and 0 deletions

View File

@ -0,0 +1,31 @@
---
# Mail server firewall configuration
# SSH port (always allow - most important!)
# Note: SSH is allowed FIRST to ensure you don't lock yourself out
# This should typically be customized to your actual SSH port (e.g., 2222)
ssh_port: 22
# Private networks allowed to access LMTP (port 24)
lmtp_private_networks:
- 127.0.0.1
- 10.0.0.0/8
# Essential ports to open (SSH first!)
essential_ports:
- { port: "{{ ssh_port }}", protocol: 'tcp', comment: 'SSH (Secure Shell) - Critical!' }
- { port: 443, protocol: 'tcp', comment: 'HTTPS - Web SSL' }
- { port: 80, protocol: 'tcp', comment: 'HTTP - Web (optional)' }
# Mail ports to open
mail_ports:
- { port: 25, protocol: 'tcp', comment: 'SMTP MX inbound' }
- { port: 587, protocol: 'tcp', comment: 'SMTP Submission (AUTH)' }
- { port: 465, protocol: 'tcp', comment: 'SMTPS (optional)' }
- { port: 993, protocol: 'tcp', comment: 'IMAPS SSL' }
# Plaintext ports to deny
denied_ports:
- { port: 110, protocol: 'tcp', comment: 'Deny POP3 plaintext' }
- { port: 143, protocol: 'tcp', comment: 'Deny IMAP plaintext' }
- { port: 995, protocol: 'tcp', comment: 'Deny POP3S plaintext' }

View File

@ -0,0 +1,2 @@
---
# Firewall handlers (reserved for future use)

View File

@ -0,0 +1,98 @@
---
- name: Install UFW
apt:
name: ufw
state: present
- name: Set default policies
ufw:
policy: "{{ item.policy }}"
direction: "{{ item.direction }}"
loop:
- { policy: 'deny', direction: 'incoming' }
- { policy: 'allow', direction: 'outgoing' }
- name: Allow essential ports (SSH first!)
ufw:
port: "{{ item.port }}"
protocol: "{{ item.protocol }}"
rule: allow
comment: "{{ item.comment }}"
loop: "{{ essential_ports }}"
- name: Allow necessary mail ports
ufw:
port: "{{ item.port }}"
protocol: "{{ item.protocol }}"
rule: allow
comment: "{{ item.comment }}"
loop: "{{ mail_ports }}"
- name: Allow LMTP from private networks
ufw:
port: 24
protocol: tcp
rule: allow
from_ip: "{{ item }}"
comment: 'LMTP private'
loop: "{{ lmtp_private_networks }}"
- name: Deny plaintext ports
ufw:
port: "{{ item.port }}"
protocol: "{{ item.protocol }}"
rule: deny
comment: "{{ item.comment }}"
loop: "{{ denied_ports }}"
- name: Enable UFW
ufw:
state: enabled
- name: Get UFW numbered status
command: ufw status numbered
register: ufw_numbered
changed_when: false
- name: Get UFW status verbose
command: ufw status verbose
register: ufw_status
changed_when: false
- name: Display UFW status
debug:
msg: |
🔥 UFW Firewall Status
====================
{{ ufw_status.stdout }}
- name: Display configured mail rules
debug:
msg: |
🔥 Mail Server Firewall Rules:
=============================
ESSENTIAL PORTS (Open - Applied First!):
{% for port in essential_ports %}
✅ {{ port.port }}/{{ port.protocol }} - {{ port.comment }}
{% endfor %}
MAIL PORTS (Open):
{% for port in mail_ports %}
✅ {{ port.port }}/{{ port.protocol }} - {{ port.comment }}
{% endfor %}
DENIED PORTS (Blocked):
{% for port in denied_ports %}
❌ {{ port.port }}/{{ port.protocol }} - {{ port.comment }}
{% endfor %}
LMTP ACCESS (Private Networks):
{% for network in lmtp_private_networks %}
✅ From {{ network }} to port 24/tcp - Local mail delivery
{% endfor %}
⚠️ SECURITY NOTES:
- SSH port {{ ssh_port }} is open - ensure you use key-based authentication
- Default policy: deny all incoming, allow all outgoing
- Only open ports that are absolutely necessary