From 2ffab4fe6d8b3d9b645d0a3c839e8bd251d4d42e Mon Sep 17 00:00:00 2001 From: Someone Date: Mon, 5 Aug 2024 19:34:51 +0200 Subject: [PATCH] [roles/base/network] setup networking and firewall (nftables) and fail2ban --- roles/base/network/defaults/main.yml | 12 + .../fail2ban.filter.repeated-offenders.conf | 15 ++ .../network/files/default/fail2ban.jail.local | 38 +++ .../default/fail2ban.nftables-common.local | 22 ++ roles/base/network/files/default/interfaces | 21 ++ .../base/network/files/default/nftables.conf | 105 ++++++++ roles/base/network/files/default/vnstat.conf | 242 ++++++++++++++++++ roles/base/network/handlers/main.yml | 38 +++ roles/base/network/tasks/main.yml | 137 ++++++++++ 9 files changed, 630 insertions(+) create mode 100644 roles/base/network/defaults/main.yml create mode 100644 roles/base/network/files/default/fail2ban.filter.repeated-offenders.conf create mode 100644 roles/base/network/files/default/fail2ban.jail.local create mode 100644 roles/base/network/files/default/fail2ban.nftables-common.local create mode 100644 roles/base/network/files/default/interfaces create mode 100644 roles/base/network/files/default/nftables.conf create mode 100644 roles/base/network/files/default/vnstat.conf create mode 100644 roles/base/network/handlers/main.yml create mode 100644 roles/base/network/tasks/main.yml diff --git a/roles/base/network/defaults/main.yml b/roles/base/network/defaults/main.yml new file mode 100644 index 0000000..d040642 --- /dev/null +++ b/roles/base/network/defaults/main.yml @@ -0,0 +1,12 @@ +##################################### +### someone's ansible provisioner ### +##################################### +# Part of: https://git.somenet.org/root/pub/somesible.git +# 2017-2024 by someone +# +# If not overridden in inventory or as a parameter, this is the value that will be used +# +--- +# Use handler to restart network. +# Often you want to keep using the old settings a little while longer. +restart_network: False diff --git a/roles/base/network/files/default/fail2ban.filter.repeated-offenders.conf b/roles/base/network/files/default/fail2ban.filter.repeated-offenders.conf new file mode 100644 index 0000000..60c8ec9 --- /dev/null +++ b/roles/base/network/files/default/fail2ban.filter.repeated-offenders.conf @@ -0,0 +1,15 @@ +# +################################################ +### Managed by someone's ansible provisioner ### +################################################ +# Part of: https://git.somenet.org/root/pub/somesible.git +# 2017-2024 by someone +# +# Fail2Ban filter for repeated offenders +# + +[Definition] + +failregex = ^.*NFT:f2b-chain:REJECT-banned.* SRC= .*$ + +ignoreregex = diff --git a/roles/base/network/files/default/fail2ban.jail.local b/roles/base/network/files/default/fail2ban.jail.local new file mode 100644 index 0000000..69e5d81 --- /dev/null +++ b/roles/base/network/files/default/fail2ban.jail.local @@ -0,0 +1,38 @@ +# +################################################ +### Managed by someone's ansible provisioner ### +################################################ +# Part of: https://git.somenet.org/root/pub/somesible.git +# 2017-2024 by someone +# + +[DEFAULT] +banaction = nftables[type=allports] +ignoreself = true + +findtime = 8h +maxretry = 5 + +bantime = 15m +bantime.increment = true + + +# prevent being abused for possible amplification attacks: +# retrying too much after already being banned leads to an additional "drop" ban. +[repeated-offenders] +enabled = true +# for some weird reason we need to define chain somewhere else than table + priority. - bug? +#banaction = nftables[type=allports, table=f2b-table-roff, chain=f2b-chain-roff, chain_priority=-2, blocktype="counter log prefix \"NFT:f2b-chain:DROP-banned; \" drop"] +chain=f2b-chain-roff +banaction = nftables[type=allports, chain=f2b-chain-roff-ignored, chain_priority=-2, blocktype=counter log prefix \"NFT:f2b-chain:DROP-banned\; \" drop] +logpath = /var/log/syslog + +findtime = 1d +maxretry = 100 + +bantime = 1d + + +[sshd] +enabled = true +mode = extra diff --git a/roles/base/network/files/default/fail2ban.nftables-common.local b/roles/base/network/files/default/fail2ban.nftables-common.local new file mode 100644 index 0000000..e24416f --- /dev/null +++ b/roles/base/network/files/default/fail2ban.nftables-common.local @@ -0,0 +1,22 @@ +# +################################################ +### Managed by someone's ansible provisioner ### +################################################ +# Part of: https://git.somenet.org/root/pub/somesible.git +# 2017-2024 by someone +# + +# only filter outside-in connections. (allow initiating connections to banned ips) +[Definition] +rule_stat = ct mark == 2 %(match)s saddr @ + + +[Init] +# by default uses "input" (=localhost only), use this for firewalls/netwide-bans. +chain_hook = prerouting + +# block all from src-IP, not just all tcp ports. +rule_match-allports = + +# count and/or log verbosely +blocktype = "counter log prefix \"NFT:f2b-chain:REJECT-banned; \" reject with icmpx type host-unreachable" diff --git a/roles/base/network/files/default/interfaces b/roles/base/network/files/default/interfaces new file mode 100644 index 0000000..bd81b64 --- /dev/null +++ b/roles/base/network/files/default/interfaces @@ -0,0 +1,21 @@ +# +################################################ +### Managed by someone's ansible provisioner ### +################################################ +# Part of: https://git.somenet.org/root/pub/somesible.git +# 2017-2024 by someone +# + +# dropins +source /etc/network/interfaces.d/* + + +# The loopback network interface +auto lo +iface lo inet loopback + + +# LAN with WOL +allow-hotplug eth0 +iface eth0 inet dhcp + ethernet-wol g diff --git a/roles/base/network/files/default/nftables.conf b/roles/base/network/files/default/nftables.conf new file mode 100644 index 0000000..1eb34c5 --- /dev/null +++ b/roles/base/network/files/default/nftables.conf @@ -0,0 +1,105 @@ +#!/usr/sbin/nft -f +################################################ +### Managed by someone's ansible provisioner ### +################################################ +# Part of: https://git.somenet.org/root/pub/somesible.git +# 2017-2024 by someone +# + +flush ruleset + +table inet filter { +# ct helper ftp-standard { type "ftp" protocol tcp; } +# +# chain RAW { +# type filter hook prerouting priority raw; policy accept; +# +# # accept any inside traffic. +# iifname "lo" counter accept +# +# # accept all other traffic, by policy. +# } + + chain PRE { + type filter hook prerouting priority -150; policy accept; + + # accept any inside traffic. + iifname "lo" counter accept + + # incoming, public facing traffic. + counter jump PRE_outside + + # accept any other traffic - should not happen. + counter log prefix "NFT:PRE:ACCEPT-unk; " accept + } + + chain PRE_outside { + # mark outside-initiated incoming connections. + ct state new meta mark set 2 ct mark set meta mark + + # accept neighbour discovery otherwise IPv6 connectivity breaks. + ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-advert, nd-neighbor-solicit, nd-router-advert} counter accept + ip protocol icmp icmp type { echo-request} counter accept + + # accept connections to these services. + tcp dport 2 counter accept + + # switch to something better than ftp, ssh/sftp for example, but if you must, use the ftp conntrack helper. +# tcp dport 21 ct state new ct helper set "ftp-standard" counter accept + + # accept traffic originated from us. + ct state established,related counter accept + + # accept any other traffic. + counter accept +# counter log prefix "NFT:PRE_outside:ACCEPT-all; " accept + } + +# chain INPUT { +# type filter hook input priority 0; policy accept; +# counter accept +# } +# chain FORWARD { +# type filter hook forward priority 0; policy accept; +# counter accept +# } +# chain OUTPUT { +# type filter hook output priority 0; policy accept; +# counter accept +# } + + chain POST { + type filter hook postrouting priority 150; policy accept; + + # accept any inside traffic. + oifname "lo" counter accept + + # outgoing, public facing traffic. + counter jump POST_outside + + # accept any other traffic - should not happen. + counter log prefix "NFT:POST:ACCEPT-unk; " accept + } + + chain POST_outside { + # mark inside-initiated outgoing traffic. + ct mark 0 meta mark set 1 ct mark set meta mark + + # accept all traffic. + counter accept +# counter log prefix "NFT:POST_outside:ACCEPT-all; " accept + } +} + + +#table ip nat { +# chain NAT_PRE { +# type nat hook prerouting priority dstnat; policy accept; +# meta l4proto tcp ip daddr 127.0.0.1 tcp dport 80 counter redirect to :1080 +# meta l4proto tcp ip daddr 127.0.0.1 tcp dport 443 counter redirect to :10443 +# } +# chain NAT_POST { +# type nat hook postrouting priority 100; policy accept; +# oifname "eth0" counter masquerade fully-random,persistent +# } +#} diff --git a/roles/base/network/files/default/vnstat.conf b/roles/base/network/files/default/vnstat.conf new file mode 100644 index 0000000..3f1f025 --- /dev/null +++ b/roles/base/network/files/default/vnstat.conf @@ -0,0 +1,242 @@ +# +################################################ +### Managed by someone's ansible provisioner ### +################################################ +# Part of: https://git.somenet.org/root/pub/somesible.git +# 2017-2024 by someone +# + +# vnStat 2.10 configuration file +# +# lines starting with # or ; are comments, everything has default +# values, remove ; before each option to change its value + + +# default interface (leave empty for automatic selection) +;Interface "" + +# location of the database directory +;DatabaseDir "/var/lib/vnstat" + +# locale (LC_ALL) ("-" = use system locale) +;Locale "-" + +# date output formats for -d, -m, -t and -w +;DayFormat "%Y-%m-%d" +;MonthFormat "%Y-%m" +;TopFormat "%Y-%m-%d" + +# characters used for visuals +;RXCharacter "%" +;TXCharacter ":" +;RXHourCharacter "r" +;TXHourCharacter "t" + +# how units are prefixed when traffic is shown +# 0 = IEC standard prefixes (KiB/MiB/GiB...) +# 1 = old style binary prefixes (KB/MB/GB...) +# 2 = SI decimal prefixes (kB/MB/GB...) +;UnitMode 0 + +# used rate unit (0 = bytes, 1 = bits) +;RateUnit 1 + +# how units are prefixed when traffic rate is shown in bits +# 0 = IEC binary prefixes (Kibit/s...) +# 1 = SI decimal prefixes (kbit/s...) +;RateUnitMode 1 + +# output style +# 0 = minimal & narrow, 1 = bar column visible +# 2 = same as 1 except rate in summary +# 3 = rate column visible +;OutputStyle 3 +;EstimateBarVisible 1 + +# number of decimals to use in outputs +;DefaultDecimals 2 +;HourlyDecimals 1 + +# spacer for separating hourly sections (0 = none, 1 = '|', 2 = '][', 3 = '[ ]') +;HourlySectionStyle 2 + +# how many seconds should sampling for -tr take by default +;Sampletime 5 + +# default query mode +# 0 = normal, 1 = days, 2 = months, 3 = top, 5 = short +# 7 = hours, 8 = xml, 9 = one line, 10 = json +;QueryMode 0 + +# default list output entry limits (0 = all) +List5Mins 50 +ListHours 50 +ListDays 50 +ListMonths 50 +ListYears 0 +ListTop 0 + +# how to match interface given for query to interface in database +# 0 = case sensitive exact match to interface name +# 1 = method 0 followed by case sensitive exact match of alias +# 2 = method 1 followed by case insensitive exact match of alias +# 3 = method 2 followed by case insensitive beginning match of alias +;InterfaceMatchMethod 3 + +# visibility of estimate line and text used in it +;EstimateVisible 1 +;EstimateText "estimated" + + +# vnstatd +## + +# switch to given user when started as root (leave empty to disable) +;DaemonUser "" + +# switch to given group when started as root (leave empty to disable) +;DaemonGroup "" + +# try to detect interface maximum bandwidth, 0 = disable feature +# MaxBandwidth will be used as fallback value when enabled +;BandwidthDetection 1 + +# maximum bandwidth (Mbit) for all interfaces, 0 = disable feature +# (unless interface specific limit is given) +;MaxBandwidth 1000 + +# interface specific limits +# example 8Mbit limit for eth0 (remove # to activate): +#MaxBWeth0 8 + +# data retention durations (-1 = unlimited, 0 = feature disabled) +5MinuteHours 0 +HourlyDays -1 +DailyDays -1 +MonthlyMonths -1 +YearlyYears -1 +TopDayEntries 0 + +# how often (in seconds) interface data is updated +;UpdateInterval 20 + +# how often (in seconds) interface status changes are checked +PollInterval 10 + +# how often (in minutes) data is saved to database +;SaveInterval 5 + +# how often (in minutes) data is saved when all interface are offline +;OfflineSaveInterval 30 + +# rescan database after save for new interfaces to be monitored (1 = enabled, 0 = disabled) +;RescanDatabaseOnSave 1 + +# automatically start monitoring all interfaces not found in the database +# (1 = enabled, 0 = disabled) +;AlwaysAddNewInterfaces 0 + +# on which day should months change +;MonthRotate 1 +;MonthRotateAffectsYears 0 + +# filesystem disk space check (1 = enabled, 0 = disabled) +;CheckDiskSpace 1 + +# how much the boot time can variate between updates (seconds) +;BootVariation 15 + +# create database entries even when there is no traffic (1 = enabled, 0 = disabled) +;TrafficlessEntries 1 + +# how many minutes to wait during daemon startup for system clock to +# sync time if most recent database update appears to be in the future +;TimeSyncWait 5 + +# how often (in minutes) bandwidth detection is done when +# BandwidthDetection is enabled (0 = disabled) +;BandwidthDetectionInterval 5 + +# force data save when interface status changes (1 = enabled, 0 = disabled) +;SaveOnStatusChange 1 + +# enable / disable logging (0 = disabled, 1 = logfile, 2 = syslog) +;UseLogging 2 + +# create dirs if needed (1 = enabled, 0 = disabled) +;CreateDirs 1 + +# update ownership of files if needed (1 = enabled, 0 = disabled) +;UpdateFileOwner 1 + +# file used for logging if UseLogging is set to 1 +;LogFile "/var/log/vnstat/vnstat.log" + +# file used as daemon pid / lock file +;PidFile "/run/vnstat/vnstat.pid" + +# 1 = 64-bit, 0 = 32-bit, -1 = old style logic, -2 = automatic detection +;64bitInterfaceCounters -2 + +# use SQLite Write-Ahead Logging mode (1 = enabled, 0 = disabled) +DatabaseWriteAheadLogging 1 + +# change the setting of the SQLite "synchronous" flag +# (-1 = auto, 0 = off, 1, = normal, 2 = full, 3 = extra) +;DatabaseSynchronous -1 + +# database uses UTC instead of local timezone (1 = enabled, 0 = disabled) +;UseUTC 0 + + +# vnstati +## + +# title timestamp format +;HeaderFormat "%Y-%m-%d %H:%M" + +# show hours with rate (1 = enabled, 0 = disabled) +;HourlyRate 1 + +# show rate in summary (1 = enabled, 0 = disabled) +;SummaryRate 1 + +# transparent background (1 = enabled, 0 = disabled) +;TransparentBg 0 + +# image size control +;LargeFonts 0 +;LineSpacingAdjustment 0 +;ImageScale 100 + +# 5 minutes graph size control +;5MinuteGraphResultCount 576 +;5MinuteGraphHeight 300 + +# hourly graph mode (0 = 24 hour sliding window, 1 = begins from midnight) +;HourlyGraphMode 0 + +# horizontal/vertical summary graph (0 = hours, 1 = 5 minutes) +;SummaryGraph 0 + +# traffic estimate bar style +# (0 = not shown, 1 = continuation of existing bar, 2 = separate bar) +;EstimateStyle 1 + +# bar column in list outputs shows rate if OutputStyle is 3 +# (1 = enabled, 0 = disabled) +;BarColumnShowsRate 0 + +# image colors +;CBackground "FFFFFF" +;CEdge "AEAEAE" +;CHeader "606060" +;CHeaderTitle "FFFFFF" +;CHeaderDate "FFFFFF" +;CText "000000" +;CLine "B0B0B0" +;CLineL "-" +;CRx "92CF00" +;CTx "606060" +;CRxD "-" +;CTxD "-" diff --git a/roles/base/network/handlers/main.yml b/roles/base/network/handlers/main.yml new file mode 100644 index 0000000..277d383 --- /dev/null +++ b/roles/base/network/handlers/main.yml @@ -0,0 +1,38 @@ +##################################### +### someone's ansible provisioner ### +##################################### +# Part of: https://git.somenet.org/root/pub/somesible.git +# 2017-2024 by someone +# +--- +- name: restart networking.service + systemd: + name: networking.service + daemon_reload: yes + state: restarted + when: restart_network | bool + ignore_errors: yes + + +- name: restart nftables.service + systemd: + name: nftables.service + daemon_reload: yes + state: restarted + ignore_errors: yes + + +- name: restart fail2ban.service + systemd: + name: fail2ban.service + daemon_reload: yes + state: restarted + ignore_errors: yes + + +- name: restart vnstat.service + systemd: + name: vnstat.service + daemon_reload: yes + state: restarted + ignore_errors: yes diff --git a/roles/base/network/tasks/main.yml b/roles/base/network/tasks/main.yml new file mode 100644 index 0000000..6fb2400 --- /dev/null +++ b/roles/base/network/tasks/main.yml @@ -0,0 +1,137 @@ +##################################### +### someone's ansible provisioner ### +##################################### +# Part of: https://git.somenet.org/root/pub/somesible.git +# 2017-2024 by someone +# +--- +- name: install networking tools + apt: + pkg: + - ethtool + - fail2ban + - ifupdown + - nftables + - python3-pyinotify + - python3-systemd + - vlan + - vnstat + state: present + policy_rc_d: 101 + tags: "online" + ignore_errors: "{{ignore_online_errors | bool}}" + + +- name: copy interfaces config + copy: + src: "{{item}}" + dest: "/etc/network/interfaces" + mode: 0644 + owner: "root" + group: "root" + with_first_found: + - "{{lookup('env','PWD')}}/host_files/{{inventory_hostname}}/{{role_name}}/interfaces" + - "{{lookup('env','PWD')}}/group_files/{{group_files_group}}/{{role_name}}/interfaces" + - "{{lookup('env','PWD')}}/group_files/all/{{role_name}}/interfaces" + - "default/interfaces" + notify: restart networking.service + + +- name: copy nftables config + copy: + src: "{{item}}" + dest: "/etc/nftables.conf" + mode: 0644 + owner: "root" + group: "root" + validate: "nft --check --file %s" + with_first_found: + - "{{lookup('env','PWD')}}/host_files/{{inventory_hostname}}/{{role_name}}/nftables.conf" + - "{{lookup('env','PWD')}}/group_files/{{group_files_group}}/{{role_name}}/nftables.conf" + - "{{lookup('env','PWD')}}/group_files/all/{{role_name}}/nftables.conf" + - "default/nftables.conf" + notify: + - restart nftables.service + - restart fail2ban.service + + +- name: copy fail2ban jail config + copy: + src: "{{item}}" + dest: "/etc/fail2ban/jail.local" + mode: 0644 + owner: "root" + group: "root" + with_first_found: + - "{{lookup('env','PWD')}}/host_files/{{inventory_hostname}}/{{role_name}}/fail2ban.jail.local" + - "{{lookup('env','PWD')}}/group_files/{{group_files_group}}/{{role_name}}/fail2ban.jail.local" + - "{{lookup('env','PWD')}}/group_files/all/{{role_name}}/fail2ban.jail.local" + - "default/fail2ban.jail.local" + notify: restart fail2ban.service + + +- name: copy fail2ban/action.d/nftables-common.local + copy: + src: "{{item}}" + dest: "/etc/fail2ban/action.d/nftables-common.local" + mode: 0644 + owner: "root" + group: "root" + with_first_found: + - "{{lookup('env','PWD')}}/host_files/{{inventory_hostname}}/{{role_name}}/fail2ban.nftables-common.local" + - "{{lookup('env','PWD')}}/group_files/{{group_files_group}}/{{role_name}}/fail2ban.nftables-common.local" + - "{{lookup('env','PWD')}}/group_files/all/{{role_name}}/fail2ban.nftables-common.local" + - "default/fail2ban.nftables-common.local" + notify: restart fail2ban.service + + +- name: copy fail2ban/filter.d/repeated-offenders.conf + copy: + src: "{{item}}" + dest: "/etc/fail2ban/filter.d/repeated-offenders.conf" + mode: 0644 + owner: "root" + group: "root" + with_first_found: + - "{{lookup('env','PWD')}}/host_files/{{inventory_hostname}}/{{role_name}}/fail2ban.filter.repeated-offenders.conf" + - "{{lookup('env','PWD')}}/group_files/{{group_files_group}}/{{role_name}}/fail2ban.filter.repeated-offenders.conf" + - "{{lookup('env','PWD')}}/group_files/all/{{role_name}}/fail2ban.filter.repeated-offenders.conf" + - "default/fail2ban.filter.repeated-offenders.conf" + notify: restart fail2ban.service + + +- name: copy vnstat.conf + copy: + src: "{{item}}" + dest: "/etc/vnstat.conf" + mode: 0644 + owner: "root" + group: "root" + with_first_found: + - "{{lookup('env','PWD')}}/host_files/{{inventory_hostname}}/{{role_name}}/vnstat.conf" + - "{{lookup('env','PWD')}}/group_files/{{group_files_group}}/{{role_name}}/vnstat.conf" + - "{{lookup('env','PWD')}}/group_files/all/{{role_name}}/vnstat.conf" + - "default/vnstat.conf" + notify: restart vnstat.service + + +- name: enable and start nftables.service + include_role: name="base/systemd/enable-and-start" + vars: + service_name: nftables.service + + +- name: enable and start fail2ban.service + include_role: name="base/systemd/enable-and-start" + vars: + service_name: fail2ban.service + # maybe the system is not fully setup yet. + ignore_errors: yes + + +- name: enable and start vnstat.service + include_role: name="base/systemd/enable-and-start" + vars: + service_name: vnstat.service + # maybe the system is not fully setup yet. + ignore_errors: yes -- 2.43.0