diff --git a/.devcontainer/Caddyfile b/.devcontainer/Caddyfile index 51ab08747..4c65f9ef7 100644 --- a/.devcontainer/Caddyfile +++ b/.devcontainer/Caddyfile @@ -1,9 +1,16 @@ -localhost +localhost { + log -log + reverse_proxy * elixir:4000 -reverse_proxy * localhost:4000 + encode gzip -encode gzip + tls internal +} -tls internal +:54321 { + handle /hello { + respond "HELLO +" + } +} diff --git a/.dockerignore b/.dockerignore index 16b80c8e8..6b3de9e85 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,9 +1,10 @@ -apps/fg_http/assets/node_modules -apps/fg_http/priv/static +apps/fz_http/assets/node_modules +apps/fz_http/priv/static/dist _build -apps/fg_http/_build -apps/fg_wall/_build -apps/fg_vpn/_build +apps/fz_http/_build +apps/fz_wall/_build +apps/fz_vpn/_build +apps/fz_common/_build **/cover docs .DS_Store diff --git a/.gitignore b/.gitignore index ef3303c7b..1a1bc1807 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,5 @@ npm-debug.log /*.deb /*.rpm - # Test screenshots apps/fz_http/screenshots diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 09e95fd28..1f20363a5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -117,6 +117,46 @@ At this point you should be able to sign in to [http://localhost:4000](http://localhost:4000) with email `firezone@localhost` and password `firezone1234`. +## Run using Docker + +To run using docker follow these steps: + +``` +docker compose build +docker compose up -d postgres +docker compose run --rm elixir mix ecto.setup +docker compose up +``` + +Now you should be able to connect to `https://localhost/` +and sign in with email `firezone@localhost` and password `firezone1234`. + +### Testing wireguard connections and NAT using wireguard-client container + +There is a `wireguard-client` container in the docker-compose configuration that helps testing +wireguard connections, it's connected to a separate network from the `caddy` container but the +firezone server is connected to both network so you can verify the connections using: + +* `docker compose exec wireguard-client ping 172.28.0.99` +* `docker compose exec wireguard-client curl -k 172.28.0.99:54321/hello` this should return `HELLO` text. + +To setup this test before doing `docker compose up` do this: +* Create a device in firezone using the default configuration except for: + * `DNS`: `127.0.0.11` (Docker internal DNS) + * `Endpoint`: `elixir:51820` (Need to edit after download) +* Download the generated configuration to `./tmp/config/wg0.conf` +* `docker compose up` + +### Testing wireguard connections and NAT in Linux from the host + +To test wireguard connections you can create an interface through the firezone website and add it +using [`wg-quick`](https://man7.org/linux/man-pages/man8/wg-quick.8.html) but after +`wg-quick up ` you need to run `./scripts/post-up-wg.sh` now all traffic originating +from the host should be going through your wireguard interface into the docker container +(except for traffic outgoing from the docker bridge network). + +After `wg-quick down ` run `./scripts/post-down-wg.sh` to clean everything up. + ## Running this inside a Devcontainer You can run this using Github Codespaces or your own devcontainer using Docker. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..7caa64c4f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,48 @@ +FROM hexpm/elixir:1.13.4-erlang-25.0.2-ubuntu-jammy-20220428 + +RUN set -xe \ + && apt-get update \ + && apt-get upgrade -y \ + && apt-get install -y apt-utils curl git \ + && curl -sL https://deb.nodesource.com/setup_16.x -o setup_node_deb \ + && bash setup_node_deb \ + && apt-get install -y \ + net-tools \ + iproute2 \ + nftables \ + inotify-tools \ + ca-certificates \ + build-essential \ + sudo \ + nodejs \ + && apt-get autoremove -y \ + && apt-get clean -y \ + && rm setup_node_deb \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /var/app + +ARG GIT_SHA=DEV +ARG MIX_ENV=dev +ARG DATABASE_URL + +ENV GIT_SHA=$GIT_SHA +ENV MIX_ENV=$MIX_ENV +ENV DATABASE_URL=$DATABASE_URL + +RUN mix local.hex --force && mix local.rebar --force + +COPY apps /var/app/apps +COPY config /var/app/config +COPY mix.exs /var/app/mix.exs +COPY mix.lock /var/app/mix.lock + +RUN npm install --prefix apps/fz_http/assets + +RUN mix do deps.get --only $MIX_ENV, deps.compile, compile + +COPY scripts/dev_start.sh /var/app/dev_start.sh + +EXPOSE 4000 51820/udp + +CMD ["/var/app/dev_start.sh"] diff --git a/apps/fz_http/priv/repo/seeds.exs b/apps/fz_http/priv/repo/seeds.exs index f583cf08e..3c489011f 100644 --- a/apps/fz_http/priv/repo/seeds.exs +++ b/apps/fz_http/priv/repo/seeds.exs @@ -55,12 +55,6 @@ alias FzHttp.{Devices, ConnectivityChecks, Rules, Users} tx_bytes: 1_934_475_211_087_234 }) -{:ok, _rule} = - Rules.create_rule(%{ - device_id: device.id, - destination: %Postgrex.INET{address: {0, 0, 0, 0}, netmask: 0} - }) - {:ok, _connectivity_check} = ConnectivityChecks.create_connectivity_check(%{ response_headers: %{"Content-Type" => "text/plain"}, diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..fc0a4eadd --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,103 @@ +version: '3.7' + +services: + caddy: + image: caddy:2 + volumes: + - ./.devcontainer/Caddyfile:/etc/caddy/Caddyfile + ports: + - 80:80 + - 443:443 + networks: + app: + ipv4_address: 172.28.0.99 + ipv6_address: 2001:3990:3990::99 + + elixir: + build: + context: . + dockerfile: Dockerfile + args: + DATABASE_URL: postgresql://postgres:postgres@postgres:5432/firezone_dev + image: firezone_dev + volumes: + - ./priv:/var/app/priv + - ./apps:/var/app/apps + - ./config:/var/app/config + - ./mix.exs:/var/app/mix.exs + - ./mix.lock:/var/app/mix.lock + # Mask the following build directories to keep compiled binaries isolated + # from the local project. This is needed when the Docker Host platform + # doesn't match the platform under which Docker Engine is running. e.g. + # WSL, Docker for Mac, etc. + - /var/app/apps/fz_http/assets/node_modules + ports: + - 51820:51820/udp + environment: + LOCAL_AUTH_ENABLED: 'true' + FZ_WALL_CLI_MODULE: FzWall.CLI.Live + FZ_VPN_WGADAPTER_MODULE: FzVpn.Interface.WGAdapter.Live + cap_add: + - NET_ADMIN + - SYS_MODULE + sysctls: + - net.ipv6.conf.all.disable_ipv6=0 + - net.ipv4.ip_forward=1 + - net.ipv6.conf.all.forwarding=1 + depends_on: + - postgres + networks: + - app + - isolation + + postgres: + image: postgres:13.5 + volumes: + - postgres-data:/var/lib/postgresql/data + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: firezone_dev + # when you want to connect db with a graphic tool, uncomment ports + # ports: + # - 5432:5432 + networks: + - app + + wireguard-log: + image: ubuntu:jammy + volumes: + - /sys/kernel/debug:/sys/kernel/debug + # cap SYSLOG was enough for reading but privilege is required for tailing + privileged: true + command: bash -c 'dmesg -wT | grep wireguard:' + + wireguard-client: + image: linuxserver/wireguard:latest + environment: + - PUID=1000 + - PGID=1000 + - TZ=UTC + - ALLOWEDIPS=0.0.0.0/0 + volumes: + - ./tmp/config:/config + cap_add: + - NET_ADMIN + - SYS_MODULE + sysctls: + - net.ipv6.conf.all.disable_ipv6=0 + - net.ipv4.conf.all.src_valid_mark=1 + networks: + - isolation + +volumes: + postgres-data: + +networks: + app: + enable_ipv6: true + ipam: + config: + - subnet: 172.28.0.0/16 + - subnet: 2001:3990:3990::/64 + isolation: diff --git a/scripts/dev_start.sh b/scripts/dev_start.sh new file mode 100755 index 000000000..4d3408f3c --- /dev/null +++ b/scripts/dev_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +ip link add dev wg-firezone type wireguard +ip address add dev wg-firezone 10.3.2.1/24 +ip -6 address add dev wg-firezone fd00::3:2:1/120 +ip link set up dev wg-firezone + +mix start diff --git a/scripts/post-down-wg.sh b/scripts/post-down-wg.sh new file mode 100755 index 000000000..a56de0bc1 --- /dev/null +++ b/scripts/post-down-wg.sh @@ -0,0 +1,9 @@ +#!/bin/bash +FIREZONE_DEV_V4='172.28.0.0/16' +FIREZONE_DEV_V6='2001:3990:3990::/64' +TABLE=333444 + +sudo ip -4 rule del from $FIREZONE_DEV_V4 table $TABLE +sudo ip -4 route flush table $TABLE +sudo ip -6 rule del from $FIREZONE_DEV_V6 table $TABLE +sudo ip -6 route flush table $TABLE diff --git a/scripts/post-up-wg.sh b/scripts/post-up-wg.sh new file mode 100755 index 000000000..424c0f733 --- /dev/null +++ b/scripts/post-up-wg.sh @@ -0,0 +1,19 @@ +#!/bin/bash +FIREZONE_DEV_V4='172.28.0.0/16' +FIREZONE_DEV_V6='2001:3990:3990::/64' +TABLE=333444 +DEFAULT_ROUTE_V4=$(sudo ip -4 route | grep ^default) +DOCKER_ROUTE_V4=$(sudo ip -4 route | grep ^$FIREZONE_DEV_V4) +DEFAULT_ROUTE_V6=$(sudo ip -6 route | grep ^default) +DOCKER_ROUTE_V6=$(sudo ip -6 route | grep ^$FIREZONE_DEV_V6) + +sudo ip -4 route add $DEFAULT_ROUTE_V4 table $TABLE +sudo ip -4 route add $DOCKER_ROUTE_V4 table $TABLE +sudo ip -6 route add $DOCKER_ROUTE_V6 table $TABLE +if [ ! -z "$DEFAULT_ROUTE_V6"] +then + sudo ip -6 route add $DEFAULT_ROUTE_V6 table $TABLE +fi + +sudo ip -4 rule add from $FIREZONE_DEV_V4 table $TABLE +sudo ip -6 rule add from $FIREZONE_DEV_V6 table $TABLE