一、概念
iptables只是Linux防火墙的管理工具而已。真正实现防火墙功能的是netfilter,它是Linux内核中实现包过滤的内部结构。
1、链
链是一些按顺序排列的规则的列表。
默认情况下,任何链中都没有规则。可以向链中添加自己想用的规则。链的默认规则通常设置为 ACCEPT,如果想确保任何包都不能通过规则集,那么可以重置为 DROP。
默认的规则总是在一条链的最后生效,所以在默认规则生效前数据包需要通过所有存在的规则。
5种链说明如下:
PREROUTING链——对数据包作路由选择前应用此链中的规则(所有的数据包进来的时侯都先由这个链处理)
INPUT链——进来的数据包应用此规则链中的策略
OUTPUT链——外出的数据包应用此规则链中的策略
FORWARD链——转发数据包时应用此规则链中的策略
POSTROUTING链——对数据包作路由选择后应用此链中的规则(所有的数据包出来的时侯都先由这个链处理)
2、表
表由一组预先定义的链组成。
filter表——用于存放所有与防火墙相关操作的默认表。通常用于过滤数据包。
nat表——用于网络地址转换
mangle表——用于处理数据包
raw表——用于配置数据包,raw 中的数据包不会被系统跟踪。
3、链和表的关系及顺序
PREROUTING: raw -> mangle -> nat
INPUT: mangle -> filter
FORWARD: mangle -> filter
OUTPUT: raw -> mangle -> nat -> filter
POSTROUTING: mangle -> nat
4、实际使用中是从表作为操作入口;表和链的关系
raw 表:PREROUTING,OUTPUT
mangle表:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
nat 表:PREROUTING,OUTPUT,POSTROUTING
filter 表:INPUT,FORWARD,OUTPUT
5、target
ACCEPT: 允许数据包通过
DROP:直接丢弃数据包,不给任何回应信息
REJECT:拒绝数据包通过,需要时会给数据发送端一个相应信息
SNAT:原地址转换,解决内网用户用同一个公网地址上网的问题
MASQUERADE:是 SNAT 的一种特殊形式,适用于动态的、临时会变的 ip 上
DNAT:目标地址转换
REDIRECT:在本机做端口映射
LOG:在/var/log/messages 文件中记录日志信息。然后将数据包传递给下一条规则。也就是只记录不做任何操作。
REJECT 其他参数
--reject-with:可以设置提示信息,拒绝时的提示信息
icmp-net-unreachable
icmp-host-unreachable
icmp-port-unreachable,
icmp-proto-unreachable
icmp-net-prohibited
icmp-host-pro-hibited
icmp-admin-prohibited
当不设置任何值时,默认值为icmp-port-unreachable。
用法:
# iptables -t filter -I INPUT 2 -j REJECT --reject-with icmp-host-unreachable
LOG
只记录匹配到的报文信息。
在配置文件 /etc/rsyslog.conf 中加入下面一行。重启服务即可。
kern.warning /var/log/iptables.log
# service rsyslog restart
LOG 参数
--log-level 选项可以指定记录日志的日志级别,可用级别有emerg,alert,crit,error,warning,notice,info,debug。
--log-prefix 选项可以给记录到的相关信息添加"标签"之类的信息,以便区分各种记录到的报文信息,方便在分析时进行过滤。
示例:
比如,想要将主动连接22号端口的报文的相关信息都记录到日志中,并且把这类记录命名为"want-in-from-port-22",则可以使用如下命令
# iptables -t filter -I INPUT -p tcp -m state --state NEW -j LOG --log-prefix "want-in-from-port-22"
SNAT
配置SNAT,可以隐藏网内主机的IP地址,也可以共享公网IP,如果只是共享IP的话,只配置如下SNAT规则即可。
示例:
# iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 123.123.2.2
如果公网IP是动态获取的,不是固定的,则可以使用MASQUERADE进行动态的SNAT操作。
# iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE
二、数据通过iptable的流程
centos 利用iptables端口复用
客户端:192.168.232.128
服务端:192.168.232.129
1、在服务端添加客户端ip访问本机的8000端口的流量转发到22端口
iptables -t nat -A PREROUTING -p tcp -s 192.168.232.128 --dport=8000 -j REDIRECT --to-port=22
iptables -L -t nat --line-numbers #显示所有带序列号的nat策略
iptables -t nat -D PREROUTING number #删除指定的nat策略
在客户端通过ssh连接8000端口,即可实现远程
2、根据源址+源端口做端口复用
服务端将来自客户端ip基于2222端口访问本地8000端口的流量转发到本机的22端口
iptables -t nat -A PREROUTING -p tcp -s 192.168.232.128 --sport=2222 --dport=8000 -j REDIRECT --to-port=22
客户端使用本地ncat/socat开启1111端口,并将1111的流量通过2222端口远程访问服务端的8000端口
nohup socat tcp-listen:1111,fork,reuseaddr tcp:192.168.232.129:8000,sourceport=2222,reuseaddr &
连接本地的1111端口即可连接到服务端ssh端口
3、利用ICMP协议做开关
iptables -t nat -N LETMEIN #创建端口复用链
iptables -t nat -A LETMEIN -p tcp -j REDIRECT --to-port 22 #创建端口复用规则,将流量转发至 22 端口
iptables -t nat -A PREROUTING -p icmp --icmp-type 8 -m length --length 1139 -m recent --set --name letmein --rsource -j ACCEPT #开启开关,如果接收到一个长为 1139 的 ICMP 包,则将来源 IP 添加到加为letmein的列表中
iptables -t nat -A PREROUTING -p icmp --icmp-type 8 -m length --length 1140 -m recent --name letmein --remove -j ACCEPT #关闭开关,如果接收到一个长为 1140 的 ICMP 包,则将来源 IP 从 letmein 列表中去掉
iptables -t nat -A PREROUTING -p tcp --dport 8000 --syn -m recent --rcheck --seconds 3600 --name letmein --rsource -j LETMEIN #如果发现 SYN 包的来源 IP 处于 letmein 列表中,将跳转到 LETMEIN 链进行处理,有效时间为 3600 秒
开启复用
#向目标发送一个长度为 1111 的 ICMP 数据包(加上包头28,总长度实际为1139)
ping -c 1 -s 1111 192.168.232.129
关闭复用
#向目标发送一个长度为 1112 的 ICMP 数据包(加上包头 28,总长度实际为 1140)
ping -c 1 -s 1112 192.168.232.129
4、利用TCP协议做开关
iptables -t nat -N Hacker # 创建子链 做为复用链
iptables -t nat -A Hacker -p tcp -j REDIRECT --to-port=22 # 创建规则,将流量转发到22端口
iptables -A INPUT -p tcp -m string --string 'on' --algo bm -m recent --set --name Hacker --rsource -j ACCEPT # 如果接受到包含'on'字符串的tcp包,就将源ip加入该子链
iptables -A INPUT -p tcp -m string --string 'off' --algo bm -m recent --name Hacker --remove -j ACCEPT # 如果接受到包含'off'字符串的tcp包,将改ip从子链中移除
iptables -t nat -A PREROUTING -p tcp --dport=8000 --syn -m recent --rcheck --seconds 3600 --name Hacker --rsource -j Hacker # 如果发现源ip在子链中,则跳转到子链处理,有效时间3600秒