diff --git a/Dockerfile b/Dockerfile index 03ac518..e91d526 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,15 @@ -FROM gcr.io/cloud-marketplace-containers/google/bazel:3.5.0 AS builder +FROM python:3.10-bullseye AS builder + +RUN apt-get update && apt-get install -y apt-transport-https curl gnupg \ + && curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor >/usr/share/keyrings/bazel-archive-keyring.gpg \ + && echo "deb [arch=amd64 signed-by=/usr/share/keyrings/bazel-archive-keyring.gpg] https://storage.googleapis.com/bazel-apt stable jdk1.8" | tee /etc/apt/sources.list.d/bazel.list \ + && apt-get update && apt-get install -y bazel \ + && rm -rf /var/lib/apt/lists/* WORKDIR /wgkex -COPY . ./ +COPY BUILD WORKSPACE requirements.txt ./ +COPY wgkex ./wgkex RUN ["bazel", "build", "//wgkex/broker:app"] RUN ["bazel", "build", "//wgkex/worker:app"] diff --git a/README.md b/README.md index c3439ff..9f9a63a 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ wgkex is a WireGuard key exchange and management tool designed and run by FFMUC. ## Overview -WireGuard Key Exchange is a tool consisting of two parts: a frontend (broker) and a backend (worker). These components +WireGuard Key Exchange is a tool consisting of two parts: a frontend (broker) and a backend (worker). These components communicate to each other via MQTT - a messaging bus. ![](Docs/architecture.png) @@ -43,7 +43,7 @@ JSON POST'd to this endpoint should be in this format: ```json { - "domain": "CONFIGURED_DOMAIN", + "domain": "CONFIGURED_DOMAIN", "public_key": "PUBLIC_KEY" } ``` @@ -53,9 +53,12 @@ The broker will validate the domain and public key, and if valid, will push the ### Backend worker The backend (worker) waits for new keys to appear on the MQTT message bus. Once a new key appears, the worker performs -validation task on the key, then injects those keys into a WireGuard instance(While also updating the VxLAN FDB). +validation task on the key, then injects those keys into a WireGuard instance(While also updating the VxLAN FDB). +It reports metrics like number of connected peers and instance data like local address, WG listening port and +external domain name (configured in config.yml) back to the broker. +Each worker must run on a machine with a unique hostname, as it is used for separation of metrics. -This tool is intended to facilitate running BATMAN over VXLAN over WireGuard as a means to create encrypted +This tool is intended to facilitate running BATMAN over VXLAN over WireGuard as a means to create encrypted high-performance mesh links. For further information, please see this [presentation on the architecture](https://www.slideshare.net/AnnikaWickert/ffmuc-goes-wild-infrastructure-recap-2020-rc3) @@ -71,11 +74,13 @@ For further information, please see this [presentation on the architecture](http The `wgkex` configuration file defaults to `/etc/wgkex.yaml` ([Sample configuration file](wgkex.yaml.example)), however can also be overwritten by setting the environment variable `WGKEX_CONFIG_FILE`. -## Running the broker +## Running the broker and worker -* The broker web frontend can be started directly from a Git checkout: +### Build using [Bazel](https://bazel.build) -``` +Worker: + +```sh # defaults to /etc/wgkex.yaml if not set export WGKEX_CONFIG_FILE=/opt/wgkex/wgkex.yaml bazel build //wgkex/worker:app @@ -83,9 +88,9 @@ bazel build //wgkex/worker:app ./bazel-bin/wgkex/worker/app ``` -* The broker can also be built and run via [bazel](https://bazel.build): +Broker: -```shell +```sh # defaults to /etc/wgkex.yaml if not set export WGKEX_CONFIG_FILE=/opt/wgkex/wgkex.yaml bazel build //wgkex/broker:app @@ -93,6 +98,21 @@ bazel build //wgkex/broker:app ./bazel-bin/wgkex/broker/app ``` +### Run using Python + +Broker: +(Using Flask development server) + +```sh +FLASK_ENV=development FLASK_DEBUG=1 FLASK_APP=wgkex/broker/app.py python3 -m flask run +``` + +Worker: + +```sh +python3 -c 'from wgkex.worker.app import main; main()' +``` + ## Client usage The client can be used via CLI: @@ -112,6 +132,30 @@ push_key = requests.get(f'{broker_url}/api/v1/wg/key/exchange', json=key_data) print(f'Key push was: {push_key.json().get("Message")]}') ``` +### Worker + +You can set up dummy interfaces for the worker using this script: + +```sh +interface_linklocal() { + # We generate a predictable v6 address + local macaddr="$(echo $1 | wg pubkey |md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/')" + local oldIFS="$IFS"; IFS=':'; set -- $macaddr; IFS="$oldIFS" + echo "fe80::$1$2:$3ff:fe$4:$5$6" +} + +sudo ip link add wg-welt type wireguard +wg genkey | sudo wg set wg-welt private-key /dev/stdin +sudo wg set wg-welt listen-port 51820 +addr=$(interface_linklocal $(sudo wg show wg-welt private-key)) +sudo ip addr add $addr dev wg-welt +sudo ip link add vx-welt type vxlan id 99 dstport 0 local $addr dev wg-welt +sudo ip addr add fe80::1/64 dev vx-welt +sudo ip link set wg-welt up +sudo ip link set vx-welt up +``` + + ## Contact -[wgkex - IRCNet](ircs://irc.ircnet.net:6697/wgkex) +[Freifunk Munich Mattermost](https://chat.ffmuc.net) diff --git a/WORKSPACE b/WORKSPACE index 4aafce8..2756b7d 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -2,12 +2,13 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "rules_python", - url = "https://github.com/bazelbuild/rules_python/releases/download/0.1.0/rules_python-0.1.0.tar.gz", - sha256 = "b6d46438523a3ec0f3cead544190ee13223a52f6a6765a29eae7b7cc24cc83a0", + sha256 = "a3a6e99f497be089f81ec082882e40246bfd435f52f4e82f37e89449b04573f6", + strip_prefix = "rules_python-0.10.2", + url = "https://github.com/bazelbuild/rules_python/archive/refs/tags/0.10.2.tar.gz", ) # PIP support. load("@rules_python//python:pip.bzl", "pip_install") pip_install( requirements = "//:requirements.txt", -) \ No newline at end of file +)