Iptables

一,iptables的原理:

当主机收到一个数据包后,数据包先在内核空间中处理,若发现目的地址是自身,则传到用户空间中交给对应的应用程序处理,若发现目的不是自身,则会将包丢弃或进行转发

iptables实现防火墙功能的原理是:在数据包经过内核的过程中有五处关键地方,分别是PREROUTING、INPUT、OUTPUT、FORWARD、POSTROUTING,称为钩子函数,iptables这款用户空间的软件可以在这5处地方写规则,对经过的数据包进行处理,规则一般的定义为“如果数据包头符合这样的条件,就这样处理数据包”。

二,iptables的四表五连:

iptables的结构:iptables -> Tables -> Chains -> Rules. 简单地讲,tables由chains组成,而chains又由rules组成。

iptables中定义有表,分别表示提供的功能,有filter表(实现包过滤)、nat表(实现网络地址转换)、mangle表(实现包修改)、raw表(实现数据跟踪),这些表具有一定的优先级:raw–>mangle–>nat–>filter

iptables中定义有5条链,说白了就是上面说的5个钩子函数,因为每个钩子函数中可以定义多条规则,每当数据包到达一个钩子函数时,iptables就会从钩子函数中第一条规则开始检查,看该数据包是否满足规则所定义的条件。如果满足,系统就会根据该条规则所定义的方法处理该数据包;否则iptables将继续检查下一条规则,如果该数据包不符合钩子函数中任一条规则,iptables就会根据该函数预先定义的默认策略来处理数据包
1. Filter表
Filter表示iptables的默认表,因此如果你没有自定义表,那么就默认使用filter表,它具有以下三种内建链:

INPUT链 – 处理来自外部的数据。
OUTPUT链 – 处理向外发送的数据。
FORWARD链 – 将数据转发到本机的其他网卡设备上。

2. NAT表
NAT表有三种内建链:

PREROUTING链 – 处理刚到达本机并在路由转发前的数据包。它会转换数据包中的目标IP地址(destination ip address),通常用于DNAT(destination NAT)。
POSTROUTING链 – 处理即将离开本机的数据包。它会转换数据包中的源IP地址(source ip address),通常用于SNAT(source NAT)。
OUTPUT链 – 处理本机产生的数据包。

3. Mangle表
Mangle表用于指定如何处理数据包。它能改变TCP头中的QoS位。Mangle表具有5个内建链:
PREROUTING OUTPUT FORWARD INPUT POSTROUTING
4. Raw表
Raw表用于处理异常,它具有2个内建链: PREROUTING chain OUTPUT chain

下图十分清晰的表明数据包的流向。由于四表中我们常用的就只有filter和nat:
这里写图片描述

三,iptables规则的书写:

理解iptables规则的关键:

Rules包括一个条件和一个目标(target)
如果满足条件,就执行目标(target)中的规则或者特定值。
如果不满足条件,就判断下一条Rules。

目标值(Target Values)
下面是你可以在target里指定的特殊值:

ACCEPT – 允许防火墙接收数据包
DROP – 防火墙丢弃包
QUEUE – 防火墙将数据包移交到用户空间
RETURN – 防火墙停止执行当前链中的后续Rules,并返回到调用链(the calling chain)中。
SNAT - 源地址转换
DNAT-目的地址转换
REDIRECT-目标端口转换
MARK-将数据包打上标记

四,iptables常用命令和参数:
以下选项指明了将要被执行的操作. 以下选项只能单独在命令行中被指明使用,除非其他被指出的情况。
-A, –append chain rule-specification
在选定的链后添加一个或者多个规则

-C, –check chain rule-specification
检测一条规则是否匹配此链中指定的规则,或者说检测匹配规则是否存在

-D, –delete chain rule-specification
-D, –delete chain rulenum
删除一个或者多个从链中指定的规则,可以使用规则号码或者匹配的规则信息

-I, –insert chain [rulenum] rule-specification
向选定的链中以给定序号向对应位置插入一条或者多条规则。

-R, –replace chain rulenum rule-specification
替换选定链中的一条规则

-L, –list [chain]
列出链中的所有规则,如果没有指定链,则所有的链中的规则都将被显示
用法:iptables -t nat -n -L
用法:iptables -L -v

-S, –list-rules [chain]
显示所与选中链中的规则,如果未选中具体的链,则所有链的规则将以iptables-save形式打印出来

-F, –flush [chain]
刷新选中的链或者所有的链(如果未指定具体的链)。此操作等于删除了所有的规则

-Z, –zero [chain [rulenum]]
将所有链中的数据包归零,或者清零给定的链,或者指定链中的具体规则

-N, –new-chain chain
用给定的名称创建一条用户自定的链

-X, –delete-chain [chain]
删除用户自定的链. 要删除的链必须不存在其他参考.

-P, –policy chain target
对于给定的目标设置链的策略

-E, –rename-chain old-chain new-chain
用给定的链名称重命名一条旧的链

-h 帮助. 给出(当前最简)语法描述.

参数陈列
以下参数明组成了一条规则的设置(例如添加、删除、插入、替换、附加等命令).

-4, –ipv4
此选项对iptables和iptables-restore无效.

-6, –ipv6
如果一条规则使用了-6参数插入iptables-restore此操作将会被默默忽略,其他的用法会报错

[!] -p, –protocol protocol
检测规则或者数据包的传输协议.

[!] -s, –source address[/mask][,…]
指明源,地址可以是网路名称,主机名,网络地址 (with /mask), 或者普通ip

[!] -d, –destination address[/mask][,…]
指明目的

-m, –match match
指明一条匹配的规则进行使用

-j, –jump target
指明规则的目标(下一跳)

-g, –goto chain
指明进程应该在用户指定的链中继续执行

[!] -i, –in-interface name
数据包要通过或者接收的接口名称(只有进入INPUT, FORWARD and PREROUTING
链的数据包需要指明)

[!] -o, –out-interface name
指明数据包将要被送往的接口名称

-c, –set-counters packets bytes
此参数可以使管理员初始化数据包和字节计数(在 INSERT, APPEND, REPLACE操作中).

更多选项参数
以下为附加的参数选项以及用法讲解

-v, –verbose
显示操作的详细输出信息

-w, –wait [秒]
等待xtables锁,阻止一个程序的多实例同时运行,并且一段时间试图去获得执行锁。默认的,如果不能获取执行锁,程序将会退出。此参数将会使进程等待,一直到获得执行锁

-n, –numeric
数字化输出,ip地址和端口号将会以数字格式显示出来。默认的,此程序会尝试列出主机名称或者网络名称或者服务名称

-x, –exact
数字详述.显示具体的数据包值以及字节数,而不是大约的K’s(multiples of 1000) M’s (multiples of 1000K)G’s (multiples of 1000M),此参数只与-L参数相关

也可以根据防火墙的连接状态来设置策略:

五,实验:
iptables -A INPUT -m state –state NEW -i lo -j ACCEPT #设置状态为NEW但是经过本地回环接口的连接允许

iptable -A INPUT -m state –state NEW -p tcp –dport 22 -j ACCEPT #设置经过22端口的新状态允许连接

iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT #设置ESTABLISHED和RELATED状态的可以连接

实验:关于源地址转换和目的地址转换:
环境:实验主机配置双网卡,eth0(172.25.254.93),eth1(172.25.92.93),eth1相当于路由器,可以实现内网和外网之间通信的桥梁。
测试主机配置ip为(172.25.92.1),相当于内网主机,配置网关为(172.25.92.93)

源地址转换:
[root@93 ~]# sysctl -p | grep ip_forward
net.ipv4.ip_forward = 1
要保证此项值为1,如果为0,则不能实现路由转发
在/etc/sysctl.conf重添加即可
这里写图片描述
[root@93 ~]# iptables -t nat -A POSTROUTING -o eth0 -j SNAT –to-source 172.25.254.93 #在93主机上添加策略:从本机上路由的数据包的源地址转变为172.25.254.93

测试,在172.25.92.1主机上:
这里写图片描述
从图中可以看见,虽然是测试主机(172.25.92.1)使用ssh连接的172.25.254.92,但是在92主机上显示的却是172.25.254.93主机连接的,这就是因为路由策略的原因。

目的地址转换:
[root@93 ~]# iptables -t nat -A PREROUTING -i eth0 -d 172.25.254.93 -j DNAT –to-dest 172.25.92.1 #将访问目的是172.25.254.93的连接转向172.25.92.1

测试:在172.25.254.92主机上:
这里写图片描述
可以看出虽然在92主机上使用ssh连接的是172.25.254.93,但是却将目的地转向172.25.92.1,这种结果就是因为路由的原因。

<think>我们正在分析用户提供的iptables规则,并给出优化建议。用户当前的iptables规则如下:ChainINPUT(policyACCEPT3147packets,242Kbytes)pktsbytestargetprotoptinoutsourcedestination18984ACCEPTtcp--**192.168.163.1230.0.0.0/0tcpdpt:80352100DROPtcp--**0.0.0.0/00.0.0.0/0tcpdpt:80ChainFORWARD(policyACCEPT0packets,0bytes)pktsbytestargetprotoptinoutsourcedestinationChainOUTPUT(policyACCEPT3800packets,285Kbytes)pktsbytestargetprotoptinoutsourcedestination16960DROPtcp--**0.0.0.0/00.0.0.0/0tcpdpt:8000DROPtcp--**0.0.0.0/00.0.0.0/0tcpdpt:8000DROPtcp--**0.0.0.0/00.0.0.0/0tcpdpt:80从规则中我们可以观察到以下情况:1.在INPUT链中:-第一条规则:允许源IP为192.168.163.123访问本机的80端口(HTTP服务)。-第二条规则:拒绝所有其他IP访问本机的80端口。2.在OUTPUT链中:-有三条规则都是拒绝所有出站流量访问远程的80端口(即本机作为客户端去访问外部的HTTP服务)。注意,这三条规则重复了,而且由于OUTPUT链的默认策略是ACCEPT,这些规则实际上会阻止本机访问外部的80端口。问题分析:1.规则顺序问题:在INPUT链中,允许特定IP的规则在拒绝所有规则之前,这是正确的。因为规则是按顺序匹配的,先匹配允许的IP,然后拒绝其他所有IP。2.重复规则:在OUTPUT链中,有三条完全相同的DROP规则(目标端口80)。这可能是配置时多次执行了相同的命令导致的。虽然不影响功能,但会使得规则列表冗长,而且计数器分散。建议只保留一条。3.规则冗余:在OUTPUT链中,如果目的是阻止本机作为客户端访问外部的80端口,那么一条规则即可。另外,注意OUTPUT链的默认策略是ACCEPT,所以只有匹配到这条规则的流量才会被拒绝。4.规则范围:当前的规则只针对80端口,如果还有其他端口需要管理,需要添加相应规则。优化建议:1.清理重复规则:删除OUTPUT链中多余的两条DROP规则,只保留一条。2.考虑其他必要规则:通常,服务器需要允许SSH连接(默认22端口)以便远程管理。当前的规则中没有允许SSH的规则,这可能导致无法通过SSH连接(如果默认策略改为DROP的话)。但注意当前INPUT链的默认策略是ACCEPT,所以其他端口(包括SSH)都是开放的。如果是为了安全,建议将默认策略改为DROP,并显式允许需要的端口(如SSH、80等)以及允许特定IP访问80。3.允许已建立连接和回环接口:在设置默认策略为DROP时,需要添加以下规则:-允许回环接口(lo)的流量:`iptables-AINPUT-ilo-jACCEPT`-允许已建立连接和相关的流量:`iptables-AINPUT-mconntrack--ctstateESTABLISHED,RELATED-jACCEPT`4.如果服务器不需要访问外部的HTTP服务,那么OUTPUT链中阻止80端口是合理的。但通常服务器可能需要访问外部的HTTP服务(例如下载更新),所以需要谨慎。5.保存规则:优化后,使用`iptables-save`(或根据发行版使用持久化工具)保存规则,防止重启后丢失。具体优化步骤:假设我们想要实现:-允许特定IP(192.168.163.123)访问本机80端口。-允许所有IP访问本机SSH端口(22)?注意:这里需要明确,如果只允许特定IP访问SSH,那么需要添加规则。但当前规则中没有涉及SSH,所以默认是开放的。如果为了安全,建议限制SSH的访问IP。-拒绝其他所有访问本机80端口的流量。-允许本机访问外部的其他端口(如443),但阻止80(根据需求决定)。步骤:1.备份当前规则:`iptables-save>/root/iptables.bak`2.清除所有规则(注意:如果通过SSH连接,清除规则可能导致断开,所以先设置默认策略为ACCEPT):```iptables-PINPUTACCEPTiptables-PFORWARDACCEPTiptables-POUTPUTACCEPTiptables-Fiptables-X```3.设置默认策略(根据需求,我们设置INPUT为DROP,但注意先允许SSH和已有连接):```iptables-PINPUTDROPiptables-PFORWARDDROPiptables-POUTPUTACCEPT#或者DROP,但通常OUTPUT可以ACCEPT,再根据需求拒绝特定端口```4.添加必要的规则(按顺序):```#允许回环iptables-AINPUT-ilo-jACCEPT#允许已建立连接和相关的流量iptables-AINPUT-mconntrack--ctstateESTABLISHED,RELATED-jACCEPT#允许SSH(这里为了安全,建议只允许特定IP,比如192.168.163.123,如果用户需要)iptables-AINPUT-ptcp--dport22-jACCEPT#或者替换为-s192.168.163.123#允许特定IP访问80iptables-AINPUT-s192.168.163.123-ptcp--dport80-jACCEPT#拒绝其他所有访问80的流量(注意:因为默认策略是DROP,所以其实不需要单独拒绝80,但为了明确,可以添加一条日志记录再拒绝,或者直接由默认策略拒绝)#如果只拒绝80,而其他端口由默认策略拒绝,那么可以不用单独写拒绝80的规则。但如果想明确拒绝80并记录日志,可以:#iptables-AINPUT-ptcp--dport80-jLOG--log-prefix"IPTABLES-DROP:"#iptables-AINPUT-ptcp--dport80-jDROP#但注意,如果默认策略是DROP,那么所有没有匹配到ACCEPT规则的流量都会被丢弃,所以不需要为每个端口单独写DROP规则。#因此,上面的规则已经实现了:允许特定IP访问80,其他IP访问80会被默认策略丢弃(因为没有匹配到任何ACCEPT规则)。但是,这样也会丢弃其他所有端口的访问(除了22和已建立的连接)。所以,如果还有其他的服务端口需要开放,需要添加相应的规则。#另外,在OUTPUT链中,如果我们要阻止本机访问外部的80端口,添加:iptables-AOUTPUT-ptcp--dport80-jDROP#注意:只保留一条即可。```5.删除重复的OUTPUT规则(在优化过程中,我们只添加了一条)。6.保存规则(根据系统不同):-Ubuntu:安装`iptables-persistent`,然后`netfilter-persistentsave`-CentOS:`serviceiptablessave`或`iptables-save>/etc/sysconfig/iptables`注意:在修改规则时,如果通过SSH连接,一定要确保在设置默认策略为DROP之前,已经放行了SSH端口,否则会断开连接。根据用户当前的规则,他们可能只需要管理80端口,但忽略了SSH和其他端口。因此,在优化时要考虑全面。另外,用户可能没有意识到默认策略是ACCEPT,这样其他端口都是开放的,存在安全隐患。建议将默认策略改为DROP,并只开放必要的端口。最后,生成相关问题。</think>### iptables 规则解析与优化建议 #### 当前规则分析(基于 `iptables -L -v -n` 输出) ```mermaid graph TD A[INPUT链] --> B[允许192.168.163.123访问80端口] A --> C[拒绝所有其他IP访问80端口] D[OUTPUT链] --> E[重复3条拒绝所有出站80端口规则] F[FORWARD链] --> G[无规则] ``` 1. **INPUT 链(入站流量)**: - 允许特定 IP `192.168.163.123` 访问 TCP 80 端口(HTTP) - 拒绝其他所有 IP 访问 TCP 80 端口 - **问题**:未处理其他端口流量(默认策略 ACCEPT 存在安全风险) 2. **OUTPUT 链(出站流量)**: - 3条完全相同的规则拒绝所有出站 TCP 80 端口访问 - **问题**:规则重复(只需1条),且未考虑 HTTPS(443) 等必要端口 3. **FORWARD 链(转发流量)**: - 无任何规则(策略 ACCEPT) - **问题**:若启用转发功能存在安全风险 #### 优化建议 ##### 1. 修复规则顺序问题 ```bash # 正确顺序:先允许特定IP,再拒绝所有 sudo iptables -I INPUT 1 -s 192.168.163.123 -p tcp --dport 80 -j ACCEPT sudo iptables -I INPUT 2 -p tcp --dport 80 -j DROP ``` ##### 2. 清理冗余规则 ```bash # 删除重复的OUTPUT规则(保留第一条) sudo iptables -D OUTPUT 1 # 删除第一条DROP规则 sudo iptables -D OUTPUT 1 # 删除第二条(原第三条) sudo iptables -D OUTPUT 1 # 删除第三条(原第四条) # 添加单条有效规则 sudo iptables -A OUTPUT -p tcp --dport 80 -j DROP ``` ##### 3. 增强安全基线配置 ```bash # 设置默认拒绝策略 sudo iptables -P INPUT DROP sudo iptables -P FORWARD DROP # 允许已建立连接和回环接口 sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT sudo iptables -A INPUT -i lo -j ACCEPT # 允许必要服务(SSH) sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 允许ICMP(ping) sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT ``` ##### 4. 优化OUTPUT链 ```bash # 允许访问外部HTTP/HTTPS sudo iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT sudo iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT # 允许DNS解析 sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT ``` #### 最终优化后规则示例 ```bash Chain INPUT (policy DROP) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 in: lo ACCEPT tcp -- 192.168.163.123 0.0.0.0/0 tcp dpt:80 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 icmptype 8 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 Chain OUTPUT (policy ACCEPT) target prot opt source destination ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 ``` #### 规则验证命令 1. 检查规则顺序: ```bash sudo iptables -L -v -n --line-numbers ``` 2. 测试规则效果: ```bash # 测试允许IP访问80端口 curl -I http://your-server --interface 192.168.163.123 # 测试其他IP被拒绝 curl -I http://your-server ``` 3. 保存规则(Ubuntu): ```bash sudo netfilter-persistent save ``` #### 性能优化技巧 1. **使用IP集合** 处理多IP: ```bash sudo ipset create allowed_ips hash:ip sudo ipset add allowed_ips 192.168.163.123 sudo iptables -A INPUT -m set --match-set allowed_ips src -p tcp --dport 80 -j ACCEPT ``` 2. **连接跟踪优化**: ```bash sudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP ``` 3. **限制访问频率**(防DDoS): ```bash sudo iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT ``` > 建议操作前备份规则:`sudo iptables-save > iptables-backup.rules`[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值