debian11_nftables/ip6tables_限制ipv6公网访问特定端口_centos8/debian仅允许部分IPv4访问端口
转载注明来源: 本文链接 来自osnosn的博客,写于 2022-05-28.
参考
限制ipv6公网访问特定端口
背景环境
- 现在有不少家用的路由器,比如 TPLINK, 华为路由,都已经支持 ipv6 了。
但它们缺省都不允许从外网,通过ipv6访问内部的机器。 - 这些路由器的防火墙配置。对于ipv4,防火墙有一些端口映射的功能可以设置。对于ipv6,防火墙就只有一个开关。
关闭这个ipv6防火墙开关之后,其实就把内网的机器完全暴露出去了。 - 这时候,就需要你自己去配置,内网机器自身的防火墙规则,从而保护内网服务器。
仅限制tcp端口的ipv6访问
- 这是个简单的例子。只是为了限制某几个端口的ipv6公网访问。
- debian 安装 nftables包。激活nftables服务,
apt install nftables; systemctl enable nftables;
- 如果系统有什么 restore-iptables 的服务,关掉它。
- 可以看到 /etc/nftables.conf 中有。
#!/usr/sbin/nft -f flush ruleset table inet filter { chain input { type filter hook input priority 0; policy accept; } chain forward { type filter hook forward priority 0; policy accept; } chain output { type filter hook output priority 0; policy accept; } }
- 只需要加一行变量定义,增加两行规则,就可以针对ipv6,限制端口从外网访问。比如限制22,8888,1080 三个tcp口。改为,
这个规则只影响ipv6,不影响ipv4。#!/usr/sbin/nft -f define ipv6_ports = { 22,8888,1080 } flush ruleset table inet filter { chain input { type filter hook input priority 0; ct state { established,related } accept ip6 saddr { fd00::/8, fe80::/64 } tcp dport $ipv6_ports ct state { new, untracked } accept; ip6 saddr ::/0 tcp dport $ipv6_ports ct state { new, untracked } drop; } chain forward { type filter hook forward priority 0; } chain output { type filter hook output priority 0; } }
- 或者加一行变量定义,只加一行规则,更简单。
这个规则只影响ipv6,不影响ipv4。#!/usr/sbin/nft -f define ipv6_ports = { 22,8888,1080 } flush ruleset table inet filter { chain input { type filter hook input priority 0; ct state { established,related } accept ip6 saddr != { fd00::/8, fe80::/64 } tcp dport $ipv6_ports ct state { new, untracked } drop; } chain forward { type filter hook forward priority 0; } chain output { type filter hook output priority 0; } }
- 增加规则中,可以用 drop,也可用 reject,看你自己喜欢。
drop,访问时,没反应。
reject,访问时,马上返回 Connection refused。 policy accept;
可以不写,因为默认就是 accept。- 修改后,执行
nft -f /etc/nftables.conf
生效。
或者重启整个系统。
nft 命令行
以上增加的规则,其实对应以下几条命令。
nft insert rule inet filter input ct state { established,related } accept
nft insert rule inet filter input ip6 saddr { fe80::/64,fd00::/8} tcp dport { 22,8888,1080 } ct state { new, untracked } accept
nft add rule inet filter input ip6 saddr ::/0 tcp dport { 22,8888,1080 } ct state { new, untracked } drop
#----分割线,上面两行和下面一行的效果是一样的。二选一。----
nft insert rule inet filter input ct state { established,related } accept
nft add rule inet filter input ip6 saddr != { fe80::/64,fd00::/8} tcp dport { 22,8888,1080 } ct state { new, untracked } drop
- nft设置 NAT端口映射例子,还有个参考【NAT 端口映射】。
ip6tables 命令行
如果系统没装 nftables,只有 iptables。则用下面三条规则。
第一条禁止所有的ipv6访问。后两条允许本地的ipv6访问,插入在第一条前面。
ip6tables -A INPUT -p tcp -m state --state NEW,UNTRACKED --dport 8888 -j DROP
ip6tables -I INPUT -s fd00::/8 -p tcp -m state --state NEW,UNTRACKED --dport 8888 -j ACCEPT
ip6tables -I INPUT -s fe80::/64 -p tcp -m state --state NEW,UNTRACKED --dport 8888 -j ACCEPT
#多个端口,参考这个写法
ip6tables -I INPUT -s fd00::/8 -p tcp -m state --state NEW,UNTRACKED -m multiport --dports 8888,1080 -j ACCEPT
为了重启系统后,保持有效。有三个办法,任选一种。
- 把三条指令,写入 /etc/rc.local 中。
- 用
ip6tables-save -f myrule
保存,在 /etc/rc.local 中执行ip6tables-restore myrule
恢复。 - 装一个 restore-iptables 的服务,或者试试
apt install iptables-persistent
包。
仅允许部分IPv4访问端口
背景
需要对部分端口做IP来源限制
centos8 仅允许部分IP访问WEB端口
系统有 firewalld 服务的情况下。
#------ CLOSE http https FOR ALL BUT iplist ----------
firewall-cmd --new-zone=my_limit --permanent # 创建一个新 zone
firewall-cmd --get-zones
firewall-cmd --reload # 激活这个 zone,否则不能对这个zone操作
firewall-cmd --zone=my_limit --add-source=10.11.22.0/24 --permanent # 添加允许的网段
firewall-cmd --zone=my_limit --add-source=10.33.44.0/24 --permanent # 添加允许的网段
firewall-cmd --zone=my_limit --add-service http --permanent # 添加允许的服务
firewall-cmd --zone=my_limit --add-service https --permanent
firewall-cmd --remove-service http --permanent #从 public zone 移除服务
firewall-cmd --remove-service https --permanent
firewall-cmd --reload
#------ OPEN http https FOR ALL ----------
firewall-cmd --zone=my_limit --remove-service http --permanent #从my_limit 中移除服务
firewall-cmd --zone=my_limit --remove-service https --permanent
firewall-cmd --add-service http --permanent # 在public中添加服务
firewall-cmd --add-service https --permanent
firewall-cmd --reload
#-----other cmd-----------
firewall-cmd --zone=my_limit --remove-source=10.11.22.0/24 #移除允许的网段
firewall-cmd --zone=my_limit --list-sources #查看my_limit 中的ip
firewall-cmd --zone=my_limit --list-all #查看my_limit 的所有
firewall-cmd --list-all-zones
#--------------------------
debian 仅允许部分IP访问WEB端口
- debian 安装
iptables
包之后。- iptables 命令生成,其实用的是
xtables-nft-multi
命令。
这个命令是把 iptables的规则命令,翻译为 nft规则命令,写入nftables中。 - iptables-legacy 命令是
xtables-legacy-multi
,才是真正的,老的iptables命令。 - 一旦执行过iptables-legacy,内核会加载
iptable_filter
模块。
再执行iptables,就会给出Warning
,说有旧模式的iptables在使用。
- iptables 命令生成,其实用的是
- 从iptables规则直接翻译为nft规则,其实并不好用。nft的很多高级特性都用不上。
还不如安装nftables
包,直接用原生的 nft规则编写。
iptables命令行 ipv4
- 限制本机的端口
iptables -A INPUT -p tcp -m state --state NEW,UNTRACKED --dport 80 -j DROP iptables -I INPUT -s 202.123.123.0/24 -p tcp -m state --state NEW,UNTRACKED --dport 80 -j ACCEPT #多端口写法 #iptables -A INPUT -p tcp -m state --state NEW,UNTRACKED -m multiport --dports 80,443 -j REJECT
- 有的系统没有
-m state --state
就换-m conntrack --ctstate
这两没区别,是一样的。 - 限制所有tcp端口
iptables -A INPUT -p tcp -m state --state NEW,UNTRACKED -j DROP
- 为了方便维护/修改,可以创建一个自定义chain,然后把上面的规则都写入到这个自定义chain中。
需要修改时,iptables -F port_limit
直接清空这个chain的内容,重新添加规则。iptables -t filter -N port_limit #自定义chain iptables -t filter -I INPUT -j port_limit #插入INPUT表中,第一条
- 限制nat转发端口
在 FORWARD 中限制。
或在 nat 的 PREROUTING 中限制。iptables -t filter -N port_forward #自定义chain iptables -t filter -I FORWARD -j port_forward #插入FORWORD表中 iptables -I port_forward -s 202.123.123.0/24 -m state -o virbr0 -d 192.168.122.0/24 --state NEW,UNTRACKED -j ACCEPT
- 在 filter 的 INPUT 中,对nat端口是无效的。
因为数据包被prerouting 处理后(目标非本地的包)转向了 forward表,不经过input表。
nft 命令行 ipv4
- 限制本机的端口
具体的插入位置,用nft list ruleset
查看,自己机器中已有的 nft chain,找到 filter hook input 的 chain。
没有的话,自己创建一个chain。
在我机器上,在table ip filter { chain INPUT { type filter hook input priority 0; } }
nft insert rule ip filter INPUT ip saddr {202.123.123.0/24, 123.23.23.0/24} ct state { new, untracked } tcp dport {80,443} counter accept nft add rule ip filter INPUT ct state { new, untracked } tcp dport {80,443} counter reject
- 限制所有tcp端口
nft add rule ip filter INPUT meta l4proto tcp ct state { new, untracked } counter reject
- 为了方便维护/修改,可以创建一个自定义chain,然后把上面的规则都写入到这个自定义chain中。
需要修改时,nft flush chain ip filter port_limit
直接清空这个chain的内容,重新添加规则。nft add chain ip filter port_limit #自定义chain nft insert rule ip filter INPUT jump port_limit #插入INPUT表中,第一条
- 限制nat转发端口
类似,找到 filter hook forward 的 chain,写入转发规则限制即可。
没有的话,自己创建一个chain。
在我机器上,在table ip filter { chain FORWARD { type filter hook forward priority 0; } }
nft add chain ip filter port_forward #自定义chain nft insert rule ip filter FORWARD jump port_forward #插入FORWORD表中 nft insert rule ip filter port_forward oifname "virbr0" ip saddr {202.123.123.0/24, 123.23.23.0/24} ip daddr 192.168.122.0/24 ct state new counter accept
nft 本地端口重定向
- 需要
nat hook prerouting
的chain,通常没有,自己创建一个chain。
如果要限制来源ip,在input chain中限制 22口就可以了。目的地,为本机的数据包,是要经过 input表的,到达input表时,目标端口已经是 22。nft add table ip nat nft add chain ip nat prerouting '{ type nat hook prerouting priority dstnat ; }' nft add rule ip nat prerouting tcp dport 1234 redirect to :22
- iptables
iptables -t nat -A PREROUTING -p tcp --dport 1234 -j REDIRECT --to-port 22
OpenWRT 在 fw4 中使用 ipset 匹配来源 IP
- op-22 使用的是 fw4,即 nft。
op-21 以及之前的版本用的是 fw3,即 iptables。 - op-22.03.03,
luci-app-firewall - git-23.035.45612
。
web luci页面,无法配置 ipset,也无法把 ipset 配置到规则中使用。
只能手工编辑 firewall 配置文件,或者使用 "uci" 命令配置。 - 升级
luci-app-firewall
到最新,web luci 就有 ipset的配置。
用命令升级,opkg upgrade luci-app-firewall
。luci-app-firewall - git-23.089.66165
luci-app-firewall - git-23.093.42704
(目前最新的版本)。
web luci页面就可以配置 ipset。IP列表文件 上传到/etc/luci-uploads/
目录中。
ipset 配置中,Packet Field Match
只能选取一个,不能填写 comment,否则出错。
不支持 iprange。
规则配置中,高级设置,有"Use ipset"的选项。
- 无论 web luci是否支持 ipset配置,手工设置总是 有效的。
- fw4 下,使用 ipset。【官方文档 IP sets】,【官方例子 fw3_config_ipset】
以下是针对luci-app-firewall - git-23.035.45612
,web luci无 ipset配置。
使用 手工编辑 firewall 配置文件,或者使用 "uci" 命令配置。- 在
/etc/config/firewall
添加以下配置行。
net_list.txt 文件如下,config ipset option name 'main_allowed' option family 'ipv4' option match 'src_net' #支持网段 和 IP #option match 'net' #rule 中要指定 src 或 dest #option match 'src_ip' #仅支持 IP。不识别网段。 ##option maxelem '256' #不需设置,除非这个ipset会 动态添加element option enabled '1' list entry '10.12.34.0/24' option loadfile '/root/net_list.txt'
"list entry" 和 "option loadfile" 可以混用。结果是它们的"合集"。# 支持 空行,支持 注释。 空行和注释会被忽略 10.12.45.0/24 10.34.56.78 10.45.67.0/24
用命令fw4 check
检查无错误。用命令fw4 restart
重启防火墙。 - "match" 是 "net",支持网段/IP。会在
table inet fw4 { }
中生成一个集合 set,
set main_allowed { type ipv4_addr; flags interval; auto-merge; }
- "match" 是 "ip",仅支持IP,写网段也会 识别为 IP。生成的集合 set,
则是set main_allowed { type ipv4_addr; }
option maxelem '0'
正常 不设置,默认值是 0,添加的条目没限制。似乎也不会预分配内存,没见到内存空间占用变大。
如果设置,会限制添加条目的数量,似乎还会预分配内存。如果设置 65536,会见到内存占用升高。(2023-04测试,op22.03.3, luci-app-firewall git-23.035)
如果某个 rule 会动态添加条目到这个 ipset,就必须设置,限制一下数量,防止条目太多而内存溢出。- uci 的例子。
uci batch << EOI add firewall ipset #set firewall.main_allowed='ipset' set firewall.@ipset[-1].name="main_allowed" set firewall.@ipset[-1].match="src_net" set firewall.@ipset[-1].enabled="1" add_list firewall.@ipset[-1].entry="10.12.34.0/24" set firewall.@ipset[-1].loadfile="/root/net_list.txt" commit firewall EOI
- 在
/etc/config/firewall
中,找到需要匹配来源 IP 的 rule,
删除这个 rule中 所有的list src_ip ...
,
加入一行option ipset 'main_allowed src'
。
例子如下,
重启防火墙生效。config rule option name 'web-server' option ipset 'main_allowed src' #无论 ipset中是否有定义,都按照 src匹配。 #option ipset 'main_allowed' #按照ipset 的 match定义中的src或dest。如无,默认是src。 #option ipset '!main_allowed src' #“!”后有无空格都行,匹配 不在ipset中的IP。 option target 'ACCEPT' option dest_port '80 443' option src '*'
/etc/init.d/firewall restart
或fw4 restart
。- 如果
list src_ip ...
和option ipset
混用,结果是要满足两种配置的"交集"才能访问。
- 如果
- 手工配置好 ipset 之后。在 web luci 中也见不到这个 ipset。(2023-04测试,op22.03.3, luci-app-firewall git-23.035)
- 上面的这个"web-server"规则。在 web luci 的 "Traffic Rules" 中,能见到这个 rule,但见不到 ipset的设置。
在 web luci 中修改这个"web-server"规则,不会丢失option ipset
的配置。(2023-04测试,op22.03.3, luci-app-firewall git-23.035)
添加 "source address" 等于添加list src_ip '4.3.2.0/24'
,会导致实际的来源 IP,必须匹配 两种配置的"交集"。
因为rule是这样的ip saddr { 4.3.2.0/24 } tcp dport { 80, 443 } ip saddr @main_allowed counter accept
清空 "source address",不丢失option ipset
的配置,规则还是最初的效果。
- 在
- fw4 还支持
config include
添加自定义 rule。
见【官方文档 includes_for_2203_and_later_with_fw4】。 - fw4 的 web luci 界面,配置 ipset 不支持 iprange,(目前最新是 luci-app-firewall git-23.093)。
而 "match" 是 "net" 时,生成集合 set 是包含 "flags interval",即支持iprange。
可以通过以下两种办法(二选一),添加 ipset 的 element,使用iprange。
假设你在 web luci 中,添加一个 ipset,名称是 "main_allowed"。- 或,创建文件
/usr/share/nftables.d/ruleset-post/add-element.nft
,如果对应目录不存在,则自己创建目录。# file: add-element.nft add element inet fw4 main_allowed { 10.12.45.100-10.12.45.200}
- 或,在 /etc/config/firewall 中添加,
config include option enabled 1 option type 'script' option path '/etc/add-ipset-element.sh' option fw4_compatible 1
#!/bin/sh # file: add-ipset-element.sh nft add element inet fw4 main_allowed { 10.12.45.100-10.12.45.200}
- 或,创建文件
PVE 的防火墙配置
禁止某ip访问特定端口
- 并统计数据包:
nft add rule inet filter input ip saddr 170.64.134.97 tcp dport 22 counter drop
限制sshd的登录
- 安装 fail2ban 来防止无限制(次数)猜密码。或者用防火墙规则,限制连接数。
参考【Debian10_Centos8_fail2ban_sshd算法_限制连接数】
----end----
转载注明来源: 本文链接 https://www.cnblogs.com/osnosn/p/16320603.html
来自 osnosn的博客 https://www.cnblogs.com/osnosn/ .