Initial commit
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
|
||||
# SSH port allowed through INPUT chain
|
||||
firewall_ssh_port: 22
|
||||
|
||||
# Additional host-level ports to allow through INPUT chain
|
||||
firewall_allowed_tcp_ports: []
|
||||
firewall_allowed_udp_ports: []
|
||||
|
||||
# Ports to allow through to Docker containers via DOCKER-USER chain
|
||||
docker_user_allowed_tcp_ports: []
|
||||
docker_user_allowed_udp_ports: []
|
||||
|
||||
wg_if: wg0
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
|
||||
- name: Reload iptables
|
||||
ansible.builtin.service:
|
||||
name: netfilter-persistent
|
||||
state: restarted
|
||||
|
||||
- name: Reload ip6tables
|
||||
ansible.builtin.service:
|
||||
name: netfilter-persistent
|
||||
state: restarted
|
||||
|
||||
- name: Restart wg0
|
||||
ansible.builtin.systemd:
|
||||
name: wg-quick@wg0
|
||||
state: restarted
|
||||
become: true
|
||||
|
||||
- name: Restart SSH
|
||||
ansible.builtin.service:
|
||||
name: ssh
|
||||
state: restarted
|
||||
|
||||
- name: Restart Docker
|
||||
ansible.builtin.service:
|
||||
name: docker
|
||||
state: restarted
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
- name: Ensure dependencies are installed
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- curl
|
||||
- ca-certificates
|
||||
- python3-requests
|
||||
state: present
|
||||
|
||||
- name: Create Docker GPG key directory
|
||||
ansible.builtin.file:
|
||||
path: /etc/apt/keyrings
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Download Docker's official GPG key
|
||||
ansible.builtin.get_url:
|
||||
url: https://download.docker.com/linux/ubuntu/gpg
|
||||
dest: /etc/apt/keyrings/docker.asc
|
||||
mode: "0644"
|
||||
|
||||
- name: Add Docker repository to Apt sources
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "deb [signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu {{ ansible_facts['distribution_release'] }} stable"
|
||||
state: present
|
||||
filename: docker
|
||||
|
||||
- name: Update apt cache after adding Docker repository
|
||||
ansible.builtin.apt:
|
||||
update_cache: yes
|
||||
|
||||
- name: Install Docker and Docker Compose
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- docker-ce
|
||||
- docker-ce-cli
|
||||
- containerd.io
|
||||
- docker-buildx-plugin
|
||||
- docker-compose-plugin
|
||||
state: present
|
||||
|
||||
- name: Ensure Docker service is enabled and started
|
||||
ansible.builtin.service:
|
||||
name: docker
|
||||
state: started
|
||||
enabled: yes
|
||||
|
||||
- name: Add matzman user to docker group
|
||||
ansible.builtin.user:
|
||||
name: matzman
|
||||
groups: docker
|
||||
append: yes
|
||||
@@ -0,0 +1,13 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# tasks file for ubuntu-docker-base
|
||||
|
||||
- name: Setup Ubuntu for Docker host
|
||||
ansible.builtin.import_tasks: setup-ubuntu.yml
|
||||
tags: [ setup-ubuntu ]
|
||||
become: true
|
||||
|
||||
- name: Install Docker on Ubuntu
|
||||
ansible.builtin.import_tasks: install-ubuntu-docker.yml
|
||||
tags: [ install-ubuntu-docker-base ]
|
||||
become: true
|
||||
@@ -0,0 +1,209 @@
|
||||
---
|
||||
- name: Show host IP
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ ansible_facts['default_ipv4'] }}"
|
||||
|
||||
|
||||
# --- Users & group ---
|
||||
|
||||
- name: Add group matzman
|
||||
ansible.builtin.group:
|
||||
name: matzman
|
||||
state: present
|
||||
gid: 1000
|
||||
|
||||
- name: Add user matzman
|
||||
ansible.builtin.user:
|
||||
name: matzman
|
||||
uid: 1000
|
||||
group: matzman
|
||||
create_home: yes
|
||||
|
||||
|
||||
# --- Install required packages ---
|
||||
|
||||
- name: Update apt cache
|
||||
ansible.builtin.apt:
|
||||
update_cache: yes
|
||||
become: true
|
||||
|
||||
- name: Upgrade all packages
|
||||
ansible.builtin.apt:
|
||||
upgrade: dist
|
||||
update_cache: yes
|
||||
|
||||
- name: Check if reboot is required
|
||||
ansible.builtin.stat:
|
||||
path: /var/run/reboot-required
|
||||
register: reboot_required
|
||||
|
||||
- name: Reboot if required
|
||||
ansible.builtin.reboot:
|
||||
reboot_timeout: 300
|
||||
when: reboot_required.stat.exists
|
||||
|
||||
- name: Install custom packages
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
# Required by an ansible task later
|
||||
- python3-requests
|
||||
state: present
|
||||
|
||||
|
||||
# --- Unattended upgrades ---
|
||||
|
||||
- name: Install unattended-upgrades
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- unattended-upgrades
|
||||
- apt-listchanges
|
||||
state: present
|
||||
|
||||
- name: Enable automatic security upgrades
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/apt/apt.conf.d/20auto-upgrades
|
||||
content: |
|
||||
APT::Periodic::Update-Package-Lists "1";
|
||||
APT::Periodic::Unattended-Upgrade "1";
|
||||
mode: "0644"
|
||||
|
||||
|
||||
# --- SSH setup ---
|
||||
|
||||
- name: Set authorized key for matzman
|
||||
ansible.posix.authorized_key:
|
||||
user: matzman
|
||||
state: present
|
||||
key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBi8TS/s2X7W7gb+rGm7A2PG9hRDLa3kYdNM9hLNY0w matzman+2025@matzman.net"
|
||||
|
||||
- name: Set authorized key for root
|
||||
ansible.posix.authorized_key:
|
||||
user: root
|
||||
state: present
|
||||
key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBi8TS/s2X7W7gb+rGm7A2PG9hRDLa3kYdNM9hLNY0w matzman+2025@matzman.net"
|
||||
|
||||
|
||||
# --- SSH hardening ---
|
||||
|
||||
- name: Disable SSH password authentication
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/ssh/sshd_config
|
||||
regexp: '^#?PasswordAuthentication'
|
||||
line: 'PasswordAuthentication no'
|
||||
notify: Restart SSH
|
||||
|
||||
#- name: Disable SSH root login
|
||||
# ansible.builtin.lineinfile:
|
||||
# path: /etc/ssh/sshd_config
|
||||
# regexp: '^#?PermitRootLogin'
|
||||
# line: 'PermitRootLogin no'
|
||||
# notify: Restart SSH
|
||||
|
||||
# --- fail2ban ---
|
||||
|
||||
- name: Install fail2ban
|
||||
ansible.builtin.package:
|
||||
name: fail2ban
|
||||
state: present
|
||||
|
||||
- name: Enable and start fail2ban
|
||||
ansible.builtin.service:
|
||||
name: fail2ban
|
||||
state: started
|
||||
enabled: yes
|
||||
|
||||
|
||||
# --- Wireguard ---
|
||||
|
||||
- name: Install wireguard packages
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- wireguard-tools
|
||||
state: present
|
||||
|
||||
- name: Ensure /etc/wireguard directory exists
|
||||
ansible.builtin.file:
|
||||
path: /etc/wireguard
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0700"
|
||||
tags: wireguard
|
||||
|
||||
- name: "Deploy {{ wg_if }} config"
|
||||
ansible.builtin.template:
|
||||
src: "{{ wg_if }}.conf.j2"
|
||||
dest: "/etc/wireguard/{{ wg_if }}.conf"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0600"
|
||||
notify: Restart wg0
|
||||
tags: wireguard
|
||||
|
||||
- name: "Enable and start wg-quick@{{ wg_if }}"
|
||||
ansible.builtin.systemd:
|
||||
name: "wg-quick@{{ wg_if }}"
|
||||
enabled: yes
|
||||
state: started
|
||||
tags: wireguard
|
||||
|
||||
|
||||
# --- Firewall ---
|
||||
|
||||
- name: Install iptables-persistent
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- iptables-persistent
|
||||
- netfilter-persistent
|
||||
state: present
|
||||
|
||||
- name: Deploy iptables rules (IPv4)
|
||||
ansible.builtin.template:
|
||||
src: rules.v4.j2
|
||||
dest: /etc/iptables/rules.v4
|
||||
mode: "0640"
|
||||
notify:
|
||||
- Reload iptables
|
||||
- Restart Docker
|
||||
|
||||
- name: Deploy iptables rules (IPv6)
|
||||
ansible.builtin.template:
|
||||
src: rules.v6.j2
|
||||
dest: /etc/iptables/rules.v6
|
||||
mode: "0640"
|
||||
notify:
|
||||
- Reload ip6tables
|
||||
- Restart Docker
|
||||
|
||||
# --- sysctl hardening ---
|
||||
|
||||
- name: Configure sysctl security settings
|
||||
ansible.posix.sysctl:
|
||||
name: "{{ item.name }}"
|
||||
value: "{{ item.value }}"
|
||||
state: present
|
||||
reload: yes
|
||||
loop:
|
||||
- { name: 'net.ipv4.conf.all.rp_filter', value: '1' }
|
||||
- { name: 'net.ipv4.conf.default.rp_filter', value: '1' }
|
||||
- { name: 'net.ipv4.conf.all.accept_redirects', value: '0' }
|
||||
- { name: 'net.ipv4.conf.default.accept_redirects', value: '0' }
|
||||
- { name: 'net.ipv4.conf.all.send_redirects', value: '0' }
|
||||
- { name: 'net.ipv4.conf.default.send_redirects', value: '0' }
|
||||
|
||||
|
||||
# --- Audit logging ---
|
||||
|
||||
- name: Install auditd
|
||||
ansible.builtin.package:
|
||||
name: auditd
|
||||
state: present
|
||||
|
||||
- name: Enable and start auditd
|
||||
ansible.builtin.service:
|
||||
name: auditd
|
||||
state: started
|
||||
enabled: yes
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# Managed by Ansible — do not edit manually
|
||||
|
||||
*filter
|
||||
|
||||
:INPUT DROP [0:0]
|
||||
:FORWARD ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
:DOCKER-USER - [0:0]
|
||||
|
||||
|
||||
# --- INPUT ---
|
||||
|
||||
# Allow loopback
|
||||
-A INPUT -i lo -j ACCEPT
|
||||
|
||||
# Allow established/related connections
|
||||
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
||||
|
||||
# Allow SSH
|
||||
-A INPUT -p tcp --dport {{ firewall_ssh_port }} -j ACCEPT
|
||||
|
||||
# Allow additional host ports
|
||||
{% for port in firewall_allowed_tcp_ports %}
|
||||
-A INPUT -p tcp --dport {{ port }} -j ACCEPT
|
||||
{% endfor %}
|
||||
{% for port in firewall_allowed_udp_ports %}
|
||||
-A INPUT -p udp --dport {{ port }} -j ACCEPT
|
||||
{% endfor %}
|
||||
|
||||
|
||||
# --- DOCKER-USER ---
|
||||
|
||||
# Allow loopback
|
||||
-A DOCKER-USER -i lo -j RETURN
|
||||
|
||||
# Allow outgoing from Docker IP range
|
||||
-A DOCKER-USER -s 172.16.0.0/12 -j RETURN
|
||||
|
||||
# Whitelist specific TCP ports to containers
|
||||
{% for port in docker_user_allowed_tcp_ports %}
|
||||
-A DOCKER-USER -p tcp --dport {{ port }} -j RETURN
|
||||
{% endfor %}
|
||||
|
||||
# Whitelist specific UDP ports to containers
|
||||
{% for port in docker_user_allowed_udp_ports %}
|
||||
-A DOCKER-USER -p udp --dport {{ port }} -j RETURN
|
||||
{% endfor %}
|
||||
|
||||
# Allow all already established connections
|
||||
-A DOCKER-USER -m conntrack --ctstate RELATED,ESTABLISHED -j RETURN
|
||||
|
||||
# Drop everything else to containers
|
||||
-A DOCKER-USER -j DROP
|
||||
|
||||
COMMIT
|
||||
@@ -0,0 +1,55 @@
|
||||
# Managed by Ansible — do not edit manually
|
||||
|
||||
*filter
|
||||
|
||||
:INPUT DROP [0:0]
|
||||
:FORWARD ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
:DOCKER-USER - [0:0]
|
||||
|
||||
|
||||
# --- INPUT ---
|
||||
|
||||
# Allow loopback
|
||||
-A INPUT -i lo -j ACCEPT
|
||||
|
||||
# Allow established/related connections
|
||||
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
||||
|
||||
# Allow SSH
|
||||
-A INPUT -p tcp --dport {{ firewall_ssh_port }} -j ACCEPT
|
||||
|
||||
# Allow additional host ports
|
||||
{% for port in firewall_allowed_tcp_ports %}
|
||||
-A INPUT -p tcp --dport {{ port }} -j ACCEPT
|
||||
{% endfor %}
|
||||
{% for port in firewall_allowed_udp_ports %}
|
||||
-A INPUT -p udp --dport {{ port }} -j ACCEPT
|
||||
{% endfor %}
|
||||
|
||||
|
||||
# --- DOCKER-USER ---
|
||||
|
||||
# Allow loopback
|
||||
-A DOCKER-USER -i lo -j RETURN
|
||||
|
||||
# Allow outgoing from Docker IP range
|
||||
-A DOCKER-USER -s 172.16.0.0/12 -j RETURN
|
||||
|
||||
# Whitelist specific TCP ports to containers
|
||||
{% for port in docker_user_allowed_tcp_ports %}
|
||||
-A DOCKER-USER -p tcp --dport {{ port }} -j RETURN
|
||||
{% endfor %}
|
||||
|
||||
# Whitelist specific UDP ports to containers
|
||||
{% for port in docker_user_allowed_udp_ports %}
|
||||
-A DOCKER-USER -p udp --dport {{ port }} -j RETURN
|
||||
{% endfor %}
|
||||
|
||||
# Allow all already established connections
|
||||
-A DOCKER-USER -m conntrack --ctstate RELATED,ESTABLISHED -j RETURN
|
||||
|
||||
# Drop everything else to containers
|
||||
-A DOCKER-USER -j DROP
|
||||
|
||||
COMMIT
|
||||
@@ -0,0 +1,23 @@
|
||||
# Managed by Ansible — do not edit manually
|
||||
|
||||
[Interface]
|
||||
Address = {{ wg_nets[wg_if].hosts[inventory_hostname].address }}
|
||||
ListenPort = {{ wg_nets[wg_if].hosts[inventory_hostname].port }}
|
||||
PrivateKey = {{ wg_nets[wg_if].secrect[inventory_hostname].private_key }}
|
||||
{% if wg_nets[wg_if].hosts[inventory_hostname].dnsserver is defined %}
|
||||
DNS = {{ wg_nets[wg_if].hosts[inventory_hostname].dnsserver }}
|
||||
{% endif %}
|
||||
|
||||
{% for peer, data in wg_nets[wg_if].hosts[inventory_hostname].peers.items() %}
|
||||
# {{ peer }}
|
||||
[Peer]
|
||||
PublicKey = {{ wg_nets[wg_if].hosts[peer].public_key }}
|
||||
AllowedIPs = {{ data.allowed_ips }}
|
||||
{% if data.preshared_key is defined %}
|
||||
PresharedKey = {{ data.preshared_key }}
|
||||
{% endif %}
|
||||
{% if data.keepalive is defined %}
|
||||
PersistentKeepalive = {{ data.keepalive }}
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
Reference in New Issue
Block a user