Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: io tcp reset support (forward only) #109

Merged
merged 2 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ io:
rcvBuf: 4194304
sndBuf: 4194304
local: true # FORWARD チェーンで OpenGFW を実行したい場合は false に設定する
rst: false # ブロックされたTCP接続に対してRSTを送信する場合はtrueに設定してください。local=falseのみです

workers:
count: 4
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ io:
rcvBuf: 4194304
sndBuf: 4194304
local: true # set to false if you want to run OpenGFW on FORWARD chain
rst: false # set to true if you want to send RST for blocked TCP connections, local=false only

workers:
count: 4
Expand Down
1 change: 1 addition & 0 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ io:
rcvBuf: 4194304
sndBuf: 4194304
local: true # 如果需要在 FORWARD 链上运行 OpenGFW,请设置为 false
rst: false # 是否对要阻断的 TCP 连接发送 RST。仅在 local=false 时有效

workers:
count: 4
Expand Down
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ type cliConfigIO struct {
ReadBuffer int `mapstructure:"rcvBuf"`
WriteBuffer int `mapstructure:"sndBuf"`
Local bool `mapstructure:"local"`
RST bool `mapstructure:"rst"`
}

type cliConfigWorkers struct {
Expand All @@ -197,6 +198,7 @@ func (c *cliConfig) fillIO(config *engine.Config) error {
ReadBuffer: c.IO.ReadBuffer,
WriteBuffer: c.IO.WriteBuffer,
Local: c.IO.Local,
RST: c.IO.RST,
})
if err != nil {
return configError{Field: "io", Err: err}
Expand Down
51 changes: 43 additions & 8 deletions io/nfqueue.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ table %s %s {
}
`, nfqueueConnMarkAccept, nfqueueConnMarkDrop, nfqueueNum, nftFamily, nftTable)

var nftRulesForwardRST = fmt.Sprintf(`
define ACCEPT_CTMARK=%d
define DROP_CTMARK=%d
define QUEUE_NUM=%d

table %s %s {
chain FORWARD {
type filter hook forward priority filter; policy accept;

ct mark $ACCEPT_CTMARK counter accept
ip protocol tcp ct mark $DROP_CTMARK counter reject with tcp reset
ct mark $DROP_CTMARK counter drop
counter queue num $QUEUE_NUM bypass
}
}
`, nfqueueConnMarkAccept, nfqueueConnMarkDrop, nfqueueNum, nftFamily, nftTable)

var nftRulesLocal = fmt.Sprintf(`
define ACCEPT_CTMARK=%d
define DROP_CTMARK=%d
Expand Down Expand Up @@ -72,6 +89,13 @@ var iptRulesForward = []iptRule{
{"filter", "FORWARD", []string{"-j", "NFQUEUE", "--queue-num", strconv.Itoa(nfqueueNum), "--queue-bypass"}},
}

var iptRulesForwardRST = []iptRule{
{"filter", "FORWARD", []string{"-m", "connmark", "--mark", strconv.Itoa(nfqueueConnMarkAccept), "-j", "ACCEPT"}},
{"filter", "FORWARD", []string{"-p", "tcp", "-m", "connmark", "--mark", strconv.Itoa(nfqueueConnMarkDrop), "-j", "REJECT", "--reject-with", "tcp-reset"}},
{"filter", "FORWARD", []string{"-m", "connmark", "--mark", strconv.Itoa(nfqueueConnMarkDrop), "-j", "DROP"}},
{"filter", "FORWARD", []string{"-j", "NFQUEUE", "--queue-num", strconv.Itoa(nfqueueNum), "--queue-bypass"}},
}

var iptRulesLocal = []iptRule{
{"filter", "INPUT", []string{"-m", "connmark", "--mark", strconv.Itoa(nfqueueConnMarkAccept), "-j", "ACCEPT"}},
{"filter", "INPUT", []string{"-m", "connmark", "--mark", strconv.Itoa(nfqueueConnMarkDrop), "-j", "DROP"}},
Expand All @@ -89,6 +113,7 @@ var errNotNFQueuePacket = errors.New("not an NFQueue packet")
type nfqueuePacketIO struct {
n *nfqueue.Nfqueue
local bool
rst bool
rSet bool // whether the nftables/iptables rules have been set

// iptables not nil = use iptables instead of nftables
Expand All @@ -101,6 +126,7 @@ type NFQueuePacketIOConfig struct {
ReadBuffer int
WriteBuffer int
Local bool
RST bool
}

func NewNFQueuePacketIO(config NFQueuePacketIOConfig) (PacketIO, error) {
Expand Down Expand Up @@ -147,6 +173,7 @@ func NewNFQueuePacketIO(config NFQueuePacketIOConfig) (PacketIO, error) {
return &nfqueuePacketIO{
n: n,
local: config.Local,
rst: config.RST,
ipt4: ipt4,
ipt6: ipt6,
}, nil
Expand Down Expand Up @@ -182,9 +209,9 @@ func (n *nfqueuePacketIO) Register(ctx context.Context, cb PacketCallback) error
}
if !n.rSet {
if n.ipt4 != nil {
err = n.setupIpt(n.local, false)
err = n.setupIpt(n.local, n.rst, false)
} else {
err = n.setupNft(n.local, false)
err = n.setupNft(n.local, n.rst, false)
}
if err != nil {
return err
Expand Down Expand Up @@ -238,21 +265,25 @@ func (n *nfqueuePacketIO) SetVerdict(p Packet, v Verdict, newPacket []byte) erro
func (n *nfqueuePacketIO) Close() error {
if n.rSet {
if n.ipt4 != nil {
_ = n.setupIpt(n.local, true)
_ = n.setupIpt(n.local, n.rst, true)
} else {
_ = n.setupNft(n.local, true)
_ = n.setupNft(n.local, n.rst, true)
}
n.rSet = false
}
return n.n.Close()
}

func (n *nfqueuePacketIO) setupNft(local, remove bool) error {
func (n *nfqueuePacketIO) setupNft(local, rst, remove bool) error {
var rules string
if local {
rules = nftRulesLocal
} else {
rules = nftRulesForward
if rst {
rules = nftRulesForwardRST
} else {
rules = nftRulesForward
}
}
var err error
if remove {
Expand All @@ -268,12 +299,16 @@ func (n *nfqueuePacketIO) setupNft(local, remove bool) error {
return nil
}

func (n *nfqueuePacketIO) setupIpt(local, remove bool) error {
func (n *nfqueuePacketIO) setupIpt(local, rst, remove bool) error {
var rules []iptRule
if local {
rules = iptRulesLocal
} else {
rules = iptRulesForward
if rst {
rules = iptRulesForwardRST
} else {
rules = iptRulesForward
}
}
var err error
if remove {
Expand Down
Loading