Skip to content

Commit

Permalink
add firewall rule for windows (#33)
Browse files Browse the repository at this point in the history
* log

* add unittest

* fix unittest

* add windows script

* update firewall

* test pass in windows 10

---------

Co-authored-by: drew.zxj <drew.zxj@alibaba-inc.com>
  • Loading branch information
xjdrew and drew.zxj authored Dec 21, 2023
1 parent e46dccb commit a0491f3
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 17 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
.idea
v2raya
/kone
/my.ini
/kone.exe
/coverage.txt
cmd/kone/local.ini
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ By now, it supports:

* linux
* macosx
* windows (8 / Server 2012 and above)
* windows (10 and above) (refer to [use kone in windows](./misc/windows/README.md) for more information)

## Use

Expand Down
4 changes: 2 additions & 2 deletions cmd/kone/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ func main() {
cfg, err := kone.ParseConfig(configFile)
if err != nil {
logger.Error(err.Error())
os.Exit(1)
os.Exit(2)
}

one, err := kone.FromConfig(cfg)
if err != nil {
logger.Error(err.Error())
os.Exit(1)
os.Exit(3)
}
one.Serve()
}
16 changes: 11 additions & 5 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package kone
import (
"os"
"strings"
"unicode"

"gopkg.in/ini.v1"
)
Expand Down Expand Up @@ -41,7 +42,7 @@ type CoreConfig struct {
}

type RuleConfig struct {
Scheme string
Schema string
Pattern string
Proxy string
}
Expand All @@ -58,19 +59,24 @@ func (cfg *KoneConfig) parseRule(sec *ini.Section) (err error) {

var ops []string
for _, key := range keys {
ops = strings.Split(key, ",")
logger.Infof("%s %v", key, ops)
ops = strings.FieldsFunc(key, func(c rune) bool {
if c == ',' || unicode.IsSpace(c) {
return true
}
return false
})
logger.Debugf("%s %v", key, ops)
if len(ops) == 3 { // ignore invalid format
cfg.Rule = append(cfg.Rule, RuleConfig{
Scheme: ops[0],
Schema: ops[0],
Pattern: ops[1],
Proxy: ops[2],
})
}
}
if len(ops) == 2 { //final rule
cfg.Rule = append(cfg.Rule, RuleConfig{
Scheme: ops[0],
Schema: ops[0],
Proxy: ops[1],
})
}
Expand Down
22 changes: 17 additions & 5 deletions config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ const (
Proxy2 = socks5://127.0.0.1:9080
[Rule]
IP-CIDR,91.108.4.0/22,Proxy1
IP-CIDR,91.108.56.0/22,Proxy1
IP-CIDR, 91.108.4.0/22, Proxy1 # rule 0
IP-CIDR,91.108.56.0/22,Proxy1 # rule 1
IP-CIDR,109.239.140.0/24,Proxy1
IP-CIDR,149.154.167.0/24,Proxy1
IP-CIDR,172.16.0.0/16,DIRECT
Expand All @@ -53,18 +53,19 @@ const (
IP-CIDR6,2001:db8:abcd:8000::/50,DIRECT
# match if the domain
DOMAIN,www.twitter.com,Proxy1
DOMAIN, www.twitter.com, Proxy1
DOMAIN-SUFFIX,twitter.com,Proxy1
DOMAIN-SUFFIX,telegram.org,Proxy1
DOMAIN-KEYWORD,google,Proxy1
DOMAIN-KEYWORD,localhost,DIRECT
DOMAIN-KEYWORD,baidu,REJECT
# match if the GeoIP test result matches a specified country code
GEOIP,US,DIRECT
GEOIP,US,DIRECT # rule 13
# define default policy for requests which are not matched by any other rules
FINAL,DIRECT`
FINAL,DIRECT # rule 14
`
)

func TestParseConfig(t *testing.T) {
Expand Down Expand Up @@ -96,4 +97,15 @@ func TestParseConfig(t *testing.T) {
assert.Equal(t, "socks5://127.0.0.1:9080", cfg.Proxy["Proxy2"])

assert.Len(t, cfg.Rule, 15)
assert.Equal(t, cfg.Rule[0].Schema, "IP-CIDR")
assert.Equal(t, cfg.Rule[0].Pattern, "91.108.4.0/22")
assert.Equal(t, cfg.Rule[0].Proxy, "Proxy1")

assert.Equal(t, cfg.Rule[1].Schema, "IP-CIDR")
assert.Equal(t, cfg.Rule[1].Pattern, "91.108.56.0/22")
assert.Equal(t, cfg.Rule[1].Proxy, "Proxy1")

assert.Equal(t, cfg.Rule[14].Schema, "FINAL")
assert.Equal(t, cfg.Rule[14].Pattern, "")
assert.Equal(t, cfg.Rule[14].Proxy, "DIRECT")
}
13 changes: 13 additions & 0 deletions misc/windows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# use kone in Windows

## 预设条件
1. 安装 tap-windows (NDIS 6)
[tap-windows](https://community.openvpn.net/openvpn/wiki/GettingTapWindows)
[直接下载](https://build.openvpn.net/downloads/releases/tap-windows-9.21.0.exe)

2. 配置防火墙,允许kone重定向连接
使用管理员权限启动 PowerShell,执行`update-firewall-rules.ps1`

>>> 请注意修改 `update-firewall-rules.ps1` 脚本中 Program 参数为kone实际路径。
3. 编译&运行kone方式同linux
19 changes: 19 additions & 0 deletions misc/windows/check-firewall-rules.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#Requires -Version 3
#Requires -Modules NetSecurity

$List = Get-NetFirewallRule -Enabled True -Action Allow -Description 'Work with Kone.' | Where-Object { 'Kone' -eq $_.DisplayName }
$Report = foreach ($Rule in $List)
{
$Program = (Get-NetFirewallApplicationFilter -AssociatedNetFirewallRule $Rule).Program

@{
Profile = $Rule.Profile
Enabled = $Rule.Enabled
Action = $Rule.Action
Protocol = (Get-NetFirewallPortFilter -AssociatedNetFirewallRule $Rule).Protocol
Program = $Program
IsPathValid = Test-Path -PathType Leaf -LiteralPath $Program
}
}
$Report
Pause
13 changes: 13 additions & 0 deletions misc/windows/update-firewall-rules.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# $Program should direct to execute file
Remove-NetFirewallRule -Description "Work with Kone." -ErrorAction SilentlyContinue
'TCP', 'UDP' | ForEach-Object {
New-NetFirewallRule `
-DisplayName "Kone" `
-Profile "Any" `
-Description "Work with Kone." `
-Direction Inbound `
-Protocol $_ `
-Action Allow `
-Program "E:\go\github\kone\kone.exe" `
| Out-Null
}
5 changes: 5 additions & 0 deletions nat.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ type Nat struct {
}

func (nat *Nat) getSession(port uint16) *NatSession {
if port < nat.tbl.from || port >= nat.tbl.to {
return nil
}

session := nat.sessions[port-nat.tbl.from]
if session != nil {
session.lastTouch = time.Now().Unix()
Expand Down Expand Up @@ -139,6 +143,7 @@ func (nat *Nat) count() int {
return nat.tbl.Count()
}

// port range [from, to)
func NewNat(from, to uint16) *Nat {
count := to - from
tbl := &NatTable{
Expand Down
6 changes: 3 additions & 3 deletions pattern.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ func NewFinalPattern(proxy string) FinalPattern {
func CreatePattern(rc RuleConfig) Pattern {
proxy := rc.Proxy
pattern := rc.Pattern
schema := strings.ToUpper(rc.Scheme)
schema := strings.ToUpper(rc.Schema)

switch schema {
case "DOMAIN":
Expand All @@ -188,7 +188,7 @@ func CreatePattern(rc RuleConfig) Pattern {
fallthrough
case "IP-CIDR6":
if proxy == "DIRECT" { // all IPNet default proxy is DIRECT
logger.Debugf("skip DIRECT rule: %s,%s,%s", rc.Scheme, rc.Pattern, rc.Proxy)
logger.Debugf("skip DIRECT rule: %s,%s,%s", rc.Schema, rc.Pattern, rc.Proxy)
return nil
}
_, ipNet, err := net.ParseCIDR(pattern)
Expand All @@ -200,6 +200,6 @@ func CreatePattern(rc RuleConfig) Pattern {
case "FINAL":
return NewFinalPattern(proxy)
}
logger.Errorf("invalid rule: %s,%s,%s", rc.Scheme, rc.Pattern, rc.Proxy)
logger.Errorf("invalid rule: %s,%s,%s", rc.Schema, rc.Pattern, rc.Proxy)
return nil
}
2 changes: 1 addition & 1 deletion tcp_relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (r *TCPRelay) handleConn(conn net.Conn) {
return
}

if proxy == "DIRECT" {
if proxy == "DIRECT" { // impossible
conn.Close()
logger.Errorf("[tcp] %s > %s traffic dead loop", conn.LocalAddr(), remoteAddr)
return
Expand Down

0 comments on commit a0491f3

Please sign in to comment.