iptables 防火墙 什么是 iptables iptables 是一个配置Linux 内核防火墙 的命令行工具。iptables 也经常指代内核级防火墙。
iptables 可以检测、修改、转发、重定向和丢弃 IPv4 数据包。
过滤 IPv4 数据包的代码已内置于内核中,并且按照不同的目的被组织成表 的集合,每一个表 都有不同的目的 。表 由一组预先定义的链 组成,链 包含依序遍历的规则 。每条规则由可条件和在条件匹配为真时执行的动作(被称为 target)组成。如果一个数据包通过了一个链的所有匹配(如果这个链是空的,也被视为通过所有匹配),链的策略决定了这个数据包的最终去向。
iptables 就是允许管理员来操作链/规则的用户工具
iptables 是基于 Netfilter 框架的,所以所有的网络相关操作都可以由 iptables 来执行。每一条 iptables 的规则都被 Linux 核心直接使用,被作为 kernel task 存在。
表
raw: 仅用于配置数据包,以使它们免于连接跟踪
filter: 默认表,通常是所有与防火墙相关行为发生的地方
nat: 被用来进行 NAT 的表
mangle: 用于特殊的数据包修改
security: 用来执行 MAC (mandatory access control) 规则
链
在进行路由选择前处理数据包(PREROUTING);
处理流入的数据包(INPUT);
处理流出的数据包(OUTPUT);
处理转发的数据包(FORWARD);
在进行路由选择后处理数据包(POSTROUTING)。
Rules 包过滤是基于 Rules(规则)的。Rules 由多个 matches (数据包必须满足的条件,能让数据包被过滤出来)和一个 target (对过滤出的数据包的行为)。
iptables 包处理流程 iptables 工作流程图说明:
小写字母为表
大写字母为链
每一个从任何网卡进入的数据包,都要经过这样从上到下的过程来决定其最终的去向
有些数据包的最终目标就是 local process,有些数据包是从 local process 产生的,因此会与其他数据包的行为表现不一致。
iptables Tutorial 1.2.2
XXXXXXXXXXXXXXXXXX XXX Network XXX XXXXXXXXXXXXXXXXXX + | v +-------------+ +------------------+ |table: filter| %3C---+ | table: nat | |chain: INPUT | | | chain: PREROUTING| +-----+-------+ | +--------+---------+ | | | v | v [local process] | **************** +--------------+ | +---------+ Routing decision +------%3E |table: filter | v **************** |chain: FORWARD| **************** +------+-------+ Routing decision | **************** | | | v **************** | +-------------+ +------> Routing decision <---------------+ |table: nat | | **************** |chain: OUTPUT| | + +-----+-------+ | | | | v v | +-------------------+ +--------------+ | | table: nat | |table: filter | +----+ | chain: POSTROUTING| |chain: OUTPUT | +--------+----------+ +--------------+ | v XXXXXXXXXXXXXXXXXX XXX Network XXX XXXXXXXXXXXXXXXXXX
iptables Configuration 清空/重置 iptables iptables -F iptables -t *table* -X *chain*
iptables -P INPUT DROP iptables -P FORWARD DROP
iptables -I INPUT -p tcp -s 192.168.3.0/24 --dport 22 -j ACCEPT iptables -P INPUT DROP ping 192.168.3.160 PING 192.168.3.160 (192.168.3.160) 56(84) bytes of data. ^C --- 192.168.3.160 ping statistics --- 6 packets transmitted, 0 received, 100% packet loss, time 5044ms iptables -A INPUT -s 192.168.3.0/24 -p icmp -j REJECT [root@localhost yum.repos.d] PING 192.168.3.160 (192.168.3.160) 56(84) bytes of data. From 192.168.3.160 icmp_seq=1 Destination Port Unreachable From 192.168.3.160 icmp_seq=2 Destination Port Unreachable ^C --- 192.168.3.160 ping statistics --- 2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1026ms iptables -R INPUT 2 -p icmp -s 192.168.3.0/24 -j ACCEPT [root@localhost ~] PING 192.168.3.160 (192.168.3.160) 56(84) bytes of data. 64 bytes from 192.168.3.160: icmp_seq=1 ttl=64 time=5.24 ms 64 bytes from 192.168.3.160: icmp_seq=2 ttl=64 time=52.0 ms ^C --- 192.168.3.160 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1002ms rtt min/avg/max/mdev = 5.248/28.666/52.085/23.419 ms iptables -R INPUT 2 -p icmp ! -s 192.168.3.162 -j ACCEPT iptables -A INPUT -p icmp -s 192.168.3.162 -j REJECT -m comment --comment "192.168.3.162 is not welcome"
查看 iptables 规则 [root@ray ansible_project_1] Chain INPUT (policy DROP 41242 packets, 72M bytes) num pkts bytes target prot opt in out source destination 1 1007 69972 ACCEPT tcp -- * * 192.168.3.0/24 0.0.0.0/0 tcp dpt:22 2 3 252 ACCEPT icmp -- * * !192.168.3.162 0.0.0.0/0 3 0 0 REJECT icmp -- * * 192.168.3.162 0.0.0.0/0 /* 192.168.3.162 is not welcome */ reject-with icmp-port-unreachable Chain FORWARD (policy DROP 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 23912 packets, 2320K bytes) num pkts bytes target prot opt in out source destination
保存 iptables 规则 service iptables save iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ]
Log Target Log 可以被用来记录命中了 rule 的数据包。不像 ACCEPT 或 DROP target,数据包会在命中 rule 后继执行后面的 rule。这就意味着,如果我们想记录所有 DROP 的数据包,我们就需要在 drop 规则前创建一条和 drop rule 一样的规则并使用 -j LOG。但是这样降低了效率而且让事情变得复杂,我们可以通过创建一个 logdrop 链来替代这种方案。
iptables -N logdrop iptables -A logdrop -m limit --limit 5/m --limit-burst 10 -j LOG iptables -A logdrop -j DROP iptables -A INPUT -p icmp -s 192.168.3.0/24 -j logdrop [root@ray ~] Chain INPUT (policy DROP 1340 packets, 1126K bytes) num pkts bytes target prot opt in out source destination 1 761 52712 ACCEPT tcp -- * * 192.168.3.0/24 0.0.0.0/0 tcp dpt:22 2 0 0 logdrop icmp -- * * 192.168.3.0/24 0.0.0.0/0 Chain FORWARD (policy DROP 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 1301 packets, 171K bytes) num pkts bytes target prot opt in out source destination Chain logdrop (1 references) num pkts bytes target prot opt in out source destination 1 0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit : avg 5/min burst 10 LOG flags 0 level 4 2 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
Log Limit 解释 iptables -A logdrop -m limit --limit 5/m --limit-burst 10 -j LOG
查看 Log journalctl -k | grep "IN=.*OUT=.*" | less Sep 12 16:40:42 ray.redhat8 kernel: IN=ens160 OUT= MAC=00:0c:29:cc:a6:10:a0:c5:89:a2:1a:ca:08:00 SRC=192.168.3.161 DST=192.168.3.160 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=55272 DF PROTO=ICMP TYPE=8 CODE=0 ID=52485 SEQ=1 Sep 12 16:40:43 ray.redhat8 kernel: IN=ens160 OUT= MAC=00:0c:29:cc:a6:10:a0:c5:89:a2:1a:ca:08:00 SRC=192.168.3.161 DST=192.168.3.160 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=55324 DF PROTO=ICMP TYPE=8 CODE=0 ID=52485 SEQ=2 Sep 12 16:40:44 ray.redhat8 kernel: IN=ens160 OUT= MAC=00:0c:29:cc:a6:10:a0:c5:89:a2:1a:ca:08:00 SRC=192.168.3.161 DST=192.168.3.160 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=55892 DF PROTO=ICMP TYPE=8 CODE=0 ID=52485 SEQ=3
Block DoS iptables -A INPUT -p tcp --dport 80 -m limit --limit 20/minute --limit-burst 100 -j ACCEPT
echo 1 > /proc/sys/net/ipv4/ip_forwardecho 1 > /proc/sys/net/ipv4/tcp_syncookiesecho 0 > /proc/sys/net/ipv4/conf/all/accept_redirectsecho 0 > /proc/sys/net/ipv4/conf/all/accept_source_routeecho 1 > /proc/sys/net/ipv4/conf/all/rp_filterecho 1 > /proc/sys/net/ipv4/conf/lo/rp_filterecho 1 > /proc/sys/net/ipv4/conf/lo/arp_ignoreecho 2 > /proc/sys/net/ipv4/conf/lo/arp_announceecho 1 > /proc/sys/net/ipv4/conf/all/arp_ignoreecho 2 > /proc/sys/net/ipv4/conf/all/arp_announceecho 0 > /proc/sys/net/ipv4/icmp_echo_ignore_allecho 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcastsecho 30 > /proc/sys/net/ipv4/tcp_fin_timeoutecho 1800 > /proc/sys/net/ipv4/tcp_keepalive_timeecho 1 > /proc/sys/net/ipv4/tcp_window_scalingecho 0 > /proc/sys/net/ipv4/tcp_sackecho 1280 > /proc/sys/net/ipv4/tcp_max_syn_backlog
Block Port Scanning iptables -N block-scan iptables -A block-scan -p tcp -tcp-flags SYN,ACK,FIN,RST RST -m limit -limit 1/s -j RETURN iptables -A block-scan -j DROP
Block Multiport Ports badport='135,136,137,138,139,445' iptables -A INPUT -p tcp -m multiport --dport $badport -j DROP iptables -A INPUT -p udp -m multiport --dport $badport -j DROP