menshen

module
v0.0.0-...-0524d7e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 22, 2024 License: GPL-3.0

README

Menshen

Menshen is a gateway & bridge distribution service for LEAP VPN.

Go Reference Go Report Card

In chinese folk religions, menshen are guardians of doors and gates.

Overview

menshen is a resource distributor for LEAP VPN. Here, resource means information for accessing either gateways, bridges, or a combination of the two. This information includes not only endpoint discovery but also crendentials (although the credential distribution is not fully integrated at this point).

After adopting 002-vpnweb-deprecation, menshen is responsible for centrally handling the resource inventory, and assigning each item on the inventory to the users of the system. How this is assigned can change from deployment to deployment, but the general idea is that menshen takes several parameters into account, including current node capacity, geolocation, user preferences (i.e., opting-in to resource marked as experimental) and possible ACLs in place.

Architecture

menshen is a single service that can bootstrapped with or without the legacy service inventory information coming from vpnweb (in the form of eip-service.json, remotely or from an in-disk file). As specified in 002-vpnweb-deprecation, this is intended as a compatibility measure that will have to be phased out at some point.

menshen also listens on an internal port where it receives information from menshen_agent running on each gateway via gRPC calls (receiving information from bridges is TBD).

The auto-generated clients from the menshen spec are feeded to bitmask-core to get clients compatible with the latest version of the spec.

graph
  eip-service.json --> menshen
  inventory -.-> menshen
  menshen_agent_gw --lb--> menshen
  menshen_agent_br -.-lb-.-> menshen
  control_br -.-> menshen
  control_gw -.-> menshen

  subgraph "gateway"
    menshen_agent_gw
    control_gw 
    openvpn
  end

  subgraph "bridge"
    menshen_agent_br
    control_br 
    obfsvpn
  end

menshen --> bitmask-core

In the diagram above, the dashed line from "inventory" marks a yet unresolved way of specifying resources in the inventory (see #26).

OpenAPI spec generation

We generate an OpenAPI spec from comments in the source code. Every commit that changes the API must update the relevant documentation (more information how to change the API).

To update the OpenAPI spec, you need to install swag:

go install github.com/swaggo/swag/cmd/swag@latest

To generate clients from the spec, you need to install swagger in your system.

To do both steps at once:

make swag

⚠ - we still miss a good way to move/copy over the generated client to the bitmask-core codebase. This should probably be automated somehow, with manual overview.

Build

go build ./cmd/menshen

Run

The parameter --from-provider-json is a file path to a provider.json. It is always required to start menshen. Use --verbose to get debug output.

by pointing to another upstream provider
a) with self-signed provider API endpoints

Further required parameters are --ca-file, --client-cert-url and an eip source (--from-eip-file or --from-eip-url ). You can start menshen from a v3 eip-service file:

go run ./cmd/menshen/main.go --verbose \
--from-provider-json-file test/data/provider.json \
--from-eip-file test/data/eip-service.json \
--ca-file test/data/demo.crt \
--client-cert-url https://api.demo.bitmask.net:4430/3/cert

Alternatively you can start menshen with a eip-service.json from an URL:

go run ./cmd/menshen/main.go --verbose \
--from-provider-json-file test/data/provider.json \
--from-eip-url https://api.demo.bitmask.net:4430/3/config/eip-service.json \
--ca-file test/demo.crt \
--client-cert-url https://api.demo.bitmask.net:4430/3/cert
b) with ca-signed provider endpoints

Additional required parameters are --client-cert-url and an eip source (--from-eip-file or --from-eip-url ). You can start menshen from a v3 eip-service file:

go run ./cmd/menshen/main.go --verbose \
--from-provider-json-file test/data/provider.json \
--from-eip-url https://api.demo.bitmask.net/3/config/eip-service.json \
--client-cert-url https://api.demo.bitmask.net/3/cert

Alternatively you can start menshen with a eip-service.json from an URL:

go run ./cmd/menshen/main.go --verbose \
--from-provider-json-file test/data/provider.json \
--from-eip-file test/data/eip-service.json \
--client-cert-url https://api.demo.bitmask.net/3/cert
Note: Replace test/data/eip-service.json and test/data/provider.json with the relevant configuration files, as they are just samples.
by configuring for local cert generation

Additional required parameters are --ovpn-ca-crt, --ovpn-ca-key and an eip source (--from-eip-file or --from-eip-url ). You can start menshen from a v3 eip-service file:

go run ./cmd/menshen/main.go --verbose \
--from-provider-json-file test/data/provider.json \
--from-eip-file test/data/eip-service.json \
--ovpn-ca-crt test/data/ovpn_client_ca.crt \
--ovpn-ca-key test/data/ovpn_client_ca.key

To visit the public url, you can point your browser to:

http://localhost:8443/api/swagger/index.html

If you want to make the general gateway and bridges endpoints public enable it by using flags --allow-gateway-list --allow-bridge-list

go run ./cmd/menshen/main.go --verbose \
--from-provider-json-file test/data/provider.json \
--from-eip-url https://api.demo.bitmask.net:4430/3/config/eip-service.json \
--ca-file test/demo.crt \
--client-cert-url https://api.demo.bitmask.net:4430/3/cert \
--allow-gateway-list --allow-bridge-list

If you're not running menshen as part of an orchestration platform that can set up TLS certificates for you, you can leverate the auto-tls functionality (for instance, while running standalone nodes for development or quick testing):

./menshen --auto-tls --server-name example.com

For help on the optional flags, run with -h:

❯ ./menshen -h
Usage of ./menshen:
      --algo string                      Select the preferred algorithm for certificate generation currently supported ecdsa, ed25519 (default "ed25519")
      --allow-bridge-list                allow public bridge listing
      --allow-gateway-list               allow public gateway listing
      --auto-tls                         configure auto TLS using Lets Encrypt
      --ca-file string                   filename with CA certificate used for validating certificates
      --client-cert-url string           url that returns a valid OpenVPN certificate and private key in plain text
      --db-file string                   location of sqlite database file (default "./sqlite.db")
      --enable-cert-v3                   enable /3/cert endpoint for rsa cert generation
      --from-eip-file string             start from eip-service file (legacy)
      --from-eip-url string              start from eip-service url (legacy)
      --from-provider-json-file string   file path to provider.json
      --lb-addr string                   Address for load balancer to listen on (default ":9003")
      --localbridges string              comma-separated list of addresses for the control port of bridges
      --metrics-port int                 port for /metrics (prometheus) to listen on (default 9002)
      --ovpn-ca-crt string               openvpn ca crt for client cert generation
      --ovpn-ca-key string               openvpn ca key for signing client cert
      --ovpn-client-crt-expiry int       openvpn client cert expiry (default 23)
      --port int                         port to listen on (default 8443)
      --server-name string               server name (for LetsEncrypt AutoTLS)
      --verbose                          set log verbosity to DEBUG

Config

You can either pass flags, as in the example above, or a yaml file, or environment variables.

The environment variables follow the uppercase-underscore convention and are prefixed with MENSHEN_. So, to pass the equivalent of --port, you'd pass MENSHEN_PORT.

Other utilities

For convenience, there's a binary that can be used to get coordinates for the locations of the remotes in your inventory with the same geolocation library used by the API:

❯ go build ./cmd/locations
❯ ./locations /tmp/eip.json get-location
New York        40.71   -74.01
Paris           48.85   2.35
Seattle         47.61   -122.33
Amsterdam       52.37   4.90
Miami           25.77   -80.19
Montreal        45.52   -73.65

Bucket token auth

Resources (bridges and gateways) can be given a "bucket" property to denote that they should be restricted/not part of publicly available assets.

Admins can then generate auth tokens which would give end users access to those resources.

You can use the accompanying CLI to generate said tokens:

❯ go run ./cmd/tokens --buckets "bucket1,bucket2" --number-tokens 10
Tokens:
solitech_z6tV8f+1jpYMBgmE0J6jZQ==
solitech_bYnFp+YzPTp/71/edSDEiw==
solitech_pusRycrUBH9lxvkVcbIyXQ==
solitech_e9JckBd9QzYmSE4wo2jQBQ==
solitech_564x5U+rANCS1jbpvIeQvA==
solitech_zNcbJeFyMANj0kIxGruIpw==
solitech_t3/B7mdKB2tPbcnNdIejpw==
solitech_tLdCZT0QVPyPuNJFdlpvvQ==
solitech_G5ACBRpwqcivbMEkC708OA==
solitech_u6Zoe3ftUcVmLb3lm/KsSw==

These tokens can then be passed in as a x-menshen-auth-token header when making requests to menshen which will allow that request access to private resources in "bucket1" and "bucket2".

Directories

Path Synopsis
Package api Code generated by swaggo/swag.
Package api Code generated by swaggo/swag.
cmd
locations
geolocation utility to add coordinates to an eip-service inventory.
geolocation utility to add coordinates to an eip-service inventory.
pkg
api
Package Menshen LEAP API
Package Menshen LEAP API
geolocate
geolocate exposes a function to obtain geographical coordinates for a given country.
geolocate exposes a function to obtain geographical coordinates for a given country.
latency
latency offers a way to lookup distance according to an empirical model of latency.
latency offers a way to lookup distance according to an empirical model of latency.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL