一、iptables从这里开始


删除现有规则


iptables -F

(OR)

iptables --flush



设置默认链策略


iptables的filter表中有三种链INPUT, FORWARD和OUTPUT。默认的链策略是ACCEPT你可以将它们设置成DROP。

iptables -P INPUT DROP


iptables -P FORWARD DROP


iptables -P OUTPUT DROP #一般出站连接设置为ACEEPT看需求



你需要明白这样做会屏蔽所有输入、输出网卡的数据包除非你明确指定哪些数据包可以通过网卡。


屏蔽指定的IP地址


以下规则将屏蔽BLOCK_THIS_IP所指定的IP地址访问本地主机


BLOCK_THIS_IP= "x.x.x.x"


iptables -A INPUT -i eth0 -s "$BLOCK_THIS_IP" -j DROP


(或者仅屏蔽来自该IP的TCP数据包


iptables -A INPUT -i eth0 -p tcp -s "$BLOCK_THIS_IP" -j DROP



允许来自外部的ping测试


iptables -A INPUT -p icmp --icmp- type echo -request -j ACCEPT


iptables -A OUTPUT -p icmp --icmp- type echo -reply -j ACCEPT



允许从本机ping外部主机


iptables -A OUTPUT -p icmp --icmp- type echo -request -j ACCEPT


iptables -A INPUT -p icmp --icmp- type echo -reply -j ACCEPT



允许环回(loopback)访问


iptables -A INPUT -i lo -j ACCEPT


iptables -A OUTPUT -o lo -j ACCEPT


二、iptables协议与端口设定


允许所有SSH连接请求


本规则允许所有来自外部的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连接


本规则和上述规则有所不同本规则意在允许本机发起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


仅允许来自指定网络的SSH连接请求


以下规则仅允许来自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地址更容易让人明白。


仅允许从本地发起到指定网络的SSH连接请求


以下规则仅允许从本地主机连接到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


允许HTTP/HTTPS连接请求

# 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连接


本规则可以允许用户从本地主机发起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端口。


-m multiport指定多个端口 

通过指定-m multiport选项可以在一条规则中同时允许SSH、HTTP、HTTPS连接


iptables -A INPUT -i eth0 -p tcp -m multiport --dports 22,80,443 -m state --state NEW,ESTABLISHED -j ACCEPT


iptables -A OUTPUT -o eth0 -p tcp -m multiport --sports 22,80,443 -m state --state ESTABLISHED -j ACCEPT


允许出站DNS连接


iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT


iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT



允许NIS连接


如果你在使用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服务但是又不想让rsync暴露在外只希望能够从内部网络192.168.101.0/24访问即可


1

2

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连接请求


你可能启用了MySQL服务但只希望DBA与相关开发人员能够从内部网络192.168.100.0/24直接登录数据库


1

2

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



允许Sendmail, Postfix邮件服务


邮件服务都使用了25端口我们只需要允许来自25端口的连接请求即可。


1

2

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与IMAPS

# IMAP143

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


# IMAPS993

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与POP3S

# POP3110

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


# POP3S995

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


防止DoS***


iptables -A INPUT -p tcp --dport 80 -m limit --limit 25 /minute --limit-burst 100 -j ACCEPT



-m limit: 启用limit扩展 

--limit 25/minute: 允许最多每分钟25个连接 

--limit-burst 100: 当达到100个连接后才启用上述25/minute限制


三、转发与NAT


允许路由


如果本地主机有两块网卡一块连接内网(eth0)一块连接外网(eth1)那么可以使用下面的规则将eth0的数据路由到eht1


iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT



DNAT与端口转发


以下规则将会把来自422端口的流量转发到22端口。这意味着来自422端口的SSH连接请求与来自22端口的请求等效。

# 1.启用DNAT转发


iptables -t nat -A PREROUTING -p tcp -d 192.168.102.37 --dport 422 -j DNAT --to-destination 192.168.102.37:22


# 2.允许连接到422端口的请求


iptables -A INPUT -i eth0 -p tcp --dport 422 -m state --state NEW,ESTABLISHED -j ACCEPT


iptables -A OUTPUT -o eth0 -p tcp --sport 422 -m state --state ESTABLISHED -j ACCEPT


假设现在外网网关是xxx.xxx.xxx.xxx那么如果我们希望把HTTP请求转发到内部的某一台计算机应该怎么做呢


iptables -t nat -A PREROUTING -p tcp -i eth0 -d xxx.xxx.xxx.xxx --dport 8888 -j DNAT --to 192.168.0.2:80


iptables -A FORWARD -p tcp -i eth0 -d 192.168.0.2 --dport 80 -j ACCEPT



当该数据包到达xxx.xxx.xxx.xxx后需要将该数据包转发给192.168.0.2的80端口事实上NAT所做的是修改该数据包的目的地址和目的端口号。然后再将该数据包路由给对应的主机。 

但是iptables会接受这样的需要路由的包么这就由FORWARD链决定。我们通过第二条命令告诉iptables可以转发目的地址为192.168.0.2:80的数据包。再看一下上例中422端口转22端口这是同一IP因此不需要设置FORWARD链。


SNAT与MASQUERADE


如下命令表示把所有10.8.0.0网段的数据包SNAT成192.168.5.3的ip然后发出去


iptables -t nat -A POSTROUTING -s 10.8.0.0 /24 -o eth0 -j snat --to- source 192.168.5.3


对于snat不管是几个地址必须明确的指定要snat的IP。假如我们的计算机使用ADSL拨号方式上网那么外网IP是动态的这时候我们可以考虑使用MASQUERADE


iptables -t nat -A POSTROUTING -s 10.8.0.0 /255 .255.255.0 -o eth0 -j MASQUERADE



负载平衡


可以利用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