English | 简体中文
Netfilter允许数据包在多个表和链进行过滤、转换和修改,其内核态通过提供setsockopt和getsockopt的多个socket option给上层以增删改查的能力,但这些socket option因为没有标准定义并不直接开放给开发者,对于c/c++开发者来说,可以考虑libiptc
来与netfilter交互,不过据netfilter官方描述,libiptc从不(NEVER)意味着对公众开放。因此对于go开发者来说,使用系统调用封装socket或使用cgo封装libiptc都不是更好的选择,按照netfilter的说明,更建议开发者使用iptables, ebtables和arptables工具来操作数据包。
Go-xtables就是对iptables, ebtables和arptables工具进行了封装,相比较其他库,额外提供ebtables和arptables的能力,全特性支持(对所有在man手册提及的扩展能力进行了封装),对外提供了链式调用和option模式,完整继承了几个tables里对用户的抽象,非常方便。
查看 iptables godoc 和 ebtables godoc 来了解70+ match
能力,50+ target
能力以10+ option
能力。
Matches:
- ✅ MatchTypeAddrType
- ✅ MatchTypeAH
- ✅ MatchTypeBPF
- ✅ MatchTypeCGroup
- ✅ MatchTypeCluster
- ✅ MatchTypeComment
- ✅ MatchTypeConnBytes
- ✅ MatchTypeConnLabel
- ✅ MatchTypeConnLimit
- ✅ MatchTypeConnMark
- ✅ MatchTypeConnTrack
- ✅ MatchTypeCPU
- ✅ MatchTypeDCCP
- ✅ MatchTypeDestination
- ✅ MatchTypeDevGroup
- ✅ MatchTypeDSCP
- ✅ MatchTypeDst
- ✅ MatchTypeECN
- ✅ MatchTypeESP
- ✅ MatchTypeEUI64
- ✅ MatchTypeFrag
- ✅ MatchTypeHashLimit
- ✅ MatchTypeHBH
- ✅ MatchTypeHelper
- ✅ MatchTypeHL
- ✅ MatchTypeICMP
- ✅ MatchTypeInInterface
- ✅ MatchTypeIPRange
- ✅ MatchTypeIPv4
- ✅ MatchTypeIPv6
- ✅ MatchTypeIPv6Header
- ✅ MatchTypeIPVS
- ✅ MatchTypeLength
- ✅ MatchTypeLimit
- ✅ MatchTypeMAC
- ✅ MatchTypeMark
- ✅ MatchTypeMH
- ✅ MatchTypeMultiPort
- ✅ MatchTypeNFAcct
- ✅ MatchTypeOSF
- ✅ MatchTypeOutInterface
- ✅ MatchTypeOwner
- ✅ MatchTypePhysDev
- ✅ MatchTypePktType
- ✅ MatchTypePolicy
- ✅ MatchTypeProtocol
- ✅ MatchTypeQuota
- ✅ MatchTypeRateEst
- ✅ MatchTypeRealm
- ✅ MatchTypeRecent
- ✅ MatchTypeRPFilter
- ✅ MatchTypeRT
- ✅ MatchTypeSCTP
- ✅ MatchTypeSet
- ✅ MatchTypeSocket
- ✅ MatchTypeSource
- ✅ MatchTypeSRH
- ✅ MatchTypeState
- ✅ MatchTypeStatistic
- ✅ MatchTypeString
- ✅ MatchTypeTCP
- ✅ MatchTypeTCPMSS
- ✅ MatchTypeTime
- ✅ MatchTypeTOS
- ✅ MatchTypeTTL
- ✅ MatchTypeU32
- ✅ MatchTypeUDP
Targets:
- ✅ TargetTypeAccept
- ✅ TargetTypeDrop
- ✅ TargetTypeReturn
- ✅ TargetTypeJumpChain
- ✅ TargetTypeGotoChain
- ✅ TargetTypeAudit
- ✅ TargetTypeCheckSum
- ✅ TargetTypeClassify
- ✅ TargetTypeClusterIP
- ✅ TargetTypeConnMark
- ✅ TargetTypeConnSecMark
- ✅ TargetTypeCT
- ✅ TargetTypeDNAT
- ✅ TargetTypeDNPT
- ✅ TargetTypeDSCP
- ✅ TargetTypeECN
- ✅ TargetTypeHL
- ✅ TargetTypeHMark
- ✅ TargetTypeIdleTimer
- ✅ TargetTypeLED
- ✅ TargetTypeLog
- ✅ TargetTypeMark
- ✅ TargetTypeMasquerade
- ✅ TargetTypeMirror
- ✅ TargetTypeNetmap
- ✅ TargetTypeNFLog
- ✅ TargetTypeNFQueue
- ✅ TargetTypeNoTrack
- ✅ TargetTypeRateEst
- ✅ TargetTypeRedirect
- ✅ TargetTypeReject
- ✅ TargetTypeSame
- ✅ TargetTypeSecMark
- ✅ TargetTypeSet
- ✅ TargetTypeSNAT
- ✅ TargetTypeSNPT
- ✅ TargetTypeSYNProxy
- ✅ TargetTypeTCPMSS
- ✅ TargetTypeTCPOptStrip
- ✅ TargetTypeTEE
- ✅ TargetTypeTOS
- ✅ TargetTypeTProxy
- ✅ TargetTypeTrace
- ✅ TargetTypeTTL
- ✅ TargetTypeULog
- 简单易用
- 多tables支持(iptables, ebtables, arptables)
- 全特性支持(全量matches, options, watchers和其他extensions)
- 链式调用(任意排序,可复用对象)
- Dryrun
- 可控日志(默认日志或logrus等)
package main
import (
"log"
"github.com/singchia/go-xtables/iptables"
"github.com/singchia/go-xtables/pkg/network"
)
func main() {
ipt := iptables.NewIPTables().Table(iptables.TableTypeFilter).Chain(iptables.ChainTypeINPUT).MatchProtocol(false, network.ProtocolTCP)
// allow ssh, http and https
err := ipt.MatchMultiPort(iptables.WithMatchMultiPortDstPorts(false, 22, 80, 443)).TargetAccept().Insert()
if err != nil {
log.Fatal(err)
}
// drop others
err = iptables.NewIPTables().Table(iptables.TableTypeFilter).Chain(iptables.ChainTypeINPUT).Policy(iptables.TargetTypeDrop)
if err != nil {
log.Fatal(err)
}
}
iptables.NewIPTables().
Table(iptables.TableTypeFilter).
Chain(iptables.ChainTypeINPUT).
MatchProtocol(false, network.ProtocolTCP).
MatchTCP(iptables.WithMatchTCPDstPort(false, 2432)).
TargetDrop().
Append()
iptables.NewIPTables().
Table(iptables.TableTypeFilter).
Chain(iptables.ChainTypeINPUT).
MatchSource(false, "192.168.1.100").
TargetAccept().
Append()
rules, err := iptables.NewIPTables().
Table(iptables.TableTypeFilter).
Chain(iptables.ChainTypeINPUT).
MatchSource(false, "192.168.1.100").
TargetAccept().
FindRules()
iptables.NewIPTables().Flush()
iptables.NewIPTables().
Table(iptables.TableTypeFilter).
Chain(iptables.ChainTypeINPUT).
MatchProtocol(false, network.ProtocolTCP).
MatchTCP(iptables.WithMatchTCPDstPort(false, 80)).
MatchLimit(iptables.WithMatchLimit(xtables.Rate{10, xtables.Minute})).
TargetAccept().
Append()
iptables.NewIPTables().
Table(iptables.TableTypeMangle).
Chain(iptables.ChainTypePREROUTING).
MatchProtocol(false, network.ProtocolTCP).
MatchTCP(iptables.WithMatchTCPDstPort(false, 2432)).
TargetTEE(net.ParseIP("192.168.1.1")).
Insert()
该示例使用ebtables,请注意该规则作用在linux-bridge
上,请先确保网卡被bridge接管。
ebtables.NewEBTables().
Table(ebtables.TableTypeFilter).
Chain(ebtables.ChainTypeINPUT).
MatchSource(false, "00:11:22:33:44:55").
TargetDrop().
Append()
custom := "SYN_FLOOD"
ipt := iptables.NewIPTables().Table(iptables.TableTypeFilter)
ipt.NewChain(custom)
ipt.Chain(iptables.ChainTypeINPUT).
MatchProtocol(false, network.ProtocolTCP).
MatchTCP(iptables.WithMatchTCPSYN(false)).
TargetJumpChain(custom).
Append()
userDefined := iptables.ChainTypeUserDefined
userDefined.SetName(custom)
rate := xtables.Rate{1, xtables.Second}
ipt.Chain(userDefined).
MatchLimit(
iptables.WithMatchLimit(rate),
iptables.WithMatchLimitBurst(3)).
TargetReturn().
Append()
ipt.Chain(userDefined).
TargetDrop().
Append()
iptables.NewIPTables().
Table(iptables.TableTypeFilter).
Chain(iptables.ChainTypeINPUT).
MatchProtocol(false, network.ProtocolICMP).
MatchICMP(false, network.ICMPType(network.EchoRequest)).
TargetDrop().
Append()
ipt := iptables.NewIPTables().Table(iptables.TableTypeFilter)
ipt.Chain(iptables.ChainTypeINPUT).
MatchInInterface(false, "lo").
TargetAccept().
Append()
ipt.Chain(iptables.ChainTypeINPUT).
MatchState(iptables.ESTABLISHED | iptables.RELATED).
TargetAccept().
Append()
ipt.Chain(iptables.ChainTypeINPUT).
MatchProtocol(false, network.ProtocolTCP).
MatchTCP(iptables.WithMatchTCPDstPort(false, 22)).
TargetAccept().
Append()
ipt.Chain(iptables.ChainTypeINPUT).Policy(iptables.TargetTypeDrop)
ipt.Chain(iptables.ChainTypeFORWARD).Policy(iptables.TargetTypeDrop)
ipt.Chain(iptables.ChainTypeOUTPUT).Policy(iptables.TargetTypeAccept)
从Linux内核版本4.18开始,nftables成为内核的一部分,并逐步替代iptables。因此,使用linux 4.18以及更高版本的发行版通常会使用nftables而不是iptables。由于nftables并不完全兼容iptables,如果还想要继续使用go-xtables,在使用这些发行版时最好能够切换到iptables以继续使用。
以下发行版需要注意兼容性:
- Debian 10(Buster) 及更高版本
- Ubuntu 18.04(Bionic Beaver) 及更高版本
- Centos 8 及更高版本
- Fedora 18 及更高版本
- OpenSUSE Leap 15.2 及更高版本
- Arch Linux
当前go-xtables处于生产就绪阶段,如果你发现任何Bug,请随意提出Issue,项目Maintainers会及时响应相关问题。
如果你希望能够提交Feature,更快速解决项目问题,满足以下简单条件下欢迎提交PR:
- 代码风格保持一致
- 每次提交一个Feature
- 提交的代码都携带单元测试
- 通过CI构建
经过Code review没问题,就会合入代码。
Released under the Apache License 2.0