AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1149589
Accepted
avi9526
avi9526
Asked: 2023-12-12 04:44:49 +0800 CST2023-12-12 04:44:49 +0800 CST 2023-12-12 04:44:49 +0800 CST

我可以提高 nftables 规则集语法的可读性吗?它会影响其功能吗?

  • 772

从手册中我不清楚这些命令的功能是否相同:

meta skuid == "root" counter accept
skuid 0 counter accept

还

ct state == { established,  related } counter accept
ct state established,related counter accept

我关于语法的问题是:

  1. 我可以跳过单词meta(似乎在使用 item 时必须跳过它log flags)?
  2. 我可以在任何匹配某些内容的命令中添加 == 符号(为了可读性)吗?
  3. 我可以将列表(项目集)写为item1,item2或不写{ item1, item2 },或者仅用于ct命令吗?
nftables
  • 1 1 个回答
  • 24 Views

1 个回答

  • Voted
  1. Best Answer
    A.B
    2023-12-12T19:53:37+08:002023-12-12T19:53:37+08:00

    要验证两个规则是否相同,甚至超出了显示相同的范围(在涉及多个协议层的极少数情况下,规则可以显示相同的内容,功能相同,但在字节码级别不完全相同,这几乎是一个再现性错误),请使用选项--debug=netlink还将显示发送到内核的字节码。如果字节码相同,则规则相同。

    这是一个交互式示例(使用 nftables 1.0.9。结果可能会根据版本略有变化):

    $ unshare -Urnm
    # nft -V
    nftables v1.0.9 (Old Doc Yak #3)
      cli:      editline
      json:     yes
      minigmp:  no
      libxtables:   yes
    # nft add table t
    # nft add chain t c
    # nft --debug=netlink add rule t c 'meta skuid == "root" counter accept'
    ip t c
      [ meta load skuid => reg 1 ]
      [ cmp eq reg 1 0x00000000 ]
      [ counter pkts 0 bytes 0 ]
      [ immediate reg 0 accept ]
    
    # nft --debug=netlink add rule t c 'skuid 0 counter accept'
    ip t c
      [ meta load skuid => reg 1 ]
      [ cmp eq reg 1 0x00000000 ]
      [ counter pkts 0 bytes 0 ]
      [ immediate reg 0 accept ]
    
    # nft --debug=netlink add rule t c 'ct state == { established,  related } counter accept'
    __set%d t 3 size 2
    __set%d t 0
        element 00000002  : 0 [end] element 00000004  : 0 [end]
    ip t c
      [ ct load state => reg 1 ]
      [ lookup reg 1 set __set%d ]
      [ counter pkts 0 bytes 0 ]
      [ immediate reg 0 accept ]
    
    # nft --debug=netlink add rule t c 'ct state established,related counter accept'
    ip t c
      [ ct load state => reg 1 ]
      [ bitwise reg 1 = ( reg 1 & 0x00000006 ) ^ 0x00000000 ]
      [ cmp neq reg 1 0x00000000 ]
      [ counter pkts 0 bytes 0 ]
      [ immediate reg 0 accept ]
    
    

    可以看出,前两个规则是相同的。Indeed"root"像往常一样由用户空间解析为 uid 0,并且meta关键字是可选的(至少对于这里的版本)。

    最后两条规则即使在功能上相同,也并不相同。On case 使用一组匿名的两个值。但这两个值应该以按位方式组合(即:所有可能的符号都有不同的 2 指数作为值),这就是最后一条规则的作用,而不是扮演,不同的角色。乍一看,我认为第二条ct规则比第一条规则更优化:不需要涉及集合查找。

    仍然使用第一种情况:当使用(一个判决映射而不是一个简单的集合)根据单个规则中的conntrackvmap状态调用不同的判决时。

    无论您选择什么,对于给定的nftables版本,它将始终以一种方式显示:

    # nft -s list ruleset
    table ip t {
        chain c {
            meta skuid 0 counter accept
            meta skuid 0 counter accept
            ct state { established, related } counter accept
            ct state established,related counter accept
        }
    }
    # 
    

    这可能应该是使用的内容,或者最终可能会被使用,只是因为当手动而不是通过工具处理时,转储规则集、编辑它并重新加载它通常是实用的。

    中的情况ct根本无法概括:只有在涉及两个值的幂时才可以完成第二个变体(如果无论如何实现了特定语法支持),以便它们可以按位运算组合:

    # nft describe ct state
    ct expression, datatype ct_state (conntrack state) (basetype bitmask, integer), 32 bits
    
    pre-defined symbolic constants (in hexadecimal):
        invalid                         0x00000001
        new                             0x00000008
        established                     0x00000002
        related                         0x00000004
        untracked                       0x00000040
    # 
    

    一个明显的例子是将 TCP 标志与nftables一起使用:

    # nft describe tcp flags
    payload expression, datatype tcp_flag (TCP flag) (basetype bitmask, integer), 8 bits
    
    pre-defined symbolic constants (in hexadecimal):
        fin                             0x01
        syn                             0x02
        rst                             0x04
        psh                             0x08
        ack                             0x10
        urg                             0x20
        ecn                             0x40
        cwr                             0x80
    # 
    

    所以就像ct:

    # nft --debug=netlink add rule t c 'tcp flags { ack,syn } accept'
    __set%d t 3 size 2
    __set%d t 0
        element 00000010  : 0 [end] element 00000002  : 0 [end]
    ip t c
      [ meta load l4proto => reg 1 ]
      [ cmp eq reg 1 0x00000006 ]
      [ payload load 1b @ transport header + 13 => reg 1 ]
      [ lookup reg 1 set __set%d ]
      [ immediate reg 0 accept ]
    
    # nft --debug=netlink add rule t c 'tcp flags ack,syn accept'
    ip t c
      [ meta load l4proto => reg 1 ]
      [ cmp eq reg 1 0x00000006 ]
      [ payload load 1b @ transport header + 13 => reg 1 ]
      [ bitwise reg 1 = ( reg 1 & 0x00000012 ) ^ 0x00000000 ]
      [ cmp neq reg 1 0x00000000 ]
      [ immediate reg 0 accept ]
    
    # nft --debug=netlink add rule t c 'tcp flags ack|syn accept'
    ip t c
      [ meta load l4proto => reg 1 ]
      [ cmp eq reg 1 0x00000006 ]
      [ payload load 1b @ transport header + 13 => reg 1 ]
      [ bitwise reg 1 = ( reg 1 & 0x00000012 ) ^ 0x00000000 ]
      [ cmp neq reg 1 0x00000000 ]
      [ immediate reg 0 accept ]
    
    # 
    

    最后两条规则(注意使用 进行|按位 OR 运算而不是,内置语法)完全相同。但第一条规则使用匿名集,就像前面的情况一样。在此示例中的所有情况下,多个 TCP 标志中的一个匹配就足以匹配:功能等效。如果需要同时匹配两个标志,则只有第二种情况可用。

    通常,下面的规则需要同时存在两个标志,不能使用匿名集来实现:

    # nft --debug=netlink add rule t c 'tcp flags & (syn|ack) == syn|ack accept'
    ip t c
      [ meta load l4proto => reg 1 ]
      [ cmp eq reg 1 0x00000006 ]
      [ payload load 1b @ transport header + 13 => reg 1 ]
      [ bitwise reg 1 = ( reg 1 & 0x00000012 ) ^ 0x00000000 ]
      [ cmp eq reg 1 0x00000012 ]
      [ immediate reg 0 accept ]
    
    
    # nft list ruleset
    [...]
            tcp flags syn,ack / syn,ack accept
    [...]
    

    注意:以这种方式组合标志是没有意义的,ct因为与 TCP 标志相反,一次只应该存在一个标志(给定的数据包不能同时具有多个conntrack状态)。

    • 2

相关问题

  • 在使用 Nftables 访问不同网络的不同接口上伪装的 NAT

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve