From 8b65f91699cd474563c0abacc726a3d47961a78f Mon Sep 17 00:00:00 2001 From: maride Date: Thu, 23 Aug 2018 11:46:23 +0200 Subject: Add VPN container and access --- src/access.go | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/access.go (limited to 'src/access.go') diff --git a/src/access.go b/src/access.go new file mode 100644 index 0000000..6072025 --- /dev/null +++ b/src/access.go @@ -0,0 +1,111 @@ +package main + +import ( + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types" + "time" + "errors" + "net/http" + "fmt" + "github.com/docker/docker/api/types/network" +) + +var vpnContainerID string +var vpnNetworkID string + +func startVPN() (err error) { + // Set up our context and Docker CLI connection + setupContext() + setupDockerCLI() + // Set up network + setupNetwork() + + // Create container + resp, err := dockerCli.ContainerCreate(dockerCtx, &container.Config{ + Image: "circus-vpn", + }, &container.HostConfig{ + Privileged: true, + }, &network.NetworkingConfig{ + EndpointsConfig: map[string]*network.EndpointSettings{ + "endpoint": { + NetworkID: vpnNetworkID, + }, + }, + }, "") + + if err != nil { + return err + } + + // Start container + err = dockerCli.ContainerStart(dockerCtx, resp.ID, types.ContainerStartOptions{}) + if err != nil { + return err + } + + vpnContainerID = resp.ID + + return nil +} + +func stopVPN() { + setupContext() + setupDockerCLI() + + timeout := time.Second * 5 + dockerCli.ContainerStop(dockerCtx, vpnContainerID, &timeout) + + vpnContainerID = "" +} + +func setupNetwork() (error) { + setupContext() + setupDockerCLI() + + if vpnNetworkID == "" { + response, err := dockerCli.NetworkCreate(dockerCtx, VPNNetworkName, types.NetworkCreate{ + Internal: true, + }) + + if err != nil { + return err + } + + vpnNetworkID = response.ID + } + + return nil +} + +func getCertificate() (string, error) { + if vpnContainerID == "" { + return "", errors.New("VPN container not up") + } + + // Get IP of VPN container + inspectJSON, err := dockerCli.ContainerInspect(dockerCtx, vpnContainerID) + if err != nil { + return "", err + } + + // get certificate + var certResponse *http.Response + + for i := 0; i < 10; i++ { + certResponse, err = http.Get(fmt.Sprintf("http://%s:9999/", inspectJSON.NetworkSettings.Networks[VPNNetworkName].IPAddress)) + + if err == nil { + break + } + time.Sleep(time.Second) + } + + if err != nil { + return "", err + } + + buffer := make([]byte, 1024) + certResponse.Body.Read(buffer) + + return string(buffer), nil +} -- cgit 1.4.1 From 65d1f311e1679d0d61b4be9162fdab23359c2403 Mon Sep 17 00:00:00 2001 From: maride Date: Thu, 23 Aug 2018 12:10:35 +0200 Subject: Add port forwarding for VPN, print remote address/port into env vars of VPN container --- README.md | 2 ++ src/access.go | 15 +++++++++++++++ src/main.go | 1 + 3 files changed, 18 insertions(+) (limited to 'src/access.go') diff --git a/README.md b/README.md index 89b2017..bef50bc 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ This executable needs some parameters to work properly: | `-accessCode` | Yes | Access code for the user. *Default: AllYourCodesAreBelongToUs* | | `-sessionSalt` | Yes | Variable to salt the session token generator with. | | `-seedFile` | Yes | JSON file to read challenge information from. | +| `-vpnRemoteAddress` | Yes | Address the VPN will run on, as rendered into the client VPN configuration file. | +| `-vpnRemotePort` | No | Port the VPN will run on | ## Seed file diff --git a/src/access.go b/src/access.go index 6072025..ddb032d 100644 --- a/src/access.go +++ b/src/access.go @@ -8,10 +8,18 @@ import ( "net/http" "fmt" "github.com/docker/docker/api/types/network" + "flag" ) var vpnContainerID string var vpnNetworkID string +var remoteAddress* string +var remotePort* int + +func registerAccessFlags() { + remoteAddress = flag.String("vpnRemoteAddress", "", "The remote domain name or IP the VPN will run on") + remotePort = flag.Int("vpnRemotePort", 1194, "The port the VPN should listen on") +} func startVPN() (err error) { // Set up our context and Docker CLI connection @@ -23,12 +31,19 @@ func startVPN() (err error) { // Create container resp, err := dockerCli.ContainerCreate(dockerCtx, &container.Config{ Image: "circus-vpn", + Env: []string{ + fmt.Sprintf("remoteAddress=%s", *remoteAddress), + fmt.Sprintf("remotePort=%d", *remotePort), + }, }, &container.HostConfig{ Privileged: true, }, &network.NetworkingConfig{ EndpointsConfig: map[string]*network.EndpointSettings{ "endpoint": { NetworkID: vpnNetworkID, + Links: []string{ + fmt.Sprintf("%d:1194/tcp", *remotePort), + }, }, }, }, "") diff --git a/src/main.go b/src/main.go index a06ee66..ae50632 100644 --- a/src/main.go +++ b/src/main.go @@ -11,6 +11,7 @@ func main() { registerSessionFlags() registerCredentialsFlags() registerSeedFlags() + registerAccessFlags() flag.Parse() // Read challenges from file -- cgit 1.4.1 From a2540513db864492ff89f9ef8622a7d4bbec1880 Mon Sep 17 00:00:00 2001 From: maride Date: Sun, 2 Sep 2018 01:49:00 +0200 Subject: Correctly link port to container, specify IP range --- src/access.go | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 12 deletions(-) (limited to 'src/access.go') diff --git a/src/access.go b/src/access.go index ddb032d..34b2470 100644 --- a/src/access.go +++ b/src/access.go @@ -1,18 +1,21 @@ package main import ( - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types" - "time" + "bytes" "errors" - "net/http" + "flag" "fmt" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" - "flag" + "github.com/docker/go-connections/nat" + "net/http" + "time" ) var vpnContainerID string var vpnNetworkID string +var vpnHostNetworkID string var remoteAddress* string var remotePort* int @@ -26,7 +29,17 @@ func startVPN() (err error) { setupContext() setupDockerCLI() // Set up network - setupNetwork() + err = setupNetwork() + + if(err != nil) { + return err + } + + err = setupVPNHostNetwork() + + if err != nil { + return err + } // Create container resp, err := dockerCli.ContainerCreate(dockerCtx, &container.Config{ @@ -35,15 +48,23 @@ func startVPN() (err error) { fmt.Sprintf("remoteAddress=%s", *remoteAddress), fmt.Sprintf("remotePort=%d", *remotePort), }, + ExposedPorts: map[nat.Port]struct{}{ + "1194/udp": {}, + }, }, &container.HostConfig{ Privileged: true, + PortBindings: nat.PortMap{ + "1194/udp": []nat.PortBinding{ + { + HostIP: "0.0.0.0", + HostPort: "1194", + }, + }, + }, }, &network.NetworkingConfig{ EndpointsConfig: map[string]*network.EndpointSettings{ - "endpoint": { - NetworkID: vpnNetworkID, - Links: []string{ - fmt.Sprintf("%d:1194/tcp", *remotePort), - }, + "startpoint": { + NetworkID: vpnHostNetworkID, }, }, }, "") @@ -52,6 +73,12 @@ func startVPN() (err error) { return err } + // Attach container network to VPN container + err = dockerCli.NetworkConnect(dockerCtx, vpnNetworkID, resp.ID, &network.EndpointSettings{}) + if err != nil { + return err + } + // Start container err = dockerCli.ContainerStart(dockerCtx, resp.ID, types.ContainerStartOptions{}) if err != nil { @@ -80,6 +107,14 @@ func setupNetwork() (error) { if vpnNetworkID == "" { response, err := dockerCli.NetworkCreate(dockerCtx, VPNNetworkName, types.NetworkCreate{ Internal: true, + IPAM: &network.IPAM{ + Config: []network.IPAMConfig{ + { + Subnet: "10.13.37.0/24", + Gateway: "10.13.37.254", + }, + }, + }, }) if err != nil { @@ -92,6 +127,25 @@ func setupNetwork() (error) { return nil } +func setupVPNHostNetwork() (error) { + setupContext() + setupDockerCLI() + + if vpnHostNetworkID == "" { + response, err := dockerCli.NetworkCreate(dockerCtx, "vpnhostnet", types.NetworkCreate{ + Internal: false, + }) + + if err != nil { + return err + } + + vpnHostNetworkID = response.ID + } + + return nil +} + func getCertificate() (string, error) { if vpnContainerID == "" { return "", errors.New("VPN container not up") @@ -122,5 +176,5 @@ func getCertificate() (string, error) { buffer := make([]byte, 1024) certResponse.Body.Read(buffer) - return string(buffer), nil + return string(bytes.Trim(buffer, "\x00")), nil } -- cgit 1.4.1 From 939ef7db9b3f209c4fa521a8d6ef4231ee397760 Mon Sep 17 00:00:00 2001 From: maride Date: Tue, 4 Sep 2018 11:07:18 +0200 Subject: Un-hardcode network name, remove fixed IP block to avoid collision on the host system --- src/access.go | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'src/access.go') diff --git a/src/access.go b/src/access.go index 34b2470..6f9cd73 100644 --- a/src/access.go +++ b/src/access.go @@ -13,6 +13,10 @@ import ( "time" ) +const( + vpnHostNetworkName = "vpnhostnet" +) + var vpnContainerID string var vpnNetworkID string var vpnHostNetworkID string @@ -107,14 +111,6 @@ func setupNetwork() (error) { if vpnNetworkID == "" { response, err := dockerCli.NetworkCreate(dockerCtx, VPNNetworkName, types.NetworkCreate{ Internal: true, - IPAM: &network.IPAM{ - Config: []network.IPAMConfig{ - { - Subnet: "10.13.37.0/24", - Gateway: "10.13.37.254", - }, - }, - }, }) if err != nil { @@ -132,7 +128,7 @@ func setupVPNHostNetwork() (error) { setupDockerCLI() if vpnHostNetworkID == "" { - response, err := dockerCli.NetworkCreate(dockerCtx, "vpnhostnet", types.NetworkCreate{ + response, err := dockerCli.NetworkCreate(dockerCtx, vpnHostNetworkName, types.NetworkCreate{ Internal: false, }) -- cgit 1.4.1