Golang中go-iptables的Insert方法使用问题求助

Golang中go-iptables的Insert方法使用问题求助 大家好,

我是Go语言的新手,请多包涵。

我正在尝试使用go-iptables包,但在使用Insert函数时遇到了问题。我在应用程序中编写了一个函数,该函数接收一个net.IP和一个端口号的string作为参数。我希望这个函数能够插入一条防火墙规则,但它没有正常工作。

以下是我的函数:

func AddFirewallRule(sourceIP net.IP, port string) {

  // 从配置中获取INPUT链
  byteValue := config.GetConfig()
  var inputChain config.Chain
  json.Unmarshal(byteValue, &inputChain)

  var chain = inputChain.InputChain

  // 构建iptables规则规范
  var rulespec string = "--protocol tcp -m tcp -s " + sourceIP.String() + " --dport " + port + " -j ACCEPT"

  // 创建新的IPTables对象
  ipt, err := iptables.New()
  if err != nil {
        fmt.Println(err)
  }

  // 从"filter"表中获取链列表
  chainList, err := ipt.ListChains("filter")
  if err != nil {
	  fmt.Printf("链列表获取失败: %s", err)
  }

  // 检查input_chain是否在chainList中,如果在则插入规则
  for i := 0; i < len(chainList); i++ {
	  if chainList[i] == chain {
		  fmt.Println("找到链:", chain, "-> 为", sourceIP.String(), "插入规则\n")

		  err = ipt.Insert("filter", chain, 1, rulespec)
		  if err != nil {
			  fmt.Println(err)
		  }

		  break
	  }
  }
}

以下是我遇到的错误:

找到链: ufw-before-input → 为 10.0.0.100 插入规则

运行 [/sbin/iptables -t filter -I ufw-before-input 1 --protocol tcp -m tcp -s 10.0.0.100 --dport 22 -j ACCEPT --wait]: 退出状态 2: iptables v1.6.0: 未知选项“–protocol tcp -m tcp -s 10.0.0.100 --dport 22 -j ACCEPT” 尝试 `iptables -h’ 或 ‘iptables --help’ 获取更多信息。

从命令行运行 /sbin/iptables -t filter -I ufw-before-input 1 --protocol tcp -m tcp -s 10.0.0.100 --dport 22 -j ACCEPT --wait 可以正常插入规则。有人能看出这里有什么明显的错误吗?我有点困惑,而且这个包的文档也很不完善。

提前感谢!


更多关于Golang中go-iptables的Insert方法使用问题求助的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

感谢,做得很好!

更多关于Golang中go-iptables的Insert方法使用问题求助的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


rulespec 只是一个字符串,整个字符串会被视为一个参数。你必须这样写:

err = ipt.Insert("filter", chain, 1, "--protocoll", "tcp", "-s", sourceIP.String(), .... 以及其他参数)

参考这个 go-iptables/iptables/iptables_test.go at main · coreos/go-iptables · GitHub

先生,您真是位绅士兼学者!这解决了我的问题。供参考,以下是更新后的函数:

func AddFirewallRule(sourceIP net.IP, port string) {

  // Get INPUT chain from config
  byteValue := config.GetConfig()
  var inputChain config.Chain
  json.Unmarshal(byteValue, &inputChain)

  var chain = inputChain.InputChain

  // Create new IPTables object
  ipt, err := iptables.New()
  if err != nil {
	  fmt.Println(err)
  }

  // Get a list of chains from the "filter" table
  chainList, err := ipt.ListChains("filter")
  if err != nil {
	  fmt.Printf("Chain listing failed: %s", err)
  }

  // Check if input_chain is in the chainList, insert rule if it is.
  for i := 0; i < len(chainList); i++ {
	  if chainList[i] == chain {
		  fmt.Println("Found chain:", chain, "-> Inserting rule for", sourceIP.String(), "\n")

		  err = ipt.Insert("filter", chain, 1, "--protocol", "tcp", "-s", sourceIP.String(), "--dport", port, "-j", "ACCEPT")
		  if err != nil {
			  fmt.Println(err)
		  }

		  break
	 }
  }
}

问题在于 go-iptables 库的 Insert 方法期望规则规范是以字符串切片([]string)的形式提供的,而不是单个字符串。你需要将规则拆分为独立的参数。

以下是修正后的代码:

func AddFirewallRule(sourceIP net.IP, port string) {
    // 从配置中获取INPUT链
    byteValue := config.GetConfig()
    var inputChain config.Chain
    json.Unmarshal(byteValue, &inputChain)

    var chain = inputChain.InputChain

    // 构建iptables规则规范为字符串切片
    rulespec := []string{
        "--protocol", "tcp",
        "-m", "tcp",
        "-s", sourceIP.String(),
        "--dport", port,
        "-j", "ACCEPT",
    }

    // 创建新的IPTables对象
    ipt, err := iptables.New()
    if err != nil {
        fmt.Println(err)
        return
    }

    // 从"filter"表中获取链列表
    chainList, err := ipt.ListChains("filter")
    if err != nil {
        fmt.Printf("链列表获取失败: %s", err)
        return
    }

    // 检查input_chain是否在chainList中,如果在则插入规则
    for i := 0; i < len(chainList); i++ {
        if chainList[i] == chain {
            fmt.Println("找到链:", chain, "-> 为", sourceIP.String(), "插入规则\n")

            err = ipt.Insert("filter", chain, 1, rulespec...)
            if err != nil {
                fmt.Println(err)
            }

            break
        }
    }
}

关键修改:

  1. rulespec 从字符串改为字符串切片 []string
  2. 每个iptables参数都作为独立的数组元素
  3. 在调用 Insert 方法时使用 rulespec... 来展开切片参数

这样生成的iptables命令就会正确解析各个参数,而不是将整个规则作为一个参数传递。

回到顶部