iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP
当我们使用-L选项验证当前规则是发现,所有的链旁边都有policy ACCEPT标注,这表明当前链的默认策略为ACCEPT:
# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT tcp -- anywhere anywhere tcp dpt:ssh DROP all -- anywhere anywhere Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
这种情况下,如果没有明确添加DROP规则,那么默认情况下将采用ACCEPT策略进行过滤。除非:
为以上三个链单独添加DROP规则:
iptables -A INPUT -j DROP iptables -A OUTPUT -j DROP iptables -A FORWARD -j DROP
更改默认策略:
iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP
如果本地主机有两块网卡,一块连接内网(eth0),一块连接外网(eth1),那么可以使用下面的规则将eth0的数据路由到eht1:
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
开放172.16.37.1对本机172.16.37.10的ping响应,和ping请求;注:若默认INPUT/OUPUT为DROP,请求和响应同时开启才能ping通
iptables -A INPUT -s 172.16.37.1 -d 172.16.37.10 -p icmp --icmp-type 8 -j ACCEPT iptables -A OUTPUT -s 172.16.37.10 -d 172.16.37.1 -p icmp --icmp-type 0 -j ACCEPT iptables -P INPUT DROP iptables -P OUTPUT DROP
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT
默认链策略为DROP的情况下,进行防火墙设置
# 1.删除现有规则 iptables -F # 2.配置默认链策略 iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP # 3.允许接收远程主机的SSH请求 iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT # 4.允许发送本地主机的SSH响应 iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
-m state: 启用状态匹配模块(state matching module)
–-state: 状态匹配模块的参数。当SSH客户端第一个数据包到达服务器时,状态字段为NEW;建立连接后数据包的状态字段都是ESTABLISHED
–sport 22: sshd监听22端口,同时也通过该端口和客户端建立连接、传送数据。因此对于SSH服务器而言,源端口就是22
–dport 22: ssh客户端程序可以从本机的随机端口与SSH服务器的22端口建立连接。因此对于SSH客户端而言,目的端口就是22
如果服务器也需要使用SSH连接其他远程主机,则还需要增加以下配置:
# 1.送出的数据包目的端口为22 iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT # 2.接收的数据包源端口为22 iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
本机IP172.16.37.10,仅允许172.16.37.1访问sshd服务
iptables -A INPUT -s 172.16.37.1 -d 172.16.37.10 -p tcp --dport 22 -j ACCEPT iptables -A OUTPUT -s 172.16.37.10 -d 172.16.37.1 -p tcp --sport 22 -j ACCEPT iptables -P INPUT DROP iptables -P OUTPUT DROP
本例实现的规则将仅允许SSH数据包通过本地计算机,其他一切连接(包括ping)都将被拒绝。
# 1.清空所有iptables规则 iptables -F # 2.接收目标端口为22的数据包 iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT # 3.拒绝所有其他数据包 iptables -A INPUT -j DROP
# Prevent SSH Attack iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 3 --name SSH -j DROP # Enable Normal SSH Connection iptables -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT
本规则允许所有来自外部的SSH连接请求,也就是说,只允许进入eth0接口,并且目的端口为22的数据包
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
本规则和上述规则有所不同,本规则意在允许本机发起SSH连接,上面的规则与此正好相反。
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
以下规则仅允许来自192.168.100.0/24的网络:
iptables -A INPUT -i eth0 -p tcp -s 192.168.100.0/24 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
上例中,你也可以使用-s 192.168.100.0/255.255.255.0作为网络地址。当然使用上面的CIDR地址更容易让人明白。
以下规则仅允许从本地主机连接到192.168.100.0/24的网络:
iptables -A OUTPUT -o eth0 -p tcp -d 192.168.100.0/24 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
# 1.删除现有规则 iptables -F # 2.配置默认链策略 iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP # 3.允许接收远程主机的HTTP请求 iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT # 4.允许发送本地主机的HTTP响应 iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
本机IP172.16.37.10,允许172.16.37.1访问httpd服务
iptables -A INPUT -s 172.16.37.1 -d 172.16.37.10 -p tcp --dport 80 -j ACCEPT iptables -A OUTPUT -s 172.16.37.10 -d 172.16.37.1 -p tcp --sport 80 -j ACCEPT iptables -P INPUT DROP iptables -P OUTPUT DROP
# 1.允许HTTP连接:80端口 iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT # 2.允许HTTPS连接:443端口 iptables -A INPUT -i eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
本规则可以允许用户从本地主机发起HTTPS连接,从而访问Internet。
iptables -A OUTPUT -o eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A INPUT -i eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
类似的,你可以设置允许HTTP协议(80端口)。
[root@localhost ~]# iptables -A INPUT -d 10.76.33.201 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT [root@localhost ~]# iptables -A OUTPUT -s 10.76.33.201 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT [root@localhost ~]# iptables -A INPUT -d 10.76.33.201 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT [root@localhost ~]# iptables -A OUTPUT -s 10.76.33.201 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
允许172.16.100.11对本机的ssh,http,https访问
iptables -I INPUT 1 -d 172.16.100.11 -p tcp -m multiport --dports 22,80,443 -j ACCEPT iptables -I OUTPUT 1 -s 172.16.100.11 -p tcp -mmultiport --sports 22,80,443 -j ACCEPT
# Open VNC for USER1 -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5800 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5900 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 6000 -j ACCEPT # Open VNC for USER2 -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5801 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5901 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 6001 -j ACCEPT
[root@localhost ~]# iptables -N clean_in [root@localhost ~]# iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP [root@localhost ~]# iptables -A clean_in -d 10.76.33.201 -p icmp -j DROP [root@localhost ~]# iptables -A clean_in -p tcp ! --syn -m state --state NEW -j DROP [root@localhost ~]# iptables -A clean_in -p tcp --tcp-flags ALL NONE -j DROP [root@localhost ~]# iptables -A clean_in -d 10.76.33.201 -j RETURN [root@localhost ~]# iptables -I INPUT -j clean_in [root@localhost ~]# iptables -L -n --line-numbers Chain INPUT (policy ACCEPT) num target prot opt source destination 1 clean_in all -- 0.0.0.0/0 0.0.0.0/0 2 REJECT all -- 0.0.0.0/0 10.76.33.201 STRING match "h7n9" ALGO name kmp TO 65535 reject-with icmp-port-unreachable 3 ACCEPT tcp -- 0.0.0.0/0 10.76.33.201 state RELATED,ESTABLISHED 4 ACCEPT tcp -- 0.0.0.0/0 10.76.33.201 multiport dports 21,22,80 state NEW 5 ACCEPT tcp -- 0.0.0.0/0 10.76.33.201 tcp dpt:21 state NEW 6 ACCEPT tcp -- 0.0.0.0/0 10.76.33.201 state NEW,RELATED,ESTABLISHED 7 LOG icmp -- 0.0.0.0/0 10.76.33.201 icmp type 8 LOG flags 0 level 4 prefix `-- firewall log for icmp --' 8 ACCEPT icmp -- 0.0.0.0/0 10.76.33.201 icmp type 8 limit: avg 5/min burst 6 Chain FORWARD (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination 1 REJECT all -- 10.76.33.201 0.0.0.0/0 STRING match "h7n9" ALGO name kmp TO 65535 reject-with icmp-port-unreachable 2 ACCEPT all -- 10.76.33.201 0.0.0.0/0 state RELATED,ESTABLISHED Chain clean_in (1 references) num target prot opt source destination 1 DROP icmp -- 0.0.0.0/0 255.255.255.255 2 DROP icmp -- 0.0.0.0/0 10.76.33.201 3 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:!0x17/0x02 state NEW 4 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:0x3F/0x00 5 RETURN all -- 0.0.0.0/0 10.76.33.201
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP
利用connlimit模块将单IP并发设置为3;会误杀使用NAT上网的用户,可以根据实际情况增大该值。
利用recent和state模块限制单IP在 300s 内只能与本机建立3个新连接,被限制5mins后即可恢复访问。
第二句:记录访问tcp 22端口的新连接,记录名称为SSH。--set 记录数据包的来源IP,如果IP已经存在将更新已经存在的条目
第三句:SSH记录中的IP,300s内发起超过3次连接则拒绝此IP的连接
--update 每次建立连接都更新列表
--seconds 必须与--rcheck或者--update同时使用
--hitcount 必须与--rcheck或者--update同时使用
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT
如果你在使用NIS管理你的用户账户,你需要允许NIS连接。即使你已允许SSH连接,你仍需允许NIS相关的ypbind连接,否则用户将无法登陆。NIS端口是动态的,当ypbind启动的时候,它会自动分配端口。因此,首先我们需要获取端口号,本例中使用的端口是853和850:
rpcinfo -p | grep ypbind
然后,允许连接到111端口的请求数据包,以及ypbind使用到的端口:
iptables -A INPUT -p tcp --dport 111 -j ACCEPT iptables -A INPUT -p udp --dport 111 -j ACCEPT iptables -A INPUT -p tcp --dport 853 -j ACCEPT iptables -A INPUT -p udp --dport 853 -j ACCEPT iptables -A INPUT -p tcp --dport 850 -j ACCEPT iptables -A INPUT -p udp --dport 850 -j ACCEPT
以上做法在你重启系统后将失效,因为ypbind会重新指派端口。我们有两种解决方法:
1.为NIS使用静态IP地址
2.每次系统启动时调用脚本获得NIS相关端口,并根据上述iptables规则添加到filter表中去。
你可能启用了rsync服务,但是又不想让rsync暴露在外,只希望能够从内部网络(192.168.101.0/24)访问即可:
iptables -A INPUT -i eth0 -p tcp -s 192.168.101.0/24 --dport 873 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 873 -m state --state ESTABLISHED -j ACCEPT
你可能启用了MySQL服务,但只希望DBA与相关开发人员能够从内部网络(192.168.100.0/24)直接登录数据库:
iptables -A INPUT -i eth0 -p tcp -s 192.168.100.0/24 --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 3306 -m state --state ESTABLISHED -j ACCEPT
邮件服务都使用了25端口,我们只需要允许来自25端口的连接请求即可。
iptables -A INPUT -i eth0 -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
# IMAP:143 iptables -A INPUT -i eth0 -p tcp --dport 143 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 143 -m state --state ESTABLISHED -j ACCEPT # IMAPS:993 iptables -A INPUT -i eth0 -p tcp --dport 993 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 993 -m state --state ESTABLISHED -j ACCEPT
# POP3:110 iptables -A INPUT -i eth0 -p tcp --dport 110 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 110 -m state --state ESTABLISHED -j ACCEPT # POP3S:995 iptables -A INPUT -i eth0 -p tcp --dport 995 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 995 -m state --state ESTABLISHED -j ACCEPT
可以利用iptables的-m nth扩展,及其参数(–counter 0 –every 3 –packet x),进行DNAT路由设置(-A PREROUTING -j DNAT –to-destination),从而将负载平均分配给3台服务器:
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 0 -j DNAT --to-destination 192.168.1.101:443 iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 1 -j DNAT --to-destination 192.168.1.102:443 iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 2 -j DNAT --to-destination 192.168.1.103:443
# 1.新建名为LOGGING的链 iptables -N LOGGING # 2.将所有来自INPUT链中的数据包跳转到LOGGING链中 iptables -A INPUT -j LOGGING # 3.指定自定义的日志前缀"IPTables Packet Dropped: " iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables Packet Dropped: " --log-level 7 # 4.丢弃这些数据包 iptables -A LOGGING -j DROP
这里以用于配置OpenVPN的NAT转发规则为例进行说明,希望读者能进一步了解规则设置的方法:
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o venet0 -j MASQUERADE iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -i ! lo -d 127.0.0.0/8 -j REJECT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 3306 -j ACCEPT iptables -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT iptables -t nat -A PREROUTING -p udp -m udp --dport 53 -j DNAT --to-destination 8.8.8.8 iptables -A INPUT -p udp --dport 1194 -j ACCEPT iptables -A INPUT -s 10.8.0.0/24 -p all -j ACCEPT iptables -A FORWARD -d 10.8.0.0/24 -j ACCEPT iptables -A INPUT -i tun+ -j ACCEPT iptables -A FORWARD -i tun+ -j ACCEPT iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7 iptables -A INPUT -j REJECT iptables -A FORWARD -j REJECT