nft role + disable iptables when nft enabled

This commit is contained in:
Mark Janssen 2024-07-24 21:32:13 +02:00
parent a74dba4557
commit 848917a72c
Signed by: foobar
GPG key ID: D8674D8FC4F69BD2
17 changed files with 348 additions and 57 deletions

View file

@ -5,6 +5,7 @@
gather_facts: true
roles:
- { role: "common", tags: [ "common" ] }
- { role: "nft", tags: [ "nft" ] }
- hosts: bank
roles:
@ -47,6 +48,7 @@
- hosts: pad
roles:
- { role: "nft", tags: [ "nft" ] }
- { role: "acme", tags: [ "acme" ] }
- { role: "nginx", tags: [ "nginx" ] }
- { role: "etherpad", tags: [ "etherpad" ] }

View file

@ -5,26 +5,21 @@ ansible_python_interpreter: auto_silent
notify_email: bestuur@bitlair.nl
acme_bootstrap_certs: no
trusted_ranges:
# localhost
- { v: ipv4, cidr: "127.0.0.1/8" }
- { v: ipv6, cidr: "::1" }
# rf1928
- { v: ipv4, cidr: "10.0.0.0/8" }
- { v: ipv4, cidr: "172.16.0.0/12" }
- { v: ipv4, cidr: "192.168.0.0/16" }
# v6 local
- { v: ipv6, cidr: "fe80::/10" }
# vihamij
- { v: ipv4, cidr: "45.88.49.140" }
# eventinfra
- { v: ipv4, cidr: "204.2.64.0/20" }
# bitlair
- { v: ipv4, cidr: "100.64.0.0/10" }
- { v: ipv4, cidr: "185.205.52.194/32" }
- { v: ipv6, cidr: "2a02:166b:92::/48" }
# foobar
- { v: ipv4, cidr: "31.187.251.213/32" }
- { v: ipv6, cidr: "2a0e:5700:4:2::/64" }
- { v: ipv4, cidr: "127.0.0.1/8", comment: "localhost" }
- { v: ipv4, cidr: "10.0.0.0/8", comment: "rfc1918" }
- { v: ipv4, cidr: "172.16.0.0/12", comment: "rfc1918" }
- { v: ipv4, cidr: "192.168.0.0/16", comment: "rfc1918" }
- { v: ipv4, cidr: "45.88.49.140", comment: "vihamij" }
- { v: ipv4, cidr: "204.2.64.0/20", comment: "eventinfra" }
- { v: ipv4, cidr: "100.64.0.0/10", comment: "bitlair" }
- { v: ipv4, cidr: "185.205.52.194/32", comment: "bitlair" }
- { v: ipv4, cidr: "31.187.251.213/32", comment: "foobar" }
# - { v: ipv6, cidr: "::/0", comment: "ipv6 localhost" }
# - { v: ipv6, cidr: "fe80::/10", comment: "ipv6 link-local" }
# - { v: ipv6, cidr: "2a02:166b:92::/48", comment: "bitlair" } # /48's kunnen niet in de ipset
- { v: ipv6, cidr: "2001:678:814:68::/64", comment: "bitlair wifi" }
- { v: ipv6, cidr: "2a05:2d01:0:4042::/64", comment: "bitlair servers" }
- { v: ipv6, cidr: "2a0e:5700:4:2::/64", comment: "foobar" }
root_access:
- ak

View file

@ -6,6 +6,11 @@ git_server_domain: git.bitlair.nl
git_server_title: Gitlair
git_server_bootstrap_cert: no
nft: true
group_nft_input:
- "# Allow web-traffic from world"
- "tcp dport { http, https } accept"
nginx_client_max_body_size: 4G
nginx_sites:

View file

@ -5,3 +5,8 @@ etherpad_domain: pad.bitlair.nl
nginx_sites:
- server_name: "pad.bitlair.nl"
localproxy: "9001"
nft: true
group_nft_input:
- "# Allow web-traffic from world"
- "tcp dport { http, https } accept"

View file

@ -6,6 +6,7 @@
- [ pad.bitlair.nl ]
roles:
- { role: "common", tags: [ "common" ] }
- { role: "nft", tags: [ "nft" ] }
- { role: "acme", tags: [ "acme" ] }
- { role: "nginx", tags: [ "nginx" ] }
- { role: "etherpad", tags: [ "etherpad" ] }

View file

@ -29,3 +29,4 @@
with_items:
- { c: iptables, ip: v4 }
- { c: ip6tables, ip: v6 }
when: not nft | bool

View file

@ -66,8 +66,6 @@
- etckeeper
- git
- htop
- iptables
- iptables-persistent
- jq
- net-tools
- netcat-openbsd
@ -133,6 +131,7 @@
- ipv4
- ipv6
notify: persist iptables
when: not nft | bool
- name: Allow ICMP
ansible.builtin.iptables:
@ -144,6 +143,7 @@
- { ip: ipv4, proto: icmp }
- { ip: ipv6, proto: ipv6-icmp }
notify: persist iptables
when: not nft | bool
- name: Allow related and established connections
ansible.builtin.iptables:
@ -155,6 +155,7 @@
- ipv4
- ipv6
notify: persist iptables
when: not nft | bool
- name: Allow local connections
ansible.builtin.iptables:
@ -164,6 +165,7 @@
ip_version: "{{ item.v }}"
with_items: "{{ trusted_ranges }}"
notify: persist iptables
when: not nft | bool
- name: Deny inbound connections
ansible.builtin.iptables:
@ -174,3 +176,4 @@
- ipv4
- ipv6
notify: persist iptables
when: not nft | bool

View file

@ -139,3 +139,4 @@
- { ip: ipv6, port: 80 }
- { ip: ipv6, port: 443 }
notify: persist iptables
when: not nft | bool

View file

@ -98,6 +98,7 @@
- { ip: ipv6, port: 22 }
- { ip: ipv6, port: 443 }
notify: persist iptables
when: not nft | bool
- ansible.builtin.debug:
msg: If Forgejo has not been setup yet, please do so manually.

View file

@ -1,42 +1,41 @@
---
- name: monitoring
tags: monitoring
block:
- name: Install nginx site
ansible.builtin.template:
src: nginx-site.conf
dest: /etc/nginx/sites-available/monitoring
owner: root
group: root
mode: 0644
notify: reload nginx
- name: Enable nginx site
ansible.builtin.file:
src: /etc/nginx/sites-available/monitoring
dest: /etc/nginx/sites-enabled/monitoring
state: link
notify: reload nginx
- name: Install nginx site
ansible.builtin.template:
src: nginx-site.conf
dest: /etc/nginx/sites-available/monitoring
owner: root
group: root
mode: 0644
notify: reload nginx
- name: Start nginx
ansible.builtin.systemd:
name: nginx
state: started
enabled: yes
- name: Enable nginx site
ansible.builtin.file:
src: /etc/nginx/sites-available/monitoring
dest: /etc/nginx/sites-enabled/monitoring
state: link
notify: reload nginx
- name: Allow HTTP/HTTPS
ansible.builtin.iptables:
chain: INPUT
protocol: tcp
destination_port: "{{ item.port }}"
ctstate: NEW
jump: ACCEPT
ip_version: "{{ item.ip }}"
action: insert
with_items:
- { ip: ipv6, port: 80 }
- { ip: ipv6, port: 443 }
notify: persist iptables
- name: Start nginx
ansible.builtin.systemd:
name: nginx
state: started
enabled: yes
- name: Allow HTTP/HTTPS
ansible.builtin.iptables:
chain: INPUT
protocol: tcp
destination_port: "{{ item.port }}"
ctstate: NEW
jump: ACCEPT
ip_version: "{{ item.ip }}"
action: insert
with_items:
- { ip: ipv6, port: 80 }
- { ip: ipv6, port: 443 }
notify: persist iptables
when: not nft | bool
- name: mqtt_exporter
tags: mqtt_exporter

View file

@ -0,0 +1,33 @@
---
nft: false # totdat alles om is
nft_main_config: "/etc/nftables.conf"
# Default policies per chain ( drop / reject / accept )
nft_policy_input: "drop"
nft_policy_forward: "accept"
nft_policy_output: "accept"
# Same for nat traffic
nft_policy_prerouting: "accept"
nft_policy_postrouting: "accept"
# Host/Port allows
nft_group_rules: []
# And per host/group additions to rules:
group_nft_input: []
group_nft_forward: []
group_nft_output: []
host_nft_input: []
host_nft_forward: []
host_nft_output: []
group_nft_postrouting: []
host_nft_postrouting: []
group_nft_prerouting: []
host_nft_prerouting: []
nft_defines: []
nft_defines_group: []

View file

@ -0,0 +1,13 @@
---
- name: Reload nftables
ansible.builtin.systemd:
name: "nftables"
state: reloaded
enabled: true
tags:
- nft
- nftservice
when:
- nft|bool

47
roles/nft/tasks/main.yaml Normal file
View file

@ -0,0 +1,47 @@
---
- name: Install nftables related packages
ansible.builtin.apt:
state: present
pkg:
- nftables
- net-tools
- ipset
- name: Template nftables.conf
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: "root"
group: "root"
mode: "0700"
validate: "{{ item.validate | default() }}"
with_items:
- { src: "nftables.conf.j2", dest: "{{ nft_main_config }}",
backup: "yes", validate: "/usr/sbin/nft -c -f %s" }
tags:
- nft
- nftconfig
when:
- nft | bool
notify:
- Reload nftables
- name: Cleanup netfilter packages
ansible.builtin.apt:
state: absent
pkg:
- netfilter-persistent
when:
- nft | bool
- name: Cleanup iptables stuff
ansible.builtin.file:
state: absent
path: "{{ item }}"
with_items:
- "/etc/iptables/rules/v4"
- "/etc/iptables/rules/v6"
- "/etc/iptables"
when:
- nft | bool

View file

@ -0,0 +1,182 @@
#!/usr/sbin/nft -f
# {{ ansible_managed }}
flush ruleset
table inet filter {
# Named sets
set trusted4 {
type ipv4_addr
flags interval
elements = {
{% for ip in trusted_ranges %}
{% if ip.v == 'ipv4' %}
{{ ip.cidr }}, # {{ ip.comment | default('') }}
{% endif %}
{% endfor %}
}
}
set trusted6 {
type ipv6_addr
flags interval
elements = {
{% for ip in trusted_ranges %}
{% if ip.v == 'ipv6' %}
{{ ip.cidr }}, # {{ ip.comment | default('') }}
{% endif %}
{% endfor %}
}
}
# Firewall chains
chain input {
type filter hook input priority 0;
policy {{ nft_policy_input }};
# Established connections
ct state established,related accept
ct state invalid counter drop comment "drop invalid packets"
# Limit icmp echo/reply
ip protocol icmp icmp type echo-request limit rate over 10/second burst 50 packets log prefix "high icmp-echo rate: " drop
# icmp6 from trusted ranges
ip6 nexthdr icmpv6 icmpv6 type echo-request accept
# icmpv6 from the rest of the world
ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate over 10/second burst 50 packets log prefix "high icmp6-echo rate: " drop
# Loopback traffic
iifname lo accept
# icmp
ip protocol icmp icmp type {
destination-unreachable,
echo-reply,
echo-request,
source-quench,
time-exceeded
} accept
# icmp6
ip6 nexthdr icmpv6 icmpv6 type {
destination-unreachable,
echo-reply,
echo-request,
nd-neighbor-solicit,
nd-router-advert,
nd-neighbor-advert,
packet-too-big,
parameter-problem,
time-exceeded
} accept
# Open ssh only for trusted machines
ip saddr @trusted4 tcp dport { ssh } accept
ip6 saddr @trusted6 tcp dport { ssh } accept
# Rules based on group-vars
{% for custom in nft_group_rules %}
{% if custom.comment is defined %}
# {{ custom.comment|default('') }}
{% endif %}
ip saddr { {{ custom.from | join(', ') }} } {{ custom.proto | default('tcp') }} dport { {{ custom.port }} } {{ custom.policy | default('accept') }}
{% endfor %}
{% for rule in group_nft_input %}
# Group input rules
{{ rule }}
{% endfor %}
{% for rule in host_nft_input %}
# Host input rules
{{ rule }}
{% endfor %}
}
chain forward {
type filter hook forward priority 0;
policy {{ nft_policy_forward }};
ct state established,related accept
{% for rule in group_nft_forward %}
# Group forward rules
{{ rule }}
{% endfor %}
{% for rule in host_nft_forward %}
# Host forward rules
{{ rule }}
{% endfor %}
counter comment "count dropped incoming packets"
}
chain output {
type filter hook output priority 0;
policy {{ nft_policy_output }};
# Established connections
ct state established,related accept
ct state invalid counter drop comment "drop invalid packets"
# icmp
ip protocol icmp icmp type {
destination-unreachable,
echo-reply,
echo-request,
source-quench,
time-exceeded
} accept
# icmp6
ip6 nexthdr icmpv6 icmpv6 type {
destination-unreachable,
echo-reply,
echo-request,
nd-neighbor-solicit,
nd-router-advert,
nd-neighbor-advert,
packet-too-big,
parameter-problem,
time-exceeded
} accept
{% for rule in group_nft_output %}
# Group output rules
{{ rule }}
{% endfor %}
{% for rule in host_nft_output %}
# Host output rules
{{ rule }}
{% endfor %}
counter comment "count dropped outgoing packets"
}
}
table ip nat {
chain prerouting {
type nat hook prerouting priority 100
policy {{ nft_policy_prerouting }};
{% for rule in group_nft_prerouting %}
# Group prerouting rules
{{ rule }}
{% endfor %}
{% for rule in host_nft_prerouting %}
# Host prerouting rules
{{ rule }}
{% endfor %}
}
chain postrouting {
type nat hook postrouting priority 100
policy {{ nft_policy_postrouting }};
{% for rule in group_nft_postrouting %}
# Group postrouting rules
{{ rule }}
{% endfor %}
{% for rule in host_nft_postrouting %}
# Host postrouting rules
{{ rule }}
{% endfor %}
}
}

View file

@ -46,3 +46,4 @@
action: insert
with_items: [ ipv4, ipv6 ]
notify: persist iptables
when: not nft | bool

View file

@ -27,3 +27,4 @@
- { ip: ipv6, port: 80 }
- { ip: ipv6, port: 443 }
notify: persist iptables
when: not nft | bool

View file

@ -19,6 +19,7 @@
- { ip: ipv4, port: 1883 }
- { ip: ipv6, port: 1883 }
notify: persist iptables
when: not nft | bool
- name: Install mqtt-simple
ansible.builtin.command: