Linux防火墙--iptables

发布于:2024-10-18 ⋅ 阅读:(9) ⋅ 点赞:(0)

iptables由五个表table和五个链chain以及一些规则组成

五个表table:

filter、nat、mangle、raw、security

filter表:过滤规则表,根据预定义的规则过滤符合条件的数据包
nat表:network address translation 地址转换规则表
mangle:修改数据标记位规则表
raw:关闭启用的连接跟踪机制,加快封包穿越防火墙速度
security:用于强制访问控制(MAC)网络规则,由Linux安全模块(如SELinux)实现

优先级由高到低的顺序为:

security -->raw-->mangle-->nat-->filter

五个内置链chain:

INPUT, OUTPUT, FORWARD, PREROUTING, POSTROUTING

链 chain:

  • 内置链:每个内置链对应于一个钩子函数
  • 自定义链:用于对内置链进行扩展或补充,可实现更灵活的规则组织管理机制;只有Hook钩子调用自定义链时,才生效

iptables命令格式详解:

iptables   [-t table]   SUBCOMMAND   chain   [-m matchname [per-match-options]]   -j targetname [per-target-options]
1、-t table:指定表

raw, mangle, nat, [filter]默认

2、SUBCOMMAND:子命令

链管理类:

-N:new, 自定义一条新的规则链
-E:重命名自定义链;引用计数不为0的自定义链不能够被重命名,也不能被删除
-X:delete,删除自定义的空的规则链
-P:Policy,设置默认策略;对filter表中的链而言,其默认策略有:ACCEPT:接受, DROP:丢弃

范例:

[root@centos7 ~]#iptables -N web_chain 
[root@centos7 ~]#iptables -N web_chain -t nat
[root@centos7 ~]#iptables -X web_chain -t nat
[root@centos7 ~]#iptables -E web_chain WEB_CHAIN
[root@centos7 ~]#iptables -A WEB_CHAIN -s 10.0.0.6 -p tcp -m multiport  --dports 80,443 -j REJECT
[root@centos7 ~]#iptables -R WEB_CHAIN 1  -s 10.0.0.6 -p tcp -m multiport  --dports 80,443,8080 -j REJECT
[root@centos7 ~]#iptables -vnL  WEB_CHAIN
Chain WEB_CHAIN (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    1    60 REJECT     tcp  --  *      *       10.0.0.6             0.0.0.0/0            multiport dports 80,443,8080 reject-with icmp-port-unreachable

[root@centos7 ~]#iptables -AINPUT -j WEB_CHAIN 
[root@centos7 ~]#iptables -X WEB_CHAIN
iptables v1.8.2 (nf_tables):  CHAIN_USER_DEL failed (Device or resource busy): chain WEB_CHAIN
[root@centos7 ~]#iptables -F  WEB_CHAIN
[root@centos7 ~]#iptables -X WEB_CHAIN
iptables v1.8.2 (nf_tables):  CHAIN_USER_DEL failed (Device or resource busy): chain WEB_CHAIN
[root@centos7 ~]#iptables -D INPUT 1
[root@centos7 ~]#iptables -X WEB_CHAIN

查看类:

-L:list, 列出指定鏈上的所有规则,本选项须置后
-n:numberic,以数字格式显示地址和端口号
-v:verbose,详细信息
-vv  更详细
-x:exactly,显示计数器结果的精确值,而非单位转换后的易读值 
--line-numbers:显示规则的序号
-S  selected,以iptables-save 命令格式显示链上规则
常用组合:
-vnL
-vvnxL –line-numbers

规则管理类:

-A:append,追加
-I:insert, 插入,要指明插入至的规则编号,默认为第一条
-D:delete,删除
       (1) 指明规则序号
       (2) 指明规则本身
-R:replace,替换指定链上的指定规则编号
-F:flush,清空指定的规则链
-Z:zero,置零
       iptables的每条规则都有两个计数器
        (1) 匹配到的报文的个数
        (2) 匹配到的所有报文的大小之和
范例:

[root@centos7 ~]#iptables -F OUTPUT

3、chain:

PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING

4、匹配条件

基本:通用的,PARAMETERS
扩展:需加载模块,MATCH EXTENTIONS
5、处理动作:

-j targetname [per-target-options]
简单:ACCEPT,DROP

扩展:

REJECT:–reject-with:icmp-port-unreachable默认
RETURN:返回调用链
REDIRECT:端口重定向
LOG:记录日志,dmesg
MARK:做防火墙标记
DNAT:目标地址转换
SNAT:源地址转换
MASQUERADE:地址伪装
自定义链

iptables 基本匹配条件
基本匹配条件:无需加载模块,由iptables/netfilter自行提供

[!] -s, --source  address[/mask][,...]:源IP地址或者不连续的IP地址
[!] -d, --destination address[/mask][,...]:目标IP地址或者不连续的IP地址
[!] -p, --protocol protocol:指定协议,可使用数字如0(all)
    protocol: tcp, udp, icmp, icmpv6, udplite,esp, ah, sctp, mh or“all“  
    参看:/etc/protocols
[!] -i, --in-interface name:报文流入的接口;只能应用于数据报文流入环节,只应用于INPUT、FORWARD、PREROUTING链
[!] -o, --out-interface name:报文流出的接口;只能应用于数据报文流出的环节,只应用于FORWARD、OUTPUT、POSTROUTING链
范例:

[root@centos7 ~]#iptables -A INPUT -s 10.0.0.6,10.0.0.10 -j REJECT
[root@centos7 ~]#iptables -I INPUT -i lo -j ACCEPT
[root@centos7 ~]#curl 127.0.0.1
10.0.0.8
[root@centos7 ~]#curl 10.0.0.8
10.0.0.8


iptables 扩展匹配条件
扩展匹配条件:需要加载扩展模块(/usr/lib64/xtables/*.so),方可生效
扩展模块的查看帮助 :man iptables-extensions

扩展匹配条件:

隐式扩展
iptables 在使用-p选项指明了特定的协议时,无需再用-m选项指明扩展模块的扩展机制,不需要手动加载扩展模块

tcp协议的扩展选项
[!] –source-port, –sport port[:port]:匹配报文源端口,可为端口连续范围
[!] –destination-port,–dport port[:port]:匹配报文目标端口,可为连续范围
[!] –tcp-flags mask comp
mask 需检查的标志位列表,用,分隔
例如 SYN,ACK,FIN,RST
comp 在mask列表中必须为1的标志位列表,无指定则必须为0,用,分隔tcp协议的扩展选项

范例:

--tcp-flags  SYN,ACK,FIN,RST  SYN  表示要检查的标志位为SYN,ACK,FIN,RST四个,其中SYN必须为1,余下的必须为0,第一次握手
--tcp-flags  SYN,ACK,FIN,RST  SYN,ACK  第二次握手

--tcp-flags ALL ALL  
--tcp_flags ALL NONE
[!] –syn:用于匹配第一次握手, 相当于:–tcp-flags SYN,ACK,FIN,RST SYN

udp 协议的扩展选项

[!] --source-port, --sport port[:port]:匹配报文的源端口或端口范围
[!] --destination-port,--dport port[:port]:匹配报文的目标端口或端口范围
icmp 协议的扩展选项

[!] --icmp-type {type[/code]|typename}
      type/code
        0/0   echo-reply        icmp应答
        8/0   echo-request      icmp请求  
范例:

[root@centos7 ~]#iptables -A INPUT -s 10.0.0.6 -p tcp --dport 21:23 -j REJECT
[root@centos7 ~]#ipn
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        1    60 REJECT     tcp  --  *      *       10.0.0.6             0.0.0.0/0            tcp dpts:21:23 reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination


范例:

[root@centos7 ~]#iptables -A INPUT  -p tcp --syn  -j REJECT


范例:

[root@centos7 ~]#iptables -A INPUT -s 10.0.0.6 -p icmp --icmp-type 8 -j REJECT 


显式扩展及相关模块
显示扩展即必须使用-m选项指明要调用的扩展模块名称,需要手动加载扩展模块

 [-m matchname [per-match-options]]
扩展模块的使用帮助:

man iptables-extensions
multiport扩展
​ 以离散方式定义多端口匹配,最多指定15个端口

#指定多个源端口
[!] --source-ports,--sports port[,port|,port:port]...

# 指定多个目标端口
[!] --destination-ports,--dports port[,port|,port:port]...

#多个源或目标端
[!] --ports port[,port|,port:port]...
范例:

[root@centos7 ~]#iptables -A INPUT -s 172.16.0.0/16 -d 172.16.100.10 -p tcp -m multiport --dports 20:22,80 -j ACCEPT

[root@centos7 ~]#iptables -A INPUT -s 10.0.0.6 -p tcp -m multiport --dports 445,139 -j REJECT

[root@centos7 ~]#iptales -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        2   120 REJECT     tcp  --  *      *       10.0.0.6             0.0.0.0/0            multiport dports 445,139 reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

iprange扩展
指明连续的(但一般不是整个网络)ip地址范围

[!] --src-range from[-to]   源IP地址范围
[!] --dst-range from[-to]   目标IP地址范围
范例:

iptables -A INPUT -d 172.16.1.100 -p tcp --dport 80 -m iprange --src-range 172.16.1.5-172.16.1.10 -j DROP


mac扩展
mac 模块可以指明源MAC地址,,适用于:PREROUTING, FORWARD,INPUT chains

[!] --mac-source XX:XX:XX:XX:XX:XX
范例:

iptables -A INPUT -s 172.16.0.100 -m mac  --mac-source  00:50:56:12:34:56 -j ACCEPT
iptables -A INPUT -s 172.16.0.100  -j REJECT


3.4.2.4 string扩展
对报文中的应用层数据做字符串模式匹配检测

--algo {bm|kmp} 字符串匹配检测算法
    bm:Boyer-Moore
    kmp:Knuth-Pratt-Morris
--from offset       开始偏移
--to offset         结束偏移
[!] --string pattern    要检测的字符串模式
[!] --hex-string pattern要检测字符串模式,16进制格式
范例:

iptables -A OUTPUT -s 172.16.100.10 -d 0/0 -p tcp --sport 80 -m string --algo bm --string "keepalived-01" -j REJECT  


                                  
time扩展
注意:CentOS 8 此模块有问题

根据将报文到达的时间与指定的时间范围进行匹配

--datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]  日期
--datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
--timestart hh:mm[:ss]        时间
--timestop hh:mm[:ss]
[!] --monthdays day[,day...]   每个月的几号
[!] --weekdays day[,day...]   星期几,1 – 7 分别表示星期一到星期日
--kerneltz:内核时区(当地时间),不建议使用,CentOS 7 系统默认为 UTC
注意: centos6 不支持kerneltz ,--localtz指定本地时区(默认)
范例:

[root@centos7 ~]#iptables -A INPUT -s 172.16.0.0/16 -d 172.16.100.10 -p tcp --dport 80 -m time --timestart 14:30 --timestop 18:30 --weekdays Sat,Sun --kerneltz -j DROP

connlimit扩展
根据每客户端IP做并发连接数数量匹配
可防止Dos(Denial of Service,拒绝服务)攻击

--connlimit-upto        #连接的数量小于等于#时匹配
--connlimit-above       #连接的数量大于#时匹配
范例:

iptables -A INPUT -d 172.16.100.10 -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
上诉命令会导致连接超过两个,所有的链接都卡死


limit扩展
基于收发报文的速率做匹配
令牌桶过滤器

--limit #[/second|/minute|/hour|/day]
--limit-burst number    #前多少个包不限制
范例:

iptables -I INPUT -d 172.25.100.10 -p icmp --icmp-type 8 -m limit --limit 10/minute --limit-burst 5 -j ACCEPT
iptables -I INPUT 2 -p icmp -j REJECT

范例: 

[root@centos7 ~]#iptables -A INPUT -p icmp -m limit --limit-burst 10 --limit 20/minute -j ACCEPT
[root@centos7 ~]#iptables -A INPUT -p icmp  -j REJECT

[root@centos7 ~]# ping 172.25.0.11
PING 172.25.0.11 (172.25.0.11) 56(84) bytes of data.
64 bytes from 172.25.0.11: icmp_seq=1 ttl=64 time=0.791 ms
64 bytes from 172.25.0.11: icmp_seq=2 ttl=64 time=1.29 ms
64 bytes from 172.25.0.11: icmp_seq=3 ttl=64 time=0.610 ms
64 bytes from 172.25.0.11: icmp_seq=4 ttl=64 time=0.708 ms
64 bytes from 172.25.0.11: icmp_seq=5 ttl=64 time=0.608 ms
64 bytes from 172.25.0.11: icmp_seq=6 ttl=64 time=0.768 ms
64 bytes from 172.25.0.11: icmp_seq=7 ttl=64 time=0.814 ms
64 bytes from 172.25.0.11: icmp_seq=8 ttl=64 time=0.424 ms
64 bytes from 172.25.0.11: icmp_seq=9 ttl=64 time=0.458 ms
64 bytes from 172.25.0.11: icmp_seq=10 ttl=64 time=0.458 ms
64 bytes from 172.25.0.11: icmp_seq=11 ttl=64 time=0.760 ms
64 bytes from 172.25.0.11: icmp_seq=12 ttl=64 time=0.858 ms
64 bytes from 172.25.0.11: icmp_seq=13 ttl=64 time=1.29 ms
64 bytes from 172.25.0.11: icmp_seq=14 ttl=64 time=0.488 ms
From 172.25.0.11 icmp_seq=15 Destination Port Unreachable
From 172.25.0.11 icmp_seq=16 Destination Port Unreachable
64 bytes from 172.25.0.11: icmp_seq=17 ttl=64 time=0.529 ms
From 172.25.0.11 icmp_seq=18 Destination Port Unreachable
From 172.25.0.11 icmp_seq=19 Destination Port Unreachable
From 172.25.0.11 icmp_seq=20 Destination Port Unreachable
64 bytes from 172.25.0.11: icmp_seq=21 ttl=64 time=0.571 ms
From 172.25.0.11 icmp_seq=22 Destination Port Unreachable
From 172.25.0.11 icmp_seq=23 Destination Port Unreachable
64 bytes from 172.25.0.11: icmp_seq=24 ttl=64 time=0.710 ms
From 172.25.0.11 icmp_seq=25 Destination Port Unreachable
^C
--- 172.25.0.11 ping statistics ---
25 packets transmitted, 17 received, +8 errors, 32% packet loss, time 24358ms
rtt min/avg/max/mdev = 0.424/0.714/1.292/0.249 ms
state扩展

state扩展模块,可以根据”连接追踪机制“去检查连接的状态,较耗资源
conntrack机制:追踪本机上的请求和响应之间的关系

状态类型

-NEW:新发出请求;连接追踪信息库中不存在此连接的相关信息条目,因此,将其识别为第一次发出的请求

-ESTABLISHED:NEW状态之后,连接追踪信息库中为其建立的条目失效之前期间内所进行的通信状态
-RELATED:新发起的但与已有连接相关联的连接,如:ftp协议中的数据连接与命令连接之间的关系
-INVALID:无效的连接,如flag标记不正确
-UNTRACKED:未进行追踪的连接,如:raw表中关闭追踪

已经追踪到的并记录下来的连接信息库

[root@centos8 ~]#cat /proc/net/nf_conntrack
ipv4     2 tcp      6 431325 ESTABLISHED src=10.0.0.7 dst=10.0.0.8 sport=49900 dport=80 src=10.0.0.8 dst=10.0.0.7 sport=80 dport=49900 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 431325 ESTABLISHED src=10.0.0.7 dst=10.0.0.8 sport=49886 dport=80 src=10.0.0.8 dst=10.0.0.7 sport=80 dport=49886 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 431325 ESTABLISHED src=10.0.0.7 dst=10.0.0.8 sport=49892 dport=80 src=10.0.0.8 dst=10.0.0.7 sport=80 dport=49892 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 431325 ESTABLISHED src=10.0.0.7 dst=10.0.0.8 sport=49904 dport=80 src=10.0.0.8 dst=10.0.0.7 sport=80 dport=49904 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 431325 ESTABLISHED src=10.0.0.7 dst=10.0.0.8 sport=49890 dport=80 src=10.0.0.8 dst=10.0.0.7 sport=80 dport=49890 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 431325 ESTABLISHED src=10.0.0.7 dst=10.0.0.8 sport=49888 dport=80 src=10.0.0.8 dst=10.0.0.7 sport=80 dport=49888 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 431325 ESTABLISHED src=10.0.0.7 dst=10.0.0.8 sport=49896 dport=80 src=10.0.0.8 dst=10.0.0.7 sport=80 dport=49896 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 431325 ESTABLISHED src=10.0.0.7 dst=10.0.0.8 sport=49898 dport=80 src=10.0.0.8 dst=10.0.0.7 sport=80 dport=49898 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 431325 ESTABLISHED src=10.0.0.7 dst=10.0.0.8 sport=49894 dport=80 src=10.0.0.8 dst=10.0.0.7 sport=80 dport=49894 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 431325 ESTABLISHED src=10.0.0.7 dst=10.0.0.8 sport=49902 dport=80 src=10.0.0.8 dst=10.0.0.7 sport=80 dport=49902 [ASSURED] mark=0 zone=0 use=2

调整连接追踪功能所能够容纳的最大连接数量

[root@centos8 ~]#cat /proc/sys/net/netfilter/nf_conntrack_max
26624
[root@centos8 ~]#cat /proc/sys/net/nf_conntrack_max
26624

查看连接跟踪有多少条目

[root@centos8 ~]#cat /proc/sys/net/netfilter/nf_conntrack_count
10

不同的协议的连接追踪时长

[root@centos8 ~]#ll /proc/sys/net/netfilter/
total 0
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_acct
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_buckets
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_checksum
-r--r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_count
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_dccp_loose
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_dccp_timeout_closereq
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_dccp_timeout_closing
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_dccp_timeout_open
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_dccp_timeout_partopen
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_dccp_timeout_request
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_dccp_timeout_respond
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_dccp_timeout_timewait
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_events
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_expect_max
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_generic_timeout
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_helper
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_icmp_timeout
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_log_invalid
-rw-r--r-- 1 root root 0 Mar 19 18:13 nf_conntrack_max
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_sctp_timeout_closed
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_sctp_timeout_cookie_echoed
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_sctp_timeout_cookie_wait
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_sctp_timeout_established
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_sctp_timeout_heartbeat_acked
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_sctp_timeout_heartbeat_sent
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_sctp_timeout_shutdown_ack_sent
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_sctp_timeout_shutdown_recd
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_sctp_timeout_shutdown_sent
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_tcp_be_liberal
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_tcp_loose
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_tcp_max_retrans
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_tcp_timeout_close
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_tcp_timeout_close_wait
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_tcp_timeout_established
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_tcp_timeout_fin_wait
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_tcp_timeout_last_ack
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_tcp_timeout_max_retrans
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_tcp_timeout_syn_recv
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_tcp_timeout_syn_sent
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_tcp_timeout_time_wait
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_tcp_timeout_unacknowledged
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_timestamp
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_udp_timeout
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_conntrack_udp_timeout_stream
dr-xr-xr-x 1 root root 0 Mar 19 18:14 nf_log
-rw-r--r-- 1 root root 0 Mar 19 18:14 nf_log_all_netns

说明:

-连接跟踪,需要加载模块: modprobe nf_conntrack_ipv4

-当服务器连接多于最大连接数时dmesg 可以观察到 :kernel: ip_conntrack: table full, dropping packet错误,并且导致建立TCP连接很慢。

-各种状态的超时后,链接会从表中删除

连接过多的解决方法两个:

(1) 加大nf_conntrack_max 值

vi /etc/sysctl.conf
net.nf_conntrack_max = 393216
net.netfilter.nf_conntrack_max = 393216 

(2) 降低 nf_conntrack timeout时间

vi /etc/sysctl.conf
net.netfilter.nf_conntrack_tcp_timeout_established = 300
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
iptables -t nat -L -n

格式:

[!] --state state

范例:

iptables -A INPUT -d 172.16.1.10 -p tcp -m multiport --dports 22,80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -s 172.16.1.10 -p tcp -m multiport --sports 22,80 -m state --state ESTABLISHED -j ACCEPT

[root@centos8 ~]#iptables -A INPUT  -m state --state ESTABLISHED -j ACCEPT
[root@centos8 ~]#iptables -A INPUT  -m state --state NEW -j REJECT

案例:开放被动模式的ftp服务

CentOS 8 此模块有bug

(1) 装载ftp连接追踪的专用模块:
跟踪模块路径:/lib/modules/kernelversion/kernel/net/netfilter

vim /etc/sysconfig/iptables-config 
IPTABLES_MODULES=“nf_conntrack_ftp"
modprobe  nf_conntrack_ftp

(2) 放行请求报文:
命令连接:NEW, ESTABLISHED
数据连接:RELATED, ESTABLISHED

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

(3) 放行响应报文:

iptables -I OUTPUT -s LocalIP -p tcp -m state --state ESTABLISHED -j ACCEPT 

范例:开放被动模式的ftp服务示例

yum install vsftpd
systemctl start vsftpd
modprobe nf_conntrack_ftp
iptables -F
iptables -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT
iptables -A OUTPUT  -m state --state ESTABLISHED -j ACCEPT
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -vnL
Target

targe包括以下类型:

ACCEPT, DROP, REJECT, RETURN,LOG,SNAT,DNAT,REDIRECT,MASQUERADE

LOG:非中断target,本身不拒绝和允许,放在拒绝和允许规则前,并将日志记录在/var/log/messages系统日志中
--log-level level    级别: debug,info,notice, warning, error, crit, alert,emerg
--log-prefix prefix 日志前缀,用于区别不同的日志,最多29个字符

范例:

[root@centos8 ~]#iptables -I INPUT  -s 10.0.1.0/24 -p tcp -m multiport --dports 80,21,22,23 -m state --state NEW -j LOG --log-prefix "new connections: " 

[root@centos8 ~]#tail -f /var/log/messages 
Mar 19 18:41:07 centos8 kernel: iptables tcp connection: IN=eth0 OUT= MAC=00:0c:29:f8:5d:b7:00:50:56:c0:00:08:08:00 SRC=10.0.0.1 DST=10.0.0.8 LEN=40 TOS=0x00 PREC=0x00 TTL=128 ID=43974 DF PROTO=TCP SPT=9844 DPT=22 WINDOW=4102 RES=0x00 ACK URGP=0 
Mar 19 18:41:07 centos8 kernel: new connections: IN=eth0 OUT= MAC=00:0c:29:f8:5d:b7:00:50:56:c0:00:08:08:00 SRC=10.0.0.1 DST=10.0.0.8 LEN=40 TOS=0x00 PREC=0x00 TTL=128 ID=43975 DF PROTO=TCP SPT=9844 DPT=22 WINDOW=4102 RES=0x00 ACK URGP=0 
Mar 19 18:41:08 centos8 kernel: new connections: IN=eth0 OUT= 

范例:

[root@centos8 ~]#iptables -R INPUT 2 -p tcp --dport 21 -m state --state NEW -j LOG --log-prefix "ftp new link: "

[root@centos8 ~]#tail -f /var/log/messages
Dec 21 10:02:31 centos8 kernel: ftp new link: IN=eth0 OUT= MAC=00:0c:29:f9:8d:90:00:0c:29:10:8a:b1:08:00 SRC=192.168.39.6 DST=192.168.39.8 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=15556 DF PROTO=TCP SPT=53706 DPT=21 WINDOW=14600 RES=0x00 SYN URGP=0
规则优化最佳实践

1.安全放行所有入站和出站的状态为ESTABLISHED状态连接,建议放在第一条,效率更高

2.谨慎放行入站的新请求

3.有特殊目的限制访问功能,要在放行规则之前加以拒绝

4.同类规则(访问同一应用,比如:http ),匹配范围小的放在前面,用于特殊处理

5.不同类的规则(访问不同应用,一个是http,另一个是mysql ),匹配范围大的放在前面,效率更高

   -s 10.0.0.6 -p tcp --dport 3306  -j REJECT
   -s 172.16.0.0/16 -p tcp --dport 80  -j REJECT

6.应该将那些可由一条规则能够描述的多个规则合并为一条

7.设置默认策略,建议白名单(只放行特定连接)

-iptables -P,不建议,容易出现“自杀现象”

-规则的最后定义规则做为默认策略,推荐使用,放在最后一条

iptables规则保存

使用iptables命令定义的规则,手动删除之前,其生效期限为kernel存活期限

持久保存规则:

CentOS 7,8

iptables-save  >  /PATH/TO/SOME_RULES_FILE

CentOS 6

#将规则覆盖保存至/etc/sysconfig/iptables文件中
service  iptables  save 

加载规则

CentOS 7 重新载入预存规则文件中规则:

iptables-restore <  /PATH/FROM/SOME_RULES_FILE

-n, –noflush:不清除原有规则
-t, –test:仅分析生成规则集,但不提交

CentOS 6:

#会自动从/etc/sysconfig/iptables 重新载入规则
service  iptables  restart

开机自动重载规则

-用脚本保存各iptables命令;让此脚本开机后自动运行
/etc/rc.d/rc.local文件中添加脚本路径 /PATH/TO/SOME_SCRIPT_FILE

-用规则文件保存各规则,开机时自动载入此规则文件中的规则
在/etc/rc.d/rc.local文件添加

  iptables-restore < /PATH/FROM/IPTABLES_RULES_FILE

定义Unit File, CentOS 7,8 可以安装 iptables-services 实现iptables.service

  yum install iptables-services
  cp /etc/sysconfig/iptables{,.bak}
  iptables-save > /etc/sysconfig/iptables
  systemctl enable iptables.service    

 

网络防火墙

iptables/netfilter 利用filter表的FORWARD链,可以充当网络防火墙:
注意的问题:
(1) 请求-响应报文均会经由FORWARD链,要注意规则的方向性
(2) 如果要启用conntrack机制,建议将双方向的状态为ESTABLISHED的报文直接放行

FORWARD 链实现内外网络的流量控制

范例:内部可以访问外部,外部禁止访问内部

[root@internet-host ~]#hostname -I
10.0.0.6 
[root@internet-host ~]#route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.0.0        0.0.0.0         255.255.255.0   U     1      0        0 eth0
0.0.0.0         10.0.0.8        0.0.0.0         UG    0      0        0 eth0

[root@firewall-host ~]#hostname -I
10.0.0.8 192.168.100.8 

[root@lan-host ~]#hostname -I
192.168.100.7 
[root@lan-host ~]#route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.100.8   0.0.0.0         UG    100    0        0 eth0
192.168.100.0   0.0.0.0         255.255.255.0   U     100    0        0 eth0

[root@firewall-host ~]#vim /etc/sysctl.conf
net.ipv4.ip_forward=1
[root@firewall-host ~]#sysctl -p
[root@firewall-host ~]#iptables -A FORWARD -d 192.168.100.0/24  -m state --state NEW  -j REJECT

范例:针对内部的特定服务可以允许外部访问,其它服务禁止访问

[root@firewall-host ~]#iptables -I FORWARD -d 192.168.100.0/24 -p tcp --dport 80 -j ACCEPT
[root@firewall-host ~]#iptables -vnL  FORWARD --line-numbers
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        6   486 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.100.0/24     tcp dpt:80
2        3   228 REJECT     all  --  *      *       0.0.0.0/0            192.168.100.0/24     state NEW reject-with icmp-port-unreachable

 

NAT: network address translation,支持PREROUTING,INPUT,OUTPUT,POSTROUTING四个链

请求报文:修改源/目标IP,由定义如何修改

响应报文:修改源/目标IP,根据跟踪机制自动实现

NAT的实现分为下面类型:

  • SNAT:source NAT ,支持POSTROUTING, INPUT,让本地网络中的主机通过某一特定地址访问外部网络,实现地址伪装,请求报文:修改源IP
  • DNAT:destination NAT 支持PREROUTING , OUTPUT,把本地网络中的主机上的某服务开放给外部网络访问(发布服务和端口映射),但隐藏真实IP,请求报文:修改目标IP
  • PNAT: port nat,端口和IP都进行修改

范例:查看本地主机访问公网时使用的IP

[root@centos8 ~]#curl http://ipinfo.io/ip/
111.199.191.204
[root@centos8 ~]#curl  http://ifconfig.me
111.199.191.204
[root@centos8 ~]#curl -L http://tool.lu/ip
当前IP: 111.199.191.204
归属地: 中国 北京 北京
SNAT

SNAT:基于nat表的target,适用于固定的公网IP

SNAT选项:

  • –to-source [ipaddr[-ipaddr]][:port[-port]]
  • –random
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j SNAT --to-source ExtIP

范例:

iptables -t nat -A POSTROUTING -s 10.0.1.0/24 ! –d 10.0.1.0/24 -j SNAT --to-source 172.18.1.6-172.18.1.9

MASQUERADE:基于nat表的target,适用于动态的公网IP,如:拨号网络

MASQUERADE选项:

  • –to-ports port[-port]
  • –random
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j MASQUERADE

范例:

iptables -t nat -A POSTROUTING -s 10.0.1.0/24  ! –d 10.0.1.0/24 -j MASQUERADE 

范例:实现SNAT

[root@internet-host ~]#hostname -I
10.0.0.6 
[root@internet-host ~]#route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.0.0        0.0.0.0         255.255.255.0   U     1      0        0 eth0

[root@firewall-host ~]#hostname -I
10.0.0.8 192.168.100.8 
[root@firewall-host ~]#sysctl -a |grep net.ipv4.ip_forward
net.ipv4.ip_forward = 1

[root@lan-host ~]#hostname -I
192.168.100.7 
[root@lan-host ~]#route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.100.8   0.0.0.0         UG    100    0        0 eth0
192.168.100.0   0.0.0.0         255.255.255.0   U     100    0        0 eth0

[root@firewall-host ~]#iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -j SNAT --to-source 10.0.0.8
[root@firewall-host ~]#iptables -vnL -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 SNAT       all  --  *      *       192.168.100.0/24     0.0.0.0/0            to:10.0.0.8

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination  

[root@lan-host ~]#curl 10.0.0.6
internet Server
[root@internet-host ~]#curl 192.168.100.7
curl: (7) Failed to connect to 192.168.100.7: Network is unreachable

[root@internet-host ~]#tail  /var/log/httpd/access_log 
10.0.0.8 - - [21/Mar/2020:16:31:35 +0800] "GET / HTTP/1.1" 200 16 "-" "curl/7.29.0"

[root@lan-host ~]#ping 10.0.0.6
PING 10.0.0.6 (10.0.0.6) 56(84) bytes of data.
64 bytes from 10.0.0.6: icmp_seq=1 ttl=63 time=0.989 ms
64 bytes from 10.0.0.6: icmp_seq=2 ttl=63 time=0.544 ms

[root@internet-host ~]#tcpdump -i eth0 -nn icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
16:34:30.171222 IP 10.0.0.8 > 10.0.0.6: ICMP echo request, id 24718, seq 120, length 64
16:34:30.171255 IP 10.0.0.6 > 10.0.0.8: ICMP echo reply, id 24718, seq 120, length 64

[root@firewall-host ~]#iptables -t nat -R POSTROUTING 1  -s 192.168.100.0/24 -j MASQUERADE 
[root@firewall-host ~]#iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MASQUERADE  all  --  *      *       192.168.100.0/24     0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination 

[root@firewall-host ~]#cat /proc/net/nf_conntrack
ipv4     2 tcp      6 32 TIME_WAIT src=192.168.100.7 dst=10.0.0.6 sport=39430 dport=80 src=10.0.0.6 dst=10.0.0.8 sport=80 dport=39430 [ASSURED] mark=0 zone=0 use=2
DNAT

DNAT:nat表的target,适用于端口映射,即可重定向到本机,也可以支持重定向至不同主机的不同端口,但不支持多目标,即不支持负载均衡功能

DNAT选项:

  • –to-destination [ipaddr[-ipaddr]][:port[-port]]
[root@firewall-host ~]#man iptables-extensions
--to-destination [ipaddr[-ipaddr]][:port[-port]]
    which  can  specify  a single new destination IP address, an inclusive range of IP addresses. Optionally a port range, if the rule also specifies one of the following protocols: tcp, udp, dccp  or  sctp.  If no port range is specified, then the destination port will never be modi‐fied. If no IP address is specified then only the destination port will be modified.  In Ker‐nels  up  to  2.6.10  you can add several --to-destination options. For those kernels, if you specify more than one destination address, either via an address range or multiple  --to-des‐tination  options,  a  simple  round-robin  (one after another in cycle) load balancing takes place between these addresses.  Later Kernels (>= 2.6.11-rc1) don't have the ability  to  NAT to multiple ranges anymore.
iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp --dport PORT -j DNAT --to-destination InterSeverIP[:PORT]

范例:

iptables -t nat -A PREROUTING -s 0/0 -d 172.18.100.6 -p tcp --dport 22 -j DNAT --to-destination 10.0.1.22

iptables -t nat -A PREROUTING -s 0/0 -d 172.18.100.6 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.22:8080

范例:

[root@firewall-host ~]#iptables -t nat -A PREROUTING -d 10.0.0.8 -p tcp --dport 80 -j DNAT --to-destination 192.168.100.7 
[root@firewall-host ~]#iptables -t nat -vnL PREROUTING
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            10.0.0.8             tcp dpt:80 to:192.168.100.7
[root@firewall-host ~]#ss -ntl
State        Recv-Q        Send-Q                 Local Address:Port                 Peer Address:Port        
LISTEN       0             128                          0.0.0.0:22                        0.0.0.0:*           
LISTEN       0             128                             [::]:22                           [::]:* 

[root@internet-host ~]#curl 10.0.0.8
lan server
[root@internet-host ~]#telnet 10.0.0.8
Trying 10.0.0.8...
telnet: connect to address 10.0.0.8: Connection refused

[root@lan-host ~]#tail -f /var/log/httpd/access_log 
10.0.0.6 - - [21/Mar/2020:17:32:37 +0800] "GET / HTTP/1.1" 200 11 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"

[root@firewall-host ~]#tail -f /proc/net/nf_conntrack
ipv4     2 tcp      6 81 TIME_WAIT src=10.0.0.6 dst=10.0.0.8 sport=59426 dport=80 src=192.168.100.7 dst=10.0.0.6 sport=80 dport=59426 [ASSURED] mark=0 zone=0 use=2

[root@lan-host ~]#vim /etc/httpd/conf/httpd.conf 
listen 8000

[root@lan-host ~]#systemctl restart httpd
[root@lan-host ~]#ss -ntl
State      Recv-Q Send-Q          Local Address:Port                         Peer Address:Port              
LISTEN     0      100                 127.0.0.1:25                                      *:*                  
LISTEN     0      128                         *:22                                      *:*                  
LISTEN     0      128                      [::]:23                                   [::]:*                  
LISTEN     0      100                     [::1]:25                                   [::]:*                  
LISTEN     0      128                      [::]:8000                                 [::]:*                  
LISTEN     0      128                      [::]:22                                   [::]:*                  

[root@firewall-host ~]#iptables -t nat -R PREROUTING 1 -d 10.0.0.8 -p tcp --dport 80 -j DNAT --to-destination 192.168.100.7:8000 
[root@firewall-host ~]#iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            10.0.0.8             tcp dpt:80 to:192.168.100.7:8000

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   11   816 MASQUERADE  all  --  *      *       192.168.100.0/24     0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
REDIRECT 转发

REDIRECT,是NAT表的 target,通过改变目标IP和端口,将接受的包转发至同一个主机的不同端口,可用于PREROUTING OUTPUT链
REDIRECT选项:

—to-ports port[-port]

范例:

iptables -t nat -A PREROUTING -d 172.16.100.10 -p tcp --dport 80 -j REDIRECT --to-ports 8080

范例:

[root@lan-host ~]#ss -ntl
State      Recv-Q Send-Q          Local Address:Port                         Peer Address:Port              
LISTEN     0      100                 127.0.0.1:25                                      *:*                  
LISTEN     0      128                         *:22                                      *:*                  
LISTEN     0      128                      [::]:23                                   [::]:*                  
LISTEN     0      100                     [::1]:25                                   [::]:*                  
LISTEN     0      128                      [::]:80                                   [::]:*                  
LISTEN     0      128                      [::]:22                                   [::]:*                  
[root@lan-host ~]#iptables -t nat -A PREROUTING  -p tcp --dport 8000 -j REDIRECT --to-ports 80

[root@lan-host ~]#iptables -vnL  -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    1    60 REDIRECT   tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8000 redir ports 80

Chain INPUT (policy ACCEPT 1 packets, 60 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 1 packets, 120 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 1 packets, 120 bytes)
 pkts bytes target     prot opt in     out     source               destination