Iptables

Posted on October 6, 2018

1. 防火墙概念

防火墙逻辑分类:

  • 主机防火墙: 针对于单个主机进行防护
  • 网络防火墙: 往往处于网络入口或边缘,针对于网络入口进行防护,服务于防火墙背后的本地局域网

防火墙物理分类:

  • 硬件防火墙: 性能高,成本高
  • 软件防火墙:性能低,成本低

Linux 防火墙: netfilter/iptables组成Linux平台下的包过滤防火墙

  • netfilter: 位于内核空间
  • iptables: 其实是一个命令行工具,位于用户空间,我们用这个工具操作netfilter

iptables并没有一个守护进程,所以并不能算是真正意义上的服务,而应该算是内核提供的功能

Iptables 的作用:

  • 数据包过滤的防火墙功能
  • 数据包内容修改
  • 网络地址转换(Network Address Translate): 因此可以实现部分负载均衡功能

2. 链与表

网络包流动过程经过的关卡

  • PREROUTING
  • INPUT
  • FORWARD
  • OUTPUT
  • POSTROUTING

链可以配置默认处理动作:

Chain OUTPUT (policy ACCEPT 417 packets, 40938 bytes)

标识OUTPUT链的默认处理动作是ACCEPT

  • 当链的默认策略为ACCEPT时,链中的规则对应的动作应该为DROP或者REJECT,表示只有匹配到规则的报文才会被拒绝,没有被规则匹配到的报文都会被默认接受,这就是”黑名单”机制
  • 当链的默认策略为DROP时,链中的规则对应的动作应该为ACCEPT,表示只有匹配到规则的报文才会被放行,没有被规则匹配到的报文都会被默认拒绝,这就是”白名单”机制

设置某链的默认规则: iptables -P INPUT DROP

各关卡应用的规则的分类集合

  • filter表:负责过滤功能
  • nat表:网络地址转换功能
  • mangle表:拆解报文,做出修改,并重新封装
  • raw表:关闭nat表上启用的连接追踪机制

规则

规则: 匹配条件+处理动作

匹配条件:

  • 基本匹配条件:
    • 源IP
    • 目标IP
  • 扩展匹配条件:
    • 源端口
    • 目标端口

当一条规则中有多个匹配条件时,这多个匹配条件之间,默认存在”与”的关系

  • -s 源地址匹配

    -s ip1,ip2

    -s 10.6.0.0/16 网段

    ! -s 192.168.1.146 取反, 注意如果只有一条规则, 只能说明满足此规则执行什么操作, 但不能说明不满足此规则的报文要执行什么操作

  • -d 目标地址匹配, 细节同上

  • -p 协议名称 协议匹配: tcp, udp, udplite, icmp, esp, ah, sctp 等

  • -i 网卡名称 流入网卡匹配, 只能用于PREROUTING链、INPUT链、FORWARD链

  • -o 网卡名称 流出网卡匹配, 只能用于FORWARD链、OUTPUT链、POSTROUTING链中

处理动作:

  • ACCEPT:允许数据包通过。
  • DROP:直接丢弃数据包,不给任何回应信息
  • REJECT:拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息
  • SNAT:源地址转换,解决内网用户用同一个公网地址上网的问题。
  • MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的ip
  • DNAT:目标地址转换
  • REDIRECT:在本机做端口映射
  • LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配

处理动作在规则列表中显示为target

规则顺序:

如果报文已经被前面的规则匹配到,iptables则会对报文执行对应的动作,即使后面的规则也能匹配到当前报文,很有可能也没有机会再对报文执行相应的动作了,就以上图为例,报文先被第一条规则匹配到了,于是当前报文被”放行”了,因为报文已经被放行了,所以,即使上图中的第二条规则即使能够匹配到刚才”放行”的报文,也没有机会再对刚才的报文进行丢弃操作了


3. 操作指南

查看规则

常用参数:

  • -L 链名: 查看该chain的规则, 如 iptables -L INPUT, 链名省略的话查看全部链
  • -t 表名: 查看该table的规则, 如 iptables -t filter -L, 如果不传递-t 默认操作filter表
  • -v 详细信息
  • -n 规则展示直接显示ip, 而不是解析后的名字
  • --line-numbers: 显示规则的编号

规则展示字段含义:

  • pkts: 对应规则匹配到的报文的个数
  • bytes: 对应匹配到的报文包的大小总和
  • target: 规则对应的target,往往表示规则对应的”动作”,也可能是自定义链, 即规则匹配成功后需要采取的措施
  • prot: 表示规则对应的协议,是否只针对某些协议应用此规则
  • opt: 表示规则对应的选项
  • in: 表示数据包由哪个接口(网卡)流入,我们可以设置通过哪块网卡流入的报文需要匹配当前规则
  • out: 表示数据包由哪个接口(网卡)流出,我们可以设置通过哪块网卡流出的报文需要匹配当前规则
  • source: 表示规则对应的源头地址,可以是一个IP,也可以是一个网段
  • destination: 表示规则对应的目标地址。可以是一个IP,也可以是一个网段

添加规则

iptables -t filter -I INPUT -s 192.168.1.6 -j DROP

  • -t 指定要操作的表, 不使用-t选项指定表时,默认为操作filter表
  • -I 链名 在指定链首增加规则
  • -I 链名 num 在指定链, 指定的位置增加规则
  • -A 链名 在指定链尾增加规则
  • -s 源地址匹配
  • -d 目标地址匹配
  • -j 动作 指定当前规则对应的动作为ACCEPT
  • -i 流入网卡 从本机发出的报文是不可能会使用到-i选项的,因为这些由本机发出的报文压根不是从网卡流入的,而是要通过网卡发出的, 因此只能用于PREROUTING链、INPUT链、FORWARD链
  • -o 流出网卡 只能用于FORWARD链、OUTPUT链、POSTROUTING链

端口相关规则:

  • --dport 目的端口 –dport选项时,必须事先指定了使用哪种协议,即必须先使用-p选项, 另外还要加上-m tcp或者-m udp 因为--dport是扩展模块
  • --dport 22:25 表示目标端口为22到25之间的所有端口
  • --dport :25 表示目标端口为0到25之间的所有端口
  • --dport 25: 表示目标端口为25到65535之间的所有端口
  • -m multiport --dports 22,36,80 离散端口需要借助模块multiport, multiport扩展只能用于tcp协议与udp协议
  • --sport 源端口

删除规则

  • 指定删除:

    iptables -t filter -D INPUT 3

    -t 指定了要操作的表(默认表示操作filter表) -D 链名 num 表示删除指定链中的某条规则,-D INPUT 3表示删除INPUT链中的第3条规则

  • 根据具体的匹配条件与动作去删除:

    iptables -D INPUT -s 192.168.1.6 -j DROP

    -s-j作为定位规则的查询条件

  • 删除指定表中某条链中的所有规则的命令

    iptables -t 表名 -F 链名 -F选项为flush之意

修改规则

TODO

保存规则

在默认的情况下,我们对”防火墙”所做出的修改都是”临时的”, 重启消失

规则存储, 系统默认 /etc/sysconfig/iptables

  • service iptables save: 对规则进行了修改以后,保存规则, 修改永久生效
  • iptables-save > /etc/sysconfig/iptables: iptables-save以将当前的iptables规则以”保存后的格式”输出到屏幕上

4. 常用扩展模块

重点在于扩展规则中的匹配条件

tcp

tcp扩展模块包括”–sport” “–dport” “–tcp-flags”

iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN -j REJECT      匹配一次握手
iptables -t filter -I OUTPUT -p tcp -m tcp --sport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN,ACK -j REJECT 匹配二次握手
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags ALL SYN -j REJECT                          匹配一次握手
iptables -t filter -I OUTPUT -p tcp -m tcp --sport 22 --tcp-flags ALL SYN,ACK -j REJECT                     匹配二次握手

udp

”–sport” “–dport”

multiport

-m multiport --dports 22,36,80 离散端口需要借助模块multiport, multiport扩展只能用于tcp协议与udp协议

icmp

todo

iprange

可以指定”一段连续的IP地址范围”,用于匹配报文的源地址或者目标地址

–src-range

–dst-range

iptables -t filter -I INPUT -m iprange --dst-range 192.168.1.127-192.168.1.146 -j DROP

string

可以指定要匹配的字符串,如果报文中包含对应的字符串,则符合匹配条件

–algo:用于指定匹配算法,可选的算法有bm与kmp,此选项为必须选项,我们不用纠结于选择哪个算法,但是我们必须指定一个

–string:用于指定需要匹配的字符串

iptables -t filter -I INPUT -p tcp --sport 80 -m string --algo bm --string "OOXX" -j REJECT

time

根据时间段区匹配报文,如果报文到达的时间在指定的时间范围以内,则符合匹配条件

connlimit

使用connlimit扩展模块,可以限制每个IP地址同时链接到server端的链接数量,注意:我们不用指定IP,其默认就是针对”每个客户端IP”

iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 20 --connlimit-mask 24 -j REJECT
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 10 --connlimit-mask 27 -j REJECT

--connlimit-mask 24 表示某个C类网段, mask为掩码之意

limit

limit模块是对”报文到达速率”进行限制的, 限制单位时间内流入的包的数量


5. 自定义链

创建:

#示例:在filter表中创建IN_WEB自定义链
iptables -t filter -N IN_WEB

挂载: 自定义链在哪里创建,应该被哪条默认链引用,取决于实际的工作场景

#示例:在INPUT链中引用刚才创建的自定义链
iptables -t filter -I INPUT -p tcp --dport 80 -j IN_WEB

解挂的话, 直接删除规则

重命名:

#示例:将IN_WEB自定义链重命名为WEB
iptables -E IN_WEB WEB

删除:

#示例:删除引用计数为0并且不包含任何规则的WEB链
iptables -X WEB

删除自定义链需要满足两个条件:

  • 自定义链没有被引用
  • 自定义链中没有任何规则

6. iptables 作为网络防火墙

网络防火墙往往处于网络的入口或者边缘,那么,如果想要使用iptables充当网络防火墙,iptables所在的主机则需要处于网络入口处

网络防火墙的职责就是”过滤并转发”: 要想”过滤”,只能在INPUT、OUTPUT、FORWARD三条链中实现,要想”转发”,报文则只会经过FORWARD链(发往本机的报文才会经过INPUT链),所以,综上所述,iptables的角色变为”网络防火墙”时,规则只能定义在FORWARD链中

Linux主机在默认情况下,并不会转发报文,如果想要让Linux主机能够转发报文, 需要额外的设置:

  • 临时生效, 重启失效: 查看/proc/sys/net/ipv4/ip_forward文件中的内容,如果文件内容为0,则表示当前主机不支持转发, 将其设置为1 即为开启转发
  • 永久生效: 设置/etc/sysctl.conf文件(centos7中配置/usr/lib/sysctl.d/00-system.conf文件),添加(或修改)配置项 net.ipv4.ip_forward = 1

todo


7.NAT

NAPT是NAT的一种,全称为Network Address Port Translation

内网到外网:

  • 内部网络的报文发送出去时,报文的源IP会被修改,也就是源地址转换:Source Network Address Translation,缩写为SNAT
  • 外部网络的报文响应时,响应报文的目标IP会再次被修改,也就是目标地址转换:Destinationnetwork address translation,缩写为DNAT

上述”整个过程”被称为SNAT, 因为”整个过程”的前半段使用了SNAT

SNAT(出口主动更换源ip): 隐藏内网IP/共享公网IP

iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 公网IP

DNAT(入口主动更换目的ip)

iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 公网端口 -j DNAT --to-destination 私网IP:端口号

自动的SNAT: MASQUERADE

MASQUERADE不用指定明确的IP,会动态的将报文的源地址修改为指定网卡上可用的IP地址

iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE

端口映射: iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080, 只能定义在PREROUTING链或者OUTPUT链中


8. 代理

iptables+redirect:

iptables+redirect 这种一般是用来重定向TCP数据的 所以代理程序可以通过getsockopt (s, SOL_IP, SO_ORIGINAL_DST, &dstaddr, &n)函数来获取原始目标地址和端口信息,大概的原理应该是通过查询系统ip_conntrack结构来获得原始目标地址和端口信息

tproxy:

在tproxy工作过程中,首先,这是tproxy向netfilter注册的一个target,该target能够在不对数据包修改的情况下,将数据包代理到本地套接字上; 他的关键点在于通过获得数据包的目的端口和目的地址(而非本地监听套接字的bind地址),再通过nf_tproxy_get_sock_v4函数,获得监听套接字,最后把skb->sock = sk;

tproxy优势:其的优势在于不对数据包(包头信息)进行任何改变(NAT),就可以重定向数据包


IPVS

你真的掌握lvs工作原理吗?

PVS:如何让服务器“情绪稳定,高速运转”?