linux命令之iptables命令详解
iptables 使用详解
iptables五表五链
五表table
-
filter 过滤数据包 (default table)常用
-
nat 网络地址转换 (端口映射,地址映射等)常用
-
mangle 对特定的数据报文进行修改
-
raw 设置raw时一般是为了不再让iptables做数据包的链接跟踪处理,加快封包穿越防火墙的速度,提高性能
-
security 优先级最高,用于强制访问控制(MAC)网络规则,由Linux安全模块实现如SElinux
优先级从高到低顺序为:
security→raw→mangle→nat→filter
五链CHAIN(内置链)
-
PRE_ROUTING 所有进入数据包都要经由此策略(数据包进入路由表之前)
-
INPUT 进来的数据包应用此策略(数据包通过路由表后目的为本机)
-
OUTPUT 流出的数据包应用此策略(数据包由本机产生,向外流出)
-
FORWARD 数据包流经本机进行转发(数据包流过路由表后,目的地不为本机)
-
POST_ROUTING 所有流出数据包都要经由此策略(数据包发送到网卡接口前)
从表到链的对应关系
可以使用iptables -t tables -nvL 查看
raw 表中的规则可以被哪些链使用:PREROUTING,OUTPUT
mangle 表中的规则可以被哪些链使用:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
nat 表中的规则可以被哪些链使用:PREROUTING,OUTPUT,POSTROUTING(centos7中有INPUT,centos6中没有)
filter 表中的规则可以被哪些链使用:INPUT,FORWARD,OUTPUT
数据报文流向
-
流入本机: 数据包→PRE_ROUTING→INPUT→用户空间进程
-
流出本机: 用户空间进程→OUTPUT→POST_ROUTING
-
转发: 数据包→PRE_ROUTING→FORWARD→POST_ROUTING
iptables 命令使用
iptables基本语法命令格式
iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网> --sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作
iptables [-t 表名] 管理选项 [链名] [匹配条件] [-j 动作处理]
例如:
iptables -t filter -A INPUT -s 10.11.12.12 -j DROP
表名、链名:指定iptables命令所操作的表和链,未指定表名时将默认使用filter表; 管理选项:表示iptables规则的操作方式,比如:插入、增加、删除、查看等; 匹配条件:指定要处理的数据包的特征,不符合指定条件的数据包不处理; 动作处理:指数据包的处理方式,比如:允许ACCEPT、拒绝REJECT、丢弃DROP、日志LOG等;
管理选项
iptables 命令的常用管理选项
# 规则管理命令
-A, --append chain rule-specification 在指定链 chain 的末尾插入指定的规则,也就是说,这条规则会被放到最后,最后才会被执行。规则是由后面的匹配来指定。
-I, --insert chain [rulenum] rule-specification 在链 chain 中的指定位置插入一条或多条规则。如果指定的规则号是1,则在链的头部插入。这也是默认的情况,如果没有指定规则号。
-D, --delete chain rule-specification -D, --delete chain rulenum 在指定的链 chain 中删除一个或多个指定规则。
-R num:Replays替换/修改第几条规则
# 查看管理命令
-n:使用数字形式显示输出结果
-v:查看规则列表时显示详细的信息
--line-numbers:查看规则列表时,同时显示规则在链中的顺序号
-L:列出指定链中所有的规则,未指定链名,则列出表中的所有链
# 链管理命令(这都是立即生效的)
-P, --policy chain target :为指定的链 chain 设置策略 target。注意,只有内置的链才允许有策略,用户自定义的是不允许的。
-F, --flush [chain] 清空指定链 chain 上面的所有规则。如果没有指定链,清空该表上所有链的所有规则。
-N, --new-chain chain 用指定的名字创建一个新的链。
-X, --delete-chain [chain] :删除指定的链,这个链必须没有被其它任何规则引用,而且这条上必须没有任何规则。如果没有指定链名,则会删除该表中所有非内置的链。
-E, --rename-chain old-chain new-chain :用指定的新名字去重命名指定的链。这并不会对链内部造成任何影响。
-Z, --zero [chain] :把指定链,或者表中的所有链上的所有计数器清零。
#帮助
-h:查看命令帮助信息
匹配条件
基本匹配条件
基本匹配条件: 无需加载模块有iptables/netfilter自行提供
[!] -s --sources 匹配来源地址IP-ADDR[/mask],可以写多个,逗号隔开.加叹号"!"表示除这个IP外。
[!] -d --destination 匹配目标地址
[!] -i --in-interface 网卡名称 匹配从这块网卡流入的数据
[!] -o --out-interface 网卡名称 匹配从这块网卡流出的数据
[!] -p --protocol 匹配协议,如tcp,udp,icmp等 参考:/etc/protocols
扩展条件模块
扩展匹配条件需要加载(/usr/ilb64/xtables/*.so),可使用man iptables-extensions 查看帮助
隐式扩展 : -p指明了特定协议后,无需在使用-m 选项指定模块,不需要手动加载模块(例如tcp)
隐式扩展
TCP协议扩展
[!] --source-port , --sport port[:port] #匹配报文源端口或者范围
[!] --destination-port , --dport port[:port] #匹配报文目标端口或者范围
[!] --tcp-flags mask comp
mask 需检测的标记位列表 用,隔开 例:SYN,ACK,FIN等
comp 在mask列表中必须为1的标记位列表,无指定则为0 用,分隔tcp协议的扩展项
--tcp-flags SYN,ACK,FI SYN #表示要检查标志位为SYN,ACK,FIN 三个,其中SYN必须为1 其余必须为0 (第一次握手)
--syn #用于匹配第一次握手等价于 --tcp-flags SYN,ACK,FIN SYN
--tcp-flags SYN,ACK,FIN SYN,ACK #表示要检查标志位为SYN,ACK,FIN 三个,其中SYN和ACK必须为1 其余必须为0 (第二次握手)
#示例1: 禁止第一次握手
iptables -t filter -A INPUT -s 10.0.0.201 -p tcp --syn -j REJECT
#此时新建链接无法连入,已建立连接的主机不受影响.
ssh 10.0.0.41
ssh: connect to host 10.0.0.41 port 22: Connection refused
#示例2: 禁止指定地址访问web服务
# 未加规则前
curl 10.0.0.41
<html>
<head><title>Index of /</title></head>
<body>
<h1>Index of /</h1><hr><pre><a href="../">../</a>
<a href="centos7/">centos7/</a> 03-Nov-2022 07:32 -
</pre><hr></body>
</html>
#添加规则禁止10.0.0.201 访问10.0.0.41的80端口
iptables -t filter -A INPUT -s 10.0.0.201 -p tcp --dport 80 -j REJECT
# 添加策略后
curl 10.0.0.41
curl: (7) Failed connect to 10.0.0.41:80; Connection refused
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请求
#例如: --icmp-type 8 | --icmp-type echo-request
iptables -t filter -A INPUT -s 10.0.0.201 -p icmp --icmp-type echo-request -j REJECT
#例如:拒绝指定地址的icmp包
#添加策略前
ping 10.0.0.41
PING 10.0.0.41 (10.0.0.41) 56(84) bytes of data.
64 bytes from 10.0.0.41: icmp_seq=1 ttl=64 time=0.805 ms
64 bytes from 10.0.0.41: icmp_seq=2 ttl=64 time=0.351 ms
iptables -t filter -A INPUT -s 10.0.0.201 -p icmp -j DROP
#命令拆解:
# -t: 指定表(默认为filter表),指定filter表时可以不写
# -A: 在指定链的末尾添加一条新的规则
# -s: 指定来源地址
# -p: 指定协议,此处为禁ping
# -j: 指定动作
iptables -nL #查看是否生效 查看详细资料可加-v
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- 10.0.0.201 0.0.0.0/0
#添加策略后
ping 10.0.0.41
PING 10.0.0.41 (10.0.0.41) 56(84) bytes of data.
--- 10.0.0.41 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3019ms
#此时双向都无法ping通
#禁止10.0.0.201 ping通10.0.0.41,但10.0.0.41 可以ping通 10.0.0.201
iptables -t filter -A INPUT -s 10.0.0.201 -p icmp --icmp-type echo-request -j REJECT
显式扩展
显式扩展: 手动加载扩展模块,必须使用--m 指定要加载的模块名称
-m --match matchname [per-match-options]
扩展模块使用帮助
-
centos7,8: man iptables-extensions
-
centos6: man iptables
1. multiport 扩展模块
以离散方式定义多个端口匹配,最多指定15个
#指定多个源端口
[!] --source-ports, --sports port_num[port_num1|,port_num:port_num]
#指定多个目标端口
[!] --destination-ports, --dports port_num[port_num1|,port_num:port_num]
#指定多个源或者目标端口
[!] --ports, port_num[port_num1|,port_num:port_num]
#示例1:禁止指定地址访问22,80-88,443端口
#指定策略前
curl 10.0.0.41
<html>
<head><title>Index of /</title></head>
<body>
<h1>Index of /</h1><hr><pre><a href="../">../</a>
<a href="centos7/">centos7/</a> 03-Nov-2022 07:32 -
</pre><hr></body>
</html>
[root@vm-centos7 ~]# ssh 10.0.0.41
root@10.0.0.41's password:
#指定策略
iptables -t filter -A INPUT -s 10.0.0.201 -p tcp -m multiport --dports 22,80:88,443 -j REJECT
#指定策略后
ssh 10.0.0.41
ssh: connect to host 10.0.0.41 port 22: Connection refused
curl 10.0.0.41
curl: (7) Failed connect to 10.0.0.41:80; Connection refused
2. string 扩展模块
对报文中的应用层数据做字符串模式匹配
--algo {bm|kmp} #字符串的匹配方式
bm: Boyer-moore
kmp: Knuth-pratt-morris
--icase #忽略大小写
--from offset #开始偏移量
--to offset #结束偏移量
[!] --string #要检测的字符串模式
[!] --hex-string #要检测的字符串模式,16进制
#例如:禁止访问包含baidu字符串的网址
iptables -t filter -A OUTPUT -p tcp --dport 80 -m string --algo bm --string "baidu" -j REJECT
3. iprange 扩展模块
指定连续的IP地址范围
[!] --src-range from[-to] # 源IP地址范围
[!] --dst-range from[-to] # 目标IP地址范围
#例如: 禁止200-250机器访问远程主机10.0.0.41的80端口
iptables -t filter -A INPUT -d 10.0.0.41 -p tcp --dport 80 -m iprange --src-range 10.0.0.200-10.0.0.250 -j REJECT
4. mac 扩展模块
mac模块指定源mac地址
[!] --mac-source XX:XX:XX:XX:XX:XX
#例如:禁止指定mac地址访问本机80和443端口
iptables -t filter -A INPUT -p tcp -m multiport --dports 80,443 -m mac --mac-source 00:0c:29:b5:d2:43 -j REJECT
iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
1 60 REJECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 80,443 MAC 00:0C:29:B5:D2:43 reject-with icmp-port-unreachable
5. time 扩展模块
根据报文到达的时间与指定的时间范围进行匹配(centos8 和rocky有问题)
--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...] # 星期几
--kerneltz #内核时间(UTC时区) 不建议使用,centos7默认为UTC
#注意 time模块的时间为UTC时区 如需换算需要-8 (UTC+8)中国时间
#例如: 15:00-16:45分禁止访问淘宝网站(注意时间要使用UTC时间进行转换)
iptables -A OUTPUT -p tcp -m multiport --dports 80:443 -m string --algo bm --string "taobao.com" -m time --timestart 7:00 --timestop 8:53 -j REJECT
6. connlimit 扩展模块
根据客户端ip做并发连接数数量匹配,可以防止ddos拒绝服务攻击
--connlimit-upto #连接数量小于等于时匹配
--connlimit-above #连接数量大于时匹配
#例如: 禁止指定地址的http并发连接数超过10次
#未指定策略前使用ab 并发100个连接,可以正常访问
ab -c 100 -n 100 10.0.0.41/
Benchmarking 10.0.0.41 (be patient).....done
Server Software: nginx/1.22.0
Server Hostname: 10.0.0.41
Server Port: 80
Document Path: /
Document Length: 248 bytes
Concurrency Level: 100
Time taken for tests: 0.023 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 37000 bytes
HTML transferred: 24800 bytes
Requests per second: 4426.93 [#/sec] (mean)
Time per request: 22.589 [ms] (mean)
Time per request: 0.226 [ms] (mean, across all concurrent requests)
Transfer rate: 1599.58 [Kbytes/sec] received
......
#指定策略
iptables -t filter -A INPUT -s 10.0.0.201 -p tcp -m multiport --dports 80,443 -m connlimit --connlimit-above 10 -j REJECT
#指定策略后 超过10个连接数后无法访问
ab -n 100 -c 11 10.0.0.41/
Benchmarking 10.0.0.41 (be patient)...apr_socket_recv: Connection refused (111)
Total of 1 requests completed
7. limit扩展模块
基于收发报文进行速率匹配控制,限流
--limit number[/second|/minute|/hour|/day] # --limit 30/minute (每分钟通过30个包)
--limit-burst number #前number个包不限制
例如: 只允许icmp 每分钟通过30个包(两秒一个),前5个包不限制
iptables -t filter -A INPUT -p icmp -m limit --limit 30/minute --limit-burst 5 -j ACCEPT
iptables -t filter -A INPUT -p icmp -j REJECT
ping 10.0.0.41
PING 10.0.0.41 (10.0.0.41) 56(84) bytes of data.
64 bytes from 10.0.0.41: icmp_seq=1 ttl=64 time=0.236 ms
64 bytes from 10.0.0.41: icmp_seq=2 ttl=64 time=0.503 ms
64 bytes from 10.0.0.41: icmp_seq=3 ttl=64 time=0.328 ms
64 bytes from 10.0.0.41: icmp_seq=4 ttl=64 time=0.432 ms
64 bytes from 10.0.0.41: icmp_seq=5 ttl=64 time=0.577 ms
64 bytes from 10.0.0.41: icmp_seq=6 ttl=64 time=0.309 ms
64 bytes from 10.0.0.41: icmp_seq=7 ttl=64 time=0.427 ms
64 bytes from 10.0.0.41: icmp_seq=8 ttl=64 time=0.676 ms
64 bytes from 10.0.0.41: icmp_seq=9 ttl=64 time=0.411 ms
From 10.0.0.41 icmp_seq=10 Destination Port Unreachable
64 bytes from 10.0.0.41: icmp_seq=11 ttl=64 time=0.518 ms
From 10.0.0.41 icmp_seq=12 Destination Port Unreachable
64 bytes from 10.0.0.41: icmp_seq=13 ttl=64 time=0.578 ms
From 10.0.0.41 icmp_seq=14 Destination Port Unreachable
64 bytes from 10.0.0.41: icmp_seq=15 ttl=64 time=0.515 ms
From 10.0.0.41 icmp_seq=16 Destination Port Unreachable
64 bytes from 10.0.0.41: icmp_seq=17 ttl=64 time=0.662 ms
From 10.0.0.41 icmp_seq=18 Destination Port Unreachable
64 bytes from 10.0.0.41: icmp_seq=19 ttl=64 time=0.335 ms
From 10.0.0.41 icmp_seq=20 Destination Port Unreachable
8. state扩展模块
state扩展模块,可以根据"连接追踪机制"去检查联动的状态
需要依赖连接追踪库 /porc/net/nf_conntrack ,可使用lsmod |grep conntrack 查看是否开启 默认关闭状态,添加策略后可自动开启
conntrack机制: 追踪本机请求和响应之前的关系
# 连接追踪功能所容纳的最大连接数
cat /proc/sys/net/netfilter/nf_conntrack_max
31112
cat /proc/sys/net/nf_conntrack_max
31112
#查看已经了多少条
#临时修改
echo '100000' > /proc/sys/net/netfilter/nf_conntrack_max
或者 sysctl -w net.netfilter.nf_conntrack_max = 100000
#永久修改
vim /etc/sysctl.conf
net.netfilter.nf_conntrack_max = 100000
sysctl -p #读取修改后的配置
#查看ESTABLISHED超时时间(连接在conntrack表中保留的时间)
#/proc/sys/net/netfilter/这个目录下的文件都记录了对应协议的超时时间
cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
432000
对于state模块的连接而言,”连接”其中的报文可以分为5种状态(与TCP协议中的状态无任何关系),报文状态可以为NEW、ESTABLISHED、RELATED、INVALID、UNTRACKED
-
NEW: 新发起的请求,连接追踪信息库中不存在此链接的相关条目 (第一次发出请求)
-
ESTABLISHED: NEW状态之后,连接追踪库中为其建立的条目失效前期间内的所有通信状态(只要不是第一次后续的连接都视为ESTABLISHED)
-
RELATED: 新发起的但是与已有的连接相关联(相关的包)
举个例子说明:
FTP有两个链接:一个是传输控制命令的链接,一个是传输数据的链接。
先建立起的链接是传输控制命令的链接,
然后,由于链接里的某个命令,需要创建一个新的链接, 那么这个新的链接里的第1个数据包的状态就是RELATED状态 新连接后续的数据包的状态也是 ESTABLISHED 状态
-
INVALID: 无效的连接(一个包没有办法被识别,或者这个包没有任何状态,如:flag标记位不正确)
-
UNTRACKED: 未进行追踪的连接(报文的状态为untracked时,表示报文未被追踪,当报文的状态为Untracked时通常表示无法找到相关的连接)
# 例如: 已建立连接的用户正常连接,新用户不可连接
iptables -t filter -A INPUT -m state ESTABLISHED -j ACCEPT #建立连接的用户正常连接
iptables -t filter -A INPUT -m state NEW -j REJECT #新用户不可连接
动作处理
处理动作(target) 也分为基本动作和扩展动作。以下列举一些常用的动作:
ACCEPT: 允许数据包通过
DROP: 直接丢弃数据包,不给任何回应信息,这时候客户端会感觉自己的请求泥牛入海了,过了超时时间才会有反应
QUEUE: 将数据包移交到用户空间
RETURN: 停止执行当前链中的后续规则,并返回到调用链(The Calling Chain)中
REJECT: 拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息
DNAT: 目标地址转换
SNAT: 源地址转换,解决内网用户用同一个公网地址上网的问题
MASQUERADE: IP伪装(NAT) 是 SNAT 的一种特殊形式,适用于动态ip
REDIRECT: 重定向,在本机做端口映射
LOG: 记录日志信息,除记录外不对数据包做任何其他操作,仍然匹配下一条规则 日志保存在/var/log/messages中
--log-level level #级别: debug,info,notice,warning,error,crit,emerg
--log-prefix prefix #日志前缀,用于区别不同的日志,最多29字符
iptables -t filter -A INPUT -s 10.0.0.201 -j DROP # 拒绝所有来自10.0.0.201的包
iptables -D INPUT 2 # 删除filter表中INPUT链的第二条规则
iptables -I INPUT 2 -s 10.0.0.42 -j ACCEPT # 将规则插入到filter表中的INPUT链的第二条
iptables -R INPUT 1 -s 10.0.0.41 -j REJECT # 将filter表中INPUT链中的第一条进行修改
自定义链
使用自定义链可以更为高效,灵活的管理各个规则
-N:自定义一条新的规则链
-E:重命名自定义链 # oldchain newchain
-X:删除自定义的空规则链
#例如:在filter表中新增一个自定义链
iptables -N WEB_TEST
iptables -vnL #查看是否生成自定义链
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain WEB_TEST (0 references)
pkts bytes target prot opt in out source destination
# 将规则添加到自定义链中
iptables -A WEB_TEST -s 10.0.0.201 -p tcp -m multiport --dport 80,443 -j REJECT
#将自定义链关联到内置链
iptables -A INPUT -j WEB_TEST
#查看定义链
iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
76 4512 WEB_TEST all -- * * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain WEB_TEST (1 references)
pkts bytes target prot opt in out source destination
0 0 REJECT tcp -- * * 10.0.0.201 0.0.0.0/0 multiport dports 80,443 reject-with icmp-port-unreachable
iptables保存与加载
使用iptables-save 输出重定向到文件可以持久保存
使用iptables-restore 输入重定向可加载配置
#例如:保存到文件
iptables-save > /root/iptables.rules
cat /root/iptables.rules
#Generated by iptables-save v1.8.4 on Wed Nov 9 15:21:18 2022
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:WEB_TEST - [0:0]
-A INPUT -s 10.0.0.0/24 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j REJECT --reject-with icmp-port-unreachable
COMMIT
# Completed on Wed Nov 9 15:21:18 2022
# 加载配置
iptables-restore < /Rroot/iptables.rules
iptables -vnL INPUT
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
28 1624 ACCEPT tcp -- * * 10.0.0.0/24 0.0.0.0/0 tcp dpt:22
1 41 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
0 0 REJECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 reject-with icmp-port-unreachable
#以上方式为手动加载,每次开关机后需要手动执行加载命令
#开机自动加载iptables规则
#方式一:
使用/etc/rc.d/rc.local 文件 在里面加入 iptables-restore < /PATH/iptable_file
(rc.local需要执行权限)
#方式二:
安装iptables-services
通过查看services启动脚本找寻配置文件所在位置,一般存在于/etc/sysconfig/iptables下
使用iptables-save 重定向保存到脚本指定位置后(/etc/sysconfig/iptables) ,将iptables-server设置为开机自启,可以实现开机自动加载
cat /usr/lib/systemd/system/iptables.service
[Unit]
Description=IPv4 firewall with iptables
AssertPathExists=/etc/sysconfig/iptables
Before=network-pre.target
Wants=network-pre.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/libexec/iptables/iptables.init start
ExecReload=/usr/libexec/iptables/iptables.init reload
ExecStop=/usr/libexec/iptables/iptables.init stop
Environment=BOOTUP=serial
Environment=CONSOLETYPE=serial
StandardOutput=syslog
StandardError=syslog
cat -n /usr/libexec/iptables/iptables.init |less
24 IPTABLES=iptables
25 IPTABLES_DATA=/etc/sysconfig/$IPTABLES
FORWARD链
FORWARD链实现内外网流量控制
环境 web1 主机 172.16.1.2 网关指向forward 172.16.1.3 forward 防火墙主机 10.0.0.3 172.16.1.3 web2 主机 10.0.0.4 网关指向forward 10.0.0.3
开启linux转发方式
临时打开:
echo 1 > /proc/sys/net/ipv4/ip_forward
或
sysctl -w net.ipv4.ip_forward=1
永久打开:
vim /etc/sysctl.conf
net.ipv4.ip_forward = 1 #将此行写入配置文件
sysctl -p #读取修改后的配置
# web1和web2可以正常通讯
ping 172.16.1.2 -c 3
PING 172.16.1.2 (172.16.1.2) 56(84) bytes of data.
64 bytes from 172.16.1.2: icmp_seq=1 ttl=63 time=0.444 ms
64 bytes from 172.16.1.2: icmp_seq=2 ttl=63 time=0.785 ms
64 bytes from 172.16.1.2: icmp_seq=3 ttl=63 time=1.04 ms
curl 172.16.1.2
web1 website
ping 10.0.0.4 -c 3
PING 10.0.0.4 (10.0.0.4) 56(84) bytes of data.
64 bytes from 10.0.0.4: icmp_seq=1 ttl=63 time=0.606 ms
64 bytes from 10.0.0.4: icmp_seq=2 ttl=63 time=0.645 ms
64 bytes from 10.0.0.4: icmp_seq=3 ttl=63 time=0.551 ms
curl 10.0.0.4
web2 website
至此准备环境已经完成
#控制转发,不允许web1访问web2,但是web2 可以访问web1
iptables -t filter -A FORWARD -m state --state ESTABLISHED -j ACCEPT
#允许与已建立连接的主机通讯
iptables -t filter -A FORWARD -s 10.0.0.4 -m state --state NEW -j ACCEPT
#允许源地址为10.0.0.4的机器进行转发(web2向外访问允许)
iptables -t filter -A FORWARD -j REJECT
#最后拒绝所有
#或者
iptables -A FORWARD -s 10.0.0.4 -j ACCEPT
#允许源地址为10.0.0.4的主机进行通讯
iptables -t filter -A FORWARD -d 10.0.0.4 -m state --state ESTABLISHED -j ACCEPT
#允许与目标地址10.0.0.4已经建立连接的机器通讯(用于响应包返回)
iptables -t filter -A FORWARD -j REJECT
#最后拒绝所有
#web1访问web2被拒绝
ping 10.0.0.4
PING 10.0.0.4 (10.0.0.4) 56(84) bytes of data.
From 172.16.1.3 icmp_seq=1 Destination Port Unreachable
From 172.16.1.3 icmp_seq=2 Destination Port Unreachable
curl 10.0.0.4
curl: (7) Failed to connect to 10.0.0.4 port 80: 拒绝连接
#web2访问web1正常
ping 172.16.1.2
PING 172.16.1.2 (172.16.1.2) 56(84) bytes of data.
64 bytes from 172.16.1.2: icmp_seq=1 ttl=63 time=0.721 ms
64 bytes from 172.16.1.2: icmp_seq=2 ttl=63 time=0.735 ms
curl 172.16.1.2
web1 website
NAT表
nat表: 负责网络地址转换,即来源与目的IP地址和port的转换。与主机本身无关,一般用于局域网共享上网或者特殊的端口转换服务相关。
nat表定义了四个链,nat功能就相当于网络的acl控制,和网络交换机acl类似
OUTPUT:和主机发出去的数据包有关,改变主机发出数据包的目标地
INPUT : 和主机J接收的数据包有关,改变主机发出数据包的目标地
PREROUTING:在数据包到达防火墙时进行路由判断之前执行的规则,作用是改变数据包的目的地址、目的端口等
POSTROUTING:在数据包离开防火墙时进行路由判断之后执行的规则,作用是改变数据包的源地址、源端口等
SNAT源地址转换
分类 | 功能 | 作用链 |
---|---|---|
SNAT | 源地址转换 | 出口POSTROUTING |
SNAT选项
-
--to-source [ipaddr[-ipaddr]][:port[-port]]:修改源地址,也可以是轮询的地址范围
-
--random:请求时随机访问多个地址
-
--persistent:随机访问到一个地址后,之后始终用固定的地址访问
MASQUERADE 选项
地址伪装,此为动态SNAT,基于nat表中的Target,适用于动态IP
选项参数
-
--to-ports port[-port]
-
--random
实例:共享上网
环境准备
web1 主机 172.16.1.2 网关指向forward 172.16.1.3
forward 防火墙主机 10.0.0.3 172.16.1.3
开启linux转发方式
临时打开:
echo 1 > /proc/sys/net/ipv4/ip_forward
或
sysctl -w net.ipv4.ip_forward=1
永久打开:
vim /etc/sysctl.conf
net.ipv4.ip_forward = 1 #将此行写入配置文件
sysctl -p #读取修改后的配置
配置SNAT
iptables -t nat -A POSTROUTING -s 172.16.1.2 -j SNAT --to-source 10.0.0.3
# 源地址为172.16.1.2的地址在转换为10.0.0.3
# 或者
iptables -t nat -A POSTROUTING -s 172.16.1.2 -j MASQUERADE
DNAT目标地址转换
分类 | 功能 | 作用链 |
---|---|---|
DNAT | 目标地址转换 | 进口PREROUTING |
DNAT选项
- --to-destination ipaddr[[-ipaddr][:port][-port]]
实例:(端口映射)web1访问防火墙主机172地址时转发到web2主机的80端口
环境
web1 主机 172.16.1.2
forward 防火墙主机 10.0.0.3 172.16.1.3
web2 主机 10.0.0.4 网关指向forward 10.0.0.3
开启linux转发方式
临时打开:
echo 1 > /proc/sys/net/ipv4/ip_forward
或
sysctl -w net.ipv4.ip_forward=1
永久打开:
vim /etc/sysctl.conf
net.ipv4.ip_forward = 1 #将此行写入配置文件
sysctl -p #读取修改后的配置
iptables -t nat -A PREROUTING -i eth1 -d 172.16.1.3 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.4:80
#当流量通过eth1进来且访问172.16.1.3的80端口是转发到10.0.0.4:80
curl 172.16.1.3(防火墙主机)
web2 website
REDIRECT 转发
redirect 通过改变目标ip和端口,将接收的包转发到同一个主机上的不同端口,可用于PREROUTING,OUTPUT链
REDIRECT选项
- --to-ports port[-port]
示例:将本机的80端口转发到本机的81端口
iptables -t nat -A PREROUTING -d 10.0.0.4 -p tcp --dport 80 -j REDIRECT --to-ports 81