REHL8.1上配置路由的nftables防火牆策略

李蔚發表於2024-11-14

日期:2024.11.9
參照:

  • 鳥哥私房菜-第七章、Linux 防火牆設定
    https://linux.vbird.org/linux_server/rocky9/0180firewall.php

在RHEL8.1的安裝過程中沒有註冊,目前yum源不能用,先註冊

[root@RHEL8 ~]# dnf repoinfo
Updating Subscription Management repositories.
Unable to read consumer identity

This system is not registered with an entitlement server. You can use subscription-manager to register.

No repositories available
[root@RHEL8 ~]# subscription-manager register --username <username> --password <password> --auto-attach
Registering to: subscription.rhsm.redhat.com:443/subscription
The system has been registered with ID: 8c101d86-fa2d-45cf-a19c-02b621032703
The registered system name is: RHEL8
Ignoring the request to auto-attach. Attaching subscriptions is disabled for organization "32546913" because Simple Content Access (SCA) is enabled.
[root@RHEL8 ~]# dnf repolist
Updating Subscription Management repositories.
repo id                                      repo name
rhel-8-for-x86_64-appstream-rpms             Red Hat Enterprise Linux 8 for x86_64 - AppStream (RPMs)
rhel-8-for-x86_64-baseos-rpms                Red Hat Enterprise Linux 8 for x86_64 - BaseOS (RPMs)

配置enp2s0和enp3s0兩塊網路卡地址,按照規劃
mac 52:54:00:00:31:72的網路卡放DMZ網段,IP為172.31.0.254
mac 52:54:00:00:31:10的網路卡放LAN網段,IP為10.31.0.254

[root@RHEL8 ~]# nmcli device show enp2s0 
GENERAL.DEVICE:                         enp2s0
GENERAL.TYPE:                           ethernet
GENERAL.HWADDR:                         52:54:00:00:31:72
GENERAL.MTU:                            1500
GENERAL.STATE:                          30 (disconnected)
GENERAL.CONNECTION:                     --
GENERAL.CON-PATH:                       --
WIRED-PROPERTIES.CARRIER:               on
IP4.GATEWAY:                            --
IP6.GATEWAY:                            --
[root@RHEL8 ~]# nmcli device show enp3s0 
GENERAL.DEVICE:                         enp3s0
GENERAL.TYPE:                           ethernet
GENERAL.HWADDR:                         52:54:00:00:31:10
GENERAL.MTU:                            1500
GENERAL.STATE:                          30 (disconnected)
GENERAL.CONNECTION:                     --
GENERAL.CON-PATH:                       --
WIRED-PROPERTIES.CARRIER:               on
IP4.GATEWAY:                            --
IP6.GATEWAY:                            --
[root@RHEL8 ~]# nmcli connection show 
NAME    UUID                                  TYPE      DEVICE 
enp1s0  ff9cc8a4-1fd4-4809-a108-0e51df4c75dd  ethernet  enp1s0 
enp2s0  6cc22494-8242-49ea-b27c-64152d90aea4  ethernet  --     
enp3s0  e73eef29-46c2-4cf5-ab11-1298739a98ab  ethernet  --   
[root@RHEL8 ~]# nmcli connection delete enp2s0 
Connection 'enp2s0' (6cc22494-8242-49ea-b27c-64152d90aea4) successfully deleted.
[root@RHEL8 ~]# nmcli connection delete enp3s0 
Connection 'enp3s0' (e73eef29-46c2-4cf5-ab11-1298739a98ab) successfully deleted.
[root@RHEL8 ~]# nmcli connection show 
NAME    UUID                                  TYPE      DEVICE 
enp1s0  ff9cc8a4-1fd4-4809-a108-0e51df4c75dd  ethernet  enp1s0 
[root@RHEL8 ~]# nmcli connection add type ethernet autoconnect yes con-name enp2s0 ifname enp2s0 ipv4.method manual ipv4.addresses 172.31.0.254/24 
Connection 'enp2s0' (e098b147-12be-415f-8ec7-a436fa30d38a) successfully added.
[root@RHEL8 ~]# nmcli connection add type ethernet autoconnect yes con-name enp3s0 ifname enp3s0 ipv4.method manual ipv4.addresses 10.31.0.254/24
Connection 'enp3s0' (831a2692-73fc-44ca-ba20-2f0f9bbeebe9) successfully added.
[root@RHEL8 ~]# nmcli connection up enp2s0
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/4)
[root@RHEL8 ~]# nmcli connection up enp3s0
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/5)

開啟ip_forward

[root@RHEL8 ~]# cat /proc/sys/net/ipv4/ip_forward
0
[root@RHEL8 ~]# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/ipforward.conf
[root@RHEL8 ~]# cat /etc/sysctl.d/ipforward.conf
net.ipv4.ip_forward=1
[root@RHEL8 ~]# sysctl -p /etc/sysctl.d/ipforward.conf
net.ipv4.ip_forward = 1
[root@RHEL8 ~]# cat /proc/sys/net/ipv4/ip_forward
1

來用下nftable

[root@RHEL8 ~]# systemctl mask firewalld.service iptables.service 
Unit iptables.service does not exist, proceeding anyway.
Created symlink /etc/systemd/system/firewalld.service → /dev/null.
Created symlink /etc/systemd/system/iptables.service → /dev/null.
[root@RHEL8 ~]# systemctl stop firewalld.service 
[root@RHEL8 ~]# systemctl enable --now nftables.service 
Created symlink /etc/systemd/system/multi-user.target.wants/nftables.service → /usr/lib/systemd/system/nftables.service.
[root@RHEL8 ~]# systemctl status nftables.service 
● nftables.service - Netfilter Tables
   Loaded: loaded (/usr/lib/systemd/system/nftables.service; enabled; vendor preset: disabled)
   Active: active (exited) since Sat 2024-11-09 22:39:24 CST; 20s ago
     Docs: man:nft(8)
  Process: 16431 ExecStart=/sbin/nft -f /etc/sysconfig/nftables.conf (code=exited, status=0/SUCCESS)
 Main PID: 16431 (code=exited, status=0/SUCCESS)

Nov 09 22:39:24 RHEL8 systemd[1]: Starting Netfilter Tables...
Nov 09 22:39:24 RHEL8 systemd[1]: Started Netfilter Tables.

檢視配置檔案,配置nftable防火牆規則的儲存路徑並建立檔案。

[root@RHEL8 ~]# rpm -qc nftables 
/etc/nftables/main.nft
/etc/nftables/nat.nft
/etc/nftables/osf/pf.os
/etc/nftables/router.nft
/etc/sysconfig/nftables.conf
[root@RHEL8 ~]# echo include '"/etc/nftables/rhel8.nft"' >> /etc/sysconfig/nftables.conf
[root@RHEL8 ~]# cat /etc/sysconfig/nftables.conf 
# Uncomment the include statement here to load the default config sample
# in /etc/nftables for nftables service.

#include "/etc/nftables/main.nft"

# To customize, either edit the samples in /etc/nftables, append further
# commands to the end of this file or overwrite it after first service
# start by calling: 'nft list ruleset >/etc/sysconfig/nftables.conf'.
include "/etc/nftables/rhel8.nft"
[root@RHEL8 ~]# touch /etc/nftables/rhel8.nft
[root@RHEL8 ~]# systemctl reload nftables.service 

新增一個存放 ipv4和ipv6過濾規則 的表NF_FILTER

[root@RHEL8 ~]# nft add table inet NFT_FILTER
[root@RHEL8 ~]# nft list tables
table inet NFT_FILTER

新增一個 過濾進入路由封包 的鏈NFC_INPUT,策略預設為 允許,配置好進入路由的規則之後再將預設策略改為拒絕

[root@RHEL8 ~]# nft add chain inet NFT_FILTER NFC_INPUT { type filter hook input priority filter \; policy accept \; }
[root@RHEL8 ~]# nft list chains
table inet NFT_FILTER {
	chain NFC_INPUT {
		type filter hook input priority filter; policy accept;
	}
}

放行已經建立的連線的封包,放行與已經建立連線相關的封包

[root@RHEL8 ~]# nft add rule inet NFT_FILTER NFC_INPUT ct state established,related accept
[root@RHEL8 ~]# nft list ruleset
table inet NFT_FILTER {
	chain NFC_INPUT {
		type filter hook input priority filter; policy accept;
		ct state established,related accept
	}
}

現在將NFC_INPUT的預設規則改為dorp,透過Xshell正在連線的ssh22埠就不會斷掉,但是一旦斷掉了也連不回去

[root@RHEL8 ~]# nft -e chain inet NFT_FILTER NFC_INPUT { type filter hook input priority filter \; policy drop \;}
[root@RHEL8 ~]# nft list ruleset
table inet NFT_FILTER {
	chain NFC_INPUT {
		type filter hook input priority filter; policy drop;
		ct state established,related accept
	}
}

允許ping封包透過,用rhel9 ping rhel8 ,一直卡住無反應,加入規則後立刻ping通。提示之前傳送了79個包,通了之後收到6個回應。

[root@RHEL8 ~]# nft -e add rule inet NFT_FILTER NFC_INPUT meta l4proto icmp accept
insert rule inet NFT_FILTER NFC_INPUT meta l4proto icmp accept
# new generation 106 by process 16776 (nft)
[root@RHEL9 ~]# ping 192.168.5.254
PING 192.168.5.254 (192.168.5.254) 56(84) bytes of data.

64 bytes from 192.168.5.254: icmp_seq=74 ttl=64 time=0.142 ms
64 bytes from 192.168.5.254: icmp_seq=75 ttl=64 time=0.115 ms
64 bytes from 192.168.5.254: icmp_seq=76 ttl=64 time=0.116 ms
64 bytes from 192.168.5.254: icmp_seq=77 ttl=64 time=0.102 ms
64 bytes from 192.168.5.254: icmp_seq=78 ttl=64 time=0.098 ms
64 bytes from 192.168.5.254: icmp_seq=79 ttl=64 time=0.103 ms
^C
--- 192.168.5.254 ping statistics ---
79 packets transmitted, 6 received, 92.4051% packet loss, time 79910ms
rtt min/avg/max/mdev = 0.098/0.112/0.142/0.014 ms

放行 本地迴環網路卡 lo 的封包

[root@RHEL8 ~]# nft -e add rule inet NFT_FILTER NFC_INPUT iifname lo accept
insert rule inet NFT_FILTER NFC_INPUT iifname "lo" accept
# new generation 107 by process 16984 (nft)

放行 連線至enp1s0網路卡的 目標埠22的 tpc協議的 封包

[root@RHEL8 ~]# nft add rule inet NFT_FILTER NFC_INPUT iifname enp1s0 tcp dport 22 accept
[root@RHEL8 ~]# nft list ruleset
table inet NFT_FILTER {
	chain NFC_INPUT {
		type filter hook input priority filter; policy drop;
		ct state established,related accept
		meta l4proto icmp accept
		iifname "lo" accept
		iifname "enp1s0" tcp dport 22 accept
	}
}

下一步要在enp3s0連線的LAN網段裡架設一個dhcp伺服器,ip:10.31.0.1,在rhel8上建立DHCPrelay,使enp2s0連線的DMZ網段裡的主機也可以獲得dncp服務

因此,放行 連線至enp2s0網路卡的 目標埠為 67的 UPD封包,讓DMZ網段裡主機的DHCP請求能夠透過enp2s0網路卡傳送給rhel8上執行的DHCPrelay服務。再由rhel8上的DHCPrelay轉發到LAN網段的10.0.0.1上

[root@RHEL8 ~]# nft add rule inet NFT_FILTER NFC_INPUT iifname enp2s0 udp dport 67 accept

設定從公網能夠ssh連線到計劃搭建的10.0.0.1dhcp伺服器的22埠
第一步 配置訪問公網ip:221.229.XX.X1:62223 的請求轉發到 rhel8 enp1s0 192.168.5.254:62223

第二步 將訪問rhel8 enp1s0 192.168.5.254:62223 的請求轉發到 enp3s0 連線的 LAN 網段裡的 10.31.0.1:22
新增一個存放 ipv4和ipv6網路地址轉換規則 的表NFT_NAT
NAT:Network Address Translation

[root@RHEL8 ~]# nft add table inet NFT_NAT
[root@RHEL8 ~]# nft list tables
table inet NFT_FILTER
table inet NFT_NAT

新增一個存放 進入路由前規則 的鏈

[root@RHEL8 ~]# nft add chain inet NFT_NAT NFC_PRE { type nat hook prerouting priority dstnat \; policy accept \; }
[root@RHEL8 ~]# nft list chains
table inet NFT_FILTER {
	chain NFC_INPUT {
		type filter hook input priority filter; policy drop;
	}
}
table inet NFT_NAT {
	chain NFC_PRE {
		type nat hook prerouting priority dstnat; policy accept;
	}
}

新增規則將訪問 enp1s0 192.168.5.254:62223 的請求轉發到 enp3s0 連線的 LAN 網段裡的 10.31.0.1:22

[root@RHEL8 ~]# nft add rule inet NFT_NAT NFC_PRE iifname enp1s0 tcp dport 62223 dnat ip to 10.31.0.1:22
[root@RHEL8 ~]# nft list chain inet NFT_NAT NFC_PRE
table inet NFT_NAT {
	chain NFC_PRE {
		type nat hook prerouting priority dstnat; policy accept;
		iifname "enp1s0" tcp dport 62223 dnat ip to 10.31.0.1:22
	}
}

配置enp2s0和enp3s0兩個網段能夠訪問公網,透過這兩個網段進入路由的資料包 在走到路由的後方時 偽裝(masquerade)成公網的IP訪問網際網路
在NFT_NAT表中新增一個存放 透過路由後的規則 的鏈

[root@RHEL8 ~]# nft add chain inet NFT_NAT NFC_POST { type nat hook postrouting priority srcnat \; policy accept \; }
[root@RHEL8 ~]# nft list chains
table inet NFT_FILTER {
	chain NFC_INPUT {
		type filter hook input priority filter; policy drop;
	}
}
table inet NFT_NAT {
	chain NFC_PRE {
		type nat hook prerouting priority dstnat; policy accept;
	}
	chain NFC_POST {
		type nat hook postrouting priority srcnat; policy accept;
	}
}

偽裝(masquerade) 由enp2s0 172.31.0.0/24 和 enp3s0 10.31.0.0/24 兩個網段進入 然後從 epn1s0 出去的 資料包

[root@RHEL8 ~]# nft add rule inet NFT_NAT NFC_POST iifname enp2s0 oifname enp1s0 ip saddr 172.31.0.0/24 masquerade
[root@RHEL8 ~]# nft add rule inet NFT_NAT NFC_POST iifname enp3s0 oifname enp1s0 ip saddr 10.31.0.0/24 masquerade
[root@RHEL8 ~]# nft list chain inet NFT_NAT NFC_POST
table inet NFT_NAT {
	chain NFC_POST {
		type nat hook postrouting priority srcnat; policy accept;
		iifname "enp2s0" oifname "enp1s0" ip saddr 172.31.0.0/24 masquerade
		iifname "enp3s0" oifname "enp1s0" ip saddr 10.31.0.0/24 masquerade
	}
}

儲存規則到配置檔案

[root@RHEL8 ~]# nft list ruleset >| /etc/nftables/rhel8.nft

設定單小時內失敗登入超過10次加入黑名單
測試加入黑名單的語句,,這裡的reject語句要插入在handle5之前,否則handle5判斷22埠accept,後面的reject語句不會生效

[root@RHEL8 ~]# nft -a list chain inet NFT_FILTER NFC_INPUT
table inet NFT_FILTER {
	chain NFC_INPUT { # handle 1
		type filter hook input priority filter; policy drop;
		ct state established,related accept # handle 2
		meta l4proto icmp accept # handle 3
		iifname "lo" accept # handle 4
		iifname "enp1s0" tcp dport 22 accept # handle 5
		iifname "enp2s0" udp dport 67 accept # handle 6
	}
}
[root@RHEL8 ~]# nft insert rule inet NFT_FILTER NFC_INPUT handle 5 iifname enp1s0 ip saddr 192.168.5.253 reject
[root@RHEL8 ~]# nft -a list chain inet NFT_FILTER NFC_INPUT
table inet NFT_FILTER {
	chain NFC_INPUT { # handle 1
		type filter hook input priority filter; policy drop;
		ct state established,related accept # handle 2
		meta l4proto icmp accept # handle 3
		iifname "lo" accept # handle 4
		iifname "enp1s0" ip saddr 192.168.5.253 reject with icmp port-unreachable # handle 25
		iifname "enp1s0" tcp dport 22 accept # handle 5
		iifname "enp2s0" udp dport 67 accept # handle 6
	}
}

用RHEL9連線被拒絕,指令生效

[root@RHEL9 ~]# ssh 192.168.5.254
ssh: connect to host 192.168.5.254 port 22: Connection refused

將測試的規則移除

[root@RHEL8 ~]# nft delete rule inet NFT_FILTER NFC_INPUT handle 25
[root@RHEL8 ~]# nft -a list chain inet NFT_FILTER NFC_INPUT
table inet NFT_FILTER {
	chain NFC_INPUT { # handle 1
		type filter hook input priority filter; policy drop;
		ct state established,related accept # handle 2
		meta l4proto icmp accept # handle 3
		iifname "lo" accept # handle 4
		iifname "enp1s0" tcp dport 22 accept # handle 5
		iifname "enp2s0" udp dport 67 accept # handle 6
	}
}

將自動拉黑指令碼的防火牆語句由原先的firewalld修改為nft

[root@RHEL8 ~]# cat awknftban.sh 
#awkban.sh
#Date: 2024-11-11
#!/bin/bash

#寫入計劃任務
#1.自動拉黑每小時登入失敗超過指定次數的IP

rulefile='/etc/nftables/rhel8.nft'

cat << EOF >> /var/spool/cron/root
0 * * * * /usr/bin/lastb | /usr/bin/awk -v hourago="\$(/usr/bin/date --date='1 hour ago' '+\%a \%b \%e \%H:')" '\$0~hourago{ip[\$3]++}END{for (i in ip){if(ip[i]>11){system("/usr/sbin/nft insert rule inet NFT_FILTER NFC_INPUT handle 5 iifname enp1s0 ip saddr "i" reject;/usr/sbin/nft -a list ruleset >| ${rulefile};/usr/bin/echo \"\$(/usr/bin/hostname) ban "i" for connected "ip[i]" times in 1 hour\" >> /tmp/baninfo")}}}';[ -e /tmp/baninfo ] && /usr/bin/cat /tmp/baninfo | /usr/bin/mail -s "Ban Info" XXXXX@XX.com && /usr/bin/rm -f /tmp/baninfo
EOF
[root@RHEL8 ~]# sh awknftban.sh 
[root@RHEL8 ~]# crontab -l
0 * * * * /usr/bin/lastb | /usr/bin/awk -v hourago="$(/usr/bin/date --date='1 hour ago' '+\%a \%b \%e \%H:')" '$0~hourago{ip[$3]++}END{for (i in ip){if(ip[i]>11){system("/usr/sbin/nft insert rule inet NFT_FILTER NFC_INPUT handle 5 iifname enp1s0 ip saddr "i" reject;/usr/sbin/nft -a list ruleset >| /etc/nftables/rhel8.nft;/usr/bin/echo \"$(/usr/bin/hostname) ban "i" for connected "ip[i]" times in 1 hour\" >> /tmp/baninfo")}}}';[ -e /tmp/baninfo ] && /usr/bin/cat /tmp/baninfo | /usr/bin/mail -s "Ban Info" XXXXX@XX.com && /usr/bin/rm -f /tmp/baninfo

在knock-server中使用nft語句
由於nft語句刪除rule需要指定handle,但是handle需要增加rule的時候才能得到,這就造成了nft在knock-server中開門容易關門難的困境,於是我打算用replace修改其中一個已知handle的rule來解決這個問題,例如選擇5號handle

[root@RHEL8 ~]# nft -a list chain inet NFT_FILTER NFC_INPUT
table inet NFT_FILTER {
	chain NFC_INPUT { # handle 1
		type filter hook input priority filter; policy drop;
		ct state established,related accept # handle 2
		meta l4proto icmp accept # handle 3
		iifname "lo" accept # handle 4
		iifname "enp1s0" tcp dport 22 accept # handle 5
		iifname "enp2s0" udp dport 67 accept # handle 6
	}
}
[root@RHEL8 ~]# nft replace rule inet NFT_FILTER NFC_INPUT handle 5 iifname enp1s0 ip saddr 127.0.0.1 tcp dport 33333 accept
[root@RHEL8 ~]# nft -a list chain inet NFT_FILTER NFC_INPUT
table inet NFT_FILTER {
	chain NFC_INPUT { # handle 1
		type filter hook input priority filter; policy drop;
		ct state established,related accept # handle 2
		meta l4proto icmp accept # handle 3
		iifname "lo" accept # handle 4
		iifname "enp1s0" ip saddr 127.0.0.1 tcp dport 33333 accept # handle 5
		iifname "enp2s0" udp dport 67 accept # handle 6
	}
}
[root@RHEL8 ~]# nft replace rule inet NFT_FILTER NFC_INPUT handle 5 iifname enp1s0 tcp dport 22 accept
[root@RHEL8 ~]# nft -a list chain inet NFT_FILTER NFC_INPUT
table inet NFT_FILTER {
	chain NFC_INPUT { # handle 1
		type filter hook input priority filter; policy drop;
		ct state established,related accept # handle 2
		meta l4proto icmp accept # handle 3
		iifname "lo" accept # handle 4
		iifname "enp1s0" tcp dport 22 accept # handle 5
		iifname "enp2s0" udp dport 67 accept # handle 6
	}
}
指令碼自動化
[root@centos7 ~]# cat rhel8route-nfs.sh 
#rhel8route-nfs.sh
#Date: 2024-11-13
#!/bin/bash

#填寫wan網段網路卡名和ip
wanif='enp1s0'
wanip='192.168.5.254'

#填寫dmz和lan網段的網路卡名和ip/掩碼(CIDR)
dmzif='enp2s0'
lanif='enp3s0'
dmzip='172.31.0.254/24'
lanip='10.31.0.254/24'

#填寫nft防火牆自定義規則存放檔案路徑
rulefile='/etc/nftables/rhel8.nft'

#配置wan網段引數
wan_netmask=$(nmcli connection show ${wanif} | sed -En 's/IP4.ADDRESS\[1\]: +.+\/([[:digit:]]+)$/\1/p')
wan_gateway=$(nmcli connection show ${wanif} | sed -En 's/^IP4.GATEWAY: +(.+)$/\1/p')
wan_dns1=$(nmcli connection show ${wanif} | sed -En 's/^IP4.DNS\[1\]: +(.+)$/\1/p')
wan_dns2=$(nmcli connection show ${wanif} | sed -En 's/^IP4.DNS\[2\]: +(.+)$/\1/p')
wanip=${wanip}/${wan_netmask}
nmcli connection modify ${wanif} ipv4.method manual ipv4.addresses ${wanip}
nmcli connection modify ${wanif} ipv4.gateway ${wan_gateway}
nmcli connection modify ${wanif} ipv4.dns ${wan_dns1} +ipv4.dns ${wan_dns2}
nmcli connection up ${wanif}

#配置dmz和lan兩個網段的網路引數
nmcli connection delete ${dmzif}
nmcli connection delete ${lanif}
nmcli connection add type ethernet autoconnect yes con-name ${dmzif} ifname ${dmzif} ipv4.method manual ipv4.addresses ${dmzip}
nmcli connection add type ethernet autoconnect yes con-name ${lanif} ifname ${lanif} ipv4.method manual ipv4.addresses ${lanip}
nmcli connection up ${dmzif}
nmcli connection up ${lanif}
dmznet=$(echo ${dmzip} | sed -En 's#([[:digit:]]+.[[:digit:]]+.[[:digit:]]+.)[[:digit:]]+(/[[:digit:]]+)#\10\2#p')
lannet=$(echo ${lanip} | sed -En 's#([[:digit:]]+.[[:digit:]]+.[[:digit:]]+.)[[:digit:]]+(/[[:digit:]]+)#\10\2#p')

#開啟IP forward
echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/ipforward.conf
sysctl -p /etc/sysctl.d/ipforward.conf

#配置使用nftables來管理防火牆
rpm -q nftables || yum install -y nftables
systemctl mask firewalld.service iptables.service
systemctl stop firewalld.service iptables.service
echo "include \"${rulefile}\"" >> /etc/sysconfig/nftables.conf
touch ${rulefile}
systemctl enable --now nftables.service

#配置防火牆規則
nft flush ruleset

nft add table inet NFT_FILTER
nft add chain inet NFT_FILTER NFC_INPUT { type filter hook input priority filter \; policy drop \; }
nft add rule inet NFT_FILTER NFC_INPUT ct state established,related accept
nft add rule inet NFT_FILTER NFC_INPUT meta l4proto icmp accept
nft add rule inet NFT_FILTER NFC_INPUT iifname lo accept
nft add rule inet NFT_FILTER NFC_INPUT iifname ${wanif} tcp dport 22 accept
nft add rule inet NFT_FILTER NFC_INPUT iifname enp2s0 udp dport 67 accept

nft add table inet NFT_NAT
nft add chain inet NFT_NAT NFC_PRE { type nat hook prerouting priority dstnat \; policy accept \; }
nft add rule inet NFT_NAT NFC_PRE iifname ${wanif} tcp dport 62223 dnat ip to 10.31.0.1:22

nft add chain inet NFT_NAT NFC_POST { type nat hook postrouting priority srcnat \; policy accept \; }
nft add rule inet NFT_NAT NFC_POST iifname ${dmzif} oifname ${wanif} ip saddr ${dmznet} masquerade
nft add rule inet NFT_NAT NFC_POST iifname ${lanif} oifname ${wanif} ip saddr ${lannet} masquerade

nft -a list ruleset >| ${rulefile}

#寫入計劃任務
#1.自動拉黑每小時登入失敗超過指定次數的IP
cat << EOF >> /var/spool/cron/root
0 * * * * /usr/bin/lastb | /usr/bin/awk -v hourago="\$(/usr/bin/date --date='1 hour ago' '+\%a \%b \%e \%H:')" '\$0~hourago{ip[\$3]++}END{for (i in ip){if(ip[i]>11){system("/usr/sbin/nft insert rule inet NFT_FILTER NFC_INPUT handle 5 iifname enp1s0 ip saddr "i" reject;/usr/sbin/nft -a list ruleset >| ${rulefile};/usr/bin/echo \"\$(/usr/bin/hostname) ban "i" for connected "ip[i]" times in 1 hour\" >> /tmp/baninfo")}}}';[ -e /tmp/baninfo ] && /usr/bin/cat /tmp/baninfo | /usr/bin/mail -s "Ban Info" xxxxx@xx.com && /usr/bin/rm -f /tmp/baninfo
EOF

相關文章