Part2——nftables基础防护配置
这里有两台机子,因此nftables的配置需要根据不同的机子分别来配。
第一台是运行mc服务端的机器,这里统一称为MC机
,为了保证性能需求,这台机子上只部署一个MCSManager面板+节点,因此MC机默认将需要额外暴露三个端口:
23333
——MCSManager的网页后台24444
——MCSManager可用的节点25565
——默认的MC服务器udp连接用端口
然后第二台是给MC机以上端口配反代和跳板的机器,这里统一称为跳板机
,这台机子上需要部署的是docker和NPM,因为需要nginx,自然跳板机将需要暴露80、443
端口。接下来分别配置这两台机器的nftables防火墙。
MC机:
首先明确需求,在MC机上我们将使用nftables禁止任何人通过ip:port
的方式访问23333
跟24444
端口,仅允许跳板机的NPM/白名单ip访问这两个端口,从而将MCSManager给藏起来。
对于25565
端口,也就是连接mc游戏服务器用的udp端口,有下面几种处理方法,能单独用也能一起用:
- 像更换ssh端口一样更换
25565
端口 - 只允许通过跳板机/白名单ip来访问MC机的
25565
端口 - 使用cf的srv来访问MC机/跳板机
这里采用的处理组合是:
- 不更换MC机设置的
25565
端口,但是nftables设置25565
端口仅允许跳板机/白名单ip访问 - 使用跳板机的NPM将MC机的
25565
端口转发到跳板机的25555
端口 - 最后,使用cf的srv记录来访问跳板机的
25555
端口
其实我也不知道要防什么东西,私人服务器搞这么复杂的处理其实会显得有点多余,不过这样做能够最大程度的保护你的MC机的ip不被泄露(对的只是MC机,跳板机还是需要暴露的只不过不是裸体这样子),另外按照我的理解,srv还能通过调整权重来达到多跳板机分流/均衡负载的效果,不过这些都有点偏题,这里就不详细展开了。
跳板机:
根据MC机的配置,很明显我们需要开放25555
端口,另外由于反代用的NPM是部署在跳板机上的,因此80、443
端口也需要开放,关于Docker和NPM的部署可以参照部署komga的另外一篇博文,这里的NPM的部署方式跟那篇博文是一模一样的。
以上是基础概念,接下来进入实战,为了防止配置冲突导致额外问题,请事先确认自己的系统使用的是nftables而不是iptables,iptables跟ufw需要提前卸载。
MC机nftables详细配置:
MC机上的服务比较单一,我们使用单个配置文件解决。debian12默认的nftables配置文件在/etc/nftables.conf
,使用nano /etc/nftables.conf
打开:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0;
# 允许来自环回接口的流量
iifname "lo" accept
# 允许已建立的连接和相关的连接
ct state {established, related} accept
# 允许来自 跳板机/NPM 1.2.3.4 的所有流量(白名单ip也可以加在这里)
ip saddr 1.2.3.4 accept
# 选择性是否开放 25565 端口 (TCP 和 UDP),开放就取消下面两行的注释
# tcp dport 25565 accept
# udp dport 25565 accept
# 允许有限的 ICMP (ping) 流量,并限制 ping 的速率
icmp type echo-request limit rate 5/second accept
icmp type echo-request drop
icmpv6 type echo-request limit rate 5/second accept
icmpv6 type echo-request drop
# 允许 SSH (确保更改端口号),限制速率,记录被drop的扫狗SSH连接
ip daddr 1.2.3.5(替换成你MC机的ip) tcp dport 12345(之前修改的ssh端口号) ct state new limit rate 10/minute accept comment "IPv4 SSH"
ip daddr 1.2.3.5(替换成你MC机的ip) tcp dport 12345(之前修改的ssh端口号) log prefix "SSH IPv4 Dropped: " drop
# 阻止 23333, 24444 端口直连
tcp dport {23333, 24444} drop
# 默认策略:丢弃所有其他流量
drop
}
chain forward {
type filter hook forward priority 0;
drop
}
chain output {
type filter hook output priority 0;
accept
}
}
保存退出,应用配置:
sudo nft -f /etc/nftables.conf
应用完成后,尝试使用白名单之外的ip,如果没设置白名单那就是任意ip尝试访问MC机的ip:23333/24444
看看是不是无法访问,如果无法访问就证明MC机上的nftables配置已经正常生效。
跳板机nftables详细配置:
跳板机上的服务比较多样,像MC机一样使用单一的nftables.conf
配置文件会显得很乱,所以我们来使用模块化配置方法,以下部分内容是从Protect Your Incus Server with NFtables学来的,我让gpt分析了一下他的nftables配置,评价是“十分健壮”,因此选择基于他的配置来修改。
模块化nftables配置结构:
/etc/nftables.conf # 主配置文件
/etc/nftables.d/ # 模块化规则目录
├── vars.conf # 变量定义
├── base-fw.nft # 基础防火墙规则
└── ssh.nft # ssh专用规则
还是那句,为了防止配置冲突导致额外问题,请事先确认自己的系统使用的是nftables而不是iptables,iptables跟ufw需要提前卸载。
因为这台机子上有使用Docker部署的NPM,因此会有docker0跟npm容器的br网桥,先执行ip a
记下两个网桥的名字,一般是就叫docker0
跟br-一串乱码
。
首先备份原来的nftables.conf
:
cp /etc/nftables.conf /etc/nftables.conf_orig_bu
创建nftables.d文件夹:
mkdir -p /etc/nftables.d
创建新的nftables.conf
文件,nano /etc/nftables.conf
:
#!/usr/sbin/nft -f
flush ruleset
# Include the variables file only once
include "/etc/nftables.d/vars.conf"
# Include all other configuration files
include "/etc/nftables.d/*.nft"
可以看见这里的结构很简单,可以把它当作只是一个入口而已,详细的变量和规则都在nftables.d文件夹里面配置。
入口搞定,接下来是/etc/nftables.d/vars.conf
:
#!/usr/sbin/nft -f
# Define interfaces
# 你的wan网卡可能未必叫"eth0",请用ip a检查
define WAN = "eth0"
define DOCKER = "docker0"
define BRIDGE = "br-一串乱码"
# Host IP addresses for the WAN interface
define IPV4 = "跳板机的ipv4地址" # Replace with your IPv4 address
define IPV6 = "跳板机的ipv6地址" # Replace with your IPv6 address
# SSH port for secure management
define SSH_PORT = 12345
然后是/etc/nftables.d/base-fw.nft
:
#!/usr/sbin/nft -f
table inet filter {
# Define allowed ICMP types
set icmp_allowed_types {
type icmp_type
elements = { destination-unreachable, time-exceeded, parameter-problem }
}
set icmpv6_allowed_types {
type icmpv6_type
elements = { destination-unreachable, packet-too-big, time-exceeded, parameter-problem,
nd-router-advert, nd-neighbor-advert, nd-router-solicit, nd-neighbor-solicit }
}
# IPv4 inbound chain
chain inbound_ipv4 {
icmp type @icmp_allowed_types accept
icmp type echo-request limit rate 5/second accept
}
# IPv6 inbound chain
chain inbound_ipv6 {
icmpv6 type @icmpv6_allowed_types accept
icmpv6 type echo-request limit rate 5/second accept
}
# Main inbound chain
chain inbound {
type filter hook input priority 0; policy drop;
# Connection tracking
ct state vmap { established : accept, related : accept, invalid : drop }
# Allow loopback
iifname lo accept
# mailx
ip daddr 127.0.0.1 tcp dport 25 accept
# Route IPv4/IPv6 traffic
meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 }
# Docker
iifname $DOCKER tcp dport { 80, 443, 25555 } accept
iifname $BRIDGE tcp dport { 80, 443, 25555 } accept
iifname $DOCKER udp dport { 80, 443, 25555 } accept
iifname $BRIDGE udp dport { 80, 443, 25555 } accept
# TCP security measures
tcp flags & (fin|syn|rst|ack) != syn ct state new drop
tcp flags & (fin|syn|rst|psh|ack|urg) == fin|syn|rst|psh|ack|urg drop
tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop
# Logging
log prefix "DROP IN: " level info
# Drop fragments
ip frag-off & 0x1fff != 0 drop
}
# Forward chain
chain forward {
type filter hook forward priority 0; policy drop;
ct state established,related accept
# Docker
iifname $BRIDGE oifname $WAN accept
iifname $WAN oifname $BRIDGE ct state new accept
log prefix "DROP FORWARD: " level info
}
# Outgoing chain
chain outgoing {
type filter hook output priority 0; policy accept;
}
}
最后是/etc/nftables.d/ssh.nft
:
#!/usr/sbin/nft -f
table inet filter {
chain inbound {
# Allow SSH access
ip daddr $IPV4 tcp dport $SSH_PORT ct state new limit rate 10/minute accept comment "IPv4 SSH"
ip6 daddr $IPV6 tcp dport $SSH_PORT ct state new limit rate 10/minute accept comment "IPv6 SSH"
# Log and drop excessive SSH attempts
ip daddr $IPV4 tcp dport $SSH_PORT log prefix "SSH IPv4 Dropped: " drop
ip6 daddr $IPV6 tcp dport $SSH_PORT log prefix "SSH IPv6 Dropped: " drop
}
}
应用配置:
sudo nft -f /etc/nftables.conf
检查已启用的nftables规则:
sudo nft list ruleset
注意,每次使用sudo nft -f /etc/nftables.conf
,或者准确来说是每次执行过nftables.conf
里的flush ruleset
之后,Docker使用的iptables-nft
兼容规则都会被清除掉,这意味着这个时候你是无法访问NPM/反代好的MCSManager面板的,每次执行完sudo nft -f /etc/nftables.conf
/flush ruleset
后,你需要手动重启一次docker:
# 重启docker命令二选一执行
service docker restart
systemctl restart docker
到这里,基于nftables防火墙和fail2ban的服务器基础防护就算是做完了。
发表回复