feat: add tcp initial syn window reset

This commit is contained in:
SunBK201 2025-11-29 18:09:15 +08:00
parent b20acf2cbe
commit 6a766e4106
8 changed files with 63 additions and 29 deletions

View File

@ -213,6 +213,10 @@ function M.add_others_fields(section)
local tcpts = section:taboption("others", Flag, "del_tcpts", translate("Delete TCP Timestamps"))
tcpts.description = translate("Remove TCP Timestamp option")
-- TCP Initial Window
local tcp_init_window = section:taboption("others", Flag, "set_tcp_init_window", translate("Set TCP Initial Window"))
tcp_init_window.description = translate("Set the TCP Initial Window to 65535 for SYN packets")
-- IP ID Setting
local ipid = section:taboption("others", Flag, "set_ipid", translate("Set IP ID"))
ipid.description = translate("Set the IP ID to 0 for packets")

View File

@ -18,7 +18,7 @@ start_service() {
local server_mode port bind ua log_level ua_regex partial_replace
local rewrite_mode rewrite_rules
local set_ttl set_ipid del_tcpts
local set_ttl set_ipid del_tcpts set_tcp_init_window
config_get server_mode "main" "server_mode" "TPROXY"
config_get port "main" "port" "1080"
config_get bind "main" "bind" "127.0.0.1"
@ -31,6 +31,7 @@ start_service() {
config_get_bool set_ttl "main" "set_ttl" 0
config_get_bool set_ipid "main" "set_ipid" 0
config_get_bool del_tcpts "main" "del_tcpts" 0
config_get_bool set_tcp_init_window "main" "set_tcp_init_window" 0
procd_open_instance "$NAME"
procd_set_param command "$PROG"
@ -46,6 +47,7 @@ start_service() {
procd_append_param env UA3F_TTL="$set_ttl"
procd_append_param env UA3F_IPID="$set_ipid"
procd_append_param env UA3F_TCPTS="$del_tcpts"
procd_append_param env UA3F_TCP_INIT_WINDOW="$set_tcp_init_window"
procd_set_param respawn
procd_set_param stdout 1

View File

@ -14,4 +14,5 @@ config 'ua3f' 'main'
option set_ttl '0'
option del_tcpts '0'
option set_ipid '0'
option set_tcp_init_window '0'
option rewrite_rules '[{"enabled":false,"type":"DEST-PORT","action":"DIRECT","match_value":"443","rewrite_header":"User-Agent","rewrite_value":"","description":""},{"enabled":true,"type":"KEYWORD","action":"DIRECT","match_value":"MicroMessenger Client","rewrite_header":"User-Agent","rewrite_value":"","description":""},{"enabled":true,"type":"KEYWORD","action":"DIRECT","match_value":"Bilibili Freedoooooom\/MarkII","rewrite_header":"User-Agent","rewrite_value":"","description":""},{"enabled":true,"type":"KEYWORD","action":"DIRECT","match_value":"Valve\/Steam HTTP Client 1.0","rewrite_header":"User-Agent","rewrite_value":"","description":""},{"enabled":true,"type":"KEYWORD","action":"REPLACE","match_value":"Mac","rewrite_header":"User-Agent","description":"","rewrite_value":"FFF"},{"enabled":true,"type":"REGEX","action":"REPLACE","match_value":"(Apple|iPhone|iPad|Macintosh|Mac OS X|Mac|Darwin|Microsoft|Windows|Linux|Android|OpenHarmony|HUAWEI|OPPO|Vivo|XiaoMi|Mobile|Dalvik)","rewrite_header":"User-Agent","description":"","rewrite_value":"FFF"},{"enabled":true,"type":"FINAL","action":"REPLACE","match_value":"","rewrite_header":"User-Agent","description":"Default Fallback Rule","rewrite_value":"FFF"}]'

View File

@ -126,7 +126,7 @@ msgid "Set TTL"
msgstr "固定 TTL"
msgid "Set the TTL 64 for packets"
msgstr "固定数据包的 TTL"
msgstr "固定数据包的 TTL 为 64"
msgid "Connection Statistics"
msgstr "连接实时统计"
@ -257,6 +257,12 @@ msgstr "删除 TCP 时间戳"
msgid "Remove TCP Timestamp option"
msgstr "移除 TCP 时间戳选项"
msgid "Set TCP Initial Window"
msgstr "固定 TCP 初始接收窗口"
msgid "Set the TCP Initial Window to 65535 for SYN packets"
msgstr "固定 TCP SYN 的 TCP 初始接收窗口设置为 65535"
msgid "Set IP ID"
msgstr "固定 IP ID"

View File

@ -27,19 +27,20 @@ const (
)
type Config struct {
ServerMode ServerMode
BindAddr string
Port int
ListenAddr string
LogLevel string
RewriteMode RewriteMode
Rules string
PayloadUA string
UARegex string
PartialReplace bool
SetTTL bool
SetIPID bool
DelTCPTimestamp bool
ServerMode ServerMode
BindAddr string
Port int
ListenAddr string
LogLevel string
RewriteMode RewriteMode
Rules string
PayloadUA string
UARegex string
PartialReplace bool
SetTTL bool
SetIPID bool
DelTCPTimestamp bool
SetTCPInitialWindow bool
}
func Parse() (*Config, bool) {
@ -97,6 +98,9 @@ func Parse() (*Config, bool) {
if os.Getenv("UA3F_IPID") == "1" {
cfg.SetIPID = true
}
if os.Getenv("UA3F_TCP_INIT_WINDOW") == "1" {
cfg.SetTCPInitialWindow = true
}
// Parse other options from -o flag
opts := strings.Split(others, ",")

View File

@ -22,7 +22,7 @@ var RuleTTL = []string{
"--ttl-set", "64",
}
var RuleDelTCPTS = []string{
var RuleHookTCPSyn = []string{
"-p", "tcp",
"--tcp-flags", "SYN", "SYN",
"-j", "NFQUEUE",
@ -61,8 +61,8 @@ func (s *Server) iptSetup() error {
}
}
}
if s.cfg.DelTCPTimestamp && !s.cfg.SetIPID {
err = s.IptDelTCPTS(ipt)
if (s.cfg.DelTCPTimestamp || s.cfg.SetTCPInitialWindow) && !s.cfg.SetIPID {
err = s.IptHookTCPSyn(ipt)
if err != nil {
return err
}
@ -83,7 +83,7 @@ func (s *Server) iptCleanup() error {
}
_ = ipt.DeleteIfExists(table, chain, RuleTTL...)
_ = ipt.DeleteIfExists(table, chain, RuleIP...)
_ = ipt.DeleteIfExists(table, chain, RuleDelTCPTS...)
_ = ipt.DeleteIfExists(table, chain, RuleHookTCPSyn...)
if s.cfg.SetTTL {
_ = s.NftCleanup()
}
@ -98,8 +98,8 @@ func (s *Server) IptSetTTL(ipt *iptables.IPTables) error {
return nil
}
func (s *Server) IptDelTCPTS(ipt *iptables.IPTables) error {
err := ipt.Append(table, chain, RuleDelTCPTS...)
func (s *Server) IptHookTCPSyn(ipt *iptables.IPTables) error {
err := ipt.Append(table, chain, RuleHookTCPSyn...)
if err != nil {
return err
}

View File

@ -45,8 +45,8 @@ func (s *Server) Start() (err error) {
slog.Error("s.Firewall.Setup", slog.Any("error", err))
return err
}
slog.Info("Packet modification configuration", slog.Bool("ttl", s.cfg.SetTTL), slog.Bool("tcpts", s.cfg.DelTCPTimestamp), slog.Bool("ipid", s.cfg.SetIPID))
if s.cfg.DelTCPTimestamp || s.cfg.SetIPID {
slog.Info("Packet modification configuration", slog.Bool("ttl", s.cfg.SetTTL), slog.Bool("tcpts", s.cfg.DelTCPTimestamp), slog.Bool("ipid", s.cfg.SetIPID), slog.Bool("tcp_init_window", s.cfg.SetTCPInitialWindow))
if s.cfg.DelTCPTimestamp || s.cfg.SetTCPInitialWindow || s.cfg.SetIPID {
return s.nfqServer.Start()
}
return nil
@ -63,8 +63,13 @@ func (s *Server) handlePacket(packet *netfilter.Packet) {
nf := s.nfqServer.Nf
modified := false
if s.cfg.DelTCPTimestamp && packet.TCP != nil {
modified = s.clearTCPTimestamp(packet.TCP) || modified
if packet.TCP != nil {
if s.cfg.DelTCPTimestamp {
modified = s.clearTCPTimestamp(packet.TCP) || modified
}
if s.cfg.SetTCPInitialWindow {
modified = s.setInitialTCPWindow(packet.TCP) || modified
}
}
if s.cfg.SetIPID {
modified = s.zeroIPID(packet) || modified
@ -110,6 +115,18 @@ func (s *Server) clearTCPTimestamp(tcp *layers.TCP) bool {
return modified
}
// setInitialTCPWindow sets the TCP initial window size to 65535 for SYN packets
func (s *Server) setInitialTCPWindow(tcp *layers.TCP) bool {
if !(tcp.SYN && !tcp.ACK) {
return false
}
if tcp.Window == uint16(65535) {
return false
}
tcp.Window = uint16(65535)
return true
}
// zeroIPID sets the IP ID field to zero for IPv4 packets
// Returns true if the packet was modified
func (s *Server) zeroIPID(packet *netfilter.Packet) bool {

View File

@ -28,8 +28,8 @@ func (s *Server) nftSetup() error {
if s.cfg.SetTTL {
s.NftSetTTL(tx, s.Nftable)
}
if s.cfg.DelTCPTimestamp && !s.cfg.SetIPID {
s.NftDelTCPTS(tx, s.Nftable)
if (s.cfg.DelTCPTimestamp || s.cfg.SetTCPInitialWindow) && !s.cfg.SetIPID {
s.NftHookTCPSyn(tx, s.Nftable)
}
if s.cfg.SetIPID {
s.NftSetIP(tx, s.Nftable)
@ -112,9 +112,9 @@ func (s *Server) NftSetTTLIngress(nft knftables.Interface, table *knftables.Tabl
return nil
}
func (s *Server) NftDelTCPTS(tx *knftables.Transaction, table *knftables.Table) {
func (s *Server) NftHookTCPSyn(tx *knftables.Transaction, table *knftables.Table) {
chain := &knftables.Chain{
Name: "DEL_TCPTS",
Name: "HOOK_TCP_SYN",
Table: table.Name,
Type: knftables.PtrTo(knftables.FilterType),
Hook: knftables.PtrTo(knftables.PostroutingHook),