一、基础概念

防火墙是是一款报文隔离工具,工作于主机或网络的边缘,它能够根据事先定义的检查规则对进出本主机或网络的报文做匹配检测,发现被规则匹配的报文则做出相应处理。Linux防火墙发展到今天,已经迭代很多次了,Linux内核1.0时代的初代防火墙被叫做ipfirewall,到Linux内核2.0的时候,防火墙就被叫做ipchains,在往后就被称为iptables了,但是到Linux内核4.0又被改名为nftables

1. 防火墙种类

  • 主机防火墙
  • 网络防火墙

2. iptables与netfilter

iptables是用户空间规则管理工具,而真正实现防火的是netfilter。netfilter工作在内核中提供网络报文过滤处理框架(framework),它在内核中提供了五个钩子函数(hooks functions),iptables是在用户空间负责向钩子函数增删改查规则的工具,netfilter只是在tpc/ip协议栈设立的五个卡哨,真正能发挥功能还要在卡哨上添加规则

3. iptables的表

(1) 过滤(filter)

可实现过滤的链

  • INPUT
  • FORWARD
  • OUTPUT

(2) 网络地址转换(nat:network address translation)

可实现NAT的链

  • PREROUTING(DNAT)
  • POSTROUTING(SNAT)
  • OUTPUT

(3) mangle(拆解报文、做出修改、封装报文)

可实现mangle的链

  • PREROUTING
  • INPUT
  • FORWARD
  • OUTPUT
  • POSTROUTING

(4) raw

防火墙为了可以将NAT转换后的请求无误的发送给每一个目标,其内部有一个追踪机制叫做raw。连接追踪很实用,但是在非常繁忙的前端负载均衡服务器一定要关闭连接追踪功能,如果开启请准备充足内存,并且调大连接追踪可用内存,不然会出现大量拒绝连接现象
可实现raw的链

  • OUTPUT
  • PREROUTING

4. 各表的生效次序

各表的生效次序
各表的生效优先级:raw --> mangle --> nat --> filter
如图所示当报文入站,需按照顺序经过raw表、mangle表、nat表的PREROUTING链处理,之后经拆解决定进入本机或转发

  • 如果报文是进入本机,则需要按照优先级经由mangle表、filter表的INPUT链过滤后,转交给本机的进程,进程处理完请求将结果按照顺序经由raw表、mangle表、nat表、filter表的OUTPUT链处理,最后按照顺序经由mangle表、nat表的POSTROUTING链完成出站
  • 如果报文需要经由本机转发,则按照次序经由mangle表、filter表的FORWARD链进行处理,最后交给mangle表、nat表的POSTROUTING完成出站

5. 报文流向需经过的链

  • 进入本机:PREROUTING --> INPUT
  • 从本机流出:OUTPUT --> POSTROUTING
  • 本机负责转发:PREROUTING --> FORWARD --> POSTROUTING

6. 规则的组成部分

(1) 报文的匹配条件

用来指定哪一类报文做出处理

  • 基本匹配条件:根据源ip、目标ip、源端口、目标端口
  • 扩展匹配:

(2) 匹配到之后的处理动作

一旦报文匹配成功后,对其的处理动作

  • 内检处理机制:DROP(丢弃)、REJECT(拒绝)
  • 扩展处理动作:
  • 自定义处理机制:仅仅能够指明跳转自定义目标链,报文不会经过自定义链,只能在内置链上通过规则引用后生效;

8. 定义规则的注意事项

各链上的规则次序即为检查次序,因此隐含一定的应用法则

  • 访问同一应用的规则:匹配范围小的应放上面
  • 访问不同类的应用的规则:匹配报文频率较大的放在上面
  • 可按需将多个小范围规则合并成一个大规则,如一条规则开放80端口、第二条规则开放443端口,可以将则两条合并成一条
  • 设定默认规则

二、命令用法

iptables命令格式用法有很多,根据不同的子命令其标准格式也不同

  • 修改规则命令格式:iptables [-t table] {-A|-C|-D} chain rule-specification
  • 修改规则命令格式:iptables [-t table] -I chain [rulenum] rule-specification
  • 替换指定规则命令格式:iptables [-t table] -R chain rulenum rule-specification
  • 删除指定规则命令格式:iptables [-t table] -D chain rulenum
    iptables [-t table] -S [chain [rulenum]]
  • 清空规则命令格式:iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]
  • 自定义链命令格式:iptables [-t table] -N chain
  • 删除自定义链命令格式:iptables [-t table] -X [chain]
  • 设置默认策略:iptables [-t table] -P chain target
  • 修改链名称命令格式:iptables [-t table] -E old-chain-name new-chain-name
命令归纳格式:iptables [-t table] COMMAND chain [rulenum] [-m m_name [m_option]] [-j target_name [t_option]]
↑ ↑ ↑ ↑ ↑
一 二 三 四 五

一、 -t table:指定表格,如果缺省则表示filter表

------------------------------------------------------------------------------------------------------------------------

二、COMMAND(命令),命令分为链管理命令和规则管理命令

链管理:
-F:清空,可以清空指定链
-t TABLE:指定表。filter、nat、mangle、raw
-N CHAIN:创建新的自定义规则链,但是不要与内建的链名冲突
-X CHAIN:删除用户自定义链,但是被删除链引用计数和规则必须为0
-Z:清零规则计数器
-P:设置默认规则
-E CHAIN_NAME NEW_NAME:重命名自定义链,引用计数不为0的自定义链,无法改名,也无法删除

规则管理:
-A:append,追加在指定链尾部
-I:insert,加入指定位置
-D:delete,删除指定规则
-R:replace,替换指定链上的指定规则

规则查看:
-L:列出指定链上的所有规则
-n:以数字格式显示端口号
-v[v|vv]:显示详细信息
--line-numbers:显示规则编号
-x:显示计数器结果的精确值

------------------------------------------------------------------------------------------------------------------------
三、chain [rulenum],指定链名称和规则编号

可指定链:
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING

------------------------------------------------------------------------------------------------------------------------

四、[-m m_name [m_option]] 匹配标准,匹配标准是对报文更加详细的描述,分为基本匹配、隐式扩展匹配、显示扩展匹配

基本匹配:
[!]-s|--src|--source IP|NETADDR:检查报文中的源地址
[!]-d|--dst|--destination IP|NETADDR:检查报文中的目标地址
[!]-p|--protocol {tcp|udp|icmp}:检查报文中的协议
[!]-i|--in-interface IFACE:数据报文的流入接口
[!]-o|--out-interface IFACE:数据报文的流出接口

隐式扩展匹配:如果使用-p选项指定协了,就可以省略 -m protocle
1. -p tcp或-m tcp m_option
--dport # | --dport #:#
--sport # | --dport #:#
--tcp-flags:tcp标志位扩展,-p tcp --tcp-flags LIST1 LIST2:LIST中可使用SYN、ACK、FIN、RST(重置连接)、PSH(立即推送)、URG(紧
急)这表示LIST1中所指定的标志位都要检查,LIST2中指定标志位都必须是LIST1中出现的且必须为1,未出现的必须为0
--tcp-flags SYN,ACK,FIN,RST SYN 相当于使用--syn

2. -p udp
--dport # | --dport #:#
--sport # | --dport #:#

3. --icmp-type #
0:echo-reply(回送应答,被别人ping是需要回送icmp类型0的报文)
8:echo-request(请求,ping它人时需要发送icmy类型8的报文)

显示扩展匹配:显示扩展必须使用-m选项
1. 多端口扩展:multiport \\ 格式:-m multiport M_OPTION
--sports #[,#|,#:#]
--dports #[,#|,#:#]

2. 地址范围:iprange \\ 格式:-m iprange M_OPTION
--src-range FROM_IP[-TO_IP]
--dst-range FROM_IP[-TO_IP]

3. 检查报文中字符串:string \\ -m string M_OPTION
--algo {bm|kmp}:字符串匹配算法,必用选项
--string PATTERN
--hex-string PATTERN
示例:iptables -I OUTPUT -m string --algo bm --string "bad" -j DROP

4. 时间控制 time \\ 格式:-m time M_OPTION
--timestart hh:mm[:ss]
--timestop hh:mm[:ss]
--weekdays #[,#]
--monthdays #[,#]
--datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
--datestop YYYY[-MM[-DD[Thh[:MM[:ss]]]]]
--kerneltz:使用内核配置的时区为准,不加此项为UTC时间
示例:iptables -A INPUT --dport 80 -m time --timestart 14:00 --timestop 17:15 -j DROP

5. 链接限制:connlimit \\ 示例:-m connlimit M_OPTION
--connlimit-above #:超过#个做限制
--connlimit-upto #:小于等于#个做限制
示例:iptables -I INPUT --dport 22 -m connlimit --connlimit-above 3 -j DROP

6. 收发报文速率限制:limit \\ 示例: -m limit M_OPTION
--limit-burst #:令牌桶最大空闲令牌数
--limit #[/second|/minute|/hour|/day]:限制报文速率
示例:iptables -A INPUT -p icmp -m limit --limit-burst 5 --limit 20/minute -j ACCEPT

7. 状态扩展:state,根据连接追踪机制跟踪每一个连接请求 \\ 示例: -state --state STATE_NAME
--state NEW:新发出的请求,链接追踪模板中不存在链接相关的信息条目
--state ESTABLISHED:new状态之后,链接追踪模板中未其建立的条目失效之前内所进行的通信状态
--state RELATED:相关链接
--state INVALIED:无法识别的链接,比如Syn和Fin标志位同时为1的错乱链接请求
--state UNTRACKED:未追踪的链接,出现在关闭链接追踪功能时

链接追踪功能固然好,但是其是在内核内存中维护链接追踪状态表的,一旦内核内存空间耗尽后,新的链接请求都会被自动拒绝。所以对于非常繁忙
的服务器我们需要手动将链接追踪相关参数开放的大一些

1)调整链接追踪功能所能够记录的最大链接数量位置:/proc/sys/net/nf_conntrack_max,默认为65536
2)已经追踪到的链接记录位置:/proc/net/nf_conntrack
3)调整不同协议或链接类型的追踪时长位置:/proc/sys/net/netfilter/

------------------------------------------------------------------------------------------------------------------------

五、处理动作:-j target_name [t_option]]
1. ACCEPT:接受
2. DROP:丢弃
3. REJECT:拒绝
--reject-with icmp-net-unreachable:网络不可达
--reject-with icmp-host-unreachable:主机不可达
--reject-with icmp-port-unreachable:端口不可达,此项为默认值
--reject-with icmp-proto-unreachable:协议不可达
--reject-with icmp-net-prohibited:网络被禁止
--reject-with icmp-host-prohibited:主机被禁止
--reject-with icmp-admin-prohibited:管理禁止
4. LOG:记录日志,默认保存于/var/log/messages文件中
--log-level:日志级别
--log-prefix "string":日志前缀
5. 自定义链:直接使用-j调用自定义链名称,具体如何处理需在自定义链中定义规则,如果自定义链中未能匹配任何一条规则,此报文将会重新调回
主链继续匹配规则。自定义链可以多级调度
6. RETURN:在自定义链中此动作可以将报文返回主链
7. REDIRECT:端口重定向
8. MARK:做防火墙标记
9. DNAT:做目标地址转换
10. SNAT:源地址转换
11. MASQUERADE:地址伪装

三、iptables构建网络防火墙

内网拓扑

1. 配置网络路由器

使用iptables构建网络防火墙需要开启核心转发功能

  • 核心转发查看:cat /proc/sys/net/ipv4/ip_forward
  • 临时开启核心转发功能:sysctl -w net.ipv4.ip_forward=1
  • 永久开启核心转发功能:编辑/etc/sysctl.conf/加入net.ipv4.ip_forward = 1

2. 客户端添加路由策略

在客户端中加入通往192.168.70.0网络的路由条目:ip route add 192.168.70.0/24 via 192.168.60.230 dev ens33

3. 配置内网web

将内网主机的默认网关调整为192.168.70.254,启动web服务

4. 在网络路由器中加入iptables策略

网络路由器开启核心转发功能、客户端添加路由条目后,就已经可以访问内网web了。不过如果把网络路由器的FORWARD链默认策略调整为DROP的话,就必须加入放行策略
iptables -I FORWARD -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -d 192.168.70.100 -p tcp --dport 80 -m state --state NEW -j ACCEPT

四、NAT

1. SNAT

源地址转换需要使用iptables处理动作的SNAT
格式:-j SNAT S_OPTION

  • --to-source ip[-ip][:port-port]:IP地址可以指定范围,在此范围内轮询
  • --random:如果指定一个IP地址范围,挑选顺序改为随机而不是轮询
  • --persistent:如果指定一个IP地址范围,挑选顺序改为固定而不是轮询

如果没有固定的IP地址,那么使用SNAT固定指定的IP地址就存在失效的可能性,这种情况可以使用另外一个target叫做MASQUERADE,不过这个target需要消耗更多的资源,它每次转换都需要去判定你的接口IP地址
格式:-j MASQUERADE

2. DNAT

格式:-j DNAT S_OPTION

  • --to-destination ip[-ip][:port-port]:IP地址可以指定范围,在此范围内轮询
  • --random:如果指定一个IP地址范围,挑选顺序改为随机而不是轮询
  • --persistent:如果指定一个IP地址范围,挑选顺序改为固定而不是轮询

3. REDIRECT

端口重定向使用REDIRECT处理动作
格式:-j REDIRECT
--to-ports #

五、iptables保存、导入规则

1. Centos 7

  • 保存规则:iptables-save > /path/to/somefile
  • 导入规则:iptables-restore < /path/to/somefile

2. Centos 6

  • 保存规则方法1:service iptables save,会覆盖保存至/etc/sysconfig/iptables文件中
  • 保存规则方法2:iptables-save > /path/to/somefile
  • 导入规则:iptables-restore < /path/to/somefile
  • 重载规则:service iptables restart,会读取/etc/sysconfig/iptables文件中的规则覆盖当前规则

六、iptables放行ftpd服务

1. 装载模块

只要启动iptables的链接追踪功能,nf_conntrack模块就会被自动装载,但是这个模块不能追踪ftpd的状态,需要使用专用模块nf_conntrack_ftp,所以第一步需要装载模块

  • modprobe nf_conntrack_ftp

2. 放行请求报文

在INPUT链中加入放行状态为NEW、ESTABLISHED、RELATED的链接

  • iptables -A INPUT -d 192.168.60.200 -p tcp --dport 21 -m state --state NEW -j ACCEPT
  • iptables -I INPUT -d 192.168.60.200 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT

3. 放行响应链接

  • iptables -I OUTPUT -s 192.168.60.200 -m state --state ESTABLISHED -j ACCEPT