about summary refs log tree commit diff
path: root/src/access.go
diff options
context:
space:
mode:
authormaride <maride@darknebu.la>2018-09-04 11:09:04 +0200
committermaride <maride@darknebu.la>2018-09-04 11:09:04 +0200
commite7be7b3a847beddccc324067de6b0bfa24b3ef12 (patch)
treebfc40755646b473a4b3081dd5c6c46ac221a8a78 /src/access.go
parent82c922d557f6628043ab771cdf10e4da9546347d (diff)
parenta46cb83df474e5f9c9be35a0f4543f85bf9f03ee (diff)
Merge branch 'access'
Diffstat (limited to 'src/access.go')
-rw-r--r--src/access.go176
1 files changed, 176 insertions, 0 deletions
diff --git a/src/access.go b/src/access.go
new file mode 100644
index 0000000..6f9cd73
--- /dev/null
+++ b/src/access.go
@@ -0,0 +1,176 @@
+package main
+
+import (
+	"bytes"
+	"errors"
+	"flag"
+	"fmt"
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/api/types/network"
+	"github.com/docker/go-connections/nat"
+	"net/http"
+	"time"
+)
+
+const(
+	vpnHostNetworkName = "vpnhostnet"
+)
+
+var vpnContainerID string
+var vpnNetworkID string
+var vpnHostNetworkID 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
+	setupContext()
+	setupDockerCLI()
+	// Set up network
+	err = setupNetwork()
+
+	if(err != nil) {
+		return err
+	}
+
+	err = setupVPNHostNetwork()
+
+	if err != nil {
+		return err
+	}
+
+	// Create container
+	resp, err := dockerCli.ContainerCreate(dockerCtx, &container.Config{
+		Image: "circus-vpn",
+		Env: []string{
+			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{
+			"startpoint": {
+				NetworkID: vpnHostNetworkID,
+			},
+		},
+	}, "")
+
+	if err != nil {
+		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 {
+		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 setupVPNHostNetwork() (error) {
+	setupContext()
+	setupDockerCLI()
+
+	if vpnHostNetworkID == "" {
+		response, err := dockerCli.NetworkCreate(dockerCtx, vpnHostNetworkName, 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")
+	}
+
+	// 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(bytes.Trim(buffer, "\x00")), nil
+}