summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkali kaneko (leap communications) <kali@leap.se>2022-06-07 23:34:41 +0200
committerkali kaneko (leap communications) <kali@leap.se>2022-06-07 23:47:08 +0200
commitfba94256f210b10e09367cb13a69cc10ab07e723 (patch)
tree6c389cd1c5491f413f01147962f628a1bf730075
parentc0903ce49a54e735765c110fe69e5c51103aba82 (diff)
[feat] add ability to manually override params and gw
-rw-r--r--docs/debug.rst23
-rw-r--r--pkg/vpn/bonafide/eip_service.go38
-rw-r--r--pkg/vpn/bonafide/gateways.go19
3 files changed, 78 insertions, 2 deletions
diff --git a/docs/debug.rst b/docs/debug.rst
index 41bb8fe..49a2c03 100644
--- a/docs/debug.rst
+++ b/docs/debug.rst
@@ -90,3 +90,26 @@ To force logging:
.. code:: bash
QT_FORCE_STDERR_LOGGING=1 ./riseup-vpn.exe
+
+
+Ciphersuites and other openvpn params
+-------------------------------------
+You can specify a custom `openvpn_configuration` block from a local file
+(instead of fetching it from `eip-service.json`) via an environment variable:
+
+.. code:: bash
+
+ LEAP_OPENVPN_EXTRA_CONFIG=../extra-config.json ./riseup-vpn
+
+Manual Gateway Selection
+------------------------
+In the same spirit, you can manually override the gateway selection via an
+environment variable that contains the hostname of the gateway:
+
+
+.. code:: bash
+
+ LEAP_GW=hostname.riseup.net ./riseup.vpn
+
+
+
diff --git a/pkg/vpn/bonafide/eip_service.go b/pkg/vpn/bonafide/eip_service.go
index 5b4c3df..ba3eef8 100644
--- a/pkg/vpn/bonafide/eip_service.go
+++ b/pkg/vpn/bonafide/eip_service.go
@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"io"
+ "io/ioutil"
"log"
"os"
"path/filepath"
@@ -104,7 +105,7 @@ func (b *Bonafide) fetchEipJSON() error {
resp, err = b.client.Post(eip3API, "", nil)
if err != nil {
- log.Println("Error fetching eip v3 json:" + eip3API)
+ log.Println("Error fetching eip v3 json: " + eip3API)
if os.Getenv("DEBUG") == "1" {
log.Println(err)
}
@@ -222,9 +223,28 @@ func (eip eipService) getGateways() []Gateway {
func (eip eipService) getOpenvpnArgs() []string {
args := []string{}
- for arg, value := range eip.OpenvpnConfiguration {
+ var cfg = eip.OpenvpnConfiguration
+
+ // for debug purposes, we allow parsing an extra block of openvpn configurations.
+ if openvpnExtra := os.Getenv("LEAP_OPENVPN_EXTRA_CONFIG"); openvpnExtra != "" {
+ extraConfig, err := parseOpenvpnArgsFromFile(openvpnExtra)
+ if err != nil {
+ log.Println("Error parsing extra config:", err)
+ } else {
+ cfg = *extraConfig
+ }
+ }
+
+ for arg, value := range cfg {
switch v := value.(type) {
case string:
+ // this is a transitioning hack for the transition to float deployment,
+ // assuming we're using openvpn 2.5. We're treating the "cipher"
+ // string that the platform sends us as the newer data-cipher
+ // which includes colon separate ciphers.
+ if arg == "cipher" {
+ arg = "data-cipher"
+ }
args = append(args, "--"+arg)
args = append(args, strings.Split(v, " ")...)
case bool:
@@ -237,3 +257,17 @@ func (eip eipService) getOpenvpnArgs() []string {
}
return args
}
+
+func parseOpenvpnArgsFromFile(path string) (*openvpnConfig, error) {
+ // TODO sanitize options: check keys against array of allowed options
+ f, err := os.Open(path)
+ defer f.Close()
+
+ if err != nil {
+ return nil, err
+ }
+ byteValue, _ := ioutil.ReadAll(f)
+ var cfg openvpnConfig
+ json.Unmarshal([]byte(byteValue), &cfg)
+ return &cfg, nil
+}
diff --git a/pkg/vpn/bonafide/gateways.go b/pkg/vpn/bonafide/gateways.go
index 615e9a9..4b7e6dd 100644
--- a/pkg/vpn/bonafide/gateways.go
+++ b/pkg/vpn/bonafide/gateways.go
@@ -4,6 +4,7 @@ import (
"errors"
"log"
"math/rand"
+ "os"
"sort"
"strconv"
"time"
@@ -279,6 +280,10 @@ func (p *gatewayPool) setRecommendedGateways(geo *geoLocation) {
/* get at most max gateways. the method of picking depends on whether we're
* doing manual override, and if we got useful info from menshen */
func (p *gatewayPool) getBest(transport string, tz, max int) ([]Gateway, error) {
+ if hostname := os.Getenv("LEAP_GW"); hostname != "" {
+ log.Printf("Gateway selection manually overriden: %v\n", hostname)
+ return p.getGatewaysByHostname(hostname)
+ }
if p.isManualLocation() {
if len(p.recommended) != 0 {
return p.getGatewaysFromMenshenByLocation(p.userChoice, transport)
@@ -369,6 +374,20 @@ func (p *gatewayPool) getGatewaysByTimezone(transport string, tzOffsetHours, max
return gws, nil
}
+// getGatewaysByHostname filters the gateway pool by hostname. If it finds a
+// gateway matching the passed hostname, it will return a Gateway array with
+// exactly one gateway. It will also return an error (which is always nil at
+// the moment, but for coherence with similar methods).
+func (p *gatewayPool) getGatewaysByHostname(hostname string) ([]Gateway, error) {
+ gws := make([]Gateway, 0)
+ for _, gw := range p.available {
+ if gw.Host == hostname {
+ gws = append(gws, gw)
+ }
+ }
+ return gws, nil
+}
+
func newGatewayPool(eip *eipService) *gatewayPool {
p := gatewayPool{}
p.available = eip.getGateways()