Initial commit

This commit is contained in:
2026-03-24 08:19:29 +01:00
commit 2b1ca2d5be
95 changed files with 1993 additions and 0 deletions
@@ -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
+13
View File
@@ -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 %}