From f002d7fca84a85d98d65de024339eed06da93710 Mon Sep 17 00:00:00 2001 From: xausky Date: Wed, 7 Aug 2019 16:50:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20Gost=20=E6=A0=B8=E5=BF=83?= =?UTF-8?q?=E5=88=B0=202.8.1=20=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 3 - README.md | 37 +- app/build.gradle | 17 +- build-go.sh => app/src/main/go/build.sh | 11 +- app/src/main/go/go.mod | 10 + app/src/main/go/go.sum | 93 +++++ main.go | 499 ------------------------ 7 files changed, 151 insertions(+), 519 deletions(-) delete mode 100644 .gitmodules rename build-go.sh => app/src/main/go/build.sh (54%) create mode 100644 app/src/main/go/go.mod create mode 100644 app/src/main/go/go.sum delete mode 100644 main.go diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 3b23f8a..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "go/src/github.com/ginuerzh/gost"] - path = go/src/github.com/ginuerzh/gost - url = https://github.com/xausky/gost.git diff --git a/README.md b/README.md index 56d3e6d..9d522c9 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,39 @@ -# ShadowsocksGostPlugin -[Gost](https://github.com/ginuerzh/gost) 的 [Shadowsocks安卓](https://github.com/shadowsocks/shadowsocks-android) 插件,可以直接在Shadowsocks安卓客户端上连接 Gost 服务器 +

Welcome to Shadowsocks Gost Plugin 👋

+

+ Version + + Documentation + +

-## 使用方法 +> [Gost](https://github.com/ginuerzh/gost) 的 [Shadowsocks安卓](https://github.com/shadowsocks/shadowsocks-android) 插件,可以直接在Shadowsocks安卓客户端上连接 Gost 服务器 + +### 🏠 [Homepage](https://github.com/xausky/ShadowsocksGostPlugin) + +## Install + +根据CPU构架下载Release内预编译好的APK安装到设备,如果不清楚构架可以下载Universal版本 + +## Usage * 在Shadowsocks客户端选中本插件,即可在参数配置除了-L 参数之为的 gost 参数以连接远程服务器或者多段代理。 -* -L 参数会自动添加,只需要在Shadowsocks界面配置`chacha20`加密和`ss123456`密码即可 +* -L 参数会自动添加,只需要在Shadowsocks界面配置`rc4-md5`加密和`gost`密码即可 * gost的参数配置里面可以用`#SS_HOST`和`#SS_PORT`代替Shadowsocks配置的主机和端口 * 注意使用#SS_HOST参数会先对填写的主机名进行DNS解析后才传递,如果是与主机名相关的远程协议比如ws协议必须之间在参数里面配置 * 在参数里面配置的域名会忽略手机系统的DNS配置固定使用114.114.114.114 + +## Author + +* Github: [@xausky](https://github.com/xausky) +* BiliBili: [@xausky](https://twitter.com/xausky) + +## 🤝 Contributing + +Contributions, issues and feature requests are welcome!
Feel free to check [issues page](https://github.com/xausky/ShadowsocksGostPlugin/issues). + +## Show your support + +Give a ⭐️ if this project helped you! + +*** +_This README was generated with ❤️ by [readme-md-generator](https://github.com/kefranabg/readme-md-generator)_ \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 03332aa..71dc3e3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,8 +6,8 @@ android { applicationId "com.github.shadowsocks.plugin.gost" minSdkVersion 21 targetSdkVersion 28 - versionCode 1 - versionName "1.0" + versionCode 281 + versionName "2.8.1" } splits { abi { @@ -20,9 +20,9 @@ android { signingConfigs { releaseConfig { storeFile file("../../xausky.jks") - storePassword project.hasProperty("KEYSTORE_PASS") ? KEYSTORE_PASS : System.getenv("KEYSTORE_PASS") - keyAlias project.hasProperty("ALIAS_NAME") ? ALIAS_NAME : System.getenv("ALIAS_NAME") - keyPassword project.hasProperty("ALIAS_PASS") ? ALIAS_PASS : System.getenv("ALIAS_PASS") + storePassword System.getenv("KEYSTORE_PASS") + keyAlias System.getenv("ALIAS_NAME") + keyPassword System.getenv("ALIAS_PASS") } } buildTypes { @@ -39,11 +39,14 @@ dependencies { } task buildGoLibrary(type: Exec) { - commandLine 'sh', '../build-go.sh' + environment ([ANDROID_NDK_ROOT: android.ndkDirectory]) + commandLine ('sh', 'src/main/go/build.sh') + inputs.files 'src/main/go/go.mod', 'src/main/go/go.sum' + outputs.dir 'src/main/jniLibs' } tasks.whenTaskAdded { theTask -> - if (theTask.name.equals("preReleaseBuild")) { + if (theTask.name.equals("preDebugBuild") || theTask.name.equals("preReleaseBuild")) { theTask.dependsOn "buildGoLibrary" } } diff --git a/build-go.sh b/app/src/main/go/build.sh similarity index 54% rename from build-go.sh rename to app/src/main/go/build.sh index 037cb18..3931e42 100644 --- a/build-go.sh +++ b/app/src/main/go/build.sh @@ -1,17 +1,16 @@ -DIR="$( cd "$( dirname "$0" )" && pwd )" -export GOPATH=$DIR/go +cd $( cd "$( dirname "$0" )" && pwd ) CC=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang \ GOOS="android" GOARCH="arm" CGO_ENABLED="1" \ -go build -a -o $DIR/app/src/main/jniLibs/armeabi-v7a/libgost-plugin.so github.com/ginuerzh/gost/cmd/gost +go build -a -o ../jniLibs/armeabi-v7a/libgost-plugin.so github.com/ginuerzh/gost/cmd/gost CC=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang \ GOOS="android" GOARCH="arm64" CGO_ENABLED="1" \ -go build -a -o $DIR/app/src/main/jniLibs/arm64-v8a/libgost-plugin.so github.com/ginuerzh/gost/cmd/gost +go build -a -o ../jniLibs/arm64-v8a/libgost-plugin.so github.com/ginuerzh/gost/cmd/gost CC=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android21-clang \ GOOS="android" GOARCH="386" CGO_ENABLED="1" \ -go build -a -o $DIR/app/src/main/jniLibs/x86/libgost-plugin.so github.com/ginuerzh/gost/cmd/gost +go build -a -o ../jniLibs/x86/libgost-plugin.so github.com/ginuerzh/gost/cmd/gost CC=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang \ GOOS="android" GOARCH="amd64" CGO_ENABLED="1" \ -go build -a -o $DIR/app/src/main/jniLibs/x86_64/libgost-plugin.so github.com/ginuerzh/gost/cmd/gost \ No newline at end of file +go build -a -o ../jniLibs/x86_64/libgost-plugin.so github.com/ginuerzh/gost/cmd/gost \ No newline at end of file diff --git a/app/src/main/go/go.mod b/app/src/main/go/go.mod new file mode 100644 index 0000000..342de48 --- /dev/null +++ b/app/src/main/go/go.mod @@ -0,0 +1,10 @@ +module gost-ss-plugin + +go 1.12 + +replace github.com/ginuerzh/gost => github.com/xausky/gost v0.0.0-20190807074259-0c3114b262f8 + +require ( + github.com/ginuerzh/gost v0.0.0-00010101000000-000000000000 + github.com/go-log/log v0.1.0 +) diff --git a/app/src/main/go/go.sum b/app/src/main/go/go.sum new file mode 100644 index 0000000..153cbb9 --- /dev/null +++ b/app/src/main/go/go.sum @@ -0,0 +1,93 @@ +git.torproject.org/pluggable-transports/goptlib.git v0.0.0-20180321061416-7d56ec4f381e h1:PYcONLFUhr00kGrq7Mf14JRtoXHG7BOSKIfIha0Hu5Q= +git.torproject.org/pluggable-transports/goptlib.git v0.0.0-20180321061416-7d56ec4f381e/go.mod h1:YT4XMSkuEXbtqlydr9+OxqFAyspUv0Gr9qhM3B++o/Q= +git.torproject.org/pluggable-transports/obfs4.git v0.0.0-20181103133120-08f4d470188e h1:c8h60PKrRxEB5debIHBmP7T+s/EUNXTklXqlmJfYiJQ= +git.torproject.org/pluggable-transports/obfs4.git v0.0.0-20181103133120-08f4d470188e/go.mod h1:jRZbfRcLIgFQoCw6tRmsnETVyIj54jOmXhHCYYa0jbs= +github.com/Yawning/chacha20 v0.0.0-20170904085104-e3b1f968fc63 h1:I6/SJSN9wJMJ+ZyQaCHUlzoTA4ypU5Bb44YWR1wTY/0= +github.com/Yawning/chacha20 v0.0.0-20170904085104-e3b1f968fc63/go.mod h1:nf+Komq6fVP4SwmKEaVGxHTyQGKREVlwjQKpvOV39yE= +github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY= +github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= +github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI= +github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= +github.com/bifurcation/mint v0.0.0-20181105071958-a14404e9a861 h1:x17NvoJaphEzay72TFej4OSSsgu3xRYBLkbIwdofS/4= +github.com/bifurcation/mint v0.0.0-20181105071958-a14404e9a861/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU= +github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= +github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/dchest/siphash v1.2.0/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4= +github.com/dchest/siphash v1.2.1 h1:4cLinnzVJDKxTCl9B01807Yiy+W7ZzVHj/KIroQRvT4= +github.com/dchest/siphash v1.2.1/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ginuerzh/gosocks4 v0.0.1 h1:ojDKUyz+uaEeRm2usY1cyQiXTqJqrKxfeE6SVBXq4m0= +github.com/ginuerzh/gosocks4 v0.0.1/go.mod h1:8SdwBMKjfJ9+BfP2vDJM1jcrgWUbWV6qxBPHHVrwptY= +github.com/ginuerzh/gosocks5 v0.2.0 h1:K0Ua23U9LU3BZrf3XpGDcs0mP8DiEpa6PJE4TA/MU3s= +github.com/ginuerzh/gosocks5 v0.2.0/go.mod h1:qp22mr6tH/prEoaN0pFukq76LlScIE+F2rP2ZP5ZHno= +github.com/ginuerzh/tls-dissector v0.0.1 h1:yF6fIt78TO4CdjiLLn6R8r0XajQJE1Lbnuq6rP8mGW8= +github.com/ginuerzh/tls-dissector v0.0.1/go.mod h1:u/kbBOqIOgJv39gywuUb3VwyzdZG5DKquOqfToKE6lk= +github.com/go-log/log v0.1.0 h1:wudGTNsiGzrD5ZjgIkVZ517ugi2XRe9Q/xRCzwEO4/U= +github.com/go-log/log v0.1.0/go.mod h1:4mBwpdRMFLiuXZDCwU2lKQFsoSCo72j3HqBK9d81N2M= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/klauspost/compress v1.4.1 h1:8VMb5+0wMgdBykOV96DwNwKFQ+WTI4pzYURP99CcB9E= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/reedsolomon v1.7.0 h1:pLFmRKGko2ZieiTGyo9DahLCIuljyxm+Zzhz/fYEonE= +github.com/klauspost/reedsolomon v1.7.0/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4= +github.com/lucas-clemente/aes12 v0.0.0-20171027163421-cd47fb39b79f h1:sSeNEkJrs+0F9TUau0CgWTTNEwF23HST3Eq0A+QIx+A= +github.com/lucas-clemente/aes12 v0.0.0-20171027163421-cd47fb39b79f/go.mod h1:JpH9J1c9oX6otFSgdUHwUBUizmKlrMjxWnIAjff4m04= +github.com/lucas-clemente/quic-go v0.10.0 h1:xEF+pSHYAOcu+U10Meunf+DTtc8vhQDRqlA0BJ6hufc= +github.com/lucas-clemente/quic-go v0.10.0/go.mod h1:wuD+2XqEx8G9jtwx5ou2BEYBsE+whgQmlj0Vz/77PrY= +github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced h1:zqEC1GJZFbGZA0tRyNZqRjep92K5fujFtFsu5ZW7Aug= +github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced/go.mod h1:NCcRLrOTZbzhZvixZLlERbJtDtYsmMw8Jc4vS8Z0g58= +github.com/miekg/dns v1.1.3 h1:1g0r1IvskvgL8rR+AcHzUA+oFmGcQlaIm4IqakufeMM= +github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 h1:7YvPJVmEeFHR1Tj9sZEYsmarJEQfMVYpd/Vyy/A8dqE= +github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/shadowsocks/go-shadowsocks2 v0.0.11 h1:dXloqEhYnZV40jblWTK8kWeC0Eb+dgql4S0tj99e8j0= +github.com/shadowsocks/go-shadowsocks2 v0.0.11/go.mod h1:R+KWaoIwRRhnpw6XV+dZil0XHi64Hc1D7hXUyXTjUzQ= +github.com/shadowsocks/shadowsocks-go v0.0.0-20170121203516-97a5c71f80ba h1:tJgNXb3S+RkB4kNPi6N5OmEWe3m+Y3Qs6LUMiNDAONM= +github.com/shadowsocks/shadowsocks-go v0.0.0-20170121203516-97a5c71f80ba/go.mod h1:mttDPaeLm87u74HMrP+n2tugXvIKWcwff/cqSX0lehY= +github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU= +github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= +github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b h1:mnG1fcsIB1d/3vbkBak2MM0u+vhGhlQwpeimUi7QncM= +github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= +github.com/tjfoc/gmsm v1.0.1 h1:R11HlqhXkDospckjZEihx9SW/2VW0RgdwrykyWMFOQU= +github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc= +github.com/xausky/gost v0.0.0-20190807055712-975576bf14a1 h1:aCPiq9lcwhYFqwDHndK/5KA9R9uW3Ez0tTaehS9SzV4= +github.com/xausky/gost v0.0.0-20190807055712-975576bf14a1/go.mod h1:eB71VwwefcibD+ECWwWneRyAzpuZN6GjHPWYAYtgqec= +github.com/xausky/gost v0.0.0-20190807074259-0c3114b262f8 h1:fS/jYX+lZCXQESMEK+AsxGvF0ewfLfHeVXgKSR34c2w= +github.com/xausky/gost v0.0.0-20190807074259-0c3114b262f8/go.mod h1:eB71VwwefcibD+ECWwWneRyAzpuZN6GjHPWYAYtgqec= +golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190130090550-b01c7a725664 h1:YbZJ76lQ1BqNhVe7dKTSB67wDrc2VPRR75IyGyyPDX8= +golang.org/x/crypto v0.0.0-20190130090550-b01c7a725664/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 h1:ulvT7fqt0yHWzpJwI57MezWnYDVpCAYBVuYst/L+fAY= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc h1:WiYx1rIFmx8c0mXAFtv5D/mHyKe1+jmuP7PViuwqwuQ= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gorilla/websocket.v1 v1.4.0 h1:lREme3ezAGPCpxSHwjGkHhAJX+ed2B6vzAJ+kaqBEIM= +gopkg.in/gorilla/websocket.v1 v1.4.0/go.mod h1:Ons1i8d00TjvJPdla7bJyeXFsdOacUyrTYbg9IetsIE= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/xtaci/kcp-go.v4 v4.3.2 h1:S9IF+L55Ugzl/hVA6wvuL3SuAtTUzH2cBBC88MXQxnE= +gopkg.in/xtaci/kcp-go.v4 v4.3.2/go.mod h1:fFYTlSOHNOHDNTKfoqarZMQsu7g7oXKwJ9wq0i9lODc= +gopkg.in/xtaci/smux.v1 v1.0.7 h1:qootIZs4ZPSx5blhvgaFpx2epdFSWkyw99xT+q0mRXI= +gopkg.in/xtaci/smux.v1 v1.0.7/go.mod h1:NbrPjLp8lNAYN8KqTplnFr2JjIBbr7CdHBkHtHsXtWA= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/main.go b/main.go deleted file mode 100644 index 8a7a334..0000000 --- a/main.go +++ /dev/null @@ -1,499 +0,0 @@ -package main - -import ( - "crypto/sha256" - "crypto/tls" - "flag" - "fmt" - "net" - "strings" - - // _ "net/http/pprof" - "os" - "runtime" - "time" - - "github.com/ginuerzh/gost" - "github.com/go-log/log" -) - -var ( - options route - routes []route -) - -func init() { - gost.SetLogger(&gost.LogLogger{}) - - var ( - configureFile string - printVersion bool - vpnMode bool - fastOpen bool - ) - localHost := os.Getenv("SS_LOCAL_HOST") - localPort := os.Getenv("SS_LOCAL_PORT") - pluginOptions := os.Getenv("SS_PLUGIN_OPTIONS") - if localHost == "" || localPort == "" { - fmt.Fprintln(os.Stderr, "Can only be used in the shadowsocks plugin.") - os.Exit(1) - } - if pluginOptions == "" { - pluginOptions = "-F ss+mws://chacha20:ss123456@#SS_HOST:#SS_PORT" - } - pluginOptions = strings.ReplaceAll(pluginOptions, "#SS_HOST", os.Getenv("SS_REMOTE_HOST")) - pluginOptions = strings.ReplaceAll(pluginOptions, "#SS_PORT", os.Getenv("SS_REMOTE_PORT")) - - os.Args = append(os.Args, "-L") - os.Args = append(os.Args, fmt.Sprintf("ss+tcp://chacha20:ss123456@[%s]:%s", localHost, localPort)) - os.Args = append(os.Args, strings.Split(pluginOptions, " ")...) - flag.Var(&options.ChainNodes, "F", "forward address, can make a forward chain") - flag.Var(&options.ServeNodes, "L", "listen address, can listen on multiple ports") - flag.StringVar(&configureFile, "C", "", "configure file") - flag.BoolVar(&options.Debug, "D", false, "enable debug log") - flag.BoolVar(&vpnMode, "V", false, "VPN Mode") - flag.BoolVar(&fastOpen, "fast-open", false, "fast Open TCP") - flag.BoolVar(&printVersion, "PV", false, "print version") - flag.Parse() - - if printVersion { - fmt.Fprintf(os.Stderr, "gost %s (%s)\n", gost.Version, runtime.Version()) - os.Exit(0) - } - if len(options.ServeNodes) > 0 { - routes = append(routes, options) - } - gost.Debug = options.Debug - - if err := loadConfigureFile(configureFile); err != nil { - log.Log(err) - os.Exit(1) - } - - if flag.NFlag() == 0 || len(routes) == 0 { - flag.PrintDefaults() - os.Exit(0) - } - -} - -func main() { - // go func() { - // log.Log(http.ListenAndServe("localhost:6060", nil)) - // }() - // NOTE: as of 2.6, you can use custom cert/key files to initialize the default certificate. - config, err := tlsConfig(defaultCertFile, defaultKeyFile) - if err != nil { - // generate random self-signed certificate. - cert, err := gost.GenCertificate() - if err != nil { - log.Log(err) - os.Exit(1) - } - config = &tls.Config{ - Certificates: []tls.Certificate{cert}, - } - } - gost.DefaultTLSConfig = config - - for _, route := range routes { - if err := route.serve(); err != nil { - log.Log(err) - os.Exit(1) - } - } - - select {} -} - -type route struct { - ChainNodes, ServeNodes stringList - Retries int - Debug bool -} - -func (r *route) initChain() (*gost.Chain, error) { - chain := gost.NewChain() - chain.Retries = r.Retries - gid := 1 // group ID - - for _, ns := range r.ChainNodes { - ngroup := gost.NewNodeGroup() - ngroup.ID = gid - gid++ - - // parse the base nodes - nodes, err := parseChainNode(ns) - if err != nil { - return nil, err - } - - nid := 1 // node ID - for i := range nodes { - nodes[i].ID = nid - nid++ - } - ngroup.AddNode(nodes...) - - go gost.PeriodReload(&peerConfig{ - group: ngroup, - baseNodes: nodes, - }, nodes[0].Get("peer")) - - chain.AddNodeGroup(ngroup) - } - - return chain, nil -} - -func parseChainNode(ns string) (nodes []gost.Node, err error) { - node, err := gost.ParseNode(ns) - if err != nil { - return - } - - users, err := parseUsers(node.Get("secrets")) - if err != nil { - return - } - if node.User == nil && len(users) > 0 { - node.User = users[0] - } - serverName, sport, _ := net.SplitHostPort(node.Addr) - if serverName == "" { - serverName = "localhost" // default server name - } - - rootCAs, err := loadCA(node.Get("ca")) - if err != nil { - return - } - tlsCfg := &tls.Config{ - ServerName: serverName, - InsecureSkipVerify: !node.GetBool("secure"), - RootCAs: rootCAs, - } - wsOpts := &gost.WSOptions{} - wsOpts.EnableCompression = node.GetBool("compression") - wsOpts.ReadBufferSize = node.GetInt("rbuf") - wsOpts.WriteBufferSize = node.GetInt("wbuf") - wsOpts.UserAgent = node.Get("agent") - - var tr gost.Transporter - switch node.Transport { - case "tls": - tr = gost.TLSTransporter() - case "mtls": - tr = gost.MTLSTransporter() - case "ws": - tr = gost.WSTransporter(wsOpts) - case "mws": - tr = gost.MWSTransporter(wsOpts) - case "wss": - tr = gost.WSSTransporter(wsOpts) - case "mwss": - tr = gost.MWSSTransporter(wsOpts) - case "kcp": - config, err := parseKCPConfig(node.Get("c")) - if err != nil { - return nil, err - } - tr = gost.KCPTransporter(config) - case "ssh": - if node.Protocol == "direct" || node.Protocol == "remote" { - tr = gost.SSHForwardTransporter() - } else { - tr = gost.SSHTunnelTransporter() - } - case "quic": - config := &gost.QUICConfig{ - TLSConfig: tlsCfg, - KeepAlive: node.GetBool("keepalive"), - Timeout: time.Duration(node.GetInt("timeout")) * time.Second, - IdleTimeout: time.Duration(node.GetInt("idle")) * time.Second, - } - - if cipher := node.Get("cipher"); cipher != "" { - sum := sha256.Sum256([]byte(cipher)) - config.Key = sum[:] - } - - tr = gost.QUICTransporter(config) - case "http2": - tr = gost.HTTP2Transporter(tlsCfg) - case "h2": - tr = gost.H2Transporter(tlsCfg) - case "h2c": - tr = gost.H2CTransporter() - - case "obfs4": - tr = gost.Obfs4Transporter() - case "ohttp": - tr = gost.ObfsHTTPTransporter() - default: - tr = gost.TCPTransporter() - } - - var connector gost.Connector - switch node.Protocol { - case "http2": - connector = gost.HTTP2Connector(node.User) - case "socks", "socks5": - connector = gost.SOCKS5Connector(node.User) - case "socks4": - connector = gost.SOCKS4Connector() - case "socks4a": - connector = gost.SOCKS4AConnector() - case "ss": - connector = gost.ShadowConnector(node.User) - case "direct": - connector = gost.SSHDirectForwardConnector() - case "remote": - connector = gost.SSHRemoteForwardConnector() - case "forward": - connector = gost.ForwardConnector() - case "sni": - connector = gost.SNIConnector(node.Get("host")) - case "http": - fallthrough - default: - node.Protocol = "http" // default protocol is HTTP - connector = gost.HTTPConnector(node.User) - } - - timeout := node.GetInt("timeout") - node.DialOptions = append(node.DialOptions, - gost.TimeoutDialOption(time.Duration(timeout)*time.Second), - ) - - handshakeOptions := []gost.HandshakeOption{ - gost.AddrHandshakeOption(node.Addr), - gost.HostHandshakeOption(node.Host), - gost.UserHandshakeOption(node.User), - gost.TLSConfigHandshakeOption(tlsCfg), - gost.IntervalHandshakeOption(time.Duration(node.GetInt("ping")) * time.Second), - gost.TimeoutHandshakeOption(time.Duration(timeout) * time.Second), - gost.RetryHandshakeOption(node.GetInt("retry")), - } - node.Client = &gost.Client{ - Connector: connector, - Transporter: tr, - } - - node.Bypass = parseBypass(node.Get("bypass")) - - ips := parseIP(node.Get("ip"), sport) - for _, ip := range ips { - node.Addr = ip - // override the default node address - node.HandshakeOptions = append(handshakeOptions, gost.AddrHandshakeOption(ip)) - // One node per IP - nodes = append(nodes, node) - } - if len(ips) == 0 { - node.HandshakeOptions = handshakeOptions - nodes = []gost.Node{node} - } - - if node.Transport == "obfs4" { - for i := range nodes { - if err := gost.Obfs4Init(nodes[i], false); err != nil { - return nil, err - } - } - } - - return -} - -func (r *route) serve() error { - chain, err := r.initChain() - if err != nil { - return err - } - - for _, ns := range r.ServeNodes { - node, err := gost.ParseNode(ns) - if err != nil { - return err - } - users, err := parseUsers(node.Get("secrets")) - if err != nil { - return err - } - if node.User != nil { - users = append(users, node.User) - } - certFile, keyFile := node.Get("cert"), node.Get("key") - tlsCfg, err := tlsConfig(certFile, keyFile) - if err != nil && certFile != "" && keyFile != "" { - return err - } - - wsOpts := &gost.WSOptions{} - wsOpts.EnableCompression = node.GetBool("compression") - wsOpts.ReadBufferSize = node.GetInt("rbuf") - wsOpts.WriteBufferSize = node.GetInt("wbuf") - - var ln gost.Listener - switch node.Transport { - case "tls": - ln, err = gost.TLSListener(node.Addr, tlsCfg) - case "mtls": - ln, err = gost.MTLSListener(node.Addr, tlsCfg) - case "ws": - wsOpts.WriteBufferSize = node.GetInt("wbuf") - ln, err = gost.WSListener(node.Addr, wsOpts) - case "mws": - ln, err = gost.MWSListener(node.Addr, wsOpts) - case "wss": - ln, err = gost.WSSListener(node.Addr, tlsCfg, wsOpts) - case "mwss": - ln, err = gost.MWSSListener(node.Addr, tlsCfg, wsOpts) - case "kcp": - config, er := parseKCPConfig(node.Get("c")) - if er != nil { - return er - } - ln, err = gost.KCPListener(node.Addr, config) - case "ssh": - config := &gost.SSHConfig{ - Users: users, - TLSConfig: tlsCfg, - } - if node.Protocol == "forward" { - ln, err = gost.TCPListener(node.Addr) - } else { - ln, err = gost.SSHTunnelListener(node.Addr, config) - } - case "quic": - config := &gost.QUICConfig{ - TLSConfig: tlsCfg, - KeepAlive: node.GetBool("keepalive"), - Timeout: time.Duration(node.GetInt("timeout")) * time.Second, - IdleTimeout: time.Duration(node.GetInt("idle")) * time.Second, - } - if cipher := node.Get("cipher"); cipher != "" { - sum := sha256.Sum256([]byte(cipher)) - config.Key = sum[:] - } - - ln, err = gost.QUICListener(node.Addr, config) - case "http2": - ln, err = gost.HTTP2Listener(node.Addr, tlsCfg) - case "h2": - ln, err = gost.H2Listener(node.Addr, tlsCfg) - case "h2c": - ln, err = gost.H2CListener(node.Addr) - case "tcp": - // Directly use SSH port forwarding if the last chain node is forward+ssh - if chain.LastNode().Protocol == "forward" && chain.LastNode().Transport == "ssh" { - chain.Nodes()[len(chain.Nodes())-1].Client.Connector = gost.SSHDirectForwardConnector() - chain.Nodes()[len(chain.Nodes())-1].Client.Transporter = gost.SSHForwardTransporter() - } - ln, err = gost.TCPListener(node.Addr) - case "rtcp": - // Directly use SSH port forwarding if the last chain node is forward+ssh - if chain.LastNode().Protocol == "forward" && chain.LastNode().Transport == "ssh" { - chain.Nodes()[len(chain.Nodes())-1].Client.Connector = gost.SSHRemoteForwardConnector() - chain.Nodes()[len(chain.Nodes())-1].Client.Transporter = gost.SSHForwardTransporter() - } - ln, err = gost.TCPRemoteForwardListener(node.Addr, chain) - case "udp": - ln, err = gost.UDPDirectForwardListener(node.Addr, time.Duration(node.GetInt("ttl"))*time.Second) - case "rudp": - ln, err = gost.UDPRemoteForwardListener(node.Addr, chain, time.Duration(node.GetInt("ttl"))*time.Second) - case "ssu": - ln, err = gost.ShadowUDPListener(node.Addr, node.User, time.Duration(node.GetInt("ttl"))*time.Second) - case "obfs4": - if err = gost.Obfs4Init(node, true); err != nil { - return err - } - ln, err = gost.Obfs4Listener(node.Addr) - case "ohttp": - ln, err = gost.ObfsHTTPListener(node.Addr) - default: - ln, err = gost.TCPListener(node.Addr) - } - if err != nil { - return err - } - - var handler gost.Handler - switch node.Protocol { - case "http2": - handler = gost.HTTP2Handler() - case "socks", "socks5": - handler = gost.SOCKS5Handler() - case "socks4", "socks4a": - handler = gost.SOCKS4Handler() - case "ss": - handler = gost.ShadowHandler() - case "http": - handler = gost.HTTPHandler() - case "tcp": - handler = gost.TCPDirectForwardHandler(node.Remote) - case "rtcp": - handler = gost.TCPRemoteForwardHandler(node.Remote) - case "udp": - handler = gost.UDPDirectForwardHandler(node.Remote) - case "rudp": - handler = gost.UDPRemoteForwardHandler(node.Remote) - case "forward": - handler = gost.SSHForwardHandler() - case "redirect": - handler = gost.TCPRedirectHandler() - case "ssu": - handler = gost.ShadowUDPdHandler() - case "sni": - handler = gost.SNIHandler() - default: - // start from 2.5, if remote is not empty, then we assume that it is a forward tunnel. - if node.Remote != "" { - handler = gost.TCPDirectForwardHandler(node.Remote) - } else { - handler = gost.AutoHandler() - } - } - - var whitelist, blacklist *gost.Permissions - if node.Values.Get("whitelist") != "" { - if whitelist, err = gost.ParsePermissions(node.Get("whitelist")); err != nil { - return err - } - } - if node.Values.Get("blacklist") != "" { - if blacklist, err = gost.ParsePermissions(node.Get("blacklist")); err != nil { - return err - } - } - - var hosts *gost.Hosts - if f, _ := os.Open(node.Get("hosts")); f != nil { - f.Close() - hosts = gost.NewHosts() - go gost.PeriodReload(hosts, node.Get("hosts")) - } - - handler.Init( - gost.AddrHandlerOption(node.Addr), - gost.ChainHandlerOption(chain), - gost.UsersHandlerOption(users...), - gost.TLSConfigHandlerOption(tlsCfg), - gost.WhitelistHandlerOption(whitelist), - gost.BlacklistHandlerOption(blacklist), - gost.BypassHandlerOption(parseBypass(node.Get("bypass"))), - gost.StrategyHandlerOption(parseStrategy(node.Get("strategy"))), - gost.ResolverHandlerOption(parseResolver(node.Get("dns"))), - gost.HostsHandlerOption(hosts), - gost.RetryHandlerOption(node.GetInt("retry")), - gost.TimeoutHandlerOption(time.Duration(node.GetInt("timeout"))*time.Second), - gost.ProbeResistHandlerOption(node.Get("probe_resist")), - ) - - srv := &gost.Server{Listener: ln} - go srv.Serve(handler) - } - - return nil -}