苏苏的博客

简约至极

Linux的防火墙iptables与firewalld

iptables相关配置

配置iptables之前,建议添加一个crontab定时重置iptables,防止将自己阻挡.

建议写入/usr/iptab.sh,加入crontab,每个整点执行

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
iptables -X
iptables -Z

查看本机关于IPTABLES的设置情况

iptables -L -n

清除原有规则.

不管你在安装linux时是否启动了防火墙,如果你想配置属于自己的防火墙,那就清除现在filter的所有规则. 清除预设表filter中的所有规则链的规则

iptables -F

清除预设表filter中使用者自定链中的规则

iptables -X

保存配置

刚刚配置的重启以后就会丢失,想要保存使用

iptables save

有的可能是iptables-save

这样就写到/etc/sysconfig/iptables 文件里了. 写入后记得把防火墙重起一下,才能起作用.

service iptables restart

设定预设规则

默认的入口,出口,转发策略都是ACCEPT 下面要改变这种规则

iptables 采用黑名单加白名单的方式, 未命中白名单的将采用预设规则

下面操作注意,为避免ssh端口22被拦截,首先添加

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

保证22端口入口畅通,注意如果你的OUTPUT模式设置为DROP(上面已经清空了,默认为ACCEPT),还需要添加

iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT

保证出口22端口畅通 下面开始折腾吧

1.修改入口流量默认规则为DROP,除非命中用户规则,否则拦截所有入口流量(注意上面一定要排除ssh的端口,否则直接掉线)

iptables -P INPUT DROP

如果你使用了docker,这里好像会对docker的网络造成影响

2.允许所有出口流量(重置iptables时,这其实就是默认的规则)

iptables -P OUTPUT ACCEPT

3.禁止所有转发流量,除了命中用户规则的

iptables -P FORWARD DROP

查看流量统计

iptables -L -vn

iptables -L -vxn

常用端口开启

开启80,443端口,http,https服务

iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

开启21端口,ftp服务

iptables -A INPUT -p tcp --dport 21 -j ACCEPT

开启基本端口

允许icmp包通过,也就是允许ping

iptables -A INPUT -p icmp -j ACCEPT

允许loopback!(不然会导致DNS无法正常关闭等问题)

如果未启用此项,常见的fastcgi_pass 127.0.0.1 将会有问题

iptables -A INPUT -i lo -p all -j ACCEPT

iptables 配置实时生效,如果拦截了ssh端口,将立即掉线!

无论iptabes启动与否,ps -ef都不会看到iptables的进程,这是因为iptables是由内核来实现的,也就是说iptables的功能已经融入到内核里面了

iptables只是一个工具,将IP规则写入内核,让内核去处理。所以iptables只有在加规则的时候才会看得到进程,加完了就退出了

iptables并不是一个普通的daemon,只是一个普通的工具,添加一些规则到kernel的filter列表里面。

systemctl stop iptables 也与进程无关,他只是执行了/usr/libexec/iptables/iptables.init stop

将规则从内核清除到存到文件.

IP 拦截

拦截一个IP

iptables -I INPUT -s 1.2.3.4 -j DROP

解封此IP

iptables -D INPUT -s 1.2.3.4 -j DROP

参数-I是表示Insert(添加),-D表示Delete(删除)

INPUT表示入站,DROP表示放弃连接

IP段

192.168.1.x 可以写 192.168.1.0/24

192.168.x.x 可以写 192.168.0.0/16

192.x.x.x 可以写 192.0.0.0/8

iptables -I INPUT -s 112.198.0.0/16 -j DROP

iptables 过滤大量IP地址任然是挨个遍历,如需拦截数以万计的IP地址,需使用ipset,能获取最佳性能. yum info ipset -y 安装ipset

iptables -A INPUT -p tcp --dport 8000 -s 1.2.3.4 -j ACCEPT
iptables -A INPUT -p tcp --dport 8000 -j DROP

iptables -D INPUT 2

https://stackoverflow.com/questions/7423309/iptables-block-access-to-port-8000-except-from-ip-address

https://stackoverflow.com/questions/10197405/how-can-i-remove-specific-rules-from-iptables

路由黑洞

linux 黑洞路由命令 net-tool 用法 route add -host 10.10.0.1 127.0.0.1 -blackhole iprouter2 用法 ip route add blackhole 192.168.32.128/32

中国 ip 段获取

wget -O- 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | awk -F\| '/CN\|ipv4/ { printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > ./ignore.list

示例:拦截ssh登录失败次数过多的IP

lastb -i | awk '{print $3}' | sort | uniq -c | sort -nr | head -50 | awk '{print "ip route add blackhole ", $2}' | sort -n | uniq | sh

前面是找出登录失败过多的IP,后面使用awk拼接 ip route 命令并执行

使用 netstat -nr 或者 route -n 可以验证,这两个命令都可以查看 Kernel IP routing table

ip route add 的好处是会自动判断是否重复给出RTNETLINK answers: File exists,但不影响未重复的添加。比起iptables也更简单

可以存储为文件,定时执行 /home/block.sh

lastb -i | awk '{print $3}' | sort | uniq -c | sort -nr | head -50 | awk '{print "/usr/sbin/ip route add blackhole ", $2}' | sort -n | uniq | sh

crontab -e 每小时执行

0 * * * * sh /home/block.sh &>/dev/null

netstat -anltp | awk '{print $5}' | grep -E -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 0.0 | sort | uniq -c | sort -nr | head -10

netstat -anltp | awk '{print $5}' | grep -E -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 0.0 | sort | uniq -c | sort -nr | head -10 | awk '{print "ip route add blackhole ", $2 }'

查看路由黑洞信息 ip route show

删除黑洞

ip route del 192.168.0.195
ip route show

批量删除符合规则的IP ip route show | grep "0.0.0 " | awk {'print "ip route del ",$2'} | sh

清除所有blackhole的规则 ip route show | grep blackhole | grep -E -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | awk {'print "ip route del ",$1'} | sh

添加的IP也可以是一个网段 192.168.0.195/32

路由黑洞的工作原理就是将攻击者的IP引导到一个不存在的地址,从而直接丢弃。 当开启路由黑洞以后,攻击者到你服务器的TCP握手将不能成功,因为你的服务器根本不会响应SYN+ACK包,但是攻击者的SYN还是发过来了,这个阻止不了。所有UDP的包也不能阻止接受,但是服务器不会发送任何响应给攻击者。简单说就是攻击你没法阻止,但可以不回应。

路由黑洞 比 iptables 更节省cpu

无论是iptables还是路由黑洞,都是依次遍历查找,效率始终不如ipset,但ipset一个set最大支持65535个ip

iptable 与 route 区别

http://www.linuxforums.org/forum/newbie/186273-iptables-forwarding-vs-ip-route-post877996.html#post877996

https://superuser.com/questions/419659/iptables-vs-route

http://www.adminsehow.com/2011/09/iptables-packet-traverse-map/

参考 http://ximunix.blogspot.com/2015/02/howto-drop-or-block-attackers-ip.html

IPSET

创建一个ipset

ipset create xxx hash:net (也可以是hash:ip ,这指的是单个ip,xxx是ipset名称)

ipset默认可以存储65536个元素,使用maxelem指定数量

ipset create blacklist hash:net maxelem 1000000 #黑名单

ipset create whitelist hash:net maxelem 1000000 #白名单

查看已创建的ipset

ipset list

加入一个名单ip

ipset add blacklist 10.60.10.xx

去除名单ip

ipset del blacklist 10.60.10.xx

创建防火墙规则,与此同时,allset这个IP集里的ip都无法访问80端口(如:CC攻击可用)

iptables -I INPUT -m set –match-set blacklist src -p tcp -j DROP

iptables -I INPUT -m set –match-set blacklist src -p tcp –destination-port 80 -j DROP

Enable blacklists

iptables -I INPUT 1 -m set --match-set blacklist src -j DROP

将ipset规则保存到文件

ipset save blacklist -f blacklist.txt ipset save whitelist -f whitelist.txt

删除ipset

ipset destroy blacklist ipset destroy whitelist

导入ipset规则

ipset restore -f blacklist.txt ipset restore -f whitelist.txt

ipset -exist restore -f blacklist.txt可以忽略已有的当冲突时不报错

ipset -exist add blacklist 10.60.10.0

查看被拦截的数据包 iptables -L INPUT -v –line-numbers

输出类似

Chain INPUT (policy DROP 60 packets, 17733 bytes)
num   pkts bytes target            prot opt in  out source   destination
1       15  1349 DROP              all  --  any any anywhere anywhere     match-set blacklist src

有效期

在创建set时可以指定有效期,单位为秒

ipset create blacklist hash:ip timeout 300

set里添加的每一条记录自添加以后默认有效期就是指定的timeout值

到期后会自动清理

可以在添加记录时覆盖默认的有效期

ipset add blacklist 6.6.6.6 timeout 60

要修改一个条目的有效期,需要使用-exist

ipset -exist add blacklist 1.2.3.4 timeout 100

如果在创建集合时没有指定 timeout,那么之后添加条目也就不支持 timeout 参数,执行 add 会收到报错。

想要默认条目不会过期(自动删除),又需要添加某些条目时加上 timeout 参数,可以在创建集合时指定 timeout 为 0。

并发限制

iptable限制,控制单个IP的最大30并发连接数

sudo iptables -I INPUT -p tcp --dport 443 -m connlimit --connlimit-above 30 -j REJECT
sudo iptables -I INPUT -p tcp --dport 80 -m connlimit --connlimit-above 30 -j REJECT

端口转发

允许服务器的IP转发功能: echo 1 > /proc/sys/net/ipv4/ip_forward

iptables -t nat -A POSTROUTING -j MASQUERADE

iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 31521 -j DNAT --to 192.168.0.211:1521

相同端口后面可省略不写 iptables -t nat -I PREROUTING -p tcp --dport 1521 -j DNAT --to 192.168.0.211

iptables -t nat -A POSTROUTING -d 192.168.203.235 -p tcp --dport 80 -j MASQUERADE

http://www.dkys.org/archives/1075.html

  • 特别注明:本地服务器 IP 未必是公网 IP ,像阿里云就是内网 IP ,请用 ipconfig 确认下走流量的网卡 IP 是外网还是内网。

单端口转发(tcp、udp)

iptables -t nat -A PREROUTING -p tcp --dport [要转发的端口号] -j DNAT --to-destination [要转发的服务器IP]
iptables -t nat -A PREROUTING -p udp --dport [要转发的端口号] -j DNAT --to-destination [要转发的服务器IP]
iptables -t nat -A POSTROUTING -p tcp -d [要转发的服务器IP] --dport [要转发的端口号] -j SNAT --to-source [本机IP]
iptables -t nat -A POSTROUTING -p udp -d [要转发的服务器IP] --dport [要转发的端口号] -j SNAT --to-source [本机IP]

端口段转发(tcp、udp)

转发10000到20000这个端口段,则填10000:20000

iptables -t nat -A PREROUTING -p tcp --dport [要转发的端口段] -j DNAT --to-destination [要转发的服务器IP]
iptables -t nat -A PREROUTING -p udp --dport [要转发的端口段] -j DNAT --to-destination [要转发的服务器IP]
iptables -t nat -A POSTROUTING -p tcp -d [要转发的服务器IP] --dport [要转发的端口段] -j SNAT --to-source [本机IP]
iptables -t nat -A POSTROUTING -p udp -d [要转发的服务器IP] --dport [要转发的端口段] -j SNAT --to-source [本机IP]

我们可能需要将访问主机的7979端口映射到8080端口。也可以iptables重定向完成

iptables -t nat -A PREROUTING -p tcp --dport 7979 -j REDIRECT --to-ports 8080 更改iptables,使之实现nat映射功能

iptables -t nat -A PREROUTING  -p tcp --dport 21358 -j DNAT --to-destination 67.215.245.160:1358
iptables -t nat -A POSTROUTING -p tcp -d 67.215.245.160 --dport 1358 -j SNAT --to-source 101.200.151.143:21358

需求很简单,把本地81端口映射到8080端口上

  1. 所有的81请求转发到了8080上.

iptables -t nat -A PREROUTING -p tcp –dport 81 -j REDIRECT –to-ports 8080

1

iptables -t nat -A PREROUTING -p tcp –dport 81 -j REDIRECT –to-ports 8080

如果需要本机也可以访问,则需要配置OUTPUT链:

iptables -t nat -A OUTPUT -p tcp –dport 81 -j REDIRECT –to-ports 8080 1 iptables -t nat -A OUTPUT -p tcp –dport 81 -j REDIRECT –to-ports 8080 原因:外网访问需要经过PREROUTING链,但是localhost不经过该链,因此需要用OUTPUT,或者POSTROUTING。POSTROUTING不行,需要看看。


#清除配置
/sbin/iptables -P INPUT ACCEPT
/sbin/iptables -F
/sbin/iptables -X
#开放本地和Ping
/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A INPUT -p icmp -j ACCEPT
#配置内网白名单
/sbin/iptables -A INPUT -s 10.0.0.0/8 -j ACCEPT
/sbin/iptables -A INPUT -s 172.16.0.0/12 -j ACCEPT
/sbin/iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
#配置外网白名单
/sbin/iptables -A INPUT -s 180.168.36.198 -j ACCEPT
/sbin/iptables -A INPUT -s 180.168.34.218 -j ACCEPT
/sbin/iptables -A INPUT -s 222.73.202.251 -j ACCEPT
#控制端口
/sbin/iptables -A INPUT -p tcp --dport 80 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 22 -j ACCEPT
#拒绝其它
/sbin/iptables -A INPUT -j DROP
/sbin/iptables -A FORWARD -j DROP
#开放出口
/sbin/iptables -A OUTPUT -j ACCEPT

参考 http://liaoph.com/iptables/

firewalld

systemctl status firewalld 查看服务状态

firewall-cmd --state 常看当前的状态

firewall-cmd --get-active-zones 查看区域信息

查看某区域打开的端口 firewall-cmd --zone=public --list-ports 添加一个开放端口

firewall-cmd --zone=public --add-port=8080/tcp

开放一段端口 firewall-cmd --zone=public --add-port=6010-6060/tcp

add-port 后只是本次生效,并没有保存到配置文件内,执行firewall-cmd --reload未保存到配置文件内的就丢失了.

需要永久生效时,添加需加上--permanent,如 firewall-cmd --permanent --zone=public --add-port=9090/tcp

firewall-cmd --reload 生效

更多可参考 http://www.ywnds.com/?p=7570&viewuser=30 https://linux.cn/article-8098-1.html

firewalld 新添加的规则,对于已经建立好的链接是无效的,iptables的规则则是立即对所有链接生效.

如果要使用iptables而不用firewalld:

yum install -y iptables-services
systemctl stop firewalld
systemctl disable firewalld
systemctl enable iptables

流量转发

echo 1 > /proc/sys/net/ipv4/ip_forward
# 开启防火墙转发
firewall-cmd --permanent --add-port=2333/tcp
firewall-cmd --permanent --add-port=2333/udp
firewall-cmd --permanent --add-masquerade
firewall-cmd --permanent --add-forward-port=port=2333:proto=tcp:toport=6666:toaddr=1.1.1.1
firewall-cmd --permanent --add-forward-port=port=2333:proto=udp:toport=6666:toaddr=1.1.1.1
firewall-cmd --reload

其中 2333 代表本地监听端口, 6666 表示欲中转服务器的端口, 1.1.1.1 代表欲中转服务器的ip地址。

配置服务器作为路由上网

需求: 有两台服务器:A,B

A,B 组成局域网, A有公网IP,可访问公网资源,B无公网IP,也无法访问互联网

现配置B自由链接到互联网.

在A上配置:

iptables -A INPUT -i eth0 -j ACCEPT

echo "1" > /proc/sys/net/ipv4/ip_forward

sysctl -w net.ipv4.ip_forward=1

iptables -t nat -A POSTROUTING -s 172.16.0.0/24 -o eth0 -j MASQUERADE

iptables -t nat -A POSTROUTING -s 172.16.0.43 -o eth0 -j MASQUERADE

iptables -t nat -A POSTROUTING -s 172.16.0.0/24 -o eth0 -j MASQUERADE

iptables -t nat -A POSTROUTING -s 172.16.0.43 -o eth0 -j MASQUERADE

iptables -t nat -A POSTROUTING -s 172.16.0.0/24 -j SNAT –to 172.16.0.148 iptables -t nat -A POSTROUTING -s 172.16.0.43 -o eth0 -j SNAT –to-source 172.16.0.148

这一行最关键!就是加入 nat table 封包伪装!本例中 $innet 是 172.168.100.0/24

而 $EXTIF 则是对外界面,本例中为 eth0

在B上配置,网关设置为A的IP

ip route delete default

ip route add default via 172.16.0.148

route add default gw 172.16.0.148

其中IP为A的局域网IP