about summary refs log tree commit diff
path: root/src/access.go
blob: ddb032dbb89faa5d075b3eb7ddd4f4f0a2a99966 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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"
	"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
	setupContext()
	setupDockerCLI()
	// Set up network
	setupNetwork()

	// 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),
				},
			},
		},
	}, "")

	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
}