mirror of
https://github.com/norouter/norouter.git
synced 2025-12-24 13:17:54 +08:00
add SOCKS mode (SOCKS4/4a/5)
SOCKS mode is similar to HTTP mode (#23) but does not depend on HTTP. Supports SOCKS4 and SOCKS4a as well as SOCKS5 (because socat doesn't support SOCKS5). The underlying library: https://pkg.go.dev/github.com/cybozu-go/usocksd@v1.1.0/socks Example manifest: ```yaml hostTemplate: http: listen: "127.0.0.1:18080" socks: listen: "127.0.0.1:18081" loopback: disable: true ports: ["80:127.0.0.1:80"] ``` This commit also adds changes for signal handling because required by the library. Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
@@ -24,6 +24,7 @@ import (
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
@@ -59,6 +60,7 @@ var managerFlags = []cli.Flag{
|
||||
var sigCh = make(chan os.Signal)
|
||||
|
||||
func managerAction(clicontext *cli.Context) error {
|
||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||
openEditor := clicontext.Bool("open-editor")
|
||||
manifestPath := clicontext.Args().First()
|
||||
if openEditor {
|
||||
@@ -71,14 +73,18 @@ func managerAction(clicontext *cli.Context) error {
|
||||
return errors.Errorf("no manifest file path was specified, run `%s show-example` to show an example, or run `%s --open-editor` to open an editor with an example file",
|
||||
os.Args[0], os.Args[0])
|
||||
}
|
||||
return runManager(manifestPath)
|
||||
err := runManager(manifestPath)
|
||||
if err == errInterrupted {
|
||||
logrus.Info("Interrupted. Exiting...")
|
||||
err = nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func runManagerWithEditor() error {
|
||||
if !isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
return errors.New("`--open-editor` requires stdout to be a terminal")
|
||||
}
|
||||
signal.Notify(sigCh, os.Interrupt)
|
||||
editor := editorcmd.Detect()
|
||||
if editor == "" {
|
||||
return errors.New("could not detect a text editor binary, try setting $EDITOR")
|
||||
|
||||
1
go.mod
1
go.mod
@@ -3,6 +3,7 @@ module github.com/norouter/norouter
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/cybozu-go/usocksd v1.1.0
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/elazarl/goproxy v0.0.0-20201021153353-00ad82a08272
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||
|
||||
35
go.sum
35
go.sum
@@ -12,6 +12,7 @@ cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20200908182639-5b44b70ab3ab/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
@@ -37,6 +38,14 @@ github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cybozu-go/log v1.5.0 h1:cjLr+pNga4NL5sj5vnnG00xKmKXSWx0grQQ4LnV1Ris=
|
||||
github.com/cybozu-go/log v1.5.0/go.mod h1:zpfovuCgUx+a/ErvQrThoT+/z1RVQoLDOf95wkBeRiw=
|
||||
github.com/cybozu-go/netutil v1.2.0 h1:UBO0+hB43zd5mIXRfD195eBMHvgWlHP2mYuQ2F5Yxtg=
|
||||
github.com/cybozu-go/netutil v1.2.0/go.mod h1:Wx92iF1dPrtuSzLUMEidtrKTFiDWpLcsYvbQ1lHSmxY=
|
||||
github.com/cybozu-go/usocksd v1.1.0 h1:0g0MbyhOFWaR0Iv3Kc+6YnlWeNXWRj3Wh67cdmvG3dk=
|
||||
github.com/cybozu-go/usocksd v1.1.0/go.mod h1:9nuohcMvU4K2oNIcyJG5ysaNdXJ8ZCQmDAaWvrO0WcU=
|
||||
github.com/cybozu-go/well v1.8.1 h1:YlEPreiDBI+KxE5rcAkkaB5j/Iyow6nIVmUpq3u5DYQ=
|
||||
github.com/cybozu-go/well v1.8.1/go.mod h1:9PK1AltjltFwZBtTWVXnCJ0fIeZMxGovYfLmCcZxQog=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -55,6 +64,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
@@ -104,6 +115,8 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
@@ -119,8 +132,12 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.4-0.20190131011033-7dc38fb350b1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mitchellh/mapstructure v1.0.0 h1:vVpGvMXJPqSDh2VYHF7gsfQj8Ncx+Xw5Y1KHeTRY+7I=
|
||||
github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mohae/deepcopy v0.0.0-20170308212314-bb9b5e7adda9/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
@@ -128,6 +145,9 @@ github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59P
|
||||
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.2-0.20181111125026-1722abf79c2f/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -146,9 +166,19 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg=
|
||||
github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
|
||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.2.1 h1:bIcUwXqLseLF3BDAZduuNfekWG87ibtFxi59Bq+oI9M=
|
||||
github.com/spf13/viper v1.2.1/go.mod h1:P4AexN0a+C9tGAnUFNwDMYYZv3pjFuvmeiMyKRaNVlI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
@@ -196,6 +226,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@@ -205,6 +236,7 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -220,6 +252,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2By
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -242,6 +275,7 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20u
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -314,6 +348,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
|
||||
@@ -10,6 +10,8 @@ cleanup() {
|
||||
if [[ -n "$pid" && -d "/proc/$pid" ]]; then kill $pid; fi
|
||||
docker rm -f host1 host2 host3
|
||||
make clean
|
||||
sleep 3
|
||||
if [[ -n "$pid" && -d "/proc/$pid" ]]; then echo "process still running?"; exit 1; fi
|
||||
set -e
|
||||
}
|
||||
cleanup
|
||||
@@ -95,6 +97,24 @@ for ((i = 0; i < $N; i++)); do
|
||||
done
|
||||
set +x
|
||||
|
||||
echo "Testing SOCKS4a mode"
|
||||
set -x
|
||||
for ((i = 0; i < $N; i++)); do
|
||||
for f in host1 host2 host3; do
|
||||
curl -fsS -o /dev/null --socks4a http://127.0.0.1:18081 http://${f}:8080
|
||||
done
|
||||
done
|
||||
set +x
|
||||
|
||||
echo "Testing SOCKS5h mode"
|
||||
set -x
|
||||
for ((i = 0; i < $N; i++)); do
|
||||
for f in host1 host2 host3; do
|
||||
curl -fsS -o /dev/null --socks5-hostname http://127.0.0.1:18081 http://${f}:8080
|
||||
done
|
||||
done
|
||||
set +x
|
||||
|
||||
echo "iperf3 from host2 to host1"
|
||||
docker exec host1 iperf3 -s > /dev/null &
|
||||
iperf3_exec_pid=$!
|
||||
|
||||
@@ -4,6 +4,8 @@ hosts:
|
||||
vip: "127.0.42.100"
|
||||
http:
|
||||
listen: "127.0.0.1:18080"
|
||||
socks:
|
||||
listen: "127.0.0.1:18081"
|
||||
host1:
|
||||
cmd: "docker exec -i host1 /mnt/norouter"
|
||||
vip: "127.0.42.101"
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
|
||||
agenthttp "github.com/norouter/norouter/pkg/agent/http"
|
||||
"github.com/norouter/norouter/pkg/agent/loopback"
|
||||
agentsocks "github.com/norouter/norouter/pkg/agent/socks"
|
||||
"github.com/norouter/norouter/pkg/bicopy/bicopyutil"
|
||||
"github.com/norouter/norouter/pkg/netstackutil"
|
||||
"github.com/norouter/norouter/pkg/stream"
|
||||
@@ -156,23 +157,52 @@ func (a *Agent) configure(args *jsonmsg.ConfigureRequestArgs) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if a.config.HTTP.Listen != "" {
|
||||
logrus.Debugf("http listen=%q", a.config.HTTP.Listen)
|
||||
l, err := net.Listen("tcp", a.config.HTTP.Listen)
|
||||
if err != nil {
|
||||
if err := a.configureHTTP(); err != nil {
|
||||
return err
|
||||
}
|
||||
httpHandler, err := agenthttp.NewHandler(a.stack, a.config.HostnameMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
srv := &http.Server{Handler: httpHandler}
|
||||
go srv.Serve(l)
|
||||
}
|
||||
|
||||
if a.config.SOCKS.Listen != "" {
|
||||
if err := a.configureSOCKS(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
go a.sendL3Routine()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Agent) configureHTTP() error {
|
||||
logrus.Debugf("http listen=%q", a.config.HTTP.Listen)
|
||||
l, err := net.Listen("tcp", a.config.HTTP.Listen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
httpHandler, err := agenthttp.NewHandler(a.stack, a.config.HostnameMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
srv := &http.Server{Handler: httpHandler}
|
||||
go srv.Serve(l)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Agent) configureSOCKS() error {
|
||||
logrus.Debugf("socks listen=%q (supports SOCKS4/4a/5)", a.config.SOCKS.Listen)
|
||||
l, err := net.Listen("tcp", a.config.SOCKS.Listen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
srv, err := agentsocks.NewServer(a.stack, a.config.HostnameMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go srv.Serve(l)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Agent) goGonetForward(me net.IP, f jsonmsg.Forward) error {
|
||||
if f.Proto != "tcp" {
|
||||
return errors.Errorf("expected proto be \"tcp\", got %q", f.Proto)
|
||||
|
||||
79
pkg/agent/socks/socks.go
Normal file
79
pkg/agent/socks/socks.go
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright (C) NoRouter authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package socks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"github.com/cybozu-go/usocksd/socks"
|
||||
"github.com/pkg/errors"
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
|
||||
func NewServer(st *stack.Stack, hostnameMap map[string]net.IP) (*socks.Server, error) {
|
||||
d, err := NewDialer(st, hostnameMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := &socks.Server{
|
||||
Dialer: d,
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func NewDialer(st *stack.Stack, hostnameMap map[string]net.IP) (socks.Dialer, error) {
|
||||
d := &dialer{
|
||||
stack: st,
|
||||
hostnameMap: hostnameMap,
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
type dialer struct {
|
||||
stack *stack.Stack
|
||||
hostnameMap map[string]net.IP
|
||||
}
|
||||
|
||||
func (d *dialer) Dial(req *socks.Request) (net.Conn, error) {
|
||||
ip := req.IP
|
||||
if len(ip) == 0 {
|
||||
if req.Hostname != "" {
|
||||
if parsed := net.ParseIP(req.Hostname); len(parsed) != 0 {
|
||||
ip = parsed
|
||||
}
|
||||
if resolved, ok := d.hostnameMap[req.Hostname]; ok {
|
||||
ip = resolved
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(ip) == 0 {
|
||||
reqWithoutPassword := *req
|
||||
if reqWithoutPassword.Password != "" {
|
||||
reqWithoutPassword.Password = "********"
|
||||
}
|
||||
return nil, errors.Errorf("failed to determine IP for request %+v", reqWithoutPassword)
|
||||
}
|
||||
fullAddr := tcpip.FullAddress{
|
||||
Addr: tcpip.Address(ip),
|
||||
Port: uint16(req.Port),
|
||||
}
|
||||
return gonet.DialContextTCP(context.TODO(), d.stack, fullAddr, ipv4.ProtocolNumber)
|
||||
}
|
||||
@@ -83,6 +83,7 @@ func NewCmdClient(ctx context.Context, hostname string, pm *parsed.ParsedManifes
|
||||
configRequestArgs.HostnameMap[k] = v.VIP
|
||||
}
|
||||
configRequestArgs.HTTP.Listen = h.HTTP.Listen
|
||||
configRequestArgs.SOCKS.Listen = h.SOCKS.Listen
|
||||
configRequestArgs.Loopback.Disable = h.Loopback.Disable
|
||||
configRequestArgsB, err := json.Marshal(configRequestArgs)
|
||||
if err != nil {
|
||||
|
||||
@@ -182,6 +182,13 @@ func (r *Manager) validateAgentFeatures(vip string, data jsonmsg.ConfigureResult
|
||||
vip, version.FeatureHTTP, cc.configRequestArgs.HTTP.Listen)
|
||||
}
|
||||
}
|
||||
if cc.configRequestArgs.SOCKS.Listen != "" {
|
||||
if _, ok := fm[version.FeatureSOCKS]; !ok {
|
||||
// not a critical error
|
||||
logrus.Warnf("%s lacks feature %q, SOCKS listen (%q) is ignored",
|
||||
vip, version.FeatureSOCKS, cc.configRequestArgs.SOCKS.Listen)
|
||||
}
|
||||
}
|
||||
if cc.configRequestArgs.Loopback.Disable {
|
||||
if _, ok := fm[version.FeatureDisableLoopback]; !ok {
|
||||
return errors.Errorf("manifest has Loopback.Disable, but %s lacks feature %q, aborting for security purpose",
|
||||
|
||||
@@ -54,6 +54,9 @@ type Host struct {
|
||||
// HTTP can be specified since NoRouter v0.4.0
|
||||
HTTP *HTTP `yaml:"http,omitempty"`
|
||||
|
||||
// SOCKS can be specified since NoRouter v0.4.0
|
||||
SOCKS *SOCKS `yaml:"socks,omitempty"`
|
||||
|
||||
// Loopback can be specified since NoRouter v0.4.0
|
||||
Loopback *Loopback `yaml:"loopback,omitempty"`
|
||||
}
|
||||
@@ -66,6 +69,16 @@ type HTTP struct {
|
||||
Listen string `yaml:"listen,omitempty"`
|
||||
}
|
||||
|
||||
// SOCKS can be specified since NoRouter v0.4.0
|
||||
type SOCKS struct {
|
||||
// Listen specifies an address of SOCKS proxy to be listened by NoRouter agent processes.
|
||||
// The address is typically a local address, e.g. "127.0.0.1:18081".
|
||||
// When the address is not specified, SOCKS proxy is disabled.
|
||||
//
|
||||
// Supported protocol versions: SOCKS4, SOCKS4a, and SOCKS5
|
||||
Listen string `yaml:"listen,omitempty"`
|
||||
}
|
||||
|
||||
// Loopback can be specified since NoRouter v0.4.0
|
||||
type Loopback struct {
|
||||
// Disable disables listening on multi-loopback addresses such as 127.0.42.100, 127.0.42.101...
|
||||
|
||||
@@ -38,17 +38,22 @@ type Host struct {
|
||||
VIP net.IP
|
||||
Ports []*jsonmsg.Forward
|
||||
HTTP HTTP
|
||||
SOCKS SOCKS
|
||||
Loopback Loopback
|
||||
}
|
||||
|
||||
type Loopback struct {
|
||||
Disable bool
|
||||
}
|
||||
|
||||
type HTTP struct {
|
||||
Listen string
|
||||
}
|
||||
|
||||
type SOCKS struct {
|
||||
Listen string
|
||||
}
|
||||
|
||||
type Loopback struct {
|
||||
Disable bool
|
||||
}
|
||||
|
||||
func New(raw *manifest.Manifest) (*ParsedManifest, error) {
|
||||
if ht := raw.HostTemplate; ht != nil {
|
||||
if ht.VIP != "" {
|
||||
@@ -105,6 +110,9 @@ func New(raw *manifest.Manifest) (*ParsedManifest, error) {
|
||||
if raw.HostTemplate.HTTP != nil {
|
||||
h.HTTP.Listen = raw.HostTemplate.HTTP.Listen
|
||||
}
|
||||
if raw.HostTemplate.SOCKS != nil {
|
||||
h.SOCKS.Listen = raw.HostTemplate.SOCKS.Listen
|
||||
}
|
||||
if raw.HostTemplate.Loopback != nil {
|
||||
h.Loopback.Disable = raw.HostTemplate.Loopback.Disable
|
||||
}
|
||||
@@ -112,6 +120,9 @@ func New(raw *manifest.Manifest) (*ParsedManifest, error) {
|
||||
if rh.HTTP != nil {
|
||||
h.HTTP.Listen = rh.HTTP.Listen
|
||||
}
|
||||
if rh.SOCKS != nil {
|
||||
h.SOCKS.Listen = rh.SOCKS.Listen
|
||||
}
|
||||
if rh.Loopback != nil {
|
||||
h.Loopback.Disable = rh.Loopback.Disable
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ type ConfigureRequestArgs struct {
|
||||
// Fields added in v0.4.0
|
||||
HostnameMap map[string]net.IP `json:"hostnameMap,omitempty"` // hostname -> ip
|
||||
HTTP HTTP `json:"http,omitempty"`
|
||||
SOCKS SOCKS `json:"socks,omitempty"`
|
||||
Loopback Loopback `json:"loopback,omitempty"`
|
||||
}
|
||||
|
||||
@@ -60,6 +61,10 @@ type HTTP struct {
|
||||
Listen string `json:"listen,omitempty"`
|
||||
}
|
||||
|
||||
type SOCKS struct {
|
||||
Listen string `json:"listen,omitempty"`
|
||||
}
|
||||
|
||||
type Loopback struct {
|
||||
Disable bool `json:"disable,omitempty"`
|
||||
}
|
||||
|
||||
@@ -25,8 +25,9 @@ const (
|
||||
// Features introduced in v0.4.0:
|
||||
FeatureHTTP = "http" // Listening on HTTP for proxy
|
||||
FeatureDisableLoopback = "disable-loopback" // Disabling loopback
|
||||
FeatureSOCKS = "socks" // Listening a SOCKS proxy (SOCKS4, SOCKS4a, and SOCKS5)
|
||||
// Features introduced in vX.Y.Z:
|
||||
// ...
|
||||
)
|
||||
|
||||
var Features = []Feature{FeatureLoopback, FeatureTCP, FeatureHTTP, FeatureDisableLoopback}
|
||||
var Features = []Feature{FeatureLoopback, FeatureTCP, FeatureHTTP, FeatureDisableLoopback, FeatureSOCKS}
|
||||
|
||||
Reference in New Issue
Block a user