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 }