iptables快速入门
iptables简介
在生产实践过程中,为了保证生产安全,通常需要进行数据加密,例如通过网络层面上将应用隔离成内网和公网应用,内网再分成生产、测试、开发、DMZ等区域,然后进行不同的策略更改,例如将重要应用添加防火墙,从物理层面看,有如下两种:
硬件防火墙:在硬件级别实现部分防火墙功能,另一部分功能基于软件实现,性能高,成本高,例如Radware公司的WAF
软件防火墙:应用软件处理逻辑运行于通用硬件平台之上的防火墙,性能低,成本低,例如微软自带的防火墙。
netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,它可以代替昂贵的商业防火墙解决方案,完成封包过滤、封包重定向和网络地址转换(NAT)等功能,在RedHat 6 系列及以下中作为内核层的防火墙,在在RedHat 7系列中采用firewall 进行替代,但同时保留iptables功能。
iptables数据传输原理
在说明iptables 功能作用前,我们先看下正常情况下用户流量访问经过iptables时,有哪些环节,针对每个环节我们再细说。
根据上图,我们能够归纳出常用场景中,网络流量流向:
到本机某进程的走向:PREROUTING –> INPUT->WEB->OUTPUT –> POSTROUTING
由本机转发的走向:PREROUTING –> FORWARD –> POSTROUTING
由本机的某进程发出走向:OUTPUT –> POSTROUTING
这就是我们日常提到的IPTABLES 实际控制的“链”路,其工作原理就是在这五条链路 设置规则(rules),规则其实就是网络管理员预定义的条件,规则一般的定义为”如果数据包头符合这样的条件,就这样处理这个数据包”。规则存储在内核空间的信息包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如TCP、UDP、ICMP)和服务类型(如HTTP、FTP和SMTP)等。当数据包与规则匹配时,iptables就根据规则所定义的方法来处理这些数据包,如放行(accept)、拒绝(reject)和丢弃(drop)等。配置防火墙的主要工作就是添加、修改和删除这些规则。
那么规则又有哪些呢?这五条链路分别又可以设置什么呢?
iptables把相同规则进行分类,集合成一个大类,也就是我们所说的“表”,包括我们自定义的规则,也是对这些表进行操作,通常我们认为有如下四张表:
1.filter表——三个链:INPUT、FORWARD、OUTPUT
作用:过滤数据包 内核模块:iptables_filter.
2.Nat表——三个链:PREROUTING、POSTROUTING、OUTPUT、INPUT(RedHat系列Linux 7 及以上可支持)
作用:用于网络地址转换(IP、端口) 内核模块:iptable_nat
3.Mangle表——五个链:PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD
作用:修改数据包的服务类型、TTL、并且可以配置路由实现QOS内核模块:iptable_mangle(所有链路都可以使用)
4.Raw表——两个链:OUTPUT、PREROUTING
作用:决定数据包是否被状态跟踪机制处理 内核模块:iptable_raw
可以明显看出,并不是所有规则表都可以作用于某一条链路,唯一一个例如就是OUTPUT 链,它作为Web 应用最后的一套防线。
当这些规则表全部在一个链路上时,并不是满足先后设定顺序限制性原则,而是按照如下顺序,进行先后执行:
raw –> mangle –> nat –> filter
上面规则十分重要,这将是下面我们执行设定规则时所依据参考的。
iptables实际应用
看完前两步,大家可能还没感觉到iptables 作用在哪,其实netfilter才是防火墙真正的安全框架(framework),netfilter位于内核空间,完成封包过滤、封包重定向和网络地址转换(NAT)等功能,用户通过iptables这个功能代理,将用户数据按照设定网络规则链表送进安全框架,从而起到软件防火墙功能。
那么如何操作iptables 呢?
命令格式: iptables [-t 表名] 命令选项 [链名] [条件匹配] [-j 目标动作或跳转]
iptables v1.4.21
Usage: iptables -[ACD] chain rule-specification [options]
iptables -I chain [rulenum] rule-specification [options]
iptables -R chain rulenum rule-specification [options]
iptables -D chain rulenum [options]
iptables -[LS] [chain [rulenum]] [options]
iptables -[FZ] [chain] [options]
iptables -[NX] chain
iptables -E old-chain-name new-chain-name
iptables -P chain target [options]
iptables -h (print this help information)
Commands:
Either long or short options are allowed.
--append -A chain Append to chain
--check -C chain Check for the existence of a rule
--delete -D chain Delete matching rule from chain
--delete -D chain rulenum
Delete rule rulenum (1 = first) from chain
--insert -I chain [rulenum]
Insert in chain as rulenum (default 1=first)
--replace -R chain rulenum
Replace rule rulenum (1 = first) in chain
--list -L [chain [rulenum]]
List the rules in a chain or all chains
--list-rules -S [chain [rulenum]]
Print the rules in a chain or all chains
--flush -F [chain] Delete all rules in chain or all chains
--zero -Z [chain [rulenum]]
Zero counters in chain or all chains
--new -N chain Create a new user-defined chain
--delete-chain
-X [chain] Delete a user-defined chain
--policy -P chain target
Change policy on chain to target
--rename-chain
-E old-chain new-chain
Change chain name, (moving any references)
Options:
--ipv4 -4 Nothing (line is ignored by ip6tables-restore)
--ipv6 -6 Error (line is ignored by iptables-restore)
[!] --protocol -p proto protocol: by number or name, eg. `tcp'
[!] --source -s address[/mask][...]
source specification
[!] --destination -d address[/mask][...]
destination specification
[!] --in-interface -i input name[+]
network interface name ([+] for wildcard)
--jump -j target
target for rule (may load target extension)
--goto -g chain
jump to chain with no return
--match -m match
extended match (may load extension)
--numeric -n numeric output of addresses and ports
[!] --out-interface -o output name[+]
network interface name ([+] for wildcard)
--table -t table table to manipulate (default: `filter')
--verbose -v verbose mode
--wait -w [seconds] maximum wait to acquire xtables lock before give up
--wait-interval -W [usecs] wait time to try to acquire xtables lock
default is 1 second
--line-numbers print line numbers when listing
--exact -x expand numbers (display exact values)
[!] --fragment -f match second or further fragments only
--modprobe=<command> try to insert modules using this command
--set-counters PKTS BYTES set the counter during insert/append
[!] --version -V print package version.
上面列举了iptables 所有参数,但实际上我们常用到其实没有这么多,主要就这几个常见:
command 选项
-A 添加防火墙规则
-D 删除防火墙规则
-I 插入防火墙规则
-F 清空防火墙规则
-L 列出添加防火墙规则
-R 替换防火墙规则
-Z 清空防火墙数据表统计信息
-P 设置链默认规则
parametes 选项
-p 协议(protocol)
# 指定规则的协议,如tcp, udp, icmp等,可以使用all来指定所有协议。
# 如果不指定-p参数,则默认是all值。这并不明智,请总是明确指定协议名称。
# 可以使用协议名(如tcp),或者是协议值(比如6代表tcp)来指定协议。映射关系请查看/etc/protocols
# 还可以使用–protocol参数代替-p参数
-s 源地址(source)
# 指定数据包的源地址
# 参数可以使IP地址、网络地址、主机名
# 例如:-s 192.168.31.101指定IP地址
# 例如:-s 192.168.31.10/24指定网络地址
# 如果不指定-s参数,就代表所有地址
-d 目的地址(destination)
# 指定目的地址
# 参数和-s相同
# 还可以使用–dst或者–destination
-j 执行目标(jump to target)
# 指定了当与规则(Rule)匹配时如何处理数据包
# 可能的值是ACCEPT, DROP, QUEUE, RETURN,MASQUERADE
# 还可以指定其他链(Chain)作为目标
# 注:MASQUERADE,地址伪装,算是snat中的一种特例,可以实现自动化的snat
-i 输入接口(input interface)
# 指定了要处理来自哪个接口的数据包
# 这些数据包即将进入INPUT, FORWARD, PREROUTE链
# 例如:-i eth0指定了要处理经由eth0进入的数据包
# 如果不指定-i参数,那么将处理进入所有接口的数据包
# 如果出现! -i eth0,那么将处理所有经由eth0以外的接口进入的数据包
# 如果出现-i eth+,那么将处理所有经由eth开头的接口进入的数据包
-o 输出(out interface)指定了数据包由哪个接口输出
# 这些数据包即将进入FORWARD, OUTPUT, POSTROUTING链
# 如果不指定-o选项,那么系统上的所有接口都可以作为输出接口
# 如果出现! -o eth0,那么将从eth0以外的接口输出
# 如果出现-i eth+,那么将仅从eth开头的接口输出
–sport 源端口(source port)针对 -p tcp 或者 -p udp
# 缺省情况下,将匹配所有端口
# 可以指定端口号或者端口名称,例如”–sport 22″与”–sport ssh”。
# 如”–sport 22:100″
–-dport 目的端口(destination port)针对-p tcp 或者 -p udp
# 参数和–sport类似
下面就实际使用情况举例:
1 查看是否支持iptables:
[root@test01 ~]# rpm -qa|grep iptables
iptables-1.4.21-33.el7.x86_64
2 查看已设定规则
[root@test01 ~]# iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
372 26903 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
130 25795 INPUT_direct all -- * * 0.0.0.0/0 0.0.0.0/0
130 25795 INPUT_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0
130 25795 INPUT_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
128 25691 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
3 防火墙的备份与还原
[root@test01 ~]# iptables-save
# Generated by iptables-save v1.4.21 on Mon Jul 11 01:38:27 2022
*nat
:PREROUTING ACCEPT [132:25859]
:INPUT ACCEPT [2:104]
:OUTPUT ACCEPT [8:500]
:POSTROUTING ACCEPT [8:500]
:OUTPUT_direct - [0:0]
:POSTROUTING_ZONES - [0:0]
:POSTROUTING_ZONES_SOURCE - [0:0]
:POSTROUTING_direct - [0:0]
:POST_public - [0:0]
:POST_public_allow - [0:0]
:POST_public_deny - [0:0]
:POST_public_log - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_public - [0:0]
:PRE_public_allow - [0:0]
:PRE_public_deny - [0:0]
:PRE_public_log - [0:0]
备份到/tmp/test.txt
[root@test01 ~]# iptables-save > /tmp/test.txt
[root@test01 ~]# cat /tmp/test.txt
# Generated by iptables-save v1.4.21 on Mon Jul 11 01:39:19 2022
*nat
:PREROUTING ACCEPT [132:25859]
:INPUT ACCEPT [2:104]
:OUTPUT ACCEPT [8:500]
:POSTROUTING ACCEPT [8:500]
:OUTPUT_direct - [0:0]
:POSTROUTING_ZONES - [0:0]
:POSTROUTING_ZONES_SOURCE - [0:0]
:POSTROUTING_direct - [0:0]
:POST_public - [0:0]
:POST_public_allow - [0:0]
:POST_public_deny - [0:0]
:POST_public_log - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_public - [0:0]
:PRE_public_allow - [0:0]
:PRE_public_deny - [0:0]
:PRE_public_log - [0:0]
从备份文件还原回来
注意,这里导入的文件必须是使用 iptables-save工具导出来的才可以。
[root@test01 ~]# iptables-restore < /tmp/test.txt
4.拒绝所有ICMP协议访问数据包,此时显示无法ping
通
iptables -I INPUT -p icmp -j REJECT
5.拒绝转发来自192.168.31.100主机的数据,允许转发来自192.168.31.0/24网段的数据
iptables -A FORWARD -s 192.168.31.100 -j REJECT
iptables -A FORWARD -s 192.168.31.0/24 -j ACCEPT
6.丢弃从外网接口(eth1)进入防火墙本机的源地址为私网地址的数据包
iptables -A INPUT -i eth1 -s 192.168.31.0/16 -j DROP
iptables -A INPUT -i eth1 -s 172.16.0.0/12 -j DROP
iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
7.将本机的80端口映射到本机的8080端口上
iptables -t nat -A PREROUTING -p tcp –dport 80 -j REDIRECT –to-ports 8080
说明:这里需要开启NAT功能,否则可能失败,实际中用的比较少,端口转发一般采用中间件nginx等,这样性能损耗会比较少。
echo 1 > /proc/sys/net/ipv4/ip_forward
隐藏网内主机的IP地址,共享公网IP,访问互联网
iptables -t nat -A POSTROUTING -s 192.168.31.0/24 -j SNAT --to-source 公网IP
反过来,将访问的IP 映射成其它IP
iptables -t nat -I PREROUTING -d 访问IP -p tcp --dport 访问端口 -j DNAT --to-destination 映射IP:端口号
8.限制访问源IP,例如只允许管理员从192.168.31.0/16
网段使用SSH远程登录防火墙主机,生产中一般采用jumpserver等堡垒机,这里是做演示。
iptables -A INPUT -p tcp --dport 22 -s 192.168.31.0/16 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
说明:使用“!”可以将条件取反,从而限制源IP。
iptables -A INPUT -p tcp -s !192.168.31.0/16 --dport 22 -j DROP
9.只允许本机开放从TCP端口20-1024提供的应用服务,包括外部访问。
iptables -A INPUT -p tcp --dport 20:1024 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 20:1024 -j ACCEPT
10.允许防火墙本机对外开放TCP端口20、80、110以及被动模式FTP端口1250-1280
iptables -I INPUT -p tcp -m multiport --dport 20,80,110,1250:1280 -j ACCEPT
iptables -A INPUT -p tcp DROP
说明:这里用“-m multiport –dport”来指定目的端口及范围
11.拒绝访问的新数据包,但允许响应连接或与已有连接相关的数据包
iptables -A INPUT -p tcp -m state --state NEW -j DROP
iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
说明:“ESTABLISHED”表示已经响应请求或者已经建立连接的数据包,“RELATED”表示与已建立的连接有相关性的,比如FTP数据连接等。
12.只开放本机的web服务(80,443)、FTP(20、21、20450-20480),放行外部主机发住服务器其它端口的应答数据包,将其他入站数据包均予以丢弃处理。
iptables -I INPUT -p tcp -m multiport --dport 20,21,80 ,443-j ACCEPT
iptables -I INPUT -p tcp --dport 20450:20480 -j ACCEPT
iptables -I INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
iptables -P INPUT DROP