From a6a456aecb7dfb5c8413a2984fe92aaae3ad7662 Mon Sep 17 00:00:00 2001 From: SunBK201 Date: Thu, 13 Nov 2025 02:31:44 +0800 Subject: [PATCH] feat: use new tcp reset option feature --- src/internal/server/netlink/iptables.go | 14 +++++- src/internal/server/netlink/nftables.go | 64 +++++++++++++++++++++---- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/internal/server/netlink/iptables.go b/src/internal/server/netlink/iptables.go index efdbaf0..fd1be09 100644 --- a/src/internal/server/netlink/iptables.go +++ b/src/internal/server/netlink/iptables.go @@ -33,6 +33,13 @@ var RuleIP = []string{ "--queue-bypass", } +var RuleRstTimestamp = []string{ + "-p", "tcp", + "--tcp-option", "8", + "-j", "TCPOPTSTRIP", + "--strip-options", "timestamp", +} + func (s *Server) iptSetup() error { ipt, err := iptables.NewWithProtocol(iptables.ProtocolIPv4) if err != nil { @@ -79,7 +86,12 @@ func (s *Server) IptSetTTL(ipt *iptables.IPTables) error { } func (s *Server) IptDelTCPTS(ipt *iptables.IPTables) error { - err := ipt.Append(table, chain, RuleDelTCPTS...) + err := ipt.Append(table, chain, RuleRstTimestamp...) + if err == nil { + return nil + } + + err = ipt.Append(table, chain, RuleDelTCPTS...) if err != nil { return err } diff --git a/src/internal/server/netlink/nftables.go b/src/internal/server/netlink/nftables.go index ee0d402..992b18a 100644 --- a/src/internal/server/netlink/nftables.go +++ b/src/internal/server/netlink/nftables.go @@ -6,6 +6,7 @@ import ( "context" "fmt" + "github.com/sirupsen/logrus" "sigs.k8s.io/knftables" ) @@ -52,8 +53,8 @@ func (s *Server) nftCleanup() error { func (s *Server) NftSetTTL(tx *knftables.Transaction, table *knftables.Table) { chain := &knftables.Chain{ Name: "TTL64", - Type: knftables.PtrTo(knftables.FilterType), Table: table.Name, + Type: knftables.PtrTo(knftables.FilterType), Hook: knftables.PtrTo(knftables.PostroutingHook), Priority: knftables.PtrTo(knftables.ManglePriority), } @@ -69,16 +70,45 @@ func (s *Server) NftSetTTL(tx *knftables.Transaction, table *knftables.Table) { func (s *Server) NftDelTCPTS(tx *knftables.Transaction, table *knftables.Table) { chain := &knftables.Chain{ - Name: "HELPER_QUEUE", - Type: knftables.PtrTo(knftables.FilterType), + Name: "DEL_TCPTS", Table: table.Name, + Type: knftables.PtrTo(knftables.FilterType), + Hook: knftables.PtrTo(knftables.PostroutingHook), + Priority: knftables.PtrTo(knftables.ManglePriority), + } + tx.Add(chain) + var rule *knftables.Rule + if resetOptionAvailable() { + rule = &knftables.Rule{ + Chain: chain.Name, + Rule: knftables.Concat( + "tcp option timestamp exists", + "counter reset tcp option timestamp", + ), + } + } else { + rule = &knftables.Rule{ + Chain: chain.Name, + Rule: knftables.Concat( + "tcp flags syn", + fmt.Sprintf("counter queue num %d bypass", s.nfqServer.QueueNum), + ), + } + } + tx.Add(rule) +} + +func (s *Server) NftSetIP(tx *knftables.Transaction, table *knftables.Table) { + chain := &knftables.Chain{ + Name: "HELPER_QUEUE", + Table: table.Name, + Type: knftables.PtrTo(knftables.FilterType), Hook: knftables.PtrTo(knftables.PostroutingHook), Priority: knftables.PtrTo(knftables.ManglePriority), } rule := &knftables.Rule{ Chain: chain.Name, Rule: knftables.Concat( - "tcp flags syn", fmt.Sprintf("counter queue num %d bypass", s.nfqServer.QueueNum), ), } @@ -86,20 +116,38 @@ func (s *Server) NftDelTCPTS(tx *knftables.Transaction, table *knftables.Table) tx.Add(rule) } -func (s *Server) NftSetIP(tx *knftables.Transaction, table *knftables.Table) { +func resetOptionAvailable() bool { + const TestName = "UA3F_TEST_RESET" + table := &knftables.Table{ + Name: TestName, + Family: knftables.InetFamily, + } + nft, err := knftables.New(table.Family, table.Name) + if err != nil { + logrus.Errorf("resetOptionAvailable knftables.New: %v", err) + return false + } + tx := nft.NewTransaction() chain := &knftables.Chain{ - Name: "HELPER_QUEUE", - Type: knftables.PtrTo(knftables.FilterType), + Name: TestName, Table: table.Name, + Type: knftables.PtrTo(knftables.FilterType), Hook: knftables.PtrTo(knftables.PostroutingHook), Priority: knftables.PtrTo(knftables.ManglePriority), } rule := &knftables.Rule{ Chain: chain.Name, Rule: knftables.Concat( - fmt.Sprintf("counter queue num %d bypass", s.nfqServer.QueueNum), + "tcp option timestamp exists", + "counter reset tcp option timestamp", ), } + tx.Add(table) tx.Add(chain) tx.Add(rule) + err = nft.Check(context.TODO(), tx) + if err != nil { + logrus.Infof("tcp option reset is not available") + } + return err == nil }