CIS + inital
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
---
|
||||
# Secure Firewall Role - Default Variables
|
||||
|
||||
# Firewall backend (ufw or iptables)
|
||||
firewall_backend: ufw
|
||||
|
||||
# Default policies
|
||||
firewall_default_input_policy: deny
|
||||
firewall_default_output_policy: allow
|
||||
firewall_default_forward_policy: deny
|
||||
|
||||
# VPN-only mode: Only allow management access from specified networks/IPs
|
||||
vpn_only_mode: true
|
||||
|
||||
# Management access sources
|
||||
# Can be:
|
||||
# - VPN network CIDR (e.g., "10.100.0.0/24" for admin VPN)
|
||||
# - Single IP (e.g., "185.112.147.205" for ValleyForge public IP)
|
||||
# - List of both
|
||||
management_allowed_sources: []
|
||||
# Example:
|
||||
# management_allowed_sources:
|
||||
# - "10.100.0.0/24" # Admin VPN network
|
||||
# - "185.112.147.205" # ValleyForge public IP
|
||||
|
||||
# Management ports (restricted to management_allowed_sources if vpn_only_mode is true)
|
||||
management_ports:
|
||||
- port: 22
|
||||
proto: tcp
|
||||
comment: "SSH"
|
||||
- port: 80
|
||||
proto: tcp
|
||||
comment: "HTTP"
|
||||
- port: 443
|
||||
proto: tcp
|
||||
comment: "HTTPS"
|
||||
- port: 8080
|
||||
proto: tcp
|
||||
comment: "Outline Manager"
|
||||
- port: 8065
|
||||
proto: tcp
|
||||
comment: "Mattermost"
|
||||
- port: 8443
|
||||
proto: tcp
|
||||
comment: "Nextcloud HTTPS"
|
||||
|
||||
# Public ports (always accessible from internet)
|
||||
public_ports:
|
||||
- port: 51820
|
||||
proto: udp
|
||||
comment: "WireGuard VPN"
|
||||
|
||||
# Rate limiting for SSH
|
||||
ssh_rate_limit: true
|
||||
ssh_rate_limit_burst: 10
|
||||
ssh_rate_limit_rate: "30/minute"
|
||||
|
||||
# Logging
|
||||
firewall_logging: "low" # off, low, medium, high, full
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
# Secure Firewall Role - Handlers
|
||||
|
||||
- name: reload ufw
|
||||
community.general.ufw:
|
||||
state: reloaded
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
galaxy_info:
|
||||
role_name: secure_firewall
|
||||
author: Security Infrastructure Team
|
||||
description: Secure firewall configuration with VPN-only access mode
|
||||
company: Your Organization
|
||||
license: MIT
|
||||
min_ansible_version: "2.15"
|
||||
platforms:
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- noble # 24.04
|
||||
- jammy # 22.04
|
||||
galaxy_tags:
|
||||
- firewall
|
||||
- ufw
|
||||
- security
|
||||
- vpn
|
||||
|
||||
dependencies:
|
||||
- role: wireguard_server
|
||||
|
||||
collections:
|
||||
- community.general
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
# Secure Firewall Role - Main Tasks
|
||||
|
||||
- name: Include UFW firewall tasks
|
||||
ansible.builtin.include_tasks: ufw.yml
|
||||
when: firewall_backend == "ufw"
|
||||
|
||||
- name: Include VPN-only access tasks
|
||||
ansible.builtin.include_tasks: vpn_only.yml
|
||||
when: vpn_only_mode | bool
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
# UFW Firewall Configuration Tasks
|
||||
|
||||
- name: Ensure UFW is installed
|
||||
ansible.builtin.apt:
|
||||
name: ufw
|
||||
state: present
|
||||
|
||||
- name: Reset UFW to default state
|
||||
community.general.ufw:
|
||||
state: reset
|
||||
when: firewall_reset | default(false) | bool
|
||||
|
||||
- name: Set UFW default policies
|
||||
community.general.ufw:
|
||||
direction: "{{ item.direction }}"
|
||||
policy: "{{ item.policy }}"
|
||||
loop:
|
||||
- { direction: 'incoming', policy: "{{ firewall_default_input_policy }}" }
|
||||
- { direction: 'outgoing', policy: "{{ firewall_default_output_policy }}" }
|
||||
- { direction: 'routed', policy: "{{ firewall_default_forward_policy }}" }
|
||||
|
||||
- name: Allow public ports (unrestricted)
|
||||
community.general.ufw:
|
||||
rule: allow
|
||||
port: "{{ item.port }}"
|
||||
proto: "{{ item.proto }}"
|
||||
comment: "{{ item.comment }}"
|
||||
loop: "{{ public_ports }}"
|
||||
|
||||
- name: Configure UFW logging
|
||||
community.general.ufw:
|
||||
logging: "{{ firewall_logging }}"
|
||||
|
||||
- name: Enable UFW
|
||||
community.general.ufw:
|
||||
state: enabled
|
||||
|
||||
- name: Display firewall status
|
||||
ansible.builtin.command: ufw status verbose
|
||||
register: ufw_status
|
||||
changed_when: false
|
||||
|
||||
- name: Show firewall status
|
||||
ansible.builtin.debug:
|
||||
var: ufw_status.stdout_lines
|
||||
@@ -0,0 +1,83 @@
|
||||
---
|
||||
# VPN-Only Access Configuration Tasks
|
||||
|
||||
- name: Validate management_allowed_sources is defined
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- management_allowed_sources is defined
|
||||
- management_allowed_sources | length > 0
|
||||
fail_msg: "management_allowed_sources must be defined and non-empty when vpn_only_mode is true"
|
||||
success_msg: "Management access sources configured: {{ management_allowed_sources | join(', ') }}"
|
||||
|
||||
- name: Restrict management ports to allowed sources only
|
||||
community.general.ufw:
|
||||
rule: allow
|
||||
port: "{{ item.0.port }}"
|
||||
proto: "{{ item.0.proto }}"
|
||||
from_ip: "{{ item.1 }}"
|
||||
comment: "{{ item.0.comment }} (from {{ item.1 }})"
|
||||
loop: "{{ management_ports | product(management_allowed_sources) | list }}"
|
||||
loop_control:
|
||||
label: "{{ item.0.comment }} port {{ item.0.port }} from {{ item.1 }}"
|
||||
|
||||
- name: Apply SSH rate limiting for each allowed source
|
||||
community.general.ufw:
|
||||
rule: limit
|
||||
port: "22"
|
||||
proto: tcp
|
||||
from_ip: "{{ item }}"
|
||||
loop: "{{ management_allowed_sources }}"
|
||||
when: ssh_rate_limit | bool
|
||||
|
||||
- name: Deny management ports from all other sources
|
||||
community.general.ufw:
|
||||
rule: deny
|
||||
port: "{{ item.port }}"
|
||||
proto: "{{ item.proto }}"
|
||||
comment: "Block {{ item.comment }} from public"
|
||||
loop: "{{ management_ports }}"
|
||||
|
||||
- name: Create VPN-only access summary
|
||||
ansible.builtin.copy:
|
||||
dest: /root/firewall-config.txt
|
||||
content: |
|
||||
# Firewall Configuration Summary
|
||||
|
||||
## VPN-Only Mode: ENABLED
|
||||
|
||||
## Management Access Allowed From:
|
||||
{% for source in management_allowed_sources %}
|
||||
- {{ source }}
|
||||
{% endfor %}
|
||||
|
||||
## Management Ports (Restricted Access):
|
||||
{% for port in management_ports %}
|
||||
- {{ port.port }}/{{ port.proto }} - {{ port.comment }}
|
||||
{% endfor %}
|
||||
|
||||
## Public Ports (Unrestricted):
|
||||
{% for port in public_ports %}
|
||||
- {{ port.port }}/{{ port.proto }} - {{ port.comment }}
|
||||
{% endfor %}
|
||||
|
||||
## Security Notes:
|
||||
- Management access ONLY from: {{ management_allowed_sources | join(', ') }}
|
||||
- SSH is rate-limited to prevent brute force
|
||||
- Default policy: DENY all incoming (except allowed above)
|
||||
- Logging level: {{ firewall_logging }}
|
||||
|
||||
## To view firewall rules:
|
||||
sudo ufw status verbose
|
||||
|
||||
## To modify rules:
|
||||
Edit inventory variables and re-run playbook
|
||||
mode: '0600'
|
||||
|
||||
- name: Display VPN-only configuration
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "VPN-Only Mode: ENABLED"
|
||||
- "Management access allowed from: {{ management_allowed_sources | join(', ') }}"
|
||||
- "Management ports are ONLY accessible from allowed sources"
|
||||
- "Public ports remain accessible from internet"
|
||||
- "Configuration saved to /root/firewall-config.txt"
|
||||
Reference in New Issue
Block a user