Skip to content

Commit

Permalink
hardcode openvpn endpoints under ooni infra
Browse files Browse the repository at this point in the history
changing the experiment as per request, to satisfy reqs for shipping the
experiment in time for Aug 2024 release.

Initially I had some concerns about this approach, but it seems to work
as long it's ensured that the server has `duplicate-cn` key in its
config, and `ping-restart` is set sufficiently low. empirically, it
seems to me that handshakes do not successfully finish if they happen
too soon back-to-back.  Needs to further investigate what's the cause,
better logging of what's happening will definitely need another release
of minivpn. I don't have time to cut a new minivpn release at this point
before the august releae of probe-cli.

In a different PR, I will attempt to ship a bunch more of certificates so
that I can minimize the likelihood of two probes having the same
certificate, in the same spirit of the work done for the wireguard probe.

For what we saw from real-data, the order of magnitude of expected
probes executing the experimental card is in the range of 100 per period
of 5 minutes.
  • Loading branch information
ainghazal committed Jul 28, 2024
1 parent 2df2cab commit 169adda
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 4 deletions.
1 change: 1 addition & 0 deletions internal/experiment/openvpn/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ func (e *endpoint) AsInputURI() string {
// to still register info about more providers that the API officially knows about.
var APIEnabledProviders = []string{
"riseupvpn",
"oonivpn",
}

// isValidProvider returns true if the provider is found as key in the array of [APIEnabledProviders].
Expand Down
36 changes: 32 additions & 4 deletions internal/experiment/openvpn/richerinput.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,18 @@ func (tl *targetLoader) Load(ctx context.Context) ([]model.ExperimentTarget, err
// If inputs and files are all empty and there are no options, let's use the backend
if len(tl.loader.StaticInputs) <= 0 && len(tl.loader.SourceFiles) <= 0 &&
reflectx.StructOrStructPtrIsZero(tl.options) {
return tl.loadFromBackend(ctx)
targets, err := tl.loadFromBackend(ctx)
if err == nil {
return targets, nil
}
}

tl.session.Logger().Warn("Error fetching OpenVPN targets from backend")

// Otherwise, attempt to load the static inputs from CLI and files
inputs, err := targetloading.LoadStatic(tl.loader)

// Handle the case where we couldn't load from CLI or files
// Handle the case where we couldn't load from CLI or files:
if err != nil {
return nil, err
}
Expand All @@ -106,11 +111,34 @@ func (tl *targetLoader) Load(ctx context.Context) ([]model.ExperimentTarget, err
URL: input,
})
}
if len(targets) > 0 {
return targets, nil
}

// Return the hardcoded endpoints.
return tl.loadFromDefaultEndpoints()
}

func (tl *targetLoader) loadFromDefaultEndpoints() ([]model.ExperimentTarget, error) {
tl.session.Logger().Info("Using default OpenVPN endpoints")
targets := []model.ExperimentTarget{}
if udp, err := defaultOONIOpenVPNTargetUDP(); err == nil {
targets = append(targets,
&Target{
Config: defaultOONIOpenVPNConfig,
URL: udp,
})
}
if tcp, err := defaultOONIOpenVPNTargetTCP(); err == nil {
targets = append(targets,
&Target{
Config: defaultOONIOpenVPNConfig,
URL: tcp,
})
}
return targets, nil
}

// TODO(https://github.com/ooni/probe/issues/2755): make the code that fetches experiment private
// and let the common code export just the bare minimum to make this possible.
func (tl *targetLoader) loadFromBackend(ctx context.Context) ([]model.ExperimentTarget, error) {
if tl.options.Provider == "" {
tl.options.Provider = defaultProvider
Expand Down
52 changes: 52 additions & 0 deletions internal/experiment/openvpn/targets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package openvpn

import (
"fmt"
"net"
)

var ()

const defaultOpenVPNEndpoint = "openvpn-server1.ooni.io"

func resolveTarget() (string, error) {
ips, err := net.LookupIP(defaultOpenVPNEndpoint)
if err != nil {
return "", err
}
if len(ips) == 0 {
return "", fmt.Errorf("cannot resolve %v", defaultOpenVPNEndpoint)
}
return ips[0].String(), nil
}

func defaultOONITarget(ip string) string {
return "openvpn://oonivpn.corp/?address=" + ip + ":1194"
}

func defaultOONIOpenVPNTargetUDP() (string, error) {
ip, err := resolveTarget()
if err != nil {
return "", err
}
return defaultOONITarget(ip) + "&transport=udp", nil
}

func defaultOONIOpenVPNTargetTCP() (string, error) {
ip, err := resolveTarget()
if err != nil {
return "", err
}
return defaultOONITarget(ip) + "&transport=tcp", nil
}

var defaultOONIOpenVPNConfig = &Config{
Auth: "SHA512",
Cipher: "AES-256-GCM",
Compress: "stub",
Provider: "oonivpn",
Obfuscation: "none",
SafeCA: "-----BEGIN CERTIFICATE-----\nMIIDbzCCAlegAwIBAgIUVZz0MWBrsd26OIEccP08bNv+bScwDQYJKoZIhvcNAQEL\nBQAwIjEgMB4GA1UEAwwXb3BlbnZwbi1zZXJ2ZXIxLm9vbmkuaW8wHhcNMjQwNzI4\nMTE0NzQwWhcNMzQwNzI2MTE0NzQwWjAiMSAwHgYDVQQDDBdvcGVudnBuLXNlcnZl\ncjEub29uaS5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKOkPmCu\nYpAOue+y46rS1dnu+t1JINmvjO+Z2s7nezQMmEgP6o06pjrb8YlLByspGn/y2u7x\nFv2G86kWvRG+cpQgc2xBsEqRq7j5n45j51pat6TKt4c9Ejjnq6kGiqs3W3zDwnn+\nkx3KuvkmnOXkVQfHsUmVaS7fQpf0586ftOC7DenOvJV9LosBEIGyLyFCipaqh0eX\n6UfSGmr8tAqSfoWj8J62JBsP+U0MoLtHpRXLn2jyE/2re2mcsFLG8nRqHpTy8LGM\n6xT7c9JZSR7WiYNXB3UFBUcOpvLZ4ru6sa0BdXJiM8WQhywjVWtnM9UPf09ct57K\nMCdjWhwR81SaVAsCAwEAAaOBnDCBmTAdBgNVHQ4EFgQUOhvQMsDoG1Iw1g/w3sFp\n7BtVqIQwXQYDVR0jBFYwVIAUOhvQMsDoG1Iw1g/w3sFp7BtVqIShJqQkMCIxIDAe\nBgNVBAMMF29wZW52cG4tc2VydmVyMS5vb25pLmlvghRVnPQxYGux3bo4gRxw/Txs\n2/5tJzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOC\nAQEAoiN+S2BSMTYVA5ydWWCmfUDN30QiD2Wb3Of7ReLfG8dN4dMXULbDpzDgMl6/\nGUfOzrnZytm+ctANIQkmwf7iNcDrxLQWuw3HlvXmWLvaXA8aEi608j5dh30b6CZ8\nRSbckRYjo6oPltsmDzUG56K7NLBk9CnmmwzfJ4Rk/gEj5aoo7/AfkYB1zDaV/QBp\n60eKZ6dm6CutGBPZB0rAlBomKrKck51iU1cmJUS/RZZsZuGa6P4T2sZC20g8psOm\ngzQY31eQuTcexEddjrLqZSzVK4ZNDpycfkd1G2u+XWf3W/U2c7BAY0LFt7tieC7p\nHov5K6t2+k9xsw0vFtdDIPm4SA==\n-----END CERTIFICATE-----\n",
SafeCert: "-----BEGIN CERTIFICATE-----\nMIIDcTCCAlmgAwIBAgIRAJU2B64KWje6NlskJbfZomAwDQYJKoZIhvcNAQELBQAw\nIjEgMB4GA1UEAwwXb3BlbnZwbi1zZXJ2ZXIxLm9vbmkuaW8wHhcNMjQwNzI4MTE0\nOTIyWhcNMjYxMDMxMTE0OTIyWjAVMRMwEQYDVQQDDApDTElFTlROQU1FMIIBIjAN\nBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0dHk7p78A4Cz/kNDdZWXF5v/kMQv\nXghZnslZij/4TN8vPZMFVdABXQDLGNm3+ycvJD3PUVmBU1SAJKC3tT6Y+rwiV9Kj\npJYDP4413CP67ZEgFd/JnuthyRnnjzkvB0VtaZ861s3hY06cZBKozqhB4PZSRK0t\nkefXLYN0uJqhVY//On1sVtzHH43zapZzkniHzljNgfqK68cwhn5LVq0B72/5hL8V\nKEYHf6WTZT/ph0pCH+5rtabLt6g+oH67XXLW6bWqgO+sgmWywHOg1nkrBhpplTUk\nGeVfH/sb4TC7syb4zEm7cEfSV2qyuSrOxh+1ATFjge6kgdUAqnXk7z7cYwIDAQAB\no4GuMIGrMAkGA1UdEwQCMAAwHQYDVR0OBBYEFLBzll2vqdxuZuys0G1In9uWmyo0\nMF0GA1UdIwRWMFSAFDob0DLA6BtSMNYP8N7BaewbVaiEoSakJDAiMSAwHgYDVQQD\nDBdvcGVudnBuLXNlcnZlcjEub29uaS5pb4IUVZz0MWBrsd26OIEccP08bNv+bScw\nEwYDVR0lBAwwCgYIKwYBBQUHAwIwCwYDVR0PBAQDAgeAMA0GCSqGSIb3DQEBCwUA\nA4IBAQADqxpvQ1GfmoXsioQZAMDjGe7OSVwLFX0JfYwfTE5b+41Ci1qNMN8MvnUE\nELPbiM4Ka5aJB4UyROml8lO8igqswqPFFSzj5MSzYJsS0oZO8RnCwOvIijxzxRjA\n/ND2tbl3HSv6h6O/9RHpqJrsqxaXIXWdtrpmwal8YNyTU1eQyh7fNnFbxwqy/6oO\n0AU3BjhDWC8GDZXrvzO5utIvE+aZmXQootiSA9AmdxfabaBs6gLKqAtip1wcVJq/\nzd//gBXi8Zu/2Narnxt1wen3wSYK/faA9qvHUtAfHxLNsFWKQiD6Cl+Ksdrj35yt\nRqTncboHHef0xRIvUleoOqQWPLnT\n-----END CERTIFICATE-----\n",
SafeKey: "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDR0eTunvwDgLP+\nQ0N1lZcXm/+QxC9eCFmeyVmKP/hM3y89kwVV0AFdAMsY2bf7Jy8kPc9RWYFTVIAk\noLe1Ppj6vCJX0qOklgM/jjXcI/rtkSAV38me62HJGeePOS8HRW1pnzrWzeFjTpxk\nEqjOqEHg9lJErS2R59ctg3S4mqFVj/86fWxW3McfjfNqlnOSeIfOWM2B+orrxzCG\nfktWrQHvb/mEvxUoRgd/pZNlP+mHSkIf7mu1psu3qD6gfrtdctbptaqA76yCZbLA\nc6DWeSsGGmmVNSQZ5V8f+xvhMLuzJvjMSbtwR9JXarK5Ks7GH7UBMWOB7qSB1QCq\ndeTvPtxjAgMBAAECggEBAJn1ky/JNxD26pxjDOgGCSVI0aGPY1ZzeBd8lZhNUkxN\n5GMhM2QBSk7NGzoz372JxhyowixmKfBUa+b0i3iR4zzwuZ6JsIw/i0iieED9oc2a\nlNmYKWDURR+EQ5ajli+WsS80qL8fuQfekgEYdAeYDSced8Vu8aZDYXBDKm2fAU0/\nFOnhhsGPOy6ojmYONnC6ny+thBaOIjNvxV87gvMds7NSfPZ4YkSkyHDe2c/qd/Wx\nq+A70zA1aONOeL/u2Vz0xugiPGqYgqkr4keooumUGtTiH8N7PmJKzQvB0ELc3XeA\nM+pWT2pG2B+ChcwpmpO0/XrZAOdQBdXre35mpqsIHsECgYEA8BHC96sIx0c5J45L\nD3FZpFjhR9ROqNuaUgPTWh2zO6gsOdfD0ENLkiLrkmpEbmg6A63itLPM7ekm+JIV\n/y39jyrg0miDRHcoZZTbBaoiDVTLapbi4o4LZcVp/XwIqm37HSZvNkD02RRFAbUc\nveajh8Dsozffr8wdGPL2BUY/rUMCgYEA375DFvTduK58IY9IMyHt80toZObGZ+W3\nKcHusWmFrnHyeVIwIetNZyJqyX1n204HbNx8EzApd7haJVojNCqn1oFVgmC+O2Rz\n1SUFp3w4AOSKtLZB7116UJ+n0AOipM19sYEkTKg+xN3saMymyshaAoEnVx9izLWr\nNNwWPsKakmECgYB1wwC0pP2FY3ax5KcFSEEE0WSQ66A6TJ8CpEXE6tTE6tXm+eRg\nAOLNKLwN8nrm/dGXhHC0244nFju7q02HA3RiClKGZCYgK6NxUPeva6mQiIvQGXvq\nTmtg3NoFMha+I30O64+aOXriEYNYNxOGQ+Dr8sMhvYLIpYOQfX4ZUEBkKQKBgQC1\n0b5hRGF9d8WF3BLXAoaEhE30WRj4S1OaCm+3GkI5LX3WmzRkC/wdiHlw/YjNTU55\nZ38odKXuFRCkc+hRtywnA3kCdy1/xDThC7HZlfdIunABRG62XqdMJ0HOp3WfKSIw\ngfqGlN5VSuaXj18nQMLscBoREX9PTX4weX1WSPwlYQKBgH7Ga1O5GEaRPDA8XCfW\nB5w1T9X8F9oSYWd8+VZVuxczCW3No68ENJGd1HJgkIp1bvoPT3XQEeYOb5ePyG3c\nR50Deu95AIsjS5U2cKGC2Aw3YyzGNPEkkGuCJqqsnT9nLc3+2lAntbXEkqdbOTfx\nWxxmiOcxGxbRFFuPOxxoXaEa\n-----END PRIVATE KEY-----\n",
}

0 comments on commit 169adda

Please sign in to comment.