diff --git a/control/README.md b/control/README.md deleted file mode 100644 index 7c400e641aa3a2b440dfb00d4bb4723005458f3f..0000000000000000000000000000000000000000 --- a/control/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# control - -A simple control plane for the obfsvpn node. -It's part of the [obfsvpn-server](/images/obfsvpn/Dockerfile) docker image. - -Control is intended to be used for communication between different services, such as the gateway and bridge distribution service [Menshen](https://0xacab.org/leap/menshen). - -It exposes the bridge configuration and offers to flag a node as down for maintenance. - -The endpoints listening to GET requests are: -* `/bridge`: returns bridge config as IP, port, certificate, location and maintenance state -* `/enable`: flags the bridge as working -* `/disable`: flags the bridge as being in maintenance - -A couple of environment variables need to be set to run control: - -`CONTROL_PORT`: port control is listening to -`OBFSVPN_STATE`: directory of private and public key, certifcate, bridge-line file -`OBFSVPN_LOCATION`: key representing a location of the OpenVPN gateway the bridge is pointing to. It will be used by [Menshen](https://0xacab.org/leap/menshen) to filter requests to the Menshen API for a bridge location -`OBFS4_IP`: public IP of the bridge, exposed in the Menshen API -`OBFS4_PORT`: port of the bridge, exposed in the Menshen API - - diff --git a/control/go.mod b/control/go.mod deleted file mode 100644 index 8103f810361ad489a6bfcf1073e55a913dfbcc9c..0000000000000000000000000000000000000000 --- a/control/go.mod +++ /dev/null @@ -1,20 +0,0 @@ -module 0xacab.org/leap/obfsvpn/control - -go 1.20 - -require ( - github.com/labstack/echo/v4 v4.11.1 - github.com/sirupsen/logrus v1.9.3 -) - -require ( - github.com/labstack/gommon v0.4.0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasttemplate v1.2.2 // indirect - golang.org/x/crypto v0.11.0 // indirect - golang.org/x/net v0.12.0 // indirect - golang.org/x/sys v0.10.0 // indirect - golang.org/x/text v0.11.0 // indirect -) diff --git a/control/go.sum b/control/go.sum deleted file mode 100644 index 5f10381eb114c8f1ed4b3be6fa8d9c48fb67678a..0000000000000000000000000000000000000000 --- a/control/go.sum +++ /dev/null @@ -1,44 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4= -github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ= -github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= -github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= -github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/control/main.go b/control/main.go deleted file mode 100644 index 124483beb9707386a0a914c935c6eebbf6a32899..0000000000000000000000000000000000000000 --- a/control/main.go +++ /dev/null @@ -1,137 +0,0 @@ -// A simple control plane for the openvpn node -package main - -import ( - "bufio" - "fmt" - "net/http" - "os" - "path/filepath" - "strconv" - "strings" - - "github.com/labstack/echo/v4" - log "github.com/sirupsen/logrus" -) - -const ( - CONTROL = "CONTROL_PORT" - STATE = "OBFSVPN_STATE" - LOCATION = "OBFSVPN_LOCATION" - IP = "OBFS4_IP" - PORT = "OBFS4_PORT" -) - -type bridgeInfo struct { - IPAddr string `json:"ip_addr"` - BridgeType string `json:"type"` - Healthy bool `json:"healthy"` - Location string `json:"location"` - Options struct { - Cert string `json:"cert"` - IatMode int `json:"iat-mode"` - } `json:"options"` - Port int `json:"port"` -} - -var ( - StateDir = os.Getenv(STATE) - Healthy = true -) - -func main() { - controlPort := os.Getenv(CONTROL) - if controlPort == "" { - fmt.Println(CONTROL, "not set") - return - } - if StateDir == "" { - StateDir = "/etc/obfsvpn/" - } - log.SetFormatter(&log.TextFormatter{}) - - e := echo.New() - e.GET("/bridge", getBridgeInfo) - e.GET("/disable", disableBridge) - e.GET("/enable", enableBridge) - e.Logger.Fatal(e.Start(":" + controlPort)) -} - -func getLocation() string { - l := os.Getenv(LOCATION) - if l == "" { - l = "unknown" - } - return l -} - -type cmdResult struct { - OK bool `json:"ok"` -} - -func disableBridge(c echo.Context) error { - Healthy = false - return c.JSON(http.StatusOK, &cmdResult{true}) -} - -func enableBridge(c echo.Context) error { - Healthy = true - return c.JSON(http.StatusOK, &cmdResult{true}) -} - -func getBridgeInfo(c echo.Context) error { - port, err := strconv.Atoi(os.Getenv(PORT)) - if err != nil { - return fmt.Errorf("error parsing port: %v", err) - } - b := &bridgeInfo{ - // TODO get kcp, hop type here - BridgeType: "obfs4", - Location: getLocation(), - IPAddr: os.Getenv(IP), - Port: port, - Healthy: Healthy, - } - - f, err := os.Open(filepath.Join(StateDir, "obfs4_bridgeline.txt")) - if err != nil { - log.Warning(err) - return echo.NewHTTPError(http.StatusInternalServerError, "could not open bridgeline file") - } - defer f.Close() - - scanner := bufio.NewScanner(f) - - var cert string - var iatMode int - - // The line we're targeting has the following format: - // Bridge obfs4 <IP ADDRESS>:<PORT> <FINGERPRINT> cert=87+zEbuoIIAWAPNPJ5Ci30hiFSroMjwESD1QBJGAyc9HTkCpKKJkF/Gh8kzK0Io9iI9Zbw iat-mode=1 - - for scanner.Scan() { - line := string(scanner.Text()) - if !strings.HasPrefix(line, "Bridge") { - continue - } - for _, chunk := range strings.Split(line, " ") { - if strings.HasPrefix(chunk, "cert=") { - cert = chunk[len("cert="):] - b.Options.Cert = cert - } - if strings.HasPrefix(chunk, "iat-mode=") { - iatStr := chunk[len("iat-mode="):] - iatMode, err = strconv.Atoi(iatStr) - if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("error reading bridgeline file: %v", err)) - } - b.Options.IatMode = iatMode - } - } - } - if err := scanner.Err(); err != nil { - log.Warning(err) - return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("error reading bridgeline file: %v", err)) - } - - return c.JSON(http.StatusOK, b) -} diff --git a/docker-compose.yml b/docker-compose.yml index be0ad3d63283780d7fd67f3964d88b63999e7150..f6df35eb5ff8e554467b0e4e743414b6ceb5bd75 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,6 +13,26 @@ services: LIVE_TEST: "$LIVE_TEST" command: "/opt/openvpn-server/start.sh" + menshen: + build: ./images/menshen + ports: + - "8443:8443/tcp" + # enable agent registration and set last-seen-cutoff + command: menshen --agent-shared-key test-agent-shared-key --last-seen-cutoff-millis 10000 + environment: + - MENSHEN_FROM_EIP_FILE=/etc/leap/test/eip-service.json + - MENSHEN_FROM_PROVIDER_JSON_FILE=/etc/leap/test/provider.json + - MENSHEN_CA_FILE=/etc/leap/test/ca.crt + - MENSHEN_DB_FILE=/tmp/sqlite.db + - MENSHEN_OVPN_CA_CRT=/etc/leap/test/ovpn_client_ca.crt + - MENSHEN_OVPN_CA_KEY=/etc/leap/test/ovpn_client_ca.key + - MENSHEN_PORT=8443 + - MENSHEN_ALLOW_GATEWAY_LIST=true + - MENSHEN_ALLOW_BRIDGE_LIST=true + - MENSHEN_AUTO_TLS=false + - MENSHEN_VERBOSE=true + - ENABLE_CERT_V3=true + obfsvpn-1: build: dockerfile: ./images/obfsvpn/Dockerfile @@ -23,10 +43,11 @@ services: - "ovpn_data:/opt/openvpn/data" restart: always environment: - CONTROL_PORT: "9090" OBFSVPN_LOCATION: "unknown" OBFS4_IP: "BRIDGE'S PUBLIC HOST IP" OBFS4_HOST: "0.0.0.0" + MENSHEN_PORT: "8443" + MENSHEN_SHARED_KEY: "test-agent-shared-key" OPENVPN_HOST: "$OPENVPN_HOST" OPENVPN_PORT: "$OPENVPN_PORT" LIVE_TEST: "$LIVE_TEST" @@ -54,10 +75,11 @@ services: volumes: - "ovpn_data:/opt/openvpn/data" environment: - CONTROL_PORT: "9090" OBFSVPN_LOCATION: "unknown" OBFS4_IP: "BRIDGE'S PUBLIC HOST IP" OBFS4_HOST: "0.0.0.0" + MENSHEN_PORT: "8443" + MENSHEN_SHARED_KEY: "test-agent-shared-key" OPENVPN_HOST: "openvpn-server" OPENVPN_PORT: "5540" HOP_PT: "$HOP_PT" @@ -106,20 +128,5 @@ services: LIVE_TEST: "$LIVE_TEST" command: "/usr/bin/start.sh" - control-client: - build: - dockerfile: ./images/control-client/Dockerfile - context: ./ - cap_add: - - NET_ADMIN - restart: always - volumes: - - "ovpn_data:/control_client" - environment: - OBFSVPN_SERVER_HOST: "obfsvpn-1" - LIVE_TEST: "$LIVE_TEST" - command: "/usr/bin/start.sh" - - volumes: ovpn_data: diff --git a/images/control-client/Dockerfile b/images/control-client/Dockerfile deleted file mode 100644 index d0cfe6f8a3bee8c4a8012b68d1c33bf4530d8f9c..0000000000000000000000000000000000000000 --- a/images/control-client/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM alpine:3.14.1 - -RUN apk --no-cache --no-progress upgrade && \ - apk --no-cache --no-progress add bash curl dumb-init jq && \ - rm -rf /tmp/* - -COPY images/control-client/start.sh /usr/bin/ - -VOLUME ["/control_client"] - -ENTRYPOINT ["dumb-init"] - diff --git a/images/control-client/start.sh b/images/control-client/start.sh deleted file mode 100755 index 803f955b12ee554499b4934a251aa66b4f67d8a8..0000000000000000000000000000000000000000 --- a/images/control-client/start.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -if [[ "$LIVE_TEST" == "1" ]]; then exit 0; fi -curl -s $OBFSVPN_SERVER_HOST:9090/bridge | jq > bridge.json -cat bridge.json -if [[ `jq .type bridge.json` == "\"obfs4\"" ]]; then echo "successfully fetched bridge info"; else echo "parsing failure"; exit 1; fi; \ No newline at end of file diff --git a/images/menshen/Dockerfile b/images/menshen/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..22639833242b2a1e7a0236bdae4cd901b3c01264 --- /dev/null +++ b/images/menshen/Dockerfile @@ -0,0 +1,3 @@ +FROM registry.0xacab.org/leap/menshen:1-6-0 + +COPY ./* /etc/leap/test/ diff --git a/images/menshen/ca.crt b/images/menshen/ca.crt new file mode 100644 index 0000000000000000000000000000000000000000..c505e18afbf91515bb16523d8578f77fe11c04e1 --- /dev/null +++ b/images/menshen/ca.crt @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBhDCCASqgAwIBAgIRAPYDVEAmiYsTQOiqOtngWWAwCgYIKoZIzj0EAwIwOTE3 +MDUGA1UEAwwuUHJvdmlkZXItWCBSb290IENBIChjbGllbnQgY2VydGlmaWNhdGVz +IG9ubHkhKTAeFw0yNDA0MTgwNjMxMzdaFw0yNDA1MjMwNjMxMzdaMBQxEjAQBgNV +BAMTCVVOTElNSVRFRDAqMAUGAytlcAMhABvfZyR9f5vc+S6OYFdSdEZzJQZpd3+b +5OsNv1aywXSwo2cwZTAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUH +AwIwHQYDVR0OBBYEFHVE6GGU/uE6fcvQT7UwthpSoyFuMB8GA1UdIwQYMBaAFN2L +7f8wCjlBf3LPaU5hINMld7beMAoGCCqGSM49BAMCA0gAMEUCIAhX1H/0vtVYPal7 +Qc1c1bzsWdO5kFlpX65TagBoqXdIAiEAvFPd8FVtY5N9Ix/2D06r9lm8qmzbc0BT +xfUbJSYMENY= +-----END CERTIFICATE----- diff --git a/images/menshen/eip-service.json b/images/menshen/eip-service.json new file mode 100644 index 0000000000000000000000000000000000000000..a197819d5c8e2a56caeea6be83aa13d3cdfac300 --- /dev/null +++ b/images/menshen/eip-service.json @@ -0,0 +1 @@ +{"gateways": [], "locations": {"Seattle": {"country_code": "US", "hemisphere": "N", "name": "Seattle", "timezone": "-7"}}, "openvpn_configuration": {"auth": "SHA512", "cipher": "AES-256-GCM", "data-ciphers": "AES-256-GCM", "dev": "tun", "float": "", "keepalive": "10 30", "key-direction": "1", "nobind": true, "persist-key": true, "rcvbuf": "0", "sndbuf": "0", "tls-cipher": "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384", "tls-version-min": "1.2", "verb": "3"}, "serial": 3, "version": 3} diff --git a/images/menshen/ovpn_client_ca.crt b/images/menshen/ovpn_client_ca.crt new file mode 100644 index 0000000000000000000000000000000000000000..478f204ae366e2a65ae8dd1947c5170a255ccae2 --- /dev/null +++ b/images/menshen/ovpn_client_ca.crt @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBpjCCAUygAwIBAgIBATAKBggqhkjOPQQDAjA5MTcwNQYDVQQDDC5Qcm92aWRl +ci1YIFJvb3QgQ0EgKGNsaWVudCBjZXJ0aWZpY2F0ZXMgb25seSEpMB4XDTI0MDQy +NTA1NTcwN1oXDTI5MDQyNTA2MDIwN1owOTE3MDUGA1UEAwwuUHJvdmlkZXItWCBS +b290IENBIChjbGllbnQgY2VydGlmaWNhdGVzIG9ubHkhKTBZMBMGByqGSM49AgEG +CCqGSM49AwEHA0IABFxrESaqiSWAHSp12Pp32bvsjDnKIUvXLLZ5MD3nU/69kHX/ +FgHQPSMZqDVlkyueclPrFU32P3RksCVT/JaCvfCjRTBDMA4GA1UdDwEB/wQEAwIC +pDASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBTdi+3/MAo5QX9yz2lOYSDT +JXe23jAKBggqhkjOPQQDAgNIADBFAiBji6IIK5dX4aBpMxWG6gfMrE7KCIZ376Q3 +1TB9KoX9uQIhAOT9E5DDdXwANLfUdRn3IE/tNTkLPXMK5JCzUsFDQaH3 +-----END CERTIFICATE----- diff --git a/images/menshen/ovpn_client_ca.key b/images/menshen/ovpn_client_ca.key new file mode 100644 index 0000000000000000000000000000000000000000..279be17f86cbf7eba31d45086c43944a805a7955 --- /dev/null +++ b/images/menshen/ovpn_client_ca.key @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIJ2/NbndB5gluHMnaoB5Wqtapce7eOMqaKbleWSyGMMYoAoGCCqGSM49 +AwEHoUQDQgAEXGsRJqqJJYAdKnXY+nfZu+yMOcohS9cstnkwPedT/r2Qdf8WAdA9 +IxmoNWWTK55yU+sVTfY/dGSwJVP8loK98A== +-----END EC PRIVATE KEY----- diff --git a/images/menshen/provider.crt b/images/menshen/provider.crt new file mode 100644 index 0000000000000000000000000000000000000000..077871e60dfb08d331a29efb1514c3fc008527f7 --- /dev/null +++ b/images/menshen/provider.crt @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBaTCCARCgAwIBAgIBATAKBggqhkjOPQQDAjAbMRkwFwYDVQQDExBQcm92aWRl +ciBSb290IENBMB4XDTI0MTAyMzEyMDQyNFoXDTI5MTAyMzEyMDkyNFowGzEZMBcG +A1UEAxMQUHJvdmlkZXIgUm9vdCBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BOub3PgGo0HQ4LvEur9nJw1CjLDRNPPCR+ICP8TKvxcgAtQaYZ4QpIFYOaMWjO21 +1i09mlfxssEebMWCxWcMmq+jRTBDMA4GA1UdDwEB/wQEAwICpDASBgNVHRMBAf8E +CDAGAQH/AgEBMB0GA1UdDgQWBBQOqRGo/9bx+kx43QeIM2SKiilUojAKBggqhkjO +PQQDAgNHADBEAiBbkdxl2y2rkeJnbZiLzavvGcx/wg149vpMO/HQi8F8fAIgHI+u +xQeeJMb8hl0yBa8O8X+m5ikGyJ1KNICJ6RduGNE= +-----END CERTIFICATE----- diff --git a/images/menshen/provider.json b/images/menshen/provider.json new file mode 100644 index 0000000000000000000000000000000000000000..f1efe1c03924ef71ae37cccaae5d958f6ee5e80e --- /dev/null +++ b/images/menshen/provider.json @@ -0,0 +1,30 @@ +{ + "api_uri":"https://api.example.org:4430", + "api_version":"3", + "ask_for_donations":true, + "ca_cert_fingerprint":"SHA256: 40ed9d9c13872c1fcba25abdcf26a7b1bdeded433d74fbe1ccb58fbaaab58e23", + "ca_cert_uri":"https://example.org/ca.crt", + "default_language":"en", + "description":{ + "en":"non-prod testing provider" + }, + "domain":"example.org", + "donate_url":"https://leap.se/donate", + "donate_period":"7", + "info_url":"https://leap.se", + "languages":[ + "en" + ], + "motd_url":"", + "name":{ + "en":"non-prod testing provider" + }, + "service":{ + "allow_anonymous":true, + "allow_registration":true + }, + "services":[ + "openvpn" + ], + "tos_url":"" + } diff --git a/images/obfsvpn/Dockerfile b/images/obfsvpn/Dockerfile index 03984a1222ca942ffe9d0aed2927d02054f1ab28..e47882334ffc770d8841bdb6ebc72dc62951ef08 100644 --- a/images/obfsvpn/Dockerfile +++ b/images/obfsvpn/Dockerfile @@ -4,7 +4,6 @@ ENV SOURCE_PATH ${GOPATH}/src/0xacab.org/leap/obfsvpn COPY . ${SOURCE_PATH}/ WORKDIR ${SOURCE_PATH} RUN cd cmd/server && CGO_ENABLED=0 go build && cp server /obfsvpn-server && cd ../.. -RUN cd control && CGO_ENABLED=0 go build && cp control /control && cd .. FROM alpine:3 @@ -15,7 +14,6 @@ ENV OBFS4_DATA_DIR ${APP_INSTALL_PATH}/data ENV OBFS4_HOST 0.0.0.0 ENV OBFS4_PORT 4430 -ENV CONTROL_PORT 9090 ENV OBFSVPN_STATE ${OBFS4_DATA_DIR} ENV OBFS4_KEY_FILE ${OBFS4_DATA_DIR}/obfs4.json @@ -26,7 +24,6 @@ WORKDIR ${APP_INSTALL_PATH} RUN apk add --no-cache dumb-init iptables iproute2 tcpdump netcat-openbsd bind-tools bash coreutils COPY --from=build /obfsvpn-server . -COPY --from=build /control . COPY images/obfsvpn/scripts . COPY server/test_data ${OBFS4_DATA_DIR} diff --git a/images/obfsvpn/scripts/start_obfsvpn.sh b/images/obfsvpn/scripts/start_obfsvpn.sh index 1e07a8308ef269be3746aa402579c9f52cd96f2e..3d86f54a95718a971a5b606be3a71c7e7c43c342 100755 --- a/images/obfsvpn/scripts/start_obfsvpn.sh +++ b/images/obfsvpn/scripts/start_obfsvpn.sh @@ -2,21 +2,10 @@ set -e -kill_foreground() { - echo "Control plane exited. Killing server." - ps -C "obfsvpn-server" -o "%p"| grep -v PID | xargs kill; -} - -kill_background() { - echo "Server exited. Killing background process." - kill 0; -} - cd "${APP_INSTALL_PATH}" # check that all environment variables are set requiredVars=( - CONTROL_PORT OBFSVPN_STATE OBFSVPN_LOCATION OBFS4_IP @@ -39,17 +28,6 @@ if [[ ${QUIT} ]]; then exit 1; fi -# ensure the control plane is stopped once we leave the script -trap "exit" INT TERM -trap "kill_background" EXIT - -# start the control plane in background -./control & -export PID1=$! - -# track existance of the background process, kill server if it's gone -( tail -f --pid=$PID1 /dev/null; kill_foreground ) & - echo ">>>> LIVE_TEST: ${LIVE_TEST}" echo ">>>> starting obfsvpn server - pointing to gateway ${OPENVPN_HOST}:${OPENVPN_PORT}" @@ -63,6 +41,11 @@ if [[ "$HOP_PT" == "1" ]]; then --state "$OBFS4_DATA_DIR" \ --config "${OBFS4_KEY_FILE:-$OBFS4_DATA_DIR/obfs4.json}" \ --persist="${PERSIST_BRIDGE_STATE:-false}" \ + --location="${OBFSVPN_LOCATION}" \ + --hostname="$(hostname)" \ + --menshen-agent-enabled="true" \ + --menshen-url="http://menshen:${MENSHEN_PORT}" \ + --menshen-agent-key="${MENSHEN_SHARED_KEY}" \ -v elif [[ "$QUIC" == "1" ]]; then # start the obfsvpn server in hopping + quic mode @@ -75,6 +58,11 @@ if [[ "$HOP_PT" == "1" ]]; then --state "$OBFS4_DATA_DIR" \ --config "${OBFS4_KEY_FILE:-$OBFS4_DATA_DIR/obfs4.json}" \ --persist="${PERSIST_BRIDGE_STATE:-false}" \ + --location="${OBFSVPN_LOCATION}" \ + --hostname="$(hostname)" \ + --menshen-agent-enabled="true" \ + --menshen-url="http://menshen:${MENSHEN_PORT}" \ + --menshen-agent-key="${MENSHEN_SHARED_KEY}" \ -v fi # start the obfsvpn server in udp hopping mode @@ -84,6 +72,11 @@ if [[ "$HOP_PT" == "1" ]]; then --state "$OBFS4_DATA_DIR" \ --config "${OBFS4_KEY_FILE:-$OBFS4_DATA_DIR/obfs4.json}" \ --persist="${PERSIST_BRIDGE_STATE:-false}" \ + --location="${OBFSVPN_LOCATION}" \ + --hostname="$(hostname)" \ + --menshen-agent-enabled="true" \ + --menshen-url="http://menshen:${MENSHEN_PORT}" \ + --menshen-agent-key="${MENSHEN_SHARED_KEY}" \ -v elif [[ "$KCP" == "1" ]]; then # start the obfsvpn server in obfs4 kcp mode @@ -96,6 +89,11 @@ elif [[ "$KCP" == "1" ]]; then --state "$OBFS4_DATA_DIR" \ --config "${OBFS4_KEY_FILE:-$OBFS4_DATA_DIR/obfs4.json}" \ --persist="${PERSIST_BRIDGE_STATE:-false}" \ + --location="${OBFSVPN_LOCATION}" \ + --hostname="$(hostname)" \ + --menshen-agent-enabled="true" \ + --menshen-url="http://menshen:${MENSHEN_PORT}" \ + --menshen-agent-key="${MENSHEN_SHARED_KEY}" \ -v elif [[ "$QUIC" == "1" ]]; then @@ -111,6 +109,11 @@ elif [[ "$QUIC" == "1" ]]; then --state "$OBFS4_DATA_DIR" \ --config "${OBFS4_KEY_FILE:-$OBFS4_DATA_DIR/obfs4.json}" \ --persist="${PERSIST_BRIDGE_STATE:-false}" \ + --location="${OBFSVPN_LOCATION}" \ + --hostname="$(hostname)" \ + --menshen-agent-enabled="true" \ + --menshen-url="http://menshen:${MENSHEN_PORT}" \ + --menshen-agent-key="${MENSHEN_SHARED_KEY}" \ -v elif [[ "$TCP" == "1" ]]; then @@ -122,6 +125,11 @@ elif [[ "$TCP" == "1" ]]; then --state "$OBFS4_DATA_DIR" \ --config "${OBFS4_KEY_FILE:-$OBFS4_DATA_DIR/obfs4.json}" \ --persist="${PERSIST_BRIDGE_STATE:-false}" \ + --location="${OBFSVPN_LOCATION}" \ + --hostname="$(hostname)" \ + --menshen-agent-enabled="true" \ + --menshen-url="http://menshen:${MENSHEN_PORT}" \ + --menshen-agent-key="${MENSHEN_SHARED_KEY}" \ -v else # start the obfsvpn server in regular obfs4 mode @@ -133,5 +141,10 @@ else --state "$OBFS4_DATA_DIR" \ --config "${OBFS4_KEY_FILE:-$OBFS4_DATA_DIR/obfs4.json}" \ --persist="${PERSIST_BRIDGE_STATE:-false}" \ + --location="${OBFSVPN_LOCATION}" \ + --hostname="$(hostname)" \ + --menshen-agent-enabled="true" \ + --menshen-url="http://menshen:${MENSHEN_PORT}" \ + --menshen-agent-key="${MENSHEN_SHARED_KEY}" \ -v fi diff --git a/scripts/integration-test.sh b/scripts/integration-test.sh index 7d7001678b4cbb8d8f7f614e83ecfae7b9ce0418..9e8636b801c9e272d226388d8b56b1097d6113ae 100755 --- a/scripts/integration-test.sh +++ b/scripts/integration-test.sh @@ -45,6 +45,8 @@ else exit 1 fi +source $env_file + docker compose -p "$mode" down --rmi all -v docker compose -p "$mode" build --parallel --no-cache docker compose -p "$mode" --env-file $env_file up -d --build @@ -66,7 +68,7 @@ counter=0 max_reconnect_retry=10 if [[ "$LIVE_TEST" == "0" ]]; then - echo "Testing reconnect" + echo "Testing reconnect" | tee -a $logfile # We can't just restart the obfsvpn servers because of some very odd way that key material is being generated so we go down and up instead 🤷 docker compose -p "$mode" --env-file $env_file down obfsvpn-1 obfsvpn-2 @@ -84,13 +86,15 @@ fi docker compose -p "$mode" --env-file $env_file exec client ndt7-client -quiet | tee -a $logfile -# Testing bridge control panel +# Testing menshen-agent registration if [[ "$LIVE_TEST" == "0" ]]; then - if [[ $(docker compose -p "$mode" logs | grep control-client | tail -n1 | cut -d "|" -f2 | xargs) == "parsing failure" ]] + echo "Testing menshen-agent registration" | tee -a $logfile + + if docker compose -p "$mode" exec obfsvpn-1 wget -qO- http://menshen:8443/api/5/bridges | jq ".[0]" | grep -q '"healthy": true' then - echo "failed to parse from control panel" | tee -a $logfile - exit 1 + echo "menshen-agent registration successful" | tee -a $logfile else - echo "control panel parsing succeeded" | tee -a $logfile + echo "menshen-agent registration failed" | tee -a $logfile + exit 1 fi -fi \ No newline at end of file +fi