百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

iptables使用详解(iptables-z)

ahcoder 2025-04-01 15:39 15 浏览

前言

最近买了一个VPS,并在上面搭了DOCKER,然后再DOCKER中安装Mysql。但只要将网络端口映射到宿主机上,那么外部网络就可以直接访问该数据。属实吓人。为此,我们需要使用防火墙。

说到防火墙,CentOS有FirewallD,Ubuntu有ufw 。它们的用法和语法不尽相同,但有一点却是一致的,那就是他们底层都使用了iptables。 所以为了在不同发行版的linux下都能安全管理我们的服务器,教练,我想学这个iptables

由于FirewallD和ufw本质都是基于iptables的,那么它们都会在iptables中添加一些规则,甚至定义一些链,为了不跟往后我们自己定义的规则相冲突,第一件事,便是停止并卸掉FirewallD和ufw对应的服务。

停掉FirewallD

sudo systemctl stop firewalld //停止FirewallD
sudo systemctl disable firewalld //让FirewallD 不要随系统启动而启动

停掉ufw

sudo ufw disable //停止并在系统启动时不启动ufw

iptables是啥

iptables是一个linux下的防火墙工具,它能帮助我们基于规则进行网络流量控制。它可以做到,但不限于以下功能:

  • o 允许/拒绝某种协议的链接建立,比如TCP,UDP
  • o 允许/拒绝 来自某个ip的访问
  • o 允许/拒绝某个端口被访问
  • o ...

表、链、规则

规则(rule)

来自192.168.2.31的访问,就要将其拒绝,这即是一条规则

链(chain)

往往我们的安全策略不只一条规则,除了 来自192.168.2.31的访问,就要将其拒绝 这条规则之外,我们还有其它规则,比如: 来自192.168.43.22的访问,也要将其拒绝

甚至,我们可能还有多个互斥的规则,这多个规则,哪个规则先执行? 这就涉及到链这个概念。简单来讲,链就是将多个规则从上大小串起来的一个集合单位。规则按从上倒下依次进行匹配。

表(table)

链条可以有多个。将多个链条再规整在一起的集合,叫做表。

总览

在iptables中,有四张表:

  • o filter:这里面的链条,规则,可以决定一个数据包是否可以到达目标进程端口
  • o mangle: 这里面的链条,规则,可以修改数据包的内容,比如ttl
  • o nat:这里面的链条,规则,可以修改源和目标的ip地址,从而进行包路由。
  • o raw:这里面的链条,规则,能基于数据包的状态进行规则设定

上述四张表中,会内置一些链,且每个链,都有默认包处理策略,默认策略一般在链中的所有规则都没匹配时生效。 filter表中的链有:

- INPUT:对路由策略分派过来的包到达目标进程端口之前进行匹配并处理,后续会讲到细节
- FORWARD:对路由策略分派过来的包进行路由转发,后续会讲到细节
- OUTPUT:判断,从本地的目标进程端口处理好的包如何返回/要不要返回给请求方

mangle表中的链有:

PREROUTING:包在到达网口时,进行规则匹配
INPUT:含义同filter
FORWARD: 含义同filter
OUTPUT: 含义同filter
POSTROUTING: 包离开网口的时候匹配

nat表中的链有:

PREROUTING:含义同mangle
OUTPUT:含义同filter
POSTROUTING:含义同mangle

raw表中的链有: PREROUTING:含义同mangle OUTPUT:含义同filter

注意,虽然不同的表中有同名的链,但他们并不是同一个链,并且一个链只能引用同一个表中的链,不能跨表引用。,平时我们的防火墙策略配置,即是在上述各个表的各个链中配置具体的规则

规则生效顺序

虽然一个链中的规则是从上到下依次匹配,但多个表中的多个链,甚至同名链的之间的匹配优先顺序是啥?这就要看下图了

PREROUTING 链

PREROUTING 链是最先生效的,当数据包到达网口时,即开始工作。同时由于其在raw, mangle, nat表中都存在,其执行的优先顺序是:raw(PREROUTING) ----> mangle(PREROUTING)----> mangle(nat)

PREROUTING 一般用作对包进行目标地址修改。比如将该包的目标地址,修改为非本机的另外的网络ip,一般通过DNAT规则进行修改。

路由决策(Routing Decision)

决定一个包该走哪个链。如果上述PREROUTING 链对包进行了目标网络ip更改。那么决策会觉得这个是一个需要转发的数据包,于是会将该包转发给 FORWARD 链。

否则, 该包会走INPUT链

FORWARD 链

FORWARD在各表中生效的优先顺序是:mangle(FORWARD) ----> filter(FORWARD) 处理路由决策派发发过来的包,到这里的包一般目标网络地址在PREROUTING链被修改过

INPUT 链

其生效顺序是: mangle(INPUT) ----> filter(INPUT) 处理路由决策派发发过来的包,到这里的包一般目标网络地址在PREROUTING链没有被修改过。

OUTPUT 链

在目标进程端口接收到输入数据包后,输出的数据包,将在这里进行规则应用。OUTPUT链在各表中生效的先后顺序是: raw(OUTPUT) ----> mangle(OUTPUT) ----> nat(OUTPUT) ----> filter(OUTPUT)

规则详解

前面铺垫了那么多,主要讲解了链的复杂生效时机,毕竟如果包最终都到不了这个链,那其中的规则配置也就没有意义。接下来,我们需要讲解,链中具体规则的设置和使用。

一个规则一般分为两大部分:

  • o 匹配: 即哪些数据包会命中这个规则,比如一个指定的ip,即是一个匹配规则
  • o 动作: 匹配到规则之后,需要做什么动作,是放行,还是拒绝。

动作分为以下几种:

  • o ACCEPT: 直接接受该数据包,不会再走其他链条和规则。比如filter中的input表中的某个规则命中后,动作是ACCEPT,那么该数据包将被直接送达目标进程端口。
  • o DROP: 直接抛弃该数据包,并且没有任何返回。且不会再走其他链和规则
  • o REJECT: 跟DROP类似,但好歹还是会跟请求方返回一些拒绝信息,比如我们拒绝掉ICMP协议后,ping该主机,会返回“destination host unreachable”
  • o RETURN: 当前规则不做任何处理,返回。让给下一个规则处理
  • o LOG : 同RETURN类似,但只是会将请求信息记录到系统日志中,记录路径为:/var/log/syslog or /var/log/messages

如何看某个表中有哪些链和规则

iptables -t nat -nvL --line-numbers

-t表示想要查看那个表,这里查看的是nat表。iptables的所有命令,如果不指定-t,如果不写默认是filter表-L表示列出该表所有链和所有规则-v详细显示,会将规则匹配的进出网口也列出来--line-numbers表示给规则进行编号处理。编号能方便我们后续对规则进行修改、删除等操作

如图所示,表头有以下信息:

  • o num 表示当前规则编号,从1开始
  • o in 表示该规则会匹配那些的输入网口,如果包是由该网口输入,则会被匹配
  • o out 表示该规则会匹配的目标网口,如果包的目标网口是该网口,则会被匹配
  • o source 表示该规则匹配的具体源ip范围
  • o destination 表示该规则匹配的具体目标ip范围

总结来看,其实一个数据包本身就有源、目标的一些信息,而规则就是基于数据包本身属性的特点进行规则设定。

在已知链末尾添加规则(举例,拒绝某个ip的访问)

iptables -t filter -A INPUT -s 59.45.175.62 -j REJECT

-A 表示Append,其后紧跟的是链的名称,表示该条规则要被添加到哪个链中。 -s 表示包的来源ip即source。除了指定固定的ip外,我们还可以指定ip范围,比如59.45.175.0/24 -j 表示jump 也即是我们最终的动作,这里的动作是拒绝

在已知链链首插入规则

链尾的规则匹配优先级最低,如果前面有规则被匹配后,并将数据包进行了终态处理(比如:ACCEPT, DROP, REJECT),那么链尾的规则将永远不会被使用。

如果我们想要该规则优先匹配,可以选择将其放入链首,使用-I参数,表示insert。举例:

iptables -t filter -I INPUT -s 59.45.175.62 -j REJECT

删除规则

想要删除已配置的规则,可以使用-D参数,参数

iptables -t filter -D INPUT -s 59.45.175.62 -j REJECT

这种删法,要我们明确知道当初添加进去的规则是怎么写的。如果忘了,我们可以通过规则编号进行删除。在查看规则时使用参数--line-numbers(例如:iptables -nvL --line-numbers),可以对规则进行编号,然后基于编号进行删除

iptables -t filter -D FOWARD 1 //表示删除filter表中的FORWARD链的第一条规则

拒绝掉对某个ip的回应

iptables -A OUTPUT -d 31.13.78.35 -j DROP

-d 表示destination,即所有返回给ip 31.13.78.35的数据包都直接丢掉,不回应。

清空某个链中的所有规则

iptables -t filter -F INPUT

所有TCP协议的数据包,都丢弃

iptables -A INPUT -p tcp -j DROP

-p表示protocol

丢弃掉某个ip对端口22的访问

iptables -A INPUT -p tcp -m tcp --dport 22 -s 59.45.175.0/24 -j DROP

由于要对端口进行精准匹配,所以先-m tcp 进行tcp module加载。

如何对多个端口进行匹配

iptables -A INPUT -p tcp -m multiport --dports 22,5901 -s 59.45.175.0/24 -j DROP

匹配指定链接状态的数据包

链接状态有以下几种:

  • o NEW:新创建的连接
  • o ESTABLISHED 已经建立的连接
  • o RELATED:跟已经创建的连接相关的连接
  • o INVALID:非正常状态
  • o DNAT:如果一个连接其目标地址被nat表PREROUTING链中的规则修改了,即是这个状态
  • o SNAT:如果一个连接其源地址被nat表中的规则修改了,即是这个状态
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

即只对已经建立的连接和由此产生的相关连接进行放行

有些版本的linux,对应的module不是conntrack,而是state。 对应指定状态的参数不是ctstate 而是--state。所以,上述写法在有些linux版本中需要替换成

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

一般来讲,这些规则不可能单独出现,如果都不允许任何NEW状态连接建立,那哪来的已建立连接和相关连接?所以正确的做法一般是:

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT //这条规则允许已经建立的连接和相关连接
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT //新建链接如果是访问22号端口,则允许访问

改变某个链的默认规则

一般每个链都有默认规则,即该链没有任何规则或者没有任何一条规则被匹配的情况下,对数据的放行策略是怎么样的。

Chain INPUT (policy ACCEPT)
...
Chain FORWARD (policy ACCEPT)
...
Chain OUTPUT (policy ACCEPT)
..

以filter表的三个链为例,默认是ACCEPT。 但是我们可以改变这个模型规则,比如默认规则就是DROP

iptables -t filter -P INPUT DROP

回环地址的访问始终允许

iptables -t filter -A INPUT -i lo -j ACCEPT //在本地网络通信的所有包,都放行

-i 表示input 输入网口。lo表示本地的网络接口。这里没有指定-s-d地址 ,表示在回环网络上通信的所有端口,都放行,这样我们本机的web service,访问本机的mysql数据库才不会有问题。当然一般INPUT的默认规则是ACCEPT,你不用配置上述的规则,只要没有其它规则去限制,那么本机回环地址之间的端口通信也是放行的,除非你对INPUT链默认开启了拒绝策略

在使用某个网络时,不响应请求

iptables -A OUTPUT -o wlan0 -d 121.18.238.0/29 -j DROP 

上述配置含义:所有发给目标网口是wlan0 且 目标ip是121.18.238.0/29 地址的包,都会被丢弃。 -o 表示 数据包的目标网口。

在linux命令行中,使用ifconfig,就能看见当前已连接的所有网络接口

规则的取反配置

上述规则配置,一般都是满足某某条件,做什么动作。除此之外,我们还可以配置,如果不满足某某条件,则做某个动作。

iptables -A INPUT -p tcp -m multiport ! --dports 22,80,443 -j DROP

这个不满足则的取动作,是通过感叹号来实现的。 上述命令的含义是:非22,80,443的端口,我们直接丢弃。

当然这条命令之前,应该要配置一条规则:

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

因为通过22或80建立的连接,可能会衍生出一些RELATED的连接,他们的端口可能不是22或80,那样也就被拒掉了。会导致通信出问题。

如何将规则持久化

上述命令对iptable的操作,并不是永久生效的,机器重启后,对应配置会丢失。如果需要持久化,则需要以下命令进行保存

centos

  1. 1. 第一步,在修改iptables配置后,将其导出到某个文件,比如: /etc/iptables.conf 。命令为:iptables-save > /etc/iptables.conf 这一步,每次修改后都要做
  2. 2. 第二步,在/etc/rc.local中添加命令iptables-restore < /etc/iptables.conf。从此之后,每次重启,系统会自动从/etc/iptables.conf恢复对应的iptables配置。这一步只需要做一次

ubuntu

安装iptables-persistent,它会在系统启动时,从/etc/iptables/rules.v4/etc/iptables/rules.v6分别加载ipv4 和ipv6的iptables 规则

sudo apt install iptables-persistent

所以,每次我们对iptables进行了任何改动,使用下面的命令,将当前生效的iptables配置,导出到/etc/iptables/rules.v4/etc/iptables/rules.v6即可

sudo iptables-save > /etc/iptables/rules.v4 //如果添加了ipv4 规则,执行这步
sudo ip6tables-save > /etc/iptables/rules.v6 //如果添加了ipv6规则,执行这步

自定义链

除了在现有的链中添加规则,我们也可以自定义链,自定义链可以帮助我们将一组规则收纳在一起,方便我们管理。比如:

  1. 1. 我们可以定义一个名为ssh-rules的链来管理ssh登录的一些规则
iptables -t filter -N ssh-rules
  1. 1. 在这个链中添加具体的规则
iptables -t filter -A ssh-rules -s 18.130.0.0/16 -j ACCEPT
iptables -t filter -A ssh-rules -s 18.11.0.0/16 -j ACCEPT
iptables -t filter -A ssh-rules -j DROP
  1. 1. 然后将该链作为一个规则出口,挂在到iptable内置的链上。
iptables -A INPUT -p tcp -m tcp --dport 22 -j ssh-rules

以上含义就是在Input链中添加一个规则,所有22号端口的访问,都会导向ssh-rules 再次强调: 只要不指定具体使用的表,默认都是filter表

删除自定义链

当我们想要删除自定义链时,使用命令:iptables -X ssh-rules

如何屏蔽docker 暴露的端口

一般我们会在filter中的input链中,配置对某个端口的限制。但是在装有docker的linux服务器上,docker暴露的任何端口,我们却无法通过在filter表中的input链的规则进行限制,这是为什么呢? 我们通过上文的对整个iptables的工作机制,来拆解下原因。

访问docker服务时,iptables的工作机制

比如,我们在docker 中启动一个mysql,暴露端口是3306。 docker宿主机所在ip: 192.168.31.102。docker 服务启动的虚拟网段:172.17.0.1/16 , 启动的mysql在该虚拟网络的ip是: 172.17.0.2

该机器真正的网口是enp0s3。 docker 启动的虚拟网口是docker0

docker服务本身会在iptables中插入很多规则,甚至定义许多自定义化的链

当我们我们在192.68.31.23 这台机器上访问192.168.31.102的3306端口时。

首先数据包被nat表中PREROUTING链命中

该链中的规则会被命中,同时将数据包导向nat表的DOCKER 链

nat中的DOCKER链修改目标地址

  • o 第一条规则的输入网口是docker0,显然从192.168.31.102外部访问该机器不可能走这个网口进入,因为docker建立了虚拟网络,不可能被外部访问,所以第一条规则不会命中
  • o 第二条规则的输入网口是!docker0,表示非docker网络,该规则能被匹配。由于mysql 实际安装在docker内,如果最终要实现访问,就要对请求包的目标地址进行修改,于是该条规则在匹配后的动作是:tcp dpt:3306 to:172.17.0.2:3306,即将目标网络端口改成docker网段下的172.17.0.2:3306

路由决策到filter中的forward链

由于prerouting对包进行了目标地址的修改,于是路由决策会将该包路由到foward链。所有表中的input 链将直接忽略。

  • o forward链中的第一条规则,会应用于DOCKER-USER链。该链的规则是直接返回包。相当于第一条规则没启作用。直接会进入第二条规则进行匹配计算
  • o 第二条链会包导入DOCKER-ISOLATION-STAGE-1链进行规则计算oo 一路链下去,最终只有图中的规则能命中,而该规则对包的处理方式,是RETURN,也即交给下个规则处理
  • o 第三条规则是对目标网口是docker0的包进行匹配,按理说我们的包会匹配这条规则, 但是这条规则被匹配还有一个条件,就是包链接的状态要是已建立的连接才行,我们第一次从外部对数据库进行访问显然不符合这个要求,于是该规则不会命中。进入第四条规则匹配
  • o 第四条规则命中后,进入DOCKER 链从截图可以看到,包到了这里,被完美匹配。该包首先是一个非docker网络到docker网络的访问,其次,其目标ip是172.17.0.2 的3306端口,匹配后,处理动作是ACCEPT。也即最终该访问被响应,我们从外部网络访问到数据库了。

docker服务无法被iptables限制问题总结及解决办法

说白了,由于数据包被更改了目标地址,于是路由策略将该包导向了FORWARD链。所以我们在INPUT链中再怎么定义规则,都无法限制外网对docker服务的访问。

那解决办法很简单,既然包导向了FORWARD链,那么在FORWARD链中添加拦路虎,不就得了嘛。DOCKER官方给的建议便是如此,比如,针对本文中的例子,我们可以添加如下规则,即可实现所有外部网络都无法访问docker中的服务:

 iptables -I DOCKER-USER -i enp0s3 -j DROP

规则含义是:所有从外部网络进入的数据包,直接被丢弃。 DOCKER-USER链是上述FORWARD链中第一个规则匹配的到的链。 外部访问的数据包,其输入网口,肯定是enp0s3,因为在本例中,它是对外通信的网口。 当然我们也可以在此,插入只允许某个网络访问,或某个网络不能访问的规则,不再赘述。

参考资料

https://www.zsythink.net/archives/1199 https://www.booleanworld.com/depth-guide-iptables-linux-firewall/ https://linuxconfig.org/how-to-make-iptables-rules-persistent-after-reboot-on-linux https://askubuntu.com/questions/579231/whats-the-difference-between-prerouting-and-forward-in-iptables https://docs.docker.com/network/iptables/

欢迎关注我的个人公众号"西北偏北UP",记录代码人生,行业思考,科技评论

相关推荐

PC也能装MAX OS X

MACBOOK向来以其时尚的外观以及易用的OSX操作系统成为了时(zhuang)尚(bi)人士的最爱。但是其动不动就上万元的昂贵价格,也将一批立志时(zhuang)尚(bi)人士的拒之门外。但是最近...

一千多元的笔记本能买吗?英特尔11代+大屏幕,豆小谷值得选吗?

前言:有很多粉丝都问过本人,一千多元到底能买到什么样的笔记本?在此笔者只想说,这样的资金预算真的太低了!如果想买全新的,那大概率买的就是性能比较拉垮的上网本,比如搭载英特赛扬N系列、J系列处理器的轻薄...

首款配备骁龙X Elite处理器的Linux笔记本:采用KDE Plasma桌面环境

德国Linux硬件供应商TUXEDOComputers宣布正在开发一款配备高通骁龙XElite处理器(SnapdragonXEliteSoC)的ARM笔记本电脑,内部将该...

System76推出Gazelle Linux笔记本:配酷睿i9-13900H处理器

IT之家3月30日消息,主打Linux硬件的厂商System76于今天发布了新一代Gazelle笔记本电脑,共有15英寸和17英寸两个版本,将于3月30日接受预订,...

Kubuntu Focus Xe Gen 2笔记本发布,预装Linux系统

IT之家3月25日消息,KubuntuFocusXeGen2笔记本于近日发布,这是一款预装Kubuntu22.04LTSGNU/Linux发行版的轻薄本。上一代Kub...

这台Linux笔记本已用上英特尔12代酷睿,最高可选i7-1255U、卖1149美元起

Linux笔记本可能因为比较小众,一般都是拿Windows笔记本换个系统而来,硬件上也会落后同期Windows笔记本一两代,不过现在专门做Linux电脑的System76,推出了一款名为LemurP...

戴尔Inspiron 14 Plus骁龙笔记本迎新补丁,支持启动Linux

IT之家4月25日消息,科技媒体phoronix今天(4月25日)发布博文,报道称最新发布的Linux内核补丁,针对骁龙芯片的戴尔Inspiron14Plus笔记本,让其...

TUXEDO推出InfinityFlex 14二合一Linux笔记本,配i5-1335U

IT之家8月12日消息,Linux硬件企业TUXEDO当地时间本月2日推出了InfinityFlex14二合一Linux笔记本。该笔记本搭载2+8核的英特尔酷睿i5-...

登月探测器嫦娥使用什么操作系统,是Linux还是其它自主研发?

这是不是国家机密啊。事实什么样的不知道,但是从美国的探测器来看,就算不是也是相似的东西。下面我来说说我知道的。龙芯已经随北斗卫星上天了.就算登月探测器嫦娥是用"龙芯+Linux"也不出奇.没必要...

DNS分离解析实验

如果本文对你有帮助,欢迎关注、点赞、收藏、转发给朋友,让我有持续创作的动力目录一、分离解析概述二、实验需求三、实验步骤3.1双网卡服务器配置3.1.1添加两张网卡(内外网)3.1.2对两个网卡进...

一个小实验巩固下进程管理

先回顾下之前的三篇文章:Linux进程在内核眼中是什么样子的?Linux进程线程是如何创建的?Linux是如何调度进程的?通过这三篇文章的学习我们知道,无论内核进程还是用户进程,都是可以用task...

VMware Kali无线WIFI密码破解

WIFI破解前准备工作一张支持Kali系统监听的无线网卡VMware虚拟机安装好Kali系统(本实验用的是Kali2022版本)Kali系统下载、安装官方网站:https://www.kali.or...

python多进程编程

forkwindows中是没有fork函数的,一开始直接在Windows中测试,直接报错importosimporttimeret=os.fork()ifret==0:...

拔电源十台电脑藏后门!德国实验惊曝Windows致命漏洞

2025年4月15日,央视突然曝出一个超级大新闻!原来美国国家安全局通过黑龙江,往微软Windows系统里发送加密信息,激活了系统里藏着的后门程序,想破坏哈尔滨亚冬会!这消息一出来,大家才发现,竟然已...

深度探索RK3568嵌入式教学平台实战案例:设备驱动开发实验

一、产品简介TL3568-PlusTEB人工智能实验箱国产高性能处理器64位4核低功耗2.0GHz超高主频1T超高算力NPU兼容鸿蒙等国产操作系统二、实验目的1、熟悉基本字符设备的驱动程序...