ctucx.git: ansible-configs

My personal ansible roles and playbooks [deprecated in favor of nixos]

commit cd76a6fbf65d04a11ff433df8fd0f95523779cff
parent 05ccb68344affd26d35b7165ba4b4d6bbd1919d3
Author: Leah (ctucx) <leah@ctu.cx>
Date: Thu, 28 Jan 2021 23:30:40 +0100

replace awall by nftables
27 files changed, 583 insertions(+), 253 deletions(-)
A
config-files/nftables/taurus.nft
|
45
+++++++++++++++++++++++++++++++++++++++++++++
A
config-files/nftables/wanderduene.nft
|
45
+++++++++++++++++++++++++++++++++++++++++++++
M
configuration/taurus.yml
|
63
++++++++++++++++++++++++++++++---------------------------------
M
configuration/wanderduene.yml
|
58
+++++++++++++++++++++++++++++++---------------------------
M
playbook-router.yml
|
16
++++++----------
M
playbook-servers.yml
|
18
+++++++++++-------
A
roles/acme-redirect/files/nftables-rule.nft
|
9
+++++++++
M
roles/acme-redirect/tasks/main.yml
|
67
+++++++++++++++++++++++++++++++++++++++----------------------------
A
roles/bind/files/nftables-rule.nft
|
10
++++++++++
M
roles/bind/tasks/main.yml
|
65
+++++++++++++++++++++++++++++++++++++++--------------------------
A
roles/common/files/sshd/nftables-rule.nft
|
9
+++++++++
A
roles/common/tasks/firewall-nftables.yml
|
72
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
roles/common/tasks/fstab.yml
|
12
++++++++++++
M
roles/common/tasks/main.yml
|
11
++++++-----
M
roles/common/tasks/sshd.yml
|
33
++++++++++++++++++++-------------
A
roles/common/templates/fstab.j2
|
4
++++
M
roles/frp/tasks/frps.yml
|
34
++++++++++++++++++++--------------
A
roles/frp/templates/nftables-rule.nft.j2
|
9
+++++++++
A
roles/maddy/files/nftables-rule.nft
|
13
+++++++++++++
M
roles/maddy/tasks/firewall.yml
|
36
+++++++++++++++++++++---------------
M
roles/maddy/tasks/remove.yml
|
32
+++++++++++++++++++-------------
A
roles/nginx/files/nftables-rule.nft
|
10
++++++++++
A
roles/nginx/files/nftables-rule_httpsOnly.nft
|
9
+++++++++
M
roles/nginx/tasks/main.yml
|
77
++++++++++++++++++++++++++++++++++++++++++++---------------------------------
A
roles/syncthing/files/nftables-rule.nft
|
10
++++++++++
M
roles/syncthing/tasks/configure.yml
|
35
+++++++++++++++++++----------------
M
roles/syncthing/tasks/remove.yml
|
34
+++++++++++++++++++++-------------
diff --git a/config-files/nftables/taurus.nft b/config-files/nftables/taurus.nft
@@ -0,0 +1,45 @@
+#!/usr/sbin/nft -f
+
+flush ruleset
+
+table inet firewall {
+    chain inbound {
+    	# By default, drop all traffic unless it meets a filter
+    	# criteria specified by the rules that follow below.
+        type filter hook input priority 0; policy drop;
+
+        # Allow traffic from established and related packets.
+        ct state established,related accept
+
+        # Drop invalid packets.
+        ct state invalid drop
+
+        # Allow loopback traffic.
+        iifname lo accept
+
+        # Allow local vlan traffic.
+        iifname eth1 accept
+
+        # Allow all ICMP and IGMP traffic, but enforce a rate limit
+        # to help prevent some types of flood attacks.
+        ip protocol icmp limit rate 5/second accept
+        ip6 nexthdr ipv6-icmp limit rate 5/second accept
+        ip protocol igmp limit rate 5/second accept
+
+        # Allow SSH on port 22.
+        tcp dport 22 accept
+    }
+
+    chain forward {
+        # Drop everything (assumes this device is not a router)
+        type filter hook forward priority 0; policy drop;
+    }
+
+    chain outbound {
+        # Allow all outbound traffic
+        type filter hook output priority 0; policy accept;
+    }
+
+}
+
+include "/etc/nftables.d/*.nft"
diff --git a/config-files/nftables/wanderduene.nft b/config-files/nftables/wanderduene.nft
@@ -0,0 +1,45 @@
+#!/usr/sbin/nft -f
+
+flush ruleset
+
+table inet firewall {
+    chain inbound {
+    	# By default, drop all traffic unless it meets a filter
+    	# criteria specified by the rules that follow below.
+        type filter hook input priority 0; policy drop;
+
+        # Allow traffic from established and related packets.
+        ct state established,related accept
+
+        # Drop invalid packets.
+        ct state invalid drop
+
+        # Allow loopback traffic.
+        iifname lo accept
+
+        # Allow vlan traffic.
+        iifname eth1 accept
+
+        # Allow all ICMP and IGMP traffic, but enforce a rate limit
+        # to help prevent some types of flood attacks.
+        ip protocol icmp limit rate 5/second accept
+        ip6 nexthdr ipv6-icmp limit rate 5/second accept
+        ip protocol igmp limit rate 5/second accept
+
+        # Allow SSH on port 22.
+        tcp dport 22 accept
+    }
+
+    chain forward {
+        # Drop everything (assumes this device is not a router)
+        type filter hook forward priority 0; policy drop;
+    }
+
+    chain outbound {
+        # Allow all outbound traffic
+        type filter hook output priority 0; policy accept;
+    }
+
+}
+
+include "/etc/nftables.d/*.nft"
diff --git a/configuration/taurus.yml b/configuration/taurus.yml
@@ -2,10 +2,11 @@ system:
   hostname: taurus
   domain: ctu.cx
   timezone: Europe/Berlin
-  alpineVersion: edge
+  alpineVersion: v3.13
   enableOwnRepos: true
   enableSSH: true
   enableSudo: true
+  enableNFTables: true
   useNTP: true
   nameservers:
     - 1.1.1.1

@@ -17,33 +18,9 @@ system:
       sshKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCw/G6x8H3ojvHx3NsTswBMMmOhp48F3rea0GUniKSvRLMRIti5b7Q4P4FXnkQEtuNSR3u7gE5r4EacaLaIx7Az9SgHRoE+hdzSo4mPAwKTx/E3HZgIjdZhTDL8PAn4SZZT6RBqr/uGb+x9fdIjY0FbdNBLjq0MNnG3T+qd1joUL8JXoS7F//ac52RhHlsA5qJXFDOhpqR/7hRMwOFNH0GKaLN1xQKcOjhpIcdswpOf8kRDVpT7xOYwfXCFF4MaY2M8047WKarvEnGdADIIw6bvWsdJINehtOQmYEFRaMuaWp1d9bglZXZKPQKNubv5lqneMP4AI7ImDYjgW6eNLIT1 cardno:000603502829"
 
 network:
-  awall:
+  nftables:
     enable: true
-    config:
-      zones:
-        WAN:
-          - iface: eth0
-      policies:
-        - in: _fw
-          action: accept
-        - in: _fw
-          out:  WAN
-          action: accept
-        - in: WAN
-          action: drop
-      filters:
-        - in: _fw
-          out: WAN
-          service:
-            - dns
-            - http
-            - https
-            - ssh
-        - in: WAN
-          out: _fw
-          service: 
-            - ping
-          action: accept
+    configFile: config-files/nftables/taurus.nft
   interfaces:
     - name: lo
       loopback: true

@@ -56,6 +33,10 @@ network:
         address: 2a03:4000:9:f8::1
         gateway: fe80::1
         netmask: 64
+    - name: eth1
+      ipv4:
+        address: 10.0.0.1
+        netmask: 255.255.255.0
 
 services:
   prometheus_node_exporter:

@@ -82,11 +63,11 @@ services:
         renew_tasks:
           - chown -R acme-redirect:acme-redirect /var/lib/acme-redirect/live/taurus.ctu.cx
           - sudo rc-service nginx restart
-      syncthing.ctu.cx:
+      syncthing.taurus.ctu.cx:
         dns_names: 
-          - syncthing.ctu.cx
+          - syncthing.taurus.ctu.cx
         renew_tasks:
-          - chown -R acme-redirect:acme-redirect /var/lib/acme-redirect/live/syncthing.ctu.cx
+          - chown -R acme-redirect:acme-redirect /var/lib/acme-redirect/live/syncthing.taurus.ctu.cx
           - sudo rc-service nginx restart
       restic.ctu.cx:
         dns_names: 

@@ -135,12 +116,12 @@ services:
     user: leah
     nginx:
       enable: true
-      domain: "syncthing.ctu.cx"
+      domain: "syncthing.taurus.ctu.cx"
       sslOnly: true
       ssl:
         enable: true
-        cert: "/var/lib/acme-redirect/live/syncthing.ctu.cx/fullchain"
-        privkey: "/var/lib/acme-redirect/live/syncthing.ctu.cx/privkey"
+        cert: "/var/lib/acme-redirect/live/syncthing.taurus.ctu.cx/fullchain"
+        privkey: "/var/lib/acme-redirect/live/syncthing.taurus.ctu.cx/privkey"
 
   rest_server:
     enable: true

@@ -155,3 +136,19 @@ services:
         enable: true
         cert: "/var/lib/acme-redirect/live/restic.ctu.cx/fullchain"
         privkey: "/var/lib/acme-redirect/live/restic.ctu.cx/privkey"
+
+  nfsserver:
+    enable: true
+    exports:
+      - path: /srv/wanderduene/pleroma
+        address: 10.0.0.2
+        options: rw,sync
+      - path: /srv/wanderduene/synapse
+        address: 10.0.0.2
+        options: rw,sync
+files:
+  /var/lib/websites/photos.ctu.cx:
+    state: "directory"
+    mode:  "0755"
+    owner: "leah"
+    group: "nginx"
diff --git a/configuration/wanderduene.yml b/configuration/wanderduene.yml
@@ -2,11 +2,27 @@ system:
   hostname: wanderduene
   domain: ctu.cx
   timezone: Europe/Berlin
-  alpineVersion: edge
+  alpineVersion: v3.13
   enableOwnRepos: true
   enableSSH: true
   enableSudo: true
   useNTP: true #todo: support archlinux
+  fstab:
+    - device: UUID=fc06e9aa-37fc-45ab-ad89-4f04e8ed78ba
+      path: /
+      fstype: ext4
+      options: rw,relatime 
+      checks: 0 1
+    - device: UUID=e12f1d27-9fb6-4417-9e34-cad1e0fc3b34
+      path: /boot
+      fstype: ext4
+      options: rw,relatime
+      checks: 0 2
+    - device: 10.0.0.1:/srv/wanderduene/pleroma
+      path: /var/lib/pleroma
+      fstype: nfs
+      options: defaults
+      checks: 0 0
   nameservers:
     - 1.1.1.1
     - 8.8.8.8

@@ -17,33 +33,9 @@ system:
       sshKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCw/G6x8H3ojvHx3NsTswBMMmOhp48F3rea0GUniKSvRLMRIti5b7Q4P4FXnkQEtuNSR3u7gE5r4EacaLaIx7Az9SgHRoE+hdzSo4mPAwKTx/E3HZgIjdZhTDL8PAn4SZZT6RBqr/uGb+x9fdIjY0FbdNBLjq0MNnG3T+qd1joUL8JXoS7F//ac52RhHlsA5qJXFDOhpqR/7hRMwOFNH0GKaLN1xQKcOjhpIcdswpOf8kRDVpT7xOYwfXCFF4MaY2M8047WKarvEnGdADIIw6bvWsdJINehtOQmYEFRaMuaWp1d9bglZXZKPQKNubv5lqneMP4AI7ImDYjgW6eNLIT1 cardno:000603502829"
 
 network:
-  awall:
+  nftables:
     enable: true
-    config:
-      zones:
-        WAN:
-          - iface: eth0
-      policies:
-        - in: _fw
-          action: accept
-        - in: _fw
-          out:  WAN
-          action: accept
-        - in: WAN
-          action: drop
-      filters:
-        - in: _fw
-          out: WAN
-          service:
-            - dns
-            - http
-            - https
-            - ssh
-        - in: WAN
-          out: _fw
-          service: 
-            - ping
-          action: accept
+    configFile: config-files/nftables/wanderduene.nft
   interfaces:
     - name: lo
       loopback: true

@@ -56,6 +48,10 @@ network:
         address: 2a03:4000:1:45d::1
         gateway: fe80::1
         netmask: 64
+    - name: eth1
+      ipv4:
+        address: 10.0.0.2
+        netmask: 255.255.255.0
 
 services:
   prometheus_node_exporter:

@@ -418,3 +414,10 @@ services:
         - isa
         - isa-mac
         - joghurtbecher
+
+files:
+  /var/lib/websites/ctu.cx:
+    state: "directory"
+    mode:  "0755"
+    owner: "leah"
+    group: "nginx"+
\ No newline at end of file
diff --git a/playbook-router.yml b/playbook-router.yml
@@ -129,14 +129,14 @@
               - DHCP: no
               - Address: 195.39.246.33/28
               - Address: 10.0.0.1/24
-              - Address: 2a0f:4ac0:acab::1/48
+              - Address: 2a0f:4ac0:acab::1/62
             - RoutingPolicyRule:
               - From: 195.39.246.32/28
               - Table: 254
               - Priority: 1900
               - SuppressPrefixLength: 0
             - RoutingPolicyRule:
-              - From: 2a0f:4ac0:acab::/48
+              - From: 2a0f:4ac0:acab::/62
               - Table: 254
               - Priority: 1900
               - SuppressPrefixLength: 0

@@ -145,7 +145,7 @@
               - Table: 1234
               - Priority: 2000
             - RoutingPolicyRule:
-              - From: 2a0f:4ac0:acab::/48
+              - From: 2a0f:4ac0:acab::/62
               - Table: 1234
               - Priority: 2000
         - name: usb-tetherring

@@ -297,9 +297,6 @@
             - f4:06:8d:df:1f:e3,                                          accesspoint,      10.0.0.2
             # tradfri gateway
             - 58:d5:0a:ba:23:29,                                          tradfri,          10.0.0.10
-            # ctucx iphone
-            - id:00:01:00:01:26:56:cb:5c:4c:57:ca:a8:b7:83,               ctucx-eifon,      [2a0f:4ac0:acab::105]
-            - 4c:57:ca:a8:b7:83,                                          ctucx-eifon,      10.0.0.105
             # ctucx macbook
             - id:00:01:00:01:27:51:55:30:80:e6:50:21:e0:6a,               toaster,          [2a0f:4ac0:acab::34]
             - 80:e6:50:21:e0:6a,                                          toaster,          195.39.246.34

@@ -309,16 +306,15 @@
             # ctucx thinkpad t470 (mac: wlan, eth)
             - id:00:04:37:8e:fd:cc:26:b8:11:b2:a8:5c:b8:77:0b:6e:a2:e6,   coladose,         [2a0f:4ac0:acab::35]
             - 7c:2a:31:fb:e6:b8, 8c:16:45:da:61:8e,                       coladose,         195.39.246.35
-            # isa iphone
-            - id:00:01:00:01:26:a9:b6:78:28:a0:2b:53:c3:c7,               IsaPhone,         [2a0f:4ac0:acab::111]
-            - 28:a0:2b:53:c3:c7,                                          isaPhone,         10.0.0.111
             # isa macbook
             - id:00:01:00:01:23:53:5d:7e:6c:40:08:af:2e:9c,               isabelles-mbp,    [2a0f:4ac0:acab::38]
             - 6c:40:08:af:2e:9c,                                          isabelles-mbp,    195.39.246.38
             # isa thinkpad x230
             - id:00:04:e8:51:c5:1d:f6:53:58:4a:9b:c0:28:59:a4:c7:76:32,   isa-x230,         [2a0f:4ac0:acab::36]
             - 64:80:99:75:c5:5c,                                          isa-x230,         195.39.246.36
-
+            # isa p2max
+            - id:00:04:97:db:54:73:1e:20:bb:fe:bf:35:dd:14:70:59:c2:d5,   isa-p2max,        [2a0f:4ac0:acab::40]
+            - ac:67:5d:12:2f:5a,                                          isa-p2max,        195.39.246.40
       syncthing:
         enable: true
         user: leah
diff --git a/playbook-servers.yml b/playbook-servers.yml
@@ -14,6 +14,8 @@
   roles: 
     - role: common            # supports: alpine, arch
       tags: common
+    - role: files             # supports: alpine, arch
+      tags: files
     - role: bind              # supports: alpine, arch(untested)
       tags: bind
     - role: acme-redirect     # supports: alpine, arch

@@ -32,8 +34,6 @@
       tags: maddy
     - role: radicale          # supports: alpine, arch(untested)
       tags: radicale
-    - role: websites          # supports: alpine, arch(untested)
-      tags: websites
     - role: pleroma           # supports: alpine
       tags: pleroma
     - role: synapse           # supports: alpine, arch(untested)

@@ -54,16 +54,18 @@
   roles:
     - role: common            # supports: alpine, arch
       tags: common
+    - role: files             # supports: alpine, arch
+      tags: files
     - role: bind              # supports: alpine, arch(untested)
       tags: bind
+    - role: nfsserver         # supports: alpine
+      tags: nfs
     - role: acme-redirect     # supports: alpine, arch
       tags: acme-redirect
     - role: nginx             # supports: alpine, arch
       tags: nginx
     - role: syncthing         # supports: alpine, arch
       tags: syncthing
-    - role: websites          # todo 
-      tags: websites
     - role: rest-server       # supports: alpine, arch(untested)
       vars:
         rest_server:

@@ -71,14 +73,17 @@
             password: "{}"
       tags: [ backup, rest-server, restic ]
 
-
 - hosts: joguhrtbecher
   name: Install joguhrtbecher
   vars_files: configuration/joguhrtbecher.yml
   roles:
     - role: common            # supports: alpine, arch
       tags: common
+    - role: kawaidesu.ansible_networkd
+      tags: systemd-networkd
+    - role: files             # supports: alpine, arch
+      tags: files
     - role: nginx             # supports: alpine, arch
       tags: nginx
     - role: syncthing         # supports: alpine, arch
-      tags: syncthing-
\ No newline at end of file
+      tags: syncthing
diff --git a/roles/acme-redirect/files/nftables-rule.nft b/roles/acme-redirect/files/nftables-rule.nft
@@ -0,0 +1,8 @@
+#!/usr/sbin/nft -f
+
+table inet firewall {
+    chain inbound {
+        # Allow dns on port 53.
+        tcp dport http accept
+    }
+}+
\ No newline at end of file
diff --git a/roles/acme-redirect/tasks/main.yml b/roles/acme-redirect/tasks/main.yml
@@ -77,26 +77,31 @@
 
 # firewall it 
 
-- name: "[awall] Create rule for: acme-redirect"
+- name: "[nftables] Create rule for: acme-redirect"
   copy:
-    src: awall-rule.json
-    dest: /etc/awall/optional/acme-redirect.json
-    validate: jq '.' %s
-  when: 
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    src: nftables-rule.nft
+    dest: /etc/nftables.d/acme-redirect.nft
+  when:
+    - network.nftables.enable is true
     - services.acme_redirect.enable is true
 
-- name: "[awall] Enable rule for: acme-redirect"
-  awall:
-    name: acme-redirect
-    state: enabled
-    activate: yes
-  when: 
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+- name: "[OpenRC] Restart service: nftables"
+  service:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "openrc"
+    - network.nftables.enable is true
     - services.acme_redirect.enable is true
 
+- name: "[systemd] Restart service: nftables"
+  systemd:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "systemd"
+    - network.nftables.enable is true
+    - services.acme_redirect.enable is true
 
 # restart and enable it 
 

@@ -170,25 +175,31 @@
 
 #defirewall it
 
-- name: "[awall] Disable rule for: acme-redirect"
-  awall:
-    name: acme-redirect
-    state: disabled
-    activate: yes
+- name: "[nftables] Delete rule for: acme-redirect"
+  file:
+    path: /etc/nftables.d/acme-redirect.nft
+    state: absent 
   when:
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    - network.nftables.enable is true
     - services.acme_redirect.enable is false
 
-- name: "[awall] Delete rule for: acme-redirect"
-  file:
-    path: /etc/awall/optional/acme-redirect.json
-    state: absent 
+- name: "[OpenRC] Restart service: nftables"
+  service:
+    name: nftables
+    state: restarted
   when:
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    - ansible_service_mgr == "openrc"
+    - network.nftables.enable is true
     - services.acme_redirect.enable is false
 
+- name: "[systemd] Restart service: nftables"
+  systemd:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "systemd"
+    - network.nftables.enable is true
+    - services.acme_redirect.enable is false
 
 # remove it 
 
diff --git a/roles/bind/files/nftables-rule.nft b/roles/bind/files/nftables-rule.nft
@@ -0,0 +1,9 @@
+#!/usr/sbin/nft -f
+
+table inet firewall {
+    chain inbound {
+        # Allow dns on port 53.
+        tcp dport domain accept
+        udp dport domain accept
+    }
+}+
\ No newline at end of file
diff --git a/roles/bind/tasks/main.yml b/roles/bind/tasks/main.yml
@@ -105,24 +105,30 @@
 
 #firewall it 
 
-- name: "[awall] Create rule for: bind"
+- name: "[nftables] Create rule for: bind"
   copy:
-    src: awall-rule.json
-    dest: /etc/awall/optional/bind.json
-    validate: jq '.' %s
+    src: nftables-rule.nft
+    dest: /etc/nftables.d/bind.nft
   when:
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    - network.nftables.enable is true
     - services.bind.enable is true
 
-- name: "[awall] Enable rule for: bind"
-  awall:
-    name: bind
-    state: enabled
-    activate: yes
+- name: "[OpenRC] Restart service: nftables"
+  service:
+    name: nftables
+    state: restarted
   when:
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    - ansible_service_mgr == "openrc"
+    - network.nftables.enable is true
+    - services.bind.enable is true
+
+- name: "[systemd] Restart service: nftables"
+  systemd:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "systemd"
+    - network.nftables.enable is true
     - services.bind.enable is true
 
 

@@ -149,23 +155,30 @@
 
 #defirewall it
 
-- name: "[awall] Disable rule for: bind"
-  awall:
-    name: bind
-    state: disabled
-    activate: yes
+- name: "[nftables] Delete rule for: bind"
+  file:
+    path: /etc/nftables.d/bind.nft
+    state: absent 
   when:
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    - network.nftables.enable is true
     - services.bind.enable is false
 
-- name: "[awall] Delete rule for: bind"
-  file:
-    path: /etc/awall/optional/bind.json
-    state: absent 
+- name: "[OpenRC] Restart service: nftables"
+  service:
+    name: nftables
+    state: restarted
   when:
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    - ansible_service_mgr == "openrc"
+    - network.nftables.enable is true
+    - services.bind.enable is false
+
+- name: "[systemd] Restart service: nftables"
+  systemd:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "systemd"
+    - network.nftables.enable is true
     - services.bind.enable is false
 
 
diff --git a/roles/common/files/sshd/nftables-rule.nft b/roles/common/files/sshd/nftables-rule.nft
@@ -0,0 +1,8 @@
+#!/usr/sbin/nft -f
+
+table inet firewall {
+    chain inbound {
+        # Allow ssh.
+        tcp dport ssh accept
+    }
+}+
\ No newline at end of file
diff --git a/roles/common/tasks/firewall-nftables.yml b/roles/common/tasks/firewall-nftables.yml
@@ -0,0 +1,72 @@
+---
+
+- name: "[Alpine] Install Package: nftables"
+  apk:
+    name: nftables
+    state: present
+    update_cache: yes
+  when: 
+    - ansible_distribution == "Alpine"
+    - network.nftables.enable is true 
+
+- name: "[Archlinux] Install Package: nftables"
+  pacman:
+    name: nftables
+    state: present
+    update_cache: yes
+  when:
+    - ansible_distribution == "Archlinux"
+    - network.nftables.enable is true
+
+- name: Fail when use nftables and no configFile
+  fail:
+    msg: Option 'network.nftables.configFile' not set!
+  when: 
+    - network.nftables.enable is true
+    - network.nftables.configFile is not defined
+
+- name: copy nftables config to destination
+  copy:
+    src: "{{ network.nftables.configFile }}"
+    dest: /etc/nftables.nft
+    mode: 0644
+  register: nftablesConfig
+  when: network.nftables.enable is true
+
+
+- name: "[OpenRC] Enable and start service: nftables"
+  service:
+    name: nftables
+    enabled: yes
+    state: started
+  when: 
+    - ansible_service_mgr == "openrc"
+    - network.nftables.enable is true
+
+- name: "[systemd] Enable and start service: nftables"
+  systemd:
+   name: nftables
+   enabled: yes
+   state: started
+  when: 
+    - ansible_service_mgr == "systemd"
+    - network.nftables.enable is true 
+
+
+- name: "[OpenRC] Restart service: nftables (to deploy new config)"
+  service:
+    name: nftables
+    state: restarted
+  when: 
+    - ansible_service_mgr == "openrc"
+    - network.nftables.enable is true
+    - nftablesConfig.changed
+
+- name: "[systemd] Restart service: nftables (to deploy new config)"
+  systemd:
+    name: nftables
+    state: restarted
+  when: 
+    - ansible_service_mgr == "systemd"
+    - network.nftables.enable is true
+    - nftablesConfig.changed
diff --git a/roles/common/tasks/fstab.yml b/roles/common/tasks/fstab.yml
@@ -0,0 +1,12 @@
+---
+
+- name: "[Alpine] Generate /etc/fstab"
+  template:
+    src: fstab.j2
+    dest: /etc/fstab
+    mode: 0755
+    owner:  root
+    group: root
+  when:
+    - ansible_distribution == "Alpine"  
+    - system.fstab is defined
diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml
@@ -8,6 +8,9 @@
 
 - include: packages.yml
 
+- include: fstab.yml
+  when: system.fstab is defined
+
 - include: timezone.yml
   when: system.timezone is defined
 

@@ -22,14 +25,12 @@
 - include: network_ip-forwarding.yml
   when: network.ipForwarding is defined 
 
-- include: firewall-awall.yml
-  when: 
-    - ansible_distribution == "Alpine"
-    - network.awall.enable is defined  
-
 - include: firewall-ferm.yml
   when: network.ferm.enable is defined 
 
+- include: firewall-nftables.yml
+  when: network.nftables.enable is defined 
+
 - include: ntp.yml
   when: system.useNTP is defined
 
diff --git a/roles/common/tasks/sshd.yml b/roles/common/tasks/sshd.yml
@@ -40,25 +40,32 @@
     - system.enableSSH is true
 
 
-- name: "[awall] Copy rule for: ssh"
+- name: "[nftables] Create rule for: sshd"
   copy:
-    src: awall/ssh.json
-    dest: /etc/awall/optional/ssh.json
-    validate: jq '.' %s
+    src: sshd/nftables-rule.nft
+    dest: /etc/nftables.d/sshd.nft
   when:
-    - ansible_distribution == "Alpine"
+    - network.nftables.enable is true
     - system.enableSSH is true
-    - network.awall.enable is true
 
-- name: "[awall] Activate rule for: ssh"
-  awall:
-    name: ssh
-    state: enabled
-    activate: yes
+- name: "[OpenRC] Restart service: nftables"
+  service:
+    name: nftables
+    state: restarted
   when:
-    - ansible_distribution == "Alpine"
+    - ansible_service_mgr == "openrc"
+    - network.nftables.enable is true
+    - system.enableSSH is true
+
+- name: "[systemd] Restart service: nftables"
+  systemd:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "systemd"
+    - network.nftables.enable is true
     - system.enableSSH is true
-    - network.awall.enable is true
+
 
 - name: "[OpenRC] Enable and start service: sshd"
   service:
diff --git a/roles/common/templates/fstab.j2 b/roles/common/templates/fstab.j2
@@ -0,0 +1,3 @@
+{% for entry in system.fstab %}
+{{ entry.device }} {{ entry.path }} {{ entry.fstype }} {{ entry.options }} {{ entry.checks }}
+{% endfor %}+
\ No newline at end of file
diff --git a/roles/frp/tasks/frps.yml b/roles/frp/tasks/frps.yml
@@ -23,23 +23,29 @@
   when: 
     - ansible_distribution == "Archlinux"
 
-- name: "[awall] Create rule for: frps"
+- name: "[nftables] Create rule for: frps"
   template:
-    src: awall-rule.json.j2
-    dest: /etc/awall/optional/frps.json
-    validate: jq '.' %s
+    src: nftables-rule.nft.j2
+    dest: /etc/nftables.d/frps.nft
   when: 
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    - network.nftables.enable is true
+
+- name: "[OpenRC] Restart service: nftables"
+  service:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "openrc"
+    - network.nftables.enable is true
+
+- name: "[systemd] Restart service: nftables"
+  systemd:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "systemd"
+    - network.nftables.enable is true
 
-- name: "[awall] Enable rule for: frps"
-  awall:
-    name: frps
-    state: enabled
-    activate: yes
-  when: 
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
 
 - name: "[OpenRC] Generate frps service config"
   template:
diff --git a/roles/frp/templates/nftables-rule.nft.j2 b/roles/frp/templates/nftables-rule.nft.j2
@@ -0,0 +1,8 @@
+#!/usr/sbin/nft -f
+
+table inet firewall {
+    chain inbound {
+        # Allow frps on port {{ services.frps.port }}.
+        tcp dport {{ services.frps.port }} accept
+    }
+}+
\ No newline at end of file
diff --git a/roles/maddy/files/nftables-rule.nft b/roles/maddy/files/nftables-rule.nft
@@ -0,0 +1,12 @@
+#!/usr/sbin/nft -f
+
+table inet firewall {
+    chain inbound {
+        # Allow mail stuff.
+        tcp dport smtp accept
+        tcp dport submissions accept
+        tcp dport submission accept
+        tcp dport imaps accept
+        tcp dport imap2 accept
+    }
+}+
\ No newline at end of file
diff --git a/roles/maddy/tasks/firewall.yml b/roles/maddy/tasks/firewall.yml
@@ -1,19 +1,25 @@
 ---
 
-- name: "[awall] Create rule for: maddy"
+- name: "[nftables] Create rule for: maddy"
   copy:
-    src: awall-rule.json
-    dest: /etc/awall/optional/maddy.json
-    validate: jq '.' %s
-  when: 
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    src: nftables-rule.nft
+    dest: /etc/nftables.d/maddy.nft
+  when:
+    - network.nftables.enable is true
+
+- name: "[OpenRC] Restart service: nftables"
+  service:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "openrc"
+    - network.nftables.enable is true
+
+- name: "[systemd] Restart service: nftables"
+  systemd:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "systemd"
+    - network.nftables.enable is true
 
-- name: "[awall] Enable rule for: syncthing"
-  awall:
-    name: maddy
-    state: enabled
-    activate: yes
-  when: 
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
diff --git a/roles/maddy/tasks/remove.yml b/roles/maddy/tasks/remove.yml
@@ -1,21 +1,27 @@
 ---
 
-- name: "[awall] Disable rule for: maddy"
-  awall:
-    name: maddy
-    state: disabled
-    activate: yes
-  when: 
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
-
-- name: "[awall] Delete rule for: maddy"
+- name: "[nftables] Delete rule for: maddy"
   file:
-    path: /etc/awall/optional/maddy.json
+    path: /etc/nftables.d/maddy.nft
     state: absent
   when: 
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    - network.nftables.enable is true
+
+- name: "[OpenRC] Restart service: nftables"
+  service:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "openrc"
+    - network.nftables.enable is true
+
+- name: "[systemd] Restart service: nftables"
+  systemd:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "systemd"
+    - network.nftables.enable is true
 
 
 - name: "[OpenRC] Disable and stop service: maddy"
diff --git a/roles/nginx/files/nftables-rule.nft b/roles/nginx/files/nftables-rule.nft
@@ -0,0 +1,9 @@
+#!/usr/sbin/nft -f
+
+table inet firewall {
+    chain inbound {
+        # Allow http(s).
+        tcp dport http accept
+        tcp dport https accept
+    }
+}+
\ No newline at end of file
diff --git a/roles/nginx/files/nftables-rule_httpsOnly.nft b/roles/nginx/files/nftables-rule_httpsOnly.nft
@@ -0,0 +1,8 @@
+#!/usr/sbin/nft -f
+
+table inet firewall {
+    chain inbound {
+        # Allow https.
+        tcp dport https accept
+    }
+}+
\ No newline at end of file
diff --git a/roles/nginx/tasks/main.yml b/roles/nginx/tasks/main.yml
@@ -115,37 +115,41 @@
 
 # firewall it
 
-- name: "[awall] Create rule for: nginx (http,https)"
+- name: "[nftables] Create rule for: nginx(http & https)"
   copy:
-    src: awall-rule.json
-    dest: /etc/awall/optional/nginx.json
-    validate: jq '.' %s
+    src: nftables-rule.nft
+    dest: /etc/nftables.d/nginx.nft
   when: 
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    - network.nftables.enable is true
     - services.nginx.enable is true
     - services.nginx.sslOnly is not defined or services.nginx.sslOnly is false
 
-- name: "[awall] Create rule for: nginx (https)"
+- name: "[nftables] Create rule for: nginx(https only)"
   copy:
-    src: awall-rule_httpsOnly.json
-    dest: /etc/awall/optional/nginx.json
-    validate: jq '.' %s
-  when: 
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    src: nftables-rule_httpsOnly.nft
+    dest: /etc/nftables.d/nginx.nft
+  when:
+    - network.nftables.enable is true
     - services.nginx.enable is true
     - services.nginx.sslOnly is defined
     - services.nginx.sslOnly is true
 
-- name: "[awall] Enable rule for: nginx"
-  awall:
-    name: nginx
-    state: enabled
-    activate: yes
+- name: "[OpenRC] Restart service: nftables"
+  service:
+    name: nftables
+    state: restarted
   when:
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    - ansible_service_mgr == "openrc"
+    - network.nftables.enable is true
+    - services.nginx.enable is true
+
+- name: "[systemd] Restart service: nftables"
+  systemd:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "systemd"
+    - network.nftables.enable is true
     - services.nginx.enable is true
 
 

@@ -193,23 +197,30 @@
 
 #defirewall it
 
-- name: "[awall] Disable rule for: nginx"
-  awall:
-    name: nginx
-    state: disabled
-    activate: yes
+- name: "[nftables] Delete rule for: bind"
+  file:
+    path: /etc/nftables.d/bind.nft
+    state: absent
+  when: 
+    - network.nftables.enable is true
+    - services.nginx.enable is false
+
+- name: "[OpenRC] Restart service: nftables"
+  service:
+    name: nftables
+    state: restarted
   when:
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    - ansible_service_mgr == "openrc"
+    - network.nftables.enable is true
     - services.nginx.enable is false
 
-- name: "[awall] Delete rule for: bind"
-  file:
-    path: /etc/awall/optional/nginx.json
-    state: absent 
+- name: "[systemd] Restart service: nftables"
+  systemd:
+    name: nftables
+    state: restarted
   when:
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    - ansible_service_mgr == "systemd"
+    - network.nftables.enable is true
     - services.nginx.enable is false
 
 
diff --git a/roles/syncthing/files/nftables-rule.nft b/roles/syncthing/files/nftables-rule.nft
@@ -0,0 +1,9 @@
+#!/usr/sbin/nft -f
+
+table inet firewall {
+    chain inbound {
+        # Allow syncthing.
+        tcp dport 22000 accept
+        udp dport 21027 accept
+    }
+}+
\ No newline at end of file
diff --git a/roles/syncthing/tasks/configure.yml b/roles/syncthing/tasks/configure.yml
@@ -8,21 +8,24 @@
   when: 
     - ansible_service_mgr == "openrc"
 
-
-- name: "[awall] Create rule for: syncthing"
+- name: "[nftables] Create rule for: syncthing"
   copy:
-    src: awall-rule.json
-    dest: /etc/awall/optional/syncthing.json
-    validate: jq '.' %s
-  when: 
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    src: nftables-rule.nft
+    dest: /etc/nftables.d/syncthing.nft
+  when:
+    - network.nftables.enable is true
+
+- name: "[OpenRC] Restart service: nftables"
+  service:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "openrc"
+
+- name: "[systemd] Restart service: nftables"
+  systemd:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "systemd"
 
-- name: "[awall] Enable rule for: syncthing"
-  awall:
-    name: syncthing
-    state: enabled
-    activate: yes
-  when: 
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
diff --git a/roles/syncthing/tasks/remove.yml b/roles/syncthing/tasks/remove.yml
@@ -18,22 +18,30 @@
 
 
 
-- name: "[awall] Disable rule for: syncthing"
-  awall:
-    name: syncthing
-    state: disabled
-    activate: yes
-  when: 
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
-
-- name: "[awall] Delete rule for: syncthing"
+- name: "[nftables] Delete rule for: syncthing"
   file:
-    path: /etc/awall/optional/syncthing.json
+    path: /etc/nftables.d/syncthing.nft
     state: absent
   when: 
-    - ansible_distribution == "Alpine" 
-    - network.awall.enable is true
+    - network.nftables.enable is true
+
+- name: "[OpenRC] Restart service: nftables"
+  service:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "openrc"
+    - network.nftables.enable is true
+
+- name: "[systemd] Restart service: nftables"
+  systemd:
+    name: nftables
+    state: restarted
+  when:
+    - ansible_service_mgr == "systemd"
+    - network.nftables.enable is true
+
+
 
 
 - name: "[OpenRC] Disable and stop service: syncthing-{{ services.syncthing.user }}"