diff --git a/README.md b/README.md index 524f582555df0426468d8c8747800ced5fedd427..b9aadee6fb0f5929421f1ebe6974368f778dd696 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,26 @@ PING 8.8.8.8 (8.8.8.8): 56 data bytes round-trip min/avg/max = 12.829/17.062/19.346 ms ``` +### Container environment variables + +#### obfsvpn server + +Before you can run a obfsvpn server container you need to make sure to set the following environment variables which are required in the [start script](./images/obfsvpn/scripts/start_obfsvpn.sh). + +| Variable | Purpose | Example | +|:--------:|:--------------:|:--------:| +| `CONTROL_PORT` | port of the [Control Plane](/control/README.md) | 9090 | +| `OBFSVPN_STATE` | directory of private and public key, certifcate, bridgeline file | ./test_data | +| `OBFSVPN_LOCATION` | location of the OpenVPN gateway the bridge is pointing to | amsterdam | +| `OBFS4_IP` | public IP of the bridge | 123.231.123.21 | +| `OBFS4_PORT` | port the bridge is listening on | 4430 | +| `OBFS4_HOST` | The IP obfsvpn server is gets assigned to | 0.0.0.0 | +| `OPENVPN_HOST` | public IP of the OpenVPN gateway the bridge is pointing to | 231.123.231.12 | +| `OPENVPN_PORT` | port | 80 | +| `OBFS4_DATA_DIR` | same as `OBFSVPN_STATE` | ./test_data | +| `HOP_PT` | run server in hopping pt mode | 1 if true | +| `KCP` | run server in KCP transport mode | 1 if true | + ### Integration testing We additionally have an `./scripts/integration-test.sh` script which starts all of the services and then does a set of very small/trivial smoke tests to ensure that the platform is working as expected. @@ -154,7 +174,178 @@ And finally to test KCP: ```sh -$ ./scripts/integration-test.sh hop +$ ./scripts/integration-test.sh kcp +``` + +### Running components separately/against live systems + +There may be scenarios when you'd prefer to run individual components on their own or targeting live systems. + +Each of the individual components *can* be run separately, though some are easier to configure than others. + +In general it's recommended to prioritize trying to work within the docker-compose environment if/when possible. + + +#### obfsvpn client +The obfsvpn client is a go binary that connects to an obfsvpn server and as a pair form a proxy through which arbitrary UDP (and in some less common scenarios TCP) traffic can be tunneled. + +You can see the arguments that are required by running it by executing it with the `--help` flag: +``` +$ go run ./cmd/client --help +Usage of /tmp/go-build901008461/b001/exe/client: + -c string + The remote obfs4 certificates separated by commas. If hopping is not enabled only the first cert will be used + -h Connect with openvpn over udp in hopping mode + -i string + The host for the local proxy (default: localhost) (default "127.0.0.1") + -j uint + A random range to wait (on top of the minimum) seconds before hopping. Only applicable to hopping (default 5) + -kcp + Enable KCP mode + -kcp-disable-flow-control + KCP DisableFlowControl (default true) + -kcp-interval int + KCP Interval (default 10) + -kcp-mtu int + KCP MTU (default 1400) + -kcp-no-delay + KCP NoDelay (default true) + -kcp-read-buffer int + KCP ReadBuffer (default 16777216) + -kcp-receive-window-size int + KCP ReceiveWindowSize (default 65535) + -kcp-resend int + KCP Resend (default 2) + -kcp-send-window-size int + KCP SendWindowSize (default 65535) + -kcp-write-buffer int + KCP WriteBuffer (default 16777216) + -m uint + The minimun number of seconds to wait before hopping. Only applicable to hopping (default 5) + -p string + The port for the local proxy (default: 8080) (default "8080") + -pc uint + The number of ports to try for each remote. Only applicable to hopping (default 100) + -ps int + The random seed to generate ports from. Only applicable to hopping (default 1) + -r string + The remote obfs4 endpoint ips (no port) separated by commas. If hopping is not enabled only the first cert will be used + -rp string + The remote obfs4 endpoint port to use. Only applicable to NON-hopping + -v Enable verbose logging +``` + +The `-c` flag is for obfs4 certificates. This will be in base64 string form. For our docker testbed, we hard code these in [the client Dockerfile](./images/obfsvpn-client/Dockerfile). + +To get information about obfs4 server bridges to connect to, you can query the menshen service. For our demo.bitmask.net deployment that could look like: +``` +❯ curl -sL https://api.demo.bitmask.net/api/5/bridges | jq ✘ 4 +[ + { + "healthy": true, + "host": "cod.demo.bitmask.net", + "ip_addr": "37.218.245.94", + "ip6_addr": "", + "load": 0, + "location": "northbrabant", + "overloaded": false, + "port": 443, + "transport": "tcp", + "type": "obfs4", + "options": { + "cert": "k0L4LFg0Wk98v7P66xvgAx2ud+kggvjZX/qul3iFTJGH5X7xSHT+vVL4UZR0WI3SkmDzUg", + "iatMode": "0" + }, + "bucket": "" + }, + { + "healthy": true, + "host": "cod.demo.bitmask.net", + "ip_addr": "37.218.245.94", + "ip6_addr": "", + "load": 0, + "location": "northbrabant", + "overloaded": false, + "port": 4431, + "transport": "kcp", + "type": "obfs4", + "options": { + "cert": "k0L4LFg0Wk98v7P66xvgAx2ud+kggvjZX/qul3iFTJGH5X7xSHT+vVL4UZR0WI3SkmDzUg", + "iatMode": "0" + }, + "bucket": "" + }, + { + "healthy": true, + "host": "mullet.demo.bitmask.net", + "ip_addr": "37.218.241.208", + "ip6_addr": "", + "load": 0, + "location": "florida", + "overloaded": false, + "port": 443, + "transport": "tcp", + "type": "obfs4", + "options": { + "cert": "k0L4LFg0Wk98v7P66xvgAx2ud+kggvjZX/qul3iFTJGH5X7xSHT+vVL4UZR0WI3SkmDzUg", + "iatMode": "0" + }, + "bucket": "" + }, + { + "healthy": true, + "host": "mullet.demo.bitmask.net", + "ip_addr": "37.218.241.208", + "ip6_addr": "", + "load": 0, + "location": "florida", + "overloaded": false, + "port": 4431, + "transport": "kcp", + "type": "obfs4", + "options": { + "cert": "k0L4LFg0Wk98v7P66xvgAx2ud+kggvjZX/qul3iFTJGH5X7xSHT+vVL4UZR0WI3SkmDzUg", + "iatMode": "0" + }, + "bucket": "" + } +] +``` + +So, supposing that you wanted to connect to the `cod.demo.bitmask.net` obfsvpn server over "normal"/non-KCP, you could run: +``` +$ go run ./cmd/client -c "k0L4LFg0Wk98v7P66xvgAx2ud+kggvjZX/qul3iFTJGH5X7xSHT+vVL4UZR0WI3SkmDzUg" -r 37.218.245.94 -rp 443 -v +2024/08/12 16:16:42 proxyAddr: 127.0.0.1:8080 +2024/08/12 16:16:42 obfs4 endpoints: [37.218.245.94:443] +2024/08/12 16:16:42 Update state: STARTING +2024/08/12 16:16:43 Update state: RUNNING +``` + +There should now be a udp listener on the default address/port: + +``` +$ ss -ul src 127.0.0.1:8080 +State Recv-Q Send-Q Local Address:Port Peer Address:Port Process +UNCONN 0 0 127.0.0.1:8080 0.0.0.0:* +``` + +You can specify a particular listening address with the `-i` flag and a particular listening port with the `-p` flag. + +If you want to connect via KCP, use the port for the host that's listening w/ KCP and specify the `-kcp` flag: + +``` +$ go run ./cmd/client -c "k0L4LFg0Wk98v7P66xvgAx2ud+kggvjZX/qul3iFTJGH5X7xSHT+vVL4UZR0WI3SkmDzUg" -r 37.218.245.94 -rp 4431 -v -kcp +2024/08/12 16:22:11 proxyAddr: 127.0.0.1:8080 +2024/08/12 16:22:11 obfs4 endpoints: [37.218.245.94:4431] +2024/08/12 16:22:11 Update state: STARTING +2024/08/12 16:22:11 Dialing kcp://37.218.245.94:4431 +2024/08/12 16:22:11 Update state: RUNNING +``` + + +If you wanted to run openvpn through that particular bridge, you'd specify the `--remote` and `--proto udp` flags when running the openvpn command: +``` +$ openvpn --remote 127.0.0.1 8080 --proto udp [A BUNCH MORE OPENVPN FLAGS/CONFIGS HERE] ``` ## Android