用于安全通信的多功能且高效的代理平台。
splice(2)
的 TCP 中继快速路径。recvmmsg(2)
和sendmmsg(2)
。 AUR 中提供了发布和 VCS 包:
从发行版下载。
使用 Go 构建并安装最新版本:
go install github.com/database64128/shadowsocks-go/cmd/shadowsocks-go@latest
go install github.com/database64128/shadowsocks-go/cmd/shadowsocks-go-domain-set-converter@latest
或者克隆存储库并手动构建它:
go build -trimpath -ldflags ' -s -w ' ./cmd/shadowsocks-go
go build -trimpath -ldflags ' -s -w ' ./cmd/shadowsocks-go-domain-set-converter
所有配置示例和 systemd 单元文件都可以在 docs 目录中找到。
clients
字段可以省略或留空。将自动添加默认的“直接”客户端。
在生产服务器上,您可能希望将udpRelayBatchSize
设置为较低的值(例如 8)以减少内存使用量,同时仍然受益于recvmmsg(2)
和sendmmsg(2)
。
UDP 数据包可以填充到根据mtu
计算得出的最大数据包大小。如果可以通过 PPPoE 连接使用服务器,则mtu
应减少到 1492。如果客户端到服务器的 PMTU 未知,则可以通过将paddingPolicy
设置为NoPadding
来完全禁用填充。
对于没有任何用户 PSK 的服务器(单用户模式), psk
字段指定 PSK, uPSKStorePath
字段可以省略或留空。当在 uPSK 存储文件中指定一个或多个用户 PSK 时, psk
字段指定身份 PSK。
要在不重新启动服务器的情况下添加/更新/删除用户,请修改 uPSK 存储文件并向服务器进程发送SIGUSR1
信号,或使用 RESTful API。来自 RESTful API 的更新将自动保存到 uPSK 存储文件中。
/etc/shadowsocks-go/config.json
{
"servers" : [
{
"name" : " ss-2022 " ,
"listen" : " :20220 " ,
"protocol" : " 2022-blake3-aes-128-gcm " ,
"enableTCP" : true ,
"listenerTFO" : true ,
"enableUDP" : true ,
"mtu" : 1500 ,
"psk" : " qQln3GlVCZi5iJUObJVNCw== " ,
"uPSKStorePath" : " /etc/shadowsocks-go/upsks.json "
}
]
}
/etc/shadowsocks-go/upsks.json
{
"Steve" : " oE/s2z9Q8EWORAB8B3UCxw== " ,
"Alex" : " hWXLOSW/r/LtNKynrA3S8Q== "
}
默认情况下,路由器使用配置的DNS服务器来解析域名并匹配IP规则。解析后的IP地址仅用于匹配IP规则。使用原始域名发出请求。要禁用域名的 IP 规则匹配,请将disableNameResolutionForIPRules
设置为 true。
{
"servers" : [
{
"name" : " socks5 " ,
"listen" : " :1080 " ,
"protocol" : " socks5 " ,
"enableTCP" : true ,
"listenerTFO" : true ,
"enableUDP" : true ,
"mtu" : 1500
},
{
"name" : " http " ,
"listen" : " :8080 " ,
"protocol" : " http " ,
"enableTCP" : true ,
"listenerTFO" : true
}
],
"clients" : [
{
"name" : " ss-2022 " ,
"protocol" : " 2022-blake3-aes-128-gcm " ,
"endpoint" : " [2001:db8:bd63:362c:2071:a0f6:827:ab6a]:20220 " ,
"enableTCP" : true ,
"dialerTFO" : true ,
"enableUDP" : true ,
"mtu" : 1500 ,
"psk" : " oE/s2z9Q8EWORAB8B3UCxw== " ,
"iPSKs" : [
" qQln3GlVCZi5iJUObJVNCw== "
]
},
{
"name" : " direct " ,
"protocol" : " direct " ,
"enableTCP" : true ,
"dialerTFO" : true ,
"enableUDP" : true ,
"mtu" : 1500
}
],
"dns" : [
{
"name" : " cf-v6 " ,
"addrPort" : " [2606:4700:4700::1111]:53 " ,
"tcpClientName" : " ss-2022 " ,
"udpClientName" : " ss-2022 "
},
{
"name" : " system " ,
"type" : " system "
}
],
"router" : {
"defaultTCPClientName" : " ss-2022 " ,
"defaultUDPClientName" : " ss-2022 " ,
"geoLite2CountryDbPath" : " /usr/share/shadowsocks-go/Country.mmdb " ,
"domainSets" : [
{
"name" : " category-ads-all " ,
"type" : " gob " ,
"path" : " /usr/share/shadowsocks-go/ss-go-gob-category-ads-all "
},
{
"name" : " private " ,
"type" : " gob " ,
"path" : " /usr/share/shadowsocks-go/ss-go-gob-private "
},
{
"name" : " cn " ,
"type" : " gob " ,
"path" : " /usr/share/shadowsocks-go/ss-go-gob-cn "
},
{
"name" : " geolocation-!cn@cn " ,
"type" : " gob " ,
"path" : " /usr/share/shadowsocks-go/ss-go-gob-geolocation-!cn@cn "
}
],
"routes" : [
{
"name" : " ads " ,
"client" : " reject " ,
"toDomainSets" : [
" category-ads-all "
]
},
{
"name" : " direct " ,
"client" : " direct " ,
"resolver" : " cf-v6 " ,
"toDomainSets" : [
" private " ,
" cn "
],
"toPrefixes" : [
" 0.0.0.0/8 " ,
" 10.0.0.0/8 " ,
" 100.64.0.0/10 " ,
" 127.0.0.0/8 " ,
" 169.254.0.0/16 " ,
" 172.16.0.0/12 " ,
" 192.0.0.0/24 " ,
" 192.0.2.0/24 " ,
" 192.88.99.0/24 " ,
" 192.168.0.0/16 " ,
" 198.18.0.0/15 " ,
" 198.51.100.0/24 " ,
" 203.0.113.0/24 " ,
" 224.0.0.0/3 " ,
" ::1/128 " ,
" fc00::/7 " ,
" fe80::/10 " ,
" ff00::/8 "
],
"toGeoIPCountries" : [
" CN "
]
},
{
"name" : " cn-verify-ip " ,
"client" : " direct " ,
"resolver" : " system " ,
"toDomainSets" : [
" geolocation-!cn@cn "
],
"toMatchedDomainExpectedGeoIPCountries" : [
" CN "
]
}
]
}
}
请参阅文档/config.json。
Shadowsocks-go 有自己的域集文件格式,因为我见过的其他格式都很糟糕!
别担心,我们有一个简单的转换工具可以在不同格式之间进行转换:shadowsocks-go-domain-set-converter
域集文本文件可以选择以容量提示注释开始。转换工具可以自动为您生成容量提示。域名匹配规则有4种类型:
domain:
匹配域。suffix:
匹配域名及其子域名。keyword:
如果域包含关键字则匹配。regexp:
如果域与正则表达式匹配则匹配。域集文本文件示例:
# shadowsocks-go domain set capacity hint 1 6 1 1 DSKR
domain:www.example.net
suffix:example.com
suffix:github.com
suffix:cube64128.xyz
suffix:api.ipify.org
suffix:api6.ipify.org
suffix:archlinux.org
keyword:dev
regexp:^adservice.google.([a-z]{2}|com?)(.[a-z]{2})?$
加载域集文本文件时,shadowsocks-go 会将所有后缀按原样加载到单个映射中。这样就达到了启动速度、内存占用和匹配速度之间的最佳平衡。如果想要更好的性能,可以使用转换工具将文本文件转换为gob格式。
gob 格式基本上是相同的,但所有内容都是二进制序列化的,并使用 trie 来存储和匹配后缀。转换工具加载后缀以构建后缀特里树,然后将该特里树和其他规则序列化到 gob 文件。非常整洁,不是吗?
当然,我不是算法大师,所以整个过程还是有很多低效率的地方。但这对我来说已经足够好了。如果您有绝妙的新想法,请告诉我!
发布分支中的 Shadowsocks-go-domain-sets 每周都会更新一组常用的域集。 Arch Linux 用户可以从 AUR 安装 Shadowsocks-go-domain-sets-git 软件包。
要使用 https://github.com/v2fly/domain-list-community 作为源生成域集,请克隆存储库并构建生成器,然后生成纯文本列表:
./domain-list-community -exportlists ' google,netflix '
使用shadowsocks-go-domain-set-converter
将明文列表转换为域集文件:
shadowsocks-go-domain-set-converter -inDlc google.txt -outGob ss-go-gob-google
shadowsocks-go-domain-set-converter -inDlc netflix.txt -outGob ss-go-gob-netflix
Shadowsocks-go 使用 MaxMind GeoLite2 Country 数据库进行 IP 地理定位。该数据库可以从 https://github.com/Dreamacro/maxmind-geoip 下载。 Arch Linux 用户可以从 AUR 安装 Shadowsocks-go-geolite2-country-git 软件包。
数据包填充策略是针对 Shadowsocks 2022 协议实现的。数据包填充策略控制是否向传出数据包添加填充。
添加填充时会考虑 MTU,因此填充后的数据包大小不会超过 MTU。因此,正确设置 MTU 非常重要。
可以为每个 Shadowsocks 2022 客户端和服务器单独配置填充策略。
PadPlainDNS
:如果目标端口为 53,则添加填充。(默认)PadAll
:填充所有数据包。NoPadding
:无填充。所有 TCP 服务器均实施拒绝策略。当接受的连接在协议的握手过程中失败时,将调用 TCP 服务器的拒绝策略。每个协议都有自己的默认拒绝策略。自定义拒绝策略对于审查规避服务器来说非常有用,可以逃避主动探测。
JustClose
:仅关闭连接。 (明文协议的默认值)ForceReset
:强制重置连接。当收到无效数据时,许多协议都会这样做。 (Shadowsocks 2022 的默认值)CloseWriteDrain
:发送 FIN 并继续读取直到 EOF。这通常是传统 Shadowsocks 服务器处理重播的方式。ReplyWithGibberish
:继续读取并在每次读取返回后发送随机垃圾。这模拟了没有重放保护的传统 Shadowsocks 服务器的行为方式,只不过它实际上并不中继重放的有效负载。Shadowsocks 2022 服务器可以配置为在握手失败时将 TCP 连接转发到后备地址。将unsafeFallbackAddress
字段添加到服务器块以指定回退地址。启动时,将打印一条警告消息,告诉您使用此功能会“污染”服务器。不安全回退仅适用于 TCP 连接。
当您的威胁模型仅包括偏离路径的攻击者,并且您希望重用端口或欺骗探针以认为服务器是其他东西时,此功能可能很有用。路径上的攻击者(例如典型的审查者)可以轻松判断常规流量与后备流量不匹配。
不安全流前缀功能允许您为 Shadowsocks 2022 流配置一对预共享的明文前缀。这些前缀被添加到请求和响应流之前以欺骗简单的防火墙。
要使用此功能,请将unsafeRequestStreamPrefix
和unsafeResponseStreamPrefix
添加到客户端和服务器块,并指定 base64 编码的前缀。客户端和服务器必须同意同一对前缀。启动时,将打印一条警告消息,告诉您使用此功能会“污染”客户端和服务器。
AGPL-3.0-或更高版本