Iptables包过滤防火墙

 Iptables加固服务器安全
包过滤防火墙(四层)、状态防火墙 主要针对网络访问
 
一、安全体系概览
Firewalls --->TCP Wrappers ---> Xinetd ---> PAM ---> SELinux ---> Server specific
 
二、预备知识:OSI 七层模型
HOST_A firefox(封装)------------------------------> httpd server(解封装)HOST_B
应用层------- ftp http smtp pop3 nfs cifs ssh dns ------- 应用层
表示层 表示层
会话层 会话层
传输层     TCP、UDP s_port:xxxx  --> d_port:80 传输层
网络层     IP、ICMP、ARP  s_IP:192.168.9.9 --> d_IP:192.168.9.99 网络层
数据链路层      s_mac:xxxxxxxxx --> d_mac:xxxxxxxxx 数据链路层
物理层 物理层
TCP: 面向连接,可靠的传输协议   类似于三次握手,四次挥手,window,确认,重传......
UDP:非面向连接,不可靠的传输协议
 
三、Firewall: netfilter/iptables
netfilter组件        内核空间,是内核一部分
iptables组件        用户空间,提供管理防火墙的手段,通过iptables插入、删除、修改规则
 
四、四张表、五条链
raw ---> mangle ---> nat ---> filter
raw        主要做连接追踪   PREROUTING、OUTPUT
mangle     对数据包进行修改,例如给数据包打标记MARK   INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING
nat        主要修改数据包的地址和端口,例如源地址或目标地址   INPUT、OUTPUT、PREROUTING、POSTROUTING
filter     实现对数据包的过滤    INPUT、OUTPUT、FORWARD
示例:
iptables -L
iptables -t filter -L
iptables -t nat -L
iptables -t raw -L
iptables -t mangle -L
 
五、iptables 语法
iptables [-t 要操作的表] <操作命令> [要操作的链] [规则号码] [匹配条件] [-j 匹配后的动作]
                 小写               大写        大写      小写            大写
表及应用顺序:raw ---> mangle ---> nat ---> filter
常用操作命令:
-L        查看,v详细,n不反解 --line-number 加行号
-A        追加,放置到最后一条
-I        插入,默认插入到第一条
-D        删除
-F        清空flush
-X        删除空的自定义链
-P        设置默认策略
-Z        计数器归零
-m        匹配
要操作的链:
INPUT
OUTPUT
FORWARD
PREROUTING
POSTROUTING
基本匹配:
-s xx.xx.xx.xx                源地址
-d xx.xx.xx.xx                目标地址
-p tcp|udp|icmp                协议
-i eth0                        input从eth0接口进入的数据包
-o eth0                        output从eth0接口出去的数据包
-p tcp --sport 80        源端口是80的数据包
-p tcp --dport 80        目标端口是80,必须和-p tcp|udp 连用
基本动作Target
filter:
-j ACCEPT      接受       filter
-j REJECT        拒绝       filter
-j DROP          丢弃       filter
-j LOG            记录日志    filter
nat:
-j SNAT           源地址转换  nat   POSTROUTING链
-j MASQUERADE   伪装     nat    
-j DNAT           目标地址转换 nat     目标地址及端口映射(转换) PREROUTING链
-j REDIRECT     端口转换       nat     本地端口转换(本机)
mangle:
-j MARK           标记 mangle
示例:# iptables -t filter -A INPUT -s 192.168.1.0/24 -j SNAT --to 1.1.1.1    错误   因为filter 表不支持SNAT源地址转换动作
 
六、iptables 应用示例
iptables -F    清空filter表链上的所有规则。默认表是filter表   
iptables -A INPUT -j REJECT              filter表input链拒绝所有   先堵后通
iptables -A INPUT -j ACCEPT             先通后堵
iptables -I INPUT -p tcp --dport 80 -j ACCEPT      访问80端口的允许,插入到链第一条,默认用拒绝所有。
iptables -I INPUT -p tcp --dport 22 -j ACCEPT      访问22端口的允许,插入到链第一条
iptables -I INPUT -p icmp -j ACCEPT                     允许使用icmp协议,可以ping.
iptables -I INPUT 2 -p tcp --dport  20:21 -j ACCEPT    允许TCP 20 21端口,插入到第二条   FTP主动模式可用,被动模式不可用
service iptables save    保存
本机无法访问本机无法ping通:iptables -I INPUT -i lo -j ACCEPT
本机无法主访问其他主机ssh不通:iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
FTP无法访问:被动模式:
iptables  -I INPUT -p tcp --dport  20:21 -j ACCEPT   指定FTP pasv端口 50000-60000
iptables -I INPUT -p tcp --dport 50000:60000 -j ACCEPT
或使用连接追踪模块:
iptables -I INPUT -p tcp --dport 20:21 -j ACCEPT
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
modprobe nf_conntrack_ftp             加载连接追踪模块(临时)
vim /etc/sysconfig/iptables-config    开机自动加载
IPTABLES_MODULES="nf_conntrack_ftp"    
nf_conntrack_ftp:针对数据端口连接时,将三次握手第一次的状态由NEW识别成RELATED
 
七、扩展匹配  MATCH EXTENSIONS
iptables -m icmp -h                //从后往前查看 icmp 所有状态
iptables -m iprange -h            //从后往前查看 iprange 所有状态
yum -y install vsftpd httpd      //安装vsftpd httpd两个服务举例
service httpd start; service vsftpd start; service sshd start  //启动服务
iptables -F  清空防火墙
iptables -A INPUT -j REJECT
 • -m icmp
# iptables -t filter -I INPUT -p icmp -m icmp --icmp-type echo-reply -j ACCEPT    //允许icmp协议的echo-reply状态回应
 • -m iprange
# iptables -t filter -I INPUT -m iprange --src-range 192.168.2.20-192.168.2.100 -j REJECT   //允许此IP段的源IP地址INPUT
 • -m multiport
# iptables -t filter -I INPUT -p tcp -m multiport --dports 20,21,22,25,80,110 -j ACCEPT   //多端口访问允许
 • -m state 跟TCP中的状态没有关系
NEW    新生态
ESTABLISHED  连接态
RELATED    衍生态
INVALID 无效态
# iptables -t filter -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT    //允许此三个状态的访问通过
实验: 使用状态防火墙,放行本机FTP服务[被动模式]
# iptables -t filter -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -t filter -I INPUT -p tcp --dport 20:21 -j ACCEPT
# iptables -t filter -A INPUT -j REJECT
# modprobe nf_conntrack_ftp
# vim /etc/sysconfig/iptables-config
IPTABLES_MODULES="nf_conntrack_ftp"
小结: 该内核模块的作用是在<连接数据端口时>,将第一次握手的数据包状态由原来的 NEW 识别成 RELATED
 • -m tos //ip协议头部type of service
# iptables -F
# tcpdump -i eth0 -nn port 22 -vvv //抓取远程主机访问本机ssh数据包,分 别于输入密码前和后观察TOS值
# tcpdump -i eth0 -nn port 22 -vvv //抓取远程从本机rsync或scp复制文件, 分别于输入密码前和后观察TOS值
小结:都是使用22/tcp,但可以通过IP报文中的TOS值来区分应用
ssh: tos 0x0  0x10
scp: tos 0x0  0x8
rsync: tos 0x0  0x8
# iptables -m tos -h
# iptables -t filter -A INPUT -p tcp --dport 22 -m tos ! --tos 0x10 -j ACCEPT //仅拒绝客户端ssh到本机
# iptables -t filter -A INPUT -j REJECT
 • -m tcp 按TCP标记匹配
Flags are:  SYN  ACK  FIN  RST  URG  PSH    ALL  NONE
# iptables -t filter -A INPUT -p tcp -m tcp --tcp-flags SYN,ACK,FIN,RST SYN -dport 80 -j ACCEPT
# iptables -t filter -A INPUT -p tcp --syn --dport 80 -j ACCEPT --tcp-flags SYN,ACK,FIN,RST SYN   // 检查四个标记位SYN,ACK,FIN,RST,但只有SYN标记位才匹配 则允许三次握手中的第一次握手,等价于 --syn
 • -m limit 限制
实验:从客户端ping本机,观察序列号
# iptables -F
# iptables -t filter -A INPUT -p icmp  -m limit --limit 20/minute -j ACCEPT
# iptables -t filter -A INPUT -j REJECT
进入本机INPUT链的ICMP,如果匹配第一条则放行,不匹配的将被第二条拒绝,默认前5个 不限
16/second
16/minute
16/hour
16/day
# iptables -t filter -A INPUT  -p tcp --syn --dport 80  -m limit --limit 50/second j ACCEPT
# iptables -t filter -A INPUT -j REJECT
 • -m connlimit 限同一IP最大连接数
# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -A INPUT -p tcp --syn --dport 22 -m connlimit ! --connlimit-above 2 -j ACCEPT //仅允许每个客户端有两个ssh连接
等价于:# iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 2 -j REJECT //超过两个连接拒绝
# iptables -A INPUT -p tcp --syn --dport 80 -m connlimit ! --connlimit-above 100 -j ACCEPT //仅允许每个客户端有100个requests
# iptables -A INPUT -j REJECT
 • -m time
# iptables -A INPUT -m time --timestart 12:00 --timestop 13:00 -j ACCEPT
# iptables -A INPUT -p tcp --syn --dport 22 -m time --timestart 12:00 -timestop 13:00 -j ACCEPT
# iptables -A INPUT -j REJECT
 • -m comment
# iptables -A INPUT -s 172.16.130.7 -m comment --comment "cloud class" -j REJECT   //按照描述匹配
 • -m mark
# iptables -t filter -A INPUT -m mark --mark 2 -j REJECT
 
八、动作扩展 TARGET EXTENSIONS
 • filter:
-j ACCEPT
-j DROP
-j REJECT
-j LOG
 • nat:
-j SNAT                            //转换源地址
-j MASQUERADE             //转换源地址
-j DNAT                           //转换目标地址及端口
-j REDIRECT                    //转换目标端口(重定向)
 • mangle:
-j MARK
 • -j LOG
# grep 'kern.*' /etc/rsyslog.conf
kern.* /var/log/kernel.log                     //确定内核日志功能开启并把Log文件放在/var/log/kernel.log
# service rsyslog restart                        //重启日志服务
# iptables -j LOG  -h                            //
# iptables -t filter -A INPUT -p tcp --syn --dport 22 -j LOG  --log-prefix " tianyun_ssh "   //满足条件的日志加前缀
# iptables -t filter -A INPUT -p tcp --syn --dport 22 -j ACCEPT    //实际允许规则,上一条只是日志规则,日志必须放上实际规则上面
# iptables -t filter -A INPUT -j REJECT
 • -j REJECT
当访问一个未开启的TCP端口时,应该返回一个带有RST标记的数据包
当访问一个未开启的UDP端口,结果返回port xxx unreachable
当访问一个开启的TCP端口,但被防火墙REJECT,结果返回port xxx unreachable
# iptables -j REJECT -h    查看帮助
# iptables -t filter -A  INPUT -p tcp --dport 22  -j REJECT --reject-with tcpreset //返回一个自定义消息类型
 • -j MARK
# iptables -t mangle -L
# iptables -j MARK -h
# iptables -t mangle -A PREROUTING -s 192.168.2.110 -j MARK --set-mark 1
# iptables -t mangle -A PREROUTING -s 192.168.2.25 -j MARK --set-mark 2
# iptables -t filter -A INPUT -m mark --mark 1 -j ACCEPT                                    //按照标记匹配
# iptables -t filter -A INPUT -m mark --mark 2 -j REJECT
 • NAT表:
POSTROUTING:    SNAT, MASQUERADE
PRETROUTING: DNAT, REDIRECT
OUTPUT:  DNAT,针对本机
 • 让KVM虚拟机访问外部网络(默认):-j SNAT/MASQUERADE  [必须开启kernel ip_forward]
# iptables -t nat -F
# iptables -F
  路由之后做源地址转换:
# iptables -t nat -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j SNAT --to 外部地址  //不常用
# iptables -t nat -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE   //常用规则
 • 暴露KVM虚拟机的服务(端口映射): -j DNAT  [必须开启kernel ip_forward]
# iptables -t nat -A PREROUTING -d 172.16.30.30 -p tcp --dport 80 -j DNAT -to  192.168.122.66:80
# iptables -t nat -A PREROUTING -d 172.16.30.30 -p tcp --dport 8080 -j DNAT --to  192.168.122.77:80
# iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to 192.168.122.66:22
# iptables -t nat -A PREROUTING -d 172.16.30.240 -p tcp --dport 80 -j DNAT -to 192.168.122.66
# iptables -t nat -A PREROUTING -d 172.16.30.240 -p tcp --dport 22 -j DNAT -to 192.168.122.66
# iptables -t nat -A PREROUTING -d 172.16.30.241 -p tcp --dport 80 -j DNAT -to 192.168.122.67
# iptables -t nat -A PREROUTING -d 172.16.30.241 -p tcp --dport 22 -j DNAT -to 192.168.122.67
为接口绑定地址
# ip addr add dev eth0 172.16.30.240/24
# ip addr add dev eth0 172.16.30.241/24
 • -j REDIRECT   //本地端口转发
# iptables -t nat -A PREROUTING -s 172.16.130.0/24 -p tcp --dport 8888 -j REDIRECT --to-ports 22