diff --git a/README.md b/README.md index 423211c..af9ef55 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,45 @@ INFO: genericlistener: 2017/03/02 19:16:52.652868 manager.go:111: &{map[] 0xc420 INFO: genericlistener: 2017/03/02 19:16:52.652869 conn_tracking.go:25: Tracking Running ``` +### Browse via tunnel +https://hfc.daplie.me:8443 + +- You'll notice that the browser is redirected to 8080 after accepting the cert. I see a meta-refresh coming back from the serve-https +- The traffic is getting back to the client. + +```bash + +INFO: genericlistener: 2017/03/02 21:24:48.472312 connection.go:207: 00000000 fe 1d 49 50 76 34 2c 31 32 37 2e 30 2e 30 2e 31 |..IPv4,127.0.0.1| +00000010 2c 35 33 35 35 39 2c 33 36 38 2c 68 74 74 70 48 |,53559,368,httpH| +00000020 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d 0a |TTP/1.1 200 OK..| +00000030 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 74 65 |Content-Type: te| +00000040 78 74 2f 68 74 6d 6c 3b 20 63 68 61 72 73 65 74 |xt/html; charset| +00000050 3d 75 74 66 2d 38 0d 0a 44 61 74 65 3a 20 46 72 |=utf-8..Date: Fr| +00000060 69 2c 20 30 33 20 4d 61 72 20 32 30 31 37 20 30 |i, 03 Mar 2017 0| +00000070 33 3a 32 34 3a 34 38 20 47 4d 54 0d 0a 43 6f 6e |3:24:48 GMT..Con| +00000080 6e 65 63 74 69 6f 6e 3a 20 6b 65 65 70 2d 61 6c |nection: keep-al| +00000090 69 76 65 0d 0a 43 6f 6e 74 65 6e 74 2d 4c 65 6e |ive..Content-Len| +000000a0 67 74 68 3a 20 32 32 37 0d 0a 0d 0a 3c 68 74 6d |gth: 227...... ....<| +00000180 2f 62 6f 64 79 3e 0a 3c 2f 68 74 6d 6c 3e 0a |/body>..| + +``` + +- this set of code works great if I am running the node-tunnel-client on a different machine with apache as a web server. +- need to work through why serve-https thinks the traffic is inecure. diff --git a/main.go b/main.go index bbd429f..ddba4a5 100644 --- a/main.go +++ b/main.go @@ -1,10 +1,96 @@ package main -import "git.daplie.com/Daplie/go-rvpn-server/rvpn/rvpnmain" +import ( + "crypto/tls" + "flag" + "fmt" + "log" + "os" + "time" -var run = rvpnmain.Run + "context" -func main() { - rvpnmain.Run() + "git.daplie.com/Daplie/go-rvpn-server/rvpn/genericlistener" + "git.daplie.com/Daplie/go-rvpn-server/rvpn/xlate" +) +var ( + loginfo *log.Logger + logdebug *log.Logger + logFlags = log.Ldate | log.Lmicroseconds | log.Lshortfile + argWssClientListener string + argGenericBinding string + argServerBinding string + argServerAdminBinding string + argServerExternalBinding string + argDeadTime int + connectionTable *genericlistener.Table + wssMapping *xlate.WssMapping + secretKey = "abc123" +) + +func init() { + flag.IntVar(&argDeadTime, "dead-time-counter", 5, "deadtime counter in seconds") + flag.StringVar(&argGenericBinding, "generic-listener", ":8443", "generic SSL Listener") + flag.StringVar(&argWssClientListener, "wss-client-listener", ":3502", "wss client listener address:port") + flag.StringVar(&argServerAdminBinding, "admin-server-port", "127.0.0.2:8000", "admin server Bind listener") + flag.StringVar(&argServerExternalBinding, "external-server-port", "127.0.0.1:8080", "external server Bind listener") +} + +//Main -- main entry point +func main() { + flag.Parse() + + loginfo = log.New(os.Stdout, "INFO: packer: ", logFlags) + logdebug = log.New(os.Stdout, "DEBUG: packer:", logFlags) + + loginfo.Println("startup") + + fmt.Println("-=-=-=-=-=-=-=-=-=-=") + + certbundle, err := tls.LoadX509KeyPair("certs/fullchain.pem", "certs/privkey.pem") + if err != nil { + loginfo.Println(err) + return + } + + ctx, cancelContext := context.WithCancel(context.Background()) + defer cancelContext() + + // Setup for GenericListenServe. + // - establish context for the generic listener + // - startup listener + // - accept with peek buffer. + // - peek at the 1st 30 bytes. + // - check for tls + // - if tls, establish, protocol peek buffer, else decrypted + // - match protocol + + connectionTracking := genericlistener.NewTracking() + go connectionTracking.Run(ctx) + + connectionTable = genericlistener.NewTable() + go connectionTable.Run(ctx) + + genericListeners := genericlistener.NewGenerListeners(ctx, connectionTable, connectionTracking, secretKey, certbundle, argDeadTime) + go genericListeners.Run(ctx, 8443) + + //go genericlistener.GenericListenAndServe(ctx, connectionTable, secretKey, argGenericBinding, certbundle, argDeadTime) + + //Run for 10 minutes and then shutdown cleanly + time.Sleep(600 * time.Second) + cancelContext() + + //wssMapping = xlate.NewwssMapping() + //go wssMapping.Run() + + //go client.LaunchClientListener(connectionTable, &secretKey, &argServerBinding) + //go external.LaunchWebRequestExternalListener(&argServerExternalBinding, connectionTable) + //go external.LaunchExternalServer(argServerExternalBinding, connectionTable) + //err = admin.LaunchAdminListener(&argServerAdminBinding, connectionTable) + //if err != nil { + // loginfo.Println("LauchAdminListener failed: ", err) + //} + + //genericlistener.LaunchWssListener(connectionTable, secretKey, argWssClientListener, "certs/fullchain.pem", "certs/privkey.pem") } diff --git a/rvpn-docker/docker-compose.yml b/rvpn-docker/docker-compose.yml new file mode 100644 index 0000000..1dbc5ec --- /dev/null +++ b/rvpn-docker/docker-compose.yml @@ -0,0 +1,15 @@ +version: '2.0' +services: + rvpn: + build: rvpn/. + ports: + - "8443:8443" + entrypoint: + - ./start.sh + expose: + - "8843" + volumes: + - $GOPATH/:/go + - ../:/go-rvpn-server + + diff --git a/rvpn-docker/readme.md b/rvpn-docker/readme.md new file mode 100644 index 0000000..11b4f7e --- /dev/null +++ b/rvpn-docker/readme.md @@ -0,0 +1,92 @@ +# Docker Deployment for RVPN + +- install docker 1.13, or the latest stable CE release (Testing on MAC using 17.03.0-ce-mac1 (15583)) +- validate installation + +```bash +hcamacho@Hanks-MBP:rvpn-docker $ docker-compose --version +docker-compose version 1.11.2, build dfed245 + +hcamacho@Hanks-MBP:rvpn-docker $ docker --version +Docker version 17.03.0-ce, build 60ccb22 +``` +- checkout code into gopath + +```bash +cd $GOPATH/src/git.daplie.com/Daplie +git clone git@git.daplie.com:Daplie/go-rvpn-server.git + +cd go-rvpn-server +go get + +``` + +## Execute Container Deployment + +- prep + +```bash +cd rvpn-docker +hcamacho@Hanks-MBP:rvpn-docker $ docker-compose build +Building rvpn +Step 1/3 : FROM golang:1.7.5 + ---> 5cfb16b630ef +Step 2/3 : LABEL maintainer "henry.f.camacho@gmail.com" + ---> Running in 5cdffef8e33d + ---> f7e09c097612 +Removing intermediate container 5cdffef8e33d +Step 3/3 : WORKDIR "/go-rvpn-server" + ---> 182aa9c814f2 +Removing intermediate container f136550d6d48 +Successfully built 182aa9c814f2 + +``` + +- execute container + +```bash +hcamacho@Hanks-MBP:rvpn-docker $ docker-compose up +Creating network "rvpndocker_default" with the default driver +Creating rvpndocker_rvpn_1 +Attaching to rvpndocker_rvpn_1 +rvpn_1 | INFO: packer: 2017/03/04 18:13:00.994955 main.go:47: startup +rvpn_1 | -=-=-=-=-=-=-=-=-=-= +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:01.000063 conn_tracking.go:25: Tracking Running +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:01.000067 connection_table.go:67: ConnectionTable starting +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:01.000214 connection_table.go:50: Reaper waiting for 300 seconds +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:00.999757 manager.go:77: ConnectionTable starting +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:01.000453 manager.go:84: &{map[] 0xc4200124e0 0xc420012540} +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:01.000505 manager.go:100: register fired 8443 +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:01.000613 manager.go:110: listener starting up 8443 +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:01.000638 manager.go:111: &{map[] 0xc4200124e0 0xc420012540} +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:01.000696 listener_generic.go:55: :⃻ +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.242287 listener_generic.go:87: Deadtime reached +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.242596 listener_generic.go:114: conn &{0xc420120000 0xc42011e000} 172.18.0.2:8443 172.18.0.1:38148 +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.242627 listener_generic.go:131: TLS10 +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.242641 listener_generic.go:148: Handle Encryption +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.242654 one_conn.go:22: Accept 172.18.0.2:8443 172.18.0.1:38148 +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.242699 listener_generic.go:177: handle Stream +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.242722 listener_generic.go:178: conn &{0xc420120060 0xc420126000} 172.18.0.2:8443 172.18.0.1:38148 +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.266803 listener_generic.go:191: identifed HTTP +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.267797 listener_generic.go:207: Valid WSS dected...sending to handler +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.267926 one_conn.go:32: addr +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.267947 one_conn.go:22: Accept 172.18.0.2:8443 172.18.0.1:38148 +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.268045 one_conn.go:17: Accept +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.268062 one_conn.go:27: close +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.268066 listener_generic.go:421: Serve error: EOF +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.268707 listener_generic.go:366: HandleFunc / +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.268727 listener_generic.go:369: websocket opening 172.18.0.1:38148 localhost.daplie.me:8443 +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.269264 listener_generic.go:397: before connection table +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.269321 connection_table.go:79: register fired +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.269523 connection_table.go:90: adding domain hfc.daplie.me to connection 172.18.0.1:38148 +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.269602 connection_table.go:90: adding domain test1.hfc.daplie.me to connection 172.18.0.1:38148 +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.269821 listener_generic.go:410: connection registration accepted &{0xc42012af00 172.18.0.1:38148 0xc420120ea0 [hfc.daplie.me test1.hfc.daplie.me] 0xc4200f49c0} +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.270168 connection.go:200: Reader Start &{0xc420104990 0xc420077560 map[hfc.daplie.me:0xc4201ee7a0 test1.hfc.daplie.me:0xc4201ee7c0] 0xc42012af00 0xc420120f00 172.18.0.1:38148 0 0 {63624247982 269492963 0x8392a0} {0 0 } [hfc.daplie.me test1.hfc.daplie.me] 0xc4200f49c0 true} +rvpn_1 | INFO: genericlistener: 2017/03/04 18:13:02.270281 connection.go:242: Writer Start &{0xc420104990 0xc420077560 map[hfc.daplie.me:0xc4201ee7a0 test1.hfc.daplie.me:0xc4201ee7c0] 0xc42012af00 0xc420120f00 172.18.0.1:38148 0 0 {63624247982 269492963 0x8392a0} {0 0 } [hfc.daplie.me test1.hfc.daplie.me] 0xc4200f49c0 true} + +``` + +The line "Connection Registration Accepted indicates a client WSS registered, was authenticated and registered its domains with the RVPN + + + diff --git a/rvpn-docker/rvpn/Dockerfile b/rvpn-docker/rvpn/Dockerfile new file mode 100644 index 0000000..839adf8 --- /dev/null +++ b/rvpn-docker/rvpn/Dockerfile @@ -0,0 +1,5 @@ +FROM golang:1.7.5 +LABEL maintainer "henry.f.camacho@gmail.com" + + +WORKDIR "/go-rvpn-server" diff --git a/rvpn-docker/rvpn/run.sh b/rvpn-docker/rvpn/run.sh new file mode 100755 index 0000000..3c14662 --- /dev/null +++ b/rvpn-docker/rvpn/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +docker-compose run --entrypoint "/bin/bash" rvpn + diff --git a/rvpn/genericlistener/listener_generic.go b/rvpn/genericlistener/listener_generic.go index 6fbf343..4270994 100644 --- a/rvpn/genericlistener/listener_generic.go +++ b/rvpn/genericlistener/listener_generic.go @@ -227,20 +227,20 @@ func handleStream(ctx context.Context, wConn *WedgeConn) { //handleExternalHTTPRequest - // - get a wConn and start processing requests -func handleExternalHTTPRequest(ctx context.Context, conn net.Conn) { +func handleExternalHTTPRequest(ctx context.Context, extConn net.Conn) { connectionTracking := ctx.Value(ctxConnectionTrack).(*Tracking) - connectionTracking.register <- conn + connectionTracking.register <- extConn defer func() { - connectionTracking.unregister <- conn - conn.Close() + connectionTracking.unregister <- extConn + extConn.Close() }() connectionTable := ctx.Value(ctxConnectionTable).(*Table) var buffer [512]byte for { - cnt, err := conn.Read(buffer[0:]) + cnt, err := extConn.Read(buffer[0:]) if err != nil { return } @@ -262,9 +262,9 @@ func handleExternalHTTPRequest(ctx context.Context, conn net.Conn) { hostname = arr[0] } - loginfo.Println("Remote: ", conn.RemoteAddr().String()) + loginfo.Println("Remote: ", extConn.RemoteAddr().String()) - remoteSplit := strings.Split(conn.RemoteAddr().String(), ":") + remoteSplit := strings.Split(extConn.RemoteAddr().String(), ":") rAddr := remoteSplit[0] rPort := remoteSplit[1] diff --git a/rvpn/rvpnmain/run.go b/rvpn/rvpnmain/run.go deleted file mode 100644 index a949dc9..0000000 --- a/rvpn/rvpnmain/run.go +++ /dev/null @@ -1,96 +0,0 @@ -package rvpnmain - -import ( - "crypto/tls" - "flag" - "fmt" - "log" - "os" - "time" - - "context" - - "git.daplie.com/Daplie/go-rvpn-server/rvpn/genericlistener" - "git.daplie.com/Daplie/go-rvpn-server/rvpn/xlate" -) - -var ( - loginfo *log.Logger - logdebug *log.Logger - logFlags = log.Ldate | log.Lmicroseconds | log.Lshortfile - argWssClientListener string - argGenericBinding string - argServerBinding string - argServerAdminBinding string - argServerExternalBinding string - argDeadTime int - connectionTable *genericlistener.Table - wssMapping *xlate.WssMapping - secretKey = "abc123" -) - -func init() { - flag.IntVar(&argDeadTime, "dead-time-counter", 5, "deadtime counter in seconds") - flag.StringVar(&argGenericBinding, "generic-listener", ":8443", "generic SSL Listener") - flag.StringVar(&argWssClientListener, "wss-client-listener", ":3502", "wss client listener address:port") - flag.StringVar(&argServerAdminBinding, "admin-server-port", "127.0.0.2:8000", "admin server Bind listener") - flag.StringVar(&argServerExternalBinding, "external-server-port", "127.0.0.1:8080", "external server Bind listener") -} - -//Run -- main entry point -func Run() { - flag.Parse() - - loginfo = log.New(os.Stdout, "INFO: packer: ", logFlags) - logdebug = log.New(os.Stdout, "DEBUG: packer:", logFlags) - - loginfo.Println("startup") - - fmt.Println("-=-=-=-=-=-=-=-=-=-=") - - certbundle, err := tls.LoadX509KeyPair("certs/fullchain.pem", "certs/privkey.pem") - if err != nil { - loginfo.Println(err) - return - } - - ctx, cancelContext := context.WithCancel(context.Background()) - defer cancelContext() - - // Setup for GenericListenServe. - // - establish context for the generic listener - // - startup listener - // - accept with peek buffer. - // - peek at the 1st 30 bytes. - // - check for tls - // - if tls, establish, protocol peek buffer, else decrypted - // - match protocol - - connectionTracking := genericlistener.NewTracking() - go connectionTracking.Run(ctx) - - connectionTable = genericlistener.NewTable() - go connectionTable.Run(ctx) - - genericListeners := genericlistener.NewGenerListeners(ctx, connectionTable, connectionTracking, secretKey, certbundle, argDeadTime) - go genericListeners.Run(ctx, 8443) - - //go genericlistener.GenericListenAndServe(ctx, connectionTable, secretKey, argGenericBinding, certbundle, argDeadTime) - - time.Sleep(300 * time.Second) - cancelContext() - time.Sleep(60 * time.Second) - - //wssMapping = xlate.NewwssMapping() - //go wssMapping.Run() - - //go client.LaunchClientListener(connectionTable, &secretKey, &argServerBinding) - //go external.LaunchWebRequestExternalListener(&argServerExternalBinding, connectionTable) - //go external.LaunchExternalServer(argServerExternalBinding, connectionTable) - //err = admin.LaunchAdminListener(&argServerAdminBinding, connectionTable) - //if err != nil { - // loginfo.Println("LauchAdminListener failed: ", err) - //} - - //genericlistener.LaunchWssListener(connectionTable, secretKey, argWssClientListener, "certs/fullchain.pem", "certs/privkey.pem") -} diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..98189e3 --- /dev/null +++ b/start.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +go build && ./go-rvpn-server + +