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

add firewall rule for windows #33

Merged
merged 6 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
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