Linux防火墙之iptables

Stella981
• 阅读 666

文章目录

  • 防火墙的相关概念

  • 四表五链

  • 五链

  • 四表

  • 链表关系

  • 规则

  • SUBCOMMAND

  • 对链操作

  • 对规则操作(后面必须加链的名称)

  • 查看规则

  • 匹配条件

  • 通用匹配

  • 扩展匹配

  • 处理动作

  • 保存规则

  • NAT实验

  • A主机配置

  • B主机配置

  • 测试

防火墙的相关概念

  • 按逻辑分类:
    • 主机防火墙:针对单个主机进行防护,在主机上进行配置
    • 网络防火墙:往往处于网络入口或边缘,针对网络入口进行防护,服务于防火墙背后的本地局域网
    • 网络防火墙和主机防火墙并不冲突,可以理解为,网络防火墙主外(集体), 主机防火墙主内(个人)
  • 按物理分类:
    • 硬件防火墙:在硬件级别实现部分防火墙功能,性能高、成本高
    • 软件防火墙:应用软件处理逻辑运行于通用硬件平台上的防火墙,性能低、成本低

iptables 不是真正的防火墙,可以把它理解成一个客户端代理,用户通过iptables这个代理,将用户的安全设定执行到对应的“安全框架“,这个”安全框架“才是真正的防火墙,叫做 netfilter

netfilter(包过滤)是Linux内核中的一个数据包处理模块,具有如下功能:

  • 网络地址转换(NAT)
  • 数据包内容修改
  • 数据包过滤的防火墙功能

虽然我们使用 service iptables startsystemctl start iptablse 来启动iptables,但是iptables并没有守护进程,所以并不能算是一个真正意义上的服务,而应该算是内核提供的功能

四表五链

五链

我们知道Linux中为了安全分成了用户空间和内核空间两个部分,报文需要进入用户空间前会先经过内核空间,而要想达到”防火“的功能,就需要在内核空间中设置”关卡“,所有进出的报文都需要通过这些关卡,匹配规则后,符合放行条件的才能放行,符合阻拦条件的则需要被阻拦,于是就出现了 inputoutput 关卡,而这些关卡在iptables中被称为”链CHAIN”

Linux防火墙之iptables

事实上上述描述的场景并不完善,因为收到的报文访问的目标地址可能并不是主机,而是其他服务器,当本机的内核支持核心转发 IP_FORWARD 时(明明是台电脑却只能卑微的当个路由器),我们可以将报文转发给其他服务器,这时候就会出现其他的”关卡“,他们就是”路由决策前“、”转发“、”路由决策后“

Linux防火墙之iptables

所以根据上图,我们能想象出某些场景中报文的流向:

  • 到本机某进程的报文:PREROUTING –> INPUT
  • 由本机转发的报文:PREROUTING –> FORWARD –> POSTROUTING
  • 由本机的某进程发出的报文:OUTPUT –> POSTROUTING

为什么这些”关卡“被称作”链“呢?iptables通过定义规则来实现不同的功能,而这些规则就写到了关卡中,防火墙的作用就在于对经过某个关卡的报文进行匹配”规则“,然后执行相应的”动作“;而每个关卡上可能不止有一条规则,而是有很多条规则,当我们将这些规则按一定的顺序串起来时,就形成了”链“,如下图所示。所以把”关卡“称为”链”会更加合适

Linux防火墙之iptables

四表

iptables通过定义规则来实现不同的功能,iptables中有四张表将这些功能分类,而要实现功能就要将规则(rules)写进这些表中,如放行(accept)、拒绝(reject)、丢弃(drop)等,而这四张表分别是:

  • filter表:负责过滤功能(也就是防火);对应的内核模块为:iptables_filter
  • nat表:提供地址转换功能;内核模块:iptables_nat
  • mangle表:拆解修改报文并重新封装;内核模块:iptables_mangle
  • raw表:关闭nat表上启用的连接追踪机制,提高性能;iptables_raw

链表关系

事实上,某些“链”中注定不会包含某类“规则”,就像某些“关卡”天生就不具备某些功能一样。比如A关卡是防空的,只能打击空中的敌人;B关卡是陆军,没有防空能力;C关卡比较牛逼,既可以防空又可以防陆;D关卡最屌,海陆空全防

从表的角度来看:

  • filter表:用于写过滤规则,只要在INPUT、OUTPUT、FORWARD链写就能很好发覆盖,就没必要在路由决策前和路由决策后写了
  • nat表:用于地址转换,源地址转换需要在路由决策后POSTROUTING修改,即SNAT;目的地址转换需要在路由决策前PREROUTING修改,即DNAT;某些进程可能自己也会做SNAT,需要在报文发出时OUTPUT修改;(CentOS 7在INPUT链上也可以设置nat表了,不过主要用的还是前两种)
  • raw表和mangle表没用过

需要注意的是,当报文经过一条链时,会将当前链上所有的规则匹配一遍,但是匹配的时候总归要有顺序,应该一条条匹配,所以还有一个表优先级的问题(由高到低):

raw --> mangle --> nat --> filter

结合上述所有描述,我们可以将报文通过防火墙的流程总结为下图:

Linux防火墙之iptables

规则

规则:根据指定的匹配条件来尝试匹配每一个流经的报文,一旦匹配成功则由规则后面执行的处理动作进行处理

语法:iptables [-t TABLE] SUBCOMMAND CHAIN [!] CRITERIA -j TARGET

SUBCOMMAND

对链操作
  • -F [CHAIN]:flush,清空某条链的所有规则
  • -P [CHAIN]:policy,定义链的默认动作
  • -N CNAME:new,添加自定义链
  • -X CNAME:删除自定义链,需要满足:自定义链没有被任何规则引用,即自定义链的引用计数为0;自定义链中没有任何规则,即自定义链为空
  • -E CNAME NEWCNAME:edit,修改自定义链的名字
  • -Z [CHAIN]:zero,清空链上的统计信息
  • 默认为对所有链做动作
对规则操作(后面必须加链的名称)
  • -A:append,将规则追加到链最后
  • -I:insert,将规则插入到指定位置,需要给定序号
  • -D:delete,将链上的规则删除,需要给定序号
  • -R:replace,对链上的规则修改,需要给定序号
查看规则

-L [CHAIN]:默认列出所有链上的规则

  • -n:不做域名解析
  • -v:显示详细信息
  • -vv:更详细
  • -vvv:再详细
  • –line-numbers:显示规则序号

匹配条件

通用匹配

即不需要指明具体模块名就能使用的匹配条件

  • -s:source,源IP
  • -d:destination,目的IP
  • -p:protocol,协议,有ip、tcp、udp、icmp等
  • -i:input interface,报文的流入接口
  • -o:output interface,报文的流出接口
扩展匹配

需要指明具体的模块名,条件作为模块的选项

隐式匹配:如果在通用匹配上使用了 -p 选项指明协议,则 -m 可有可无

  • tcp:
    • –dport:目的端口
    • –sport:源端口
    • –tcp-flags LIST1 LIST2
      • LIST1:要检查的标志位
      • LIST2:LIST2必须在LIST1中出现,且必须为1的标志位,其余必须为0
      • –tcp-flags sys,ack,fin,rst syn:相当于 –syn,也就是三次握手的第一次握手
    • –syn:用来匹配tcp会话第一次握手
    • iptables -A INPUT -p tcp -s 172.16.100.0/24 --dport 22 -j ACCEPT:放行172.16.100.0/24网段的所有主机对22端口的访问(ssh)
  • udp:
    • –sport
    • –dport
  • icmp:
    • –icmp-type:指定匹配icmp报文类型
      • 0:echo reply
      • 8:echo request

显示匹配:显示指定使用iptables的具体模块进行匹配

用法:-m 模块名 [模块选项]

  • multiport:多端口扩展
    • –sports PORT1[,PORT2…]
    • –dports PORT1[,PORT2…]
    • –ports PORT1[,PORT2,…]
    • iptables -A INPUT -d 10.1.1.1 -p tcp -m multiport --dports 22,80,443 -j ACCEPT:放行10.1.1.1对22、80、443端口的访问
  • iprange:多ip扩展
    • –src-range IP[-IP2]
    • –dst-range IP[-IP2]
    • iptables -A INPUT -d 10.1.1.1 -p tcp --dport 22 -m iprange --src-range 192.168.1.1-192.168.1.100 -j ACCEPT
  • time:指定匹配时段
    • –datestart YYYY\[-MM]\[-DD][-hh[-:mm[:ss]]]
    • –datestop
    • –timestart
    • –timestop
    • –weekdays DAY1[,DAY2…]
    • –mouthdays
    • 每天9点到19点不能访问:iptables -A INPUT -p tcp --dport 80 -m time --timestart 9:00 --timestop 19:00 -j DROP
    • 指定周一周二不能访问:iptables -A INPUT -p tcp --dport 80 -m time --weekdays Mon,Tue -j DROP
  • connlimit:限制同时并发连接数
    • –connlimit-above N
    • –connlimit-mask N:不可单独使用,与上一个选项配合使用,用于针对”某个IP段内的一定数量的IP“进行连接数量限制(IP段内所有IP共享限制)
    • 限制每个IP能打开5个连接:iptables -A INPUT -p tcp --dport 22 -m connlimit --connlimit-above 6 -j REJECT
    • 限制某网段内的主机只能打开10个连接:iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 10 --connlimit-mask 27 -j REJECT
  • limit:限制发包速率
    • –limit n/[minute|second|hour|day]
    • –limit-burst:”令牌桶“算法,指定令牌桶中令牌的最大数量,相当于进程池
  • state:基于连接追踪模板(nf_conntrack),用于记录各连接以及相关状态,基于ip实现,与tcp协议无关
    • NEW:新建立的连接,连接追踪模板无相应记录,客户端第一次发出的请求
    • ESTABLISHED:NEW之后进入模板中直到状态被删除之前的过程
    • RELATED:相关联的连接,如ftp的被动模式(20,21)
    • INVALIED:无法识别的状态
  • string:匹配字符串
    • –algo:指定对应的匹配算法,可用的算法为bm、kmp等,此选项为必选选项
    • –string:指定需要匹配的字符串

处理动作

  • ACCPET:允许数据包通过
  • DROP:直接丢弃数据包,不给任何回应,这时候客户端超时才能察觉
  • REJECT:拒绝数据包通过,并响应发送一个拒绝信息给发送方
  • SNAT:源地址转换,解决内网用户用同一个公网地址上网问题
    • iptables -t nat -A POSTROUTING -s 内网网段 -j SNAT --to-source 需转换成的源地址
  • MASQUERADE:SNAT的特殊形式,相当于动态SNAT
    • iptables -t nat -A POSTROUTING -s 内网网段 -o 出接口 -j MASQUERADE
  • DNAT:目的地址转换,用于外网地址访问内网主机
    • iptables -t nat -A PREROUTING -d 100.1.1.1 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.1
  • 自定义链:跳转到自定义链上,此时自定义链就”挂“在了某条链上,自定义链上的引用计数会+1

保存规则

iptables save

NAT实验

Linux防火墙之iptables

要求


A主机配置

# 修改ip地址
ip addr add 172.16.10.1/24 dev ens33

# 修改默认路由
ip route add default via 172.16.10.2 dev ens33

# 重启网络
systemctl restart network

Linux防火墙之iptables
Linux防火墙之iptables


B主机配置

# 添加一个子接口
ifconfig eth0:0 172.16.10.2 netmask 255.255.255.0

# 关闭selinux
setenforce 0

# 清空filter表默认配置
iptables -F

# 为主机A配置SNAT
iptables -A POSTROUTING -t nat -s 172.16.10.0/24 -o eth0 -j MASQUERADE

# 为主机A配置DNAT
iptables -A PREROUTING -t nat -d 192.168.159.144 -p tcp --dport 2222 -j DNAT --to-destination 172.16.10.1:22

# 开启核心转发
echo 1 > /proc/sys/net/ipv4/ip_forward

测试

  • 在 A 中 ping 192.168.159.1

    [root@inside ~]# ping 192.168.159.1 PING 192.168.159.1 (192.168.159.1) 56(84) bytes of data. 64 bytes from 192.168.159.1: icmp_seq=1 ttl=127 time=0.714 ms 64 bytes from 192.168.159.1: icmp_seq=2 ttl=127 time=0.648 ms 64 bytes from 192.168.159.1: icmp_seq=3 ttl=127 time=0.525 ms 64 bytes from 192.168.159.1: icmp_seq=4 ttl=127 time=0.563 ms ^C --- 192.168.159.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3002ms rtt min/avg/max/mdev = 0.525/0.612/0.714/0.077 ms

  • 在 C 上 ssh root@192.168.159.144

    C:\Users\Ti>ssh root@192.168.159.144 -p 2222 The authenticity of host '[192.168.159.144]:2222 ([192.168.159.144]:2222)' can't be established. ECDSA key fingerprint is SHA256:9T6E0aufwGnBm7L16GFC9+FFWimqK7uOeRwX4d0nCh4. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '[192.168.159.144]:2222' (ECDSA) to the list of known hosts. root@192.168.159.144's password: Last login: Mon May 11 22:20:23 2020 from 172.16.10.2 [root@inside ~]# ip ad sh 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:73:3a:9e brd ff:ff:ff:ff:ff:ff inet 172.16.10.1/24 brd 172.16.10.255 scope global ens33 valid_lft forever preferred_lft forever inet6 fe80::8646:ee5f:9334:9c2f/64 scope link valid_lft forever preferred_lft forever [root@inside ~]#


参考文章,讲的非常具体并且有具体实验:iptables

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
3年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这