Setup of a multi-purpose home-server using Ansible: systemd, nftables, port-knocking, etckeeper, Let’s Encrypt, dynamic DNS, OpenLDAP, SSO, mail, PostgreSQL, Dotclear, Gitea, Nextcloud, NFS, XMPP, print & scan, DLNA, Transmission, iodine…
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

215 lines
6.7 KiB

  1. #!/usr/bin/env nft -f
  2. # The home-server project produces a multi-purpose setup using Ansible.
  3. # Copyright © 2018 Y. Gablin, under the GPL-3.0-or-later license.
  4. # Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing.
  5. flush ruleset
  6. {% for V in ['4', '6'] %}
  7. {% set v = V | replace('4', '') %}
  8. {% macro trust(list) %}
  9. {% for net in list.split(' ') %}
  10. {% if not net is match('127(?:\.\d{1,3}){3}(?:/\d+)?|::1|^$') %}
  11. {% if (net is match('\d{1,3}(?:\.\d{1,3}){3}(?:/\d+)?')
  12. and V == '4') or (net is search(':') and V == '6') %}
  13. {{caller(net)}}
  14. {% endif %}
  15. {% endif %}
  16. {% endfor %}
  17. {% endmacro %}
  18. table ip{{v}} Inet{{V}} {
  19. set https_ban {
  20. type ipv{{V}}_addr
  21. flags timeout
  22. }
  23. set mail_ban {
  24. type ipv{{V}}_addr
  25. flags timeout
  26. }
  27. set sshd_ban {
  28. type ipv{{V}}_addr
  29. flags timeout
  30. }
  31. {% set seq = fw_portknock_seq.split(' ') %}
  32. {% for port in seq %}
  33. set Knocked_{{loop.index}} {
  34. type ipv{{V}}_addr
  35. flags timeout
  36. {% if loop.last %}
  37. timeout {{fw_knock_timeout_min}}m
  38. {% else %}
  39. timeout 10s
  40. {% endif %}
  41. gc-interval 4s
  42. }
  43. {% endfor %}
  44. chain doBan {
  45. type filter hook prerouting priority -200; policy accept;
  46. ip{{v}} saddr @https_ban tcp dport {80, 443} drop
  47. ip{{v}} saddr @mail_ban tcp dport {25, 465, 587, 993} drop
  48. ip{{v}} saddr @sshd_ban tcp dport {22, 2222, 22000} drop
  49. }
  50. chain NAT_in {
  51. type nat hook prerouting priority -100
  52. {% call(net) trust(SafeZone_IP) %}
  53. # Git SSH
  54. tcp dport 2222 log prefix "DNAT/git: " dnat to {{net}}
  55. {% endcall %}
  56. # Trusted hosts
  57. tcp dport 443 ip{{v}} saddr @Knocked_{{seq | length}} log prefix "DNAT/HTTPS after Port-Knock: " redirect to 444
  58. {% call(net) trust(net_trusted_ranges) %}
  59. tcp dport 443 ip{{v}} saddr {{net}} redirect to 444
  60. {% endcall %}
  61. tcp dport 22 ip{{v}} saddr @Knocked_{{seq | length}} log prefix "DNAT/SSH after Port-Knock: " redirect to 23
  62. {% call(net) trust(net_trusted_ranges) %}
  63. tcp dport 22 ip{{v}} saddr {{net}} redirect to 23
  64. {% endcall %}
  65. }
  66. chain NAT_out {
  67. type nat hook postrouting priority 100
  68. ct status dnat masquerade
  69. }
  70. {% for port in seq %}
  71. chain Knock_{{loop.index}} {
  72. {% if not loop.first %}
  73. set update ip{{v}} saddr timeout 0s @Knocked_{{loop.index-1}}
  74. {% endif %}
  75. set add ip{{v}} saddr @Knocked_{{loop.index}}{% if loop.last %} log prefix "Port-Knock accepted: "{% endif %}
  76. }
  77. {% if not loop.last %}
  78. chain Unknock_{{loop.index}} {
  79. set update ip{{v}} saddr timeout 0s @Knocked_{{loop.index}}
  80. }
  81. {% endif %}
  82. {% endfor %}
  83. chain RefreshKnock {
  84. set update ip{{v}} saddr timeout {{fw_knock_timeout_min}}m @Knocked_{{seq | length}}
  85. }
  86. chain PortKnock {
  87. {% for port in seq | reverse %}
  88. {% if loop.first %}
  89. ct state new ip{{v}} saddr @Knocked_{{loop.revindex}} goto RefreshKnock
  90. {% else %}
  91. tcp dport {{seq[loop.revindex]}} ct state new ip{{v}} saddr @Knocked_{{loop.revindex}} goto Knock_{{loop.revindex+1}}
  92. tcp dport {{port}} ct state new ip{{v}} saddr @Knocked_{{loop.revindex}} return
  93. ip{{v}} saddr @Knocked_{{loop.revindex}} ct state new goto Unknock_{{loop.revindex}}
  94. {% endif %}
  95. {% if loop.last %}
  96. tcp dport {{port}} ct state new goto Knock_{{loop.revindex}}
  97. {% endif %}
  98. {% endfor %}
  99. }
  100. chain FilterIn {
  101. type filter hook input priority 0
  102. policy drop
  103. # allow established/related connections
  104. ct state {established, related} accept
  105. # early drop of invalid connections
  106. ct state invalid drop
  107. # allow from loopback
  108. meta iif lo accept
  109. # allow icmp
  110. {% if V == '4' %}
  111. ip protocol icmp accept
  112. {% else %}
  113. ip6 nexthdr icmpv6 accept
  114. {% endif %}
  115. # allow iodine
  116. meta iifname dns0 accept
  117. # port-knocking
  118. jump PortKnock
  119. # trusted ssh and https
  120. ct status dnat accept
  121. # smtp
  122. tcp dport 25 accept
  123. # iodine
  124. tcp dport 53 accept
  125. udp dport 53 accept
  126. # http
  127. tcp dport 80 accept
  128. # https
  129. tcp dport 443 accept
  130. # smtps
  131. tcp dport 465 accept
  132. # submission (smtp)
  133. tcp dport 587 accept
  134. # ipp
  135. {% call(net) trust(net_trusted_ranges) %}
  136. tcp dport 631 ip{{v}} saddr {{net}} accept
  137. udp dport 631 ip{{v}} saddr {{net}} accept
  138. {% endcall %}
  139. # imaps
  140. tcp dport 993 accept
  141. # xmpp client
  142. tcp dport 5222 accept
  143. # xmpp server
  144. tcp dport 5269 accept
  145. # xmpp components
  146. tcp dport 5347 accept
  147. # zeroconf
  148. {% call(net) trust(net_trusted_ranges) %}
  149. udp dport 5353 ip{{v}} saddr {{net}} accept
  150. {% endcall %}
  151. # remote-help ssh
  152. tcp dport 22000 accept
  153. {% call(net) trust(net_trusted_ranges) %}
  154. tcp dport 22001-22009 ip{{v}} saddr {{net}} accept
  155. {% endcall %}
  156. # transmission
  157. tcp dport {{transmission_bt_port}} accept
  158. udp dport {{transmission_bt_port}} accept
  159. }
  160. chain FilterOut {
  161. type filter hook output priority 0
  162. policy drop
  163. ct state {established, related} accept
  164. meta oif lo accept
  165. {% call(net) trust(SafeZone_IP + ' ' + dns_hosts + ' ' + allowed_domains_ip + ' ' + ntp_hosts) %}
  166. ip{{v}} daddr {{net}} accept
  167. {% endcall %}
  168. meta skuid {{aur_user}} accept
  169. meta skuid exim tcp dport 25 accept
  170. meta skuid prosody accept
  171. meta skgid spamd accept
  172. meta skuid transmission tcp dport 443 accept
  173. meta skuid transmission udp dport 443 accept
  174. meta skuid transmission tcp dport > 1024 accept
  175. meta skuid transmission udp dport > 1024 accept
  176. }
  177. }
  178. {% endfor %}