netfilter 和 iptables

本文详细介绍了iptables的工作原理,包括netfilter框架、iptables的钩子、表、链及规则,阐述了如何通过iptables进行数据包过滤和网络地址转换(NAT)。并通过实战示例展示了如何配置iptables以实现NAT转发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. netfilter

1. 什么是entfilter 和 iptables

  • netfilter指整个项目名
  • 在这个项目里面,netfilter特指内核中的netfilter框架,
  • iptables指用户空间的配置工具。
  • netfilter在协议栈中添加了5个钩子,允许内核模块在这些钩子的地方注册回调函数,这样经过钩子的所有数据包都会被注册在相应钩子上的函数所处理,包括修改数据包内容、给数据包标记 或者丢掉数据包等。
  • netfilter框架负责维护钩子上注册的处理函数或者模块,以及它们的优先级。
  • iptables是用户空间的一个程序,通过netlink和内核的netfilter框架打交道,负责往钩子上配置回调函数。
  • netfilter框架负责在需要的时候动态加载其它的内核模块, 有 ip_conntrack、nf_conntrack、NAT subsystem等。

通常使用中 可能会感觉iptables代表了整个项目, 代表了防火墙, 但是在开发者中, 可能netfilter 才是整个项目.

2. netfilter 钩子 (hooks)

  • 内核协议栈中,有5个跟netfilter有关的钩子,数据包经过每个钩子时,都会检查上面是否注册有函数,如果有的话,就会调用相应的函数处理该数据包.

2.1 5个钩子

  • NF_IP_PRE_ROUTING:
    • 接收的数据包刚进来,还没有经过路由选择,即还不知道数据包是要发给本机还是其它机器。
  • NF_IP_LOCAL_IN:
    • 已经经过路由选择,并且该数据包的目的IP是本机,进入本地数据包处理流程。
  • NF_IP_FORWARD:
    • 已经经过路由选择,但该数据包的目的IP不是本机,而是其它机器,进入forward流程。
  • NF_IP_LOCAL_OUT:
    • 本地程序要发出去的数据包刚到IP层,还没进行路由选择。
  • NF_IP_POST_ROUTING:
    • 本地程序发出去的数据包,或者转发(forward)的数据包已经经过了路由选择,即将交由下层发送出去。

2.2 位置图

                      |
                      |   In
                      ↓
             +-----------------+ 
             | IP_PRE_ROUTING  | 
             +-----------------+    
                      |
                      ↓
             +_________________+            +---------------+
             |  Route table    | ---------> | IP_LOCAL_IN   |
             +_________________+            +---------------+
                      |                             |
                      |                             
                      |                     +_______________+
                      |                     |     local     |
                      |                     +_______________+
                      |                             |
                      |                             |
                      ↓                             ↓   
             +---------------+              +---------------+
             |  IP_FORWARD   |              | IP_LOCAL_OUT  |
             +---------------+              +---------------+
                      |                             |
                      |-----------------------------+
                      |                             
                      ↓                             
             +-----------------+
             | IP_POST_ROUTING |
             +-----------------+
                      |
                      | Out
                      ↓

  • 上面显示的可以看出, 一个数据包只会经过 下面三种路径的一种.
    • 本机收到的IP是本机的数据包: IP_PRE_ROUTING -> IP_LOCAL_IN
    • 本机收到目的地IP 不是本地的: IP_PRE_ROUTING -> IP_FORWARD -> IP_POST_ROUTING
    • 本机发出的数据包: IP_LOCAL_OUT -> IP_POST_ROUTING

2.3 iptables 中的表(tables)

  • iptables 是使用表(tables) 来分配管它的规则的(rule) , 根据rule 的作用划分了几个表, 比如用啦过滤数据包 的rule 放在了 filter 表中, 用来处理 地址转换的 rule 放在了 nat 表中, 其中rule 就是 应用在 netfilter 钩子上的函数, 用来修改 数据包的内容或者过滤数据包, 目前 iptables 支持的表有:
  1. filter

    • filter 表内的 rule 用来过滤数据, 用来控制让那些数据可以通过, 那些数据不可以通过.
  2. nat

    • nat 表内的 rule 用来控制网络地址转换, 控制要不要进行地址过滤, 以及如何修改源地址和目的地址, 从而影响数据包的路由, 达到连通的目的, 是路由器的必备功能.
  3. Mangle

    • 该表内的 rule 用于修改IP数据包头, 如修改 TTL, 同时也可以为数据包添加一些标记, 便于后续其他模块 对数据包处理,( 添加标记是指 网内核skb 结构中添加, 而不是给IP数据包加东西)
  4. raw 在 natfilter 里面有个 connection tracking功能, 用来追踪所有的连接, 而且可以看到 raw 表内的 rule 功能给数据包打的标记, 从而控制那些数据包不被 connection tracking 追踪

  5. security 在cnetos7 中新加的, 用于设置和 SElinux 相关, 主要设置 一些SELinux 标记, 便于和 SELinux 相关的模块来处理数据包.

2.4 链

  • 根据不同功能的 rule 在不同的表内, iptables 将表中的rule 在分类, 让 rule 属于 不同的链(chain), 有 chain来决定什么时候触发 chain 上的 那些rule.

  • iptables 的5个链分别对应5个钩子:

    1. PREROUTING:
      • 数据包经过NF_IP_PRE_ROUTING 会触发 chain 上的rule
    2. INPUT
      • 数据包经过 IP_LOCAL_IN 时会触发 chain 上的 rule
    3. FORWARD
      • 数据包经过 IP_FORWARD 时 会触发 chain 的rule
    4. OUTPUT
      • 数据包经过 IP_LOCAL_OUT时 会触发chain 的rule
    5. POSTROUTING
      • 数据包经过 IP_POST_ROUTING 时会触发 chain 的rule
  • 每个表都可以有多个 chains , 但是并不表示每个表都包含了多个 chains, 应为有些表上的 chains 上时没有意义的, 如 raw 上只有 connection tracking 有意义.

2.5 每个表包含的 chain

                                    |
                                    |   In
                                    |
                                    ↓                 ++---------------------++
                           +-----------------+        ||  raw                ||
                           | IP_PRE_ROUTING  | ------>||  (connection trak)  ||
                           +-----------------+        ||  mangle             ||
                                    |                 ||  nat (DNAT)         ||
                                    |                 ++---------------------++
                                    ↓                                                 ++-------------++
                           +_________________+            +---------------+           || mangle      ||
                           |  Route table    | ---------> | IP_LOCAL_IN   | --------> || filter      ||
                           +_________________+            +---------------+           || security    ||
                                    |                             |                   || nat {SNAT}  ||
                                    |                             |                   ++-------------++
                                    |                             |
                                    |                     +_______________+
                                    |                     |     local     |
                                    |                     +_______________+
                                    |                             |                   ++---------------------++
                                    |                             |                   ||  raw                ||
         ++----------++             ↓                             ↓                   ||  (connection track) ||
         ||  mangle  ||    +---------------+              +---------------+           ||  mangle             ||
         ||  filter  || <--|  IP_FORWARD   |              | IP_LOCAL_OUT  | --------> ||  nat(DNAT)          ||
         || security ||    +---------------+              +---------------+           ||  filter             ||
         ++----------++             |                             |                   ||  security           ||
                                    |-----------------------------+                   ++---------------------++
                                    |                             
                                    ↓                 ++----------++
                           +-----------------+        ||mangle    ||
                           | IP_POST_ROUTING | -----> ||nat(SNAT) ||
                           +-----------------+        ||          ||
                                    |                 ++----------++
                                    | Out
                                    ↓


  • 这里以 NF_IP_PRE_ROUTING 为例:
    • 数据包到了这里, 首先会执行raw 表中的 PREROUTING (chain) 里面的 rule,
    • 然后执行 connection tracking, 接着执行 managle 表中 PREROUTING 中的 rule,
    • 最后执行 nat(DNAT) 表中的 PREROUTING 里的rule
  • 以 filter 为例:
    • 只能注册在 IP_LOCAL_IN, IP_FORWARD, 和 IP_LOCAL_OUT中, 所以只支持 INPUT, FORWARD 和OUTPUT 三个 chain

3. iptables 中的规则(Rules)

  • rule 存放在表的忒丁 chain 上, 每个 rule 都有两部分信息.
    1. Matching
      • matching 是如何匹配一个数据包, 匹配条件很多, 比如, 协议类型, 源/目的 地址, 源/目的 端口, in/out 接口, 保内的数据以及连接状态.
    2. Targets
      • target 是用于匹配到数据包后 如何做处理
        • DROP: 丢弃数据包, 不做任何处理
        • RETURN: 跳出当前chaing, 该 chain内的后续rule 不执行
        • QUEUE: 将数据包放入用户空间, 由用户程序处理
        • ACCEPT: 同意数据包通过, 执行后续 rule
        • 跳转到其他用户自定义的 chain 执行

4. iptables 语法

4.1 语法和选项

  • 语法: iptables [-t table] OPTION [chain] rule-specification
    • -t table 指定表名
    • OPTION 指定选项操作
    • chain 指定链chain
    • rule-speci 规则说明

4.2 选项

  • table
filter:     默认表( 不使用-t 指定表时的默认), 包含的链有 INPUT, FORWARD, OUTPUT 
nat:        在创建新的连接时, 会查看此表. 包含的链有 PREROUTING, OUTPUT, POSTROUTING
mangle:     用于修改 数据包, 包含的链有: PREROUTING, OUTPUT, INPUT, FORWARD, POSTROUTING
raw:       该表用于和 NOTRACCK 配合设置耿总路由的豁免, 具有需要较高的优先级的钩子上注册, 因此 ip conntrack 或者其他表调用之前,  内置的链有 PREOUTING, OUTPUT
security:  用于设置强制访问网络规则, 配合 selinux 规则使用.
  • OPTIONS:
# 规则相关
-A:     --append 追加规则到所选择的链的末端, 当 源/目的 地址为多个时, 会为每个可能的地址配备一个规则.
-I:     --insert 再选中的链中插入规则, 可以选择规则号, 如果没有指定则默认插入到 第一条
-D      --delete 删除一条或多规则, 可以删除规则号, 或者匹配规则
-C      --check 检查选中链 是否存在和规范的规则,
-R      --replace 替换选中链中的 规则, 如果 源/目的 地址有多个, 会设置失败, 规则号从 1开始

# 链相关
-N      --new-chain chain   创建一个新的用户定义链.
-L      --list              列出选中链的所有规则, 如果没有选择链, 则列出所有, 常用于配合 -n (不使用 dns解析),
-F      --flush             清空选中链的 所有规则
-X      --delete-chain      删除用户自定义的空链.
-E      --rename-chain      重命名链
-P      --policy chain      指定链上到的 默认策略(ACCEPT, DROP, REJECT)

# 重要参数
-i:     --in-interface  指定接受 数据包的接口, (仅用作INPUT, FORWARD, PREROUTING 链), 可以使用 ! 符号表示取反, 
-o      --out-interface 指定发出数据包的接口 (作用 OUTPUT, FORWARD, OUTROUTING 链), 可用 ! 取反
-p:     --protocol      指定协议, 
        --sport:            源端口
        --dport:            目的端口
        --icmp-type:        指定协议为 icmp 的类型,(Ping)
-s:     --source address    指定该条规则的定的源, 可以是 主机名, 网络名, ip网段(掩码), 也可以是 ip地址
-d:     --destination addr 指定该条规则的 目的地, 地址和 source 一样
-m:     --match match   指定要使用的匹配项, 测试特定的扩展模块, 匹配的合集构成了条件
-j:     --jump target   指定给你规则目标, 即, 如果匹配成功, 如何去做, 目标可以是用户定义的链, 或者一个扩展.
-g:     --goto chain    指定用户的 链中继续处理 和 jump 不同, 汇报不会继续.


# 其他选项
-v:     --verbose   更详细的显示
-w:     --wait  设置抓用锁, 等待时间
-n:     --numeric 数字输出, ip和 端口号 使用 数字显示
  • -m 指定匹配模块以及扩扎模块

mulitiport:     指定多端口, 最大15个, 端口可以是 N-M,或范围, 这些端口只能是同一个协议下的. 如 udp, tcp, dccp, sctp
            --dport     目的端口
            --sport     源端口
iprange:        指定ip范围 
                --src-range 192.168.1.100-192.168.1.200  # 范围内的源ip
                --dest-range

time:          如果分组到达时间在给定范围内, 则匹配, 所有选项都可以设置,
                该项可以设置定时允许访问网络, 定时关闭访问.
                --datestart hh:mm[:ss]      开始时间
                --datestop hh:mm[:ss]           结束时间

                --monthdays:    指定每月的 day1,day2... 通过匹配
                --weekdays:     指定每周的 day1, day2...  通过匹配


icmp:           如果协议是icmp , 则可以用这个选项
            --icmp-type {type[/code] |typename}
                允许指定ICMP烈性, 可以是数字类型, 名称, 代码, 或二者ICMP类型之一 iptables -p icmp -h

mac:            源端mac 匹配
  
limit:          限制, 该模块用作有限速率匹配,  可以结合日志做限速日志,
            --limit 速率[秒/分/时/天][second/minute/hour/day]
                    最大平均速率, 指定值, 默认是3小时

            --limit-burst NUM
                    匹配最大的初始分组, 当达到上面设置的值, 将可以突破 NUM 次

hashlimit:      hashlimit 是使用hash 算法来记录匹配一组连接的速率. 
                分组可以由每个主机组(源/目的 地址) 和/或 端口来匹配.
                可以使用N package.

length:         用与匹配长度.

string:         对报文中的应用层数据做字符串模式匹配检测, (通过算法实现)
            --algo(bm|kmp):     字符匹配查找时使用的算法
            --string 'STRING'   查找的字符
            --hex-string "HEX_STRING" : 使用16进制格式

connlimit:      每个IP并发连接数量限制
            --connlimit-upto n  连接数小于 n 匹配
            --connlimit-above n 连接数大于 n 匹配

state:          追踪请求和相应之间报文状态:
                5种状态: 
                    INVALID: 无法识别的连接
                    ESTABLISHED 已建立的连接
                    NEW,        新连接请求
                    RELATED,    相关联的连接 的一个新请求 
                    UNTRACKED   未追踪的连接
                规则:
                    对进入的 ESTABLISHED 都应该放行
                    对出去的 ESTABLISHED 都应该放行
                    检查管理 进入状态的 NEW 连接
                    拒绝 进出 的 INVAIED 


ipvs:           匹配ipvs 连接特性
            --ipvs:     分组属于ipvs 连接
            --vproto proto :    匹配vip 协议, 按 编号或名称, 如 TCP
            --vaddr:    vip 地址,
            --vport:    匹配vip 端口号
            --vdir:     vip 报文流向
            --vmethod:  ipvs 转发方式
  • 处理动作
ACCEPT:     允许数据包通过
DROP:       丢弃数据包, 不回应
REJECT:     拒绝数据包通过, 会返回响应信息
LOG:        在日志中记录信息, 并放给下一个规则
QUEUE:      防火墙将数据包交给用户空间
RETURN:     防火墙执行当前链的 后续 Rule, 并返回到调用链
REDIRECT:   端口从定向
MARK:       做防火墙标记
DNAT:       目标地址转化
SNAT:       源地址转换
MASQUEREAD: 地址伪装

5. iptables 实战示例

  1. 查看当前防火墙状态

  1. 首先为ssh 端口开放

  1. 此时可以看到默认规则是accept, 将其改为 DROP 然后测试

  1. 开放 TCP 的 80端口

  • 此时会发现由于设置了 -P OUTPUT DROP 所以本机无法建立新的连接.
  • 所以需要设置 -P OUTPUT ACCEPT, 不过此处我使用了 -m state --state NEW,ESTABLISHED -j ACCEPT 对新建立的连接和 已建立的连接,放行

  1. 不让其他主机ping 本机, 但是本机可以ping 其他地址
  • 这里需要准备规则有
      1. 禁止其他地址的 icmp 协议进入, 或者本机 INPUT表默认是 DROP.
      1. 本机 OUTPUT 需要允许 ICMP协议包, 或者允许新建的连接和已建立的连接 (state NEW,ESTABLISHED)
      • -A OUTPUT -p icmp -j ACCEPT

6. iptables nat 转发实例

6.1 环境

  • 网络:

    • 外网: 192.168.10.0/24
    • 内网: 192.168.20.0/24
  • 服务端:

    • 外网IP: 192.168.10.11/24
    • 内网IP: 192.168.20.11/24
  • 客户端:

    • IP: 192.168.20.3/24
  • 服务机

  • 客户机

6.2 配置操作

  1. 服务端开启内核的 ip 转发
  2. 需要将服务端的 内网接入数据包配置转发,
  3. 将客户端的 默认路由设置为 服务端的内网IP

6.3 操作

  1. 服务端开启内核的转发
[root@node10011 ~]# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf 
[root@node10011 ~]# grep forward /etc/sysctl.conf 
net.ipv4.ip_forward = 1
[root@node10011 ~]# sysctl -p
-------------------
# 或临时生效
[root@node10011 ~]# echo 1 >  /proc/sys/net/ipv4/ip_forward
  1. 添加IP 转发规则

  • iptables -t nat -I POSTROUTING -d 192.168.20.0/24 -j ACCEPT --to 192.168.10.11

  1. 客户端添加默认路由信息
[fangfc@node10003 ~]$ ip route
169.254.0.0/16 dev eno33554960  scope link  metric 1003 
192.168.20.0/24 dev eno33554960  proto kernel  scope link  src 192.168.20.3 
[fangfc@node10003 ~]$ sudo ip route add default via 192.168.20.11 dev eno33554960
[fangfc@node10003 ~]$ 
[fangfc@node10003 ~]$ ip route
default via 192.168.20.11 dev eno33554960 
169.254.0.0/16 dev eno33554960  scope link  metric 1003 
192.168.20.0/24 dev eno33554960  proto kernel  scope link  src 192.168.20.3 
  • 添加DNS
    • vi /etc/resolv.conf

  1. 测试

END

转载于:https://my.oschina.net/nikoF/blog/2877831

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值