diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..dbaf2e0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +.git +_build +*.xen +*.bz2 +*.tar.bz2 +*.tgz diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..4f5485a --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,32 @@ +name: Main workflow + +on: + pull_request: + push: + schedule: + # Prime the caches every Monday + - cron: 0 1 * * MON + +jobs: + build: + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - run: ./build-with.sh docker + + - run: sh -exc 'if [ "$(sha256sum ./dist/qubes-miragevpn.xen)" = "$(cat ./qubes-miragevpn.sha256)" ]; then echo "SHA256 MATCHES"; else exit 42; fi' + + - name: Upload Artifact + uses: actions/upload-artifact@v3 + with: + name: miragevpn.tar.bz2 + path: miragevpn.tar.bz2 diff --git a/.github/workflows/podman.yml b/.github/workflows/podman.yml new file mode 100644 index 0000000..f3f732d --- /dev/null +++ b/.github/workflows/podman.yml @@ -0,0 +1,32 @@ +name: Main workflow + +on: + pull_request: + push: + schedule: + # Prime the caches every Monday + - cron: 0 1 * * MON + +jobs: + build: + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - run: ./build-with.sh podman + + - run: sh -exc 'if [ "$(sha256sum ./dist/qubes-miragevpn.xen)" = "$(cat ./qubes-miragevpn.sha256)" ]; then echo "SHA256 MATCHES"; else exit 42; fi' + + - name: Upload Artifact + uses: actions/upload-artifact@v3 + with: + name: mirage-firewall.tar.bz2 + path: mirage-firewall.tar.bz2 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a726314 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,38 @@ +# Pin the base image to a specific hash for maximum reproducibility. +# It will probably still work on newer images, though, unless an update +# changes some compiler optimisations (unlikely). +# bookworm-slim taken from https://hub.docker.com/_/debian/tags?page=1&name=bookworm-slim +FROM debian@sha256:3d5df92588469a4c503adbead0e4129ef3f88e223954011c2169073897547cac +# install remove default packages repository +RUN rm /etc/apt/sources.list.d/debian.sources +# and set the package source to a specific release too +# taken from https://snapshot.debian.org/archive/debian +RUN printf "deb [check-valid-until=no] http://snapshot.debian.org/archive/debian/20240419T024211Z bookworm main\n" > /etc/apt/sources.list +# taken from https://snapshot.debian.org/archive/debian-security/ +RUN printf "deb [check-valid-until=no] http://snapshot.debian.org/archive/debian-security/20240419T111010Z bookworm-security main\n" >> /etc/apt/sources.list + +RUN apt update && apt install --no-install-recommends --no-install-suggests -y wget ca-certificates git patch unzip bzip2 xz-utils make gcc g++ libc-dev +RUN wget -O /usr/bin/opam https://github.com/ocaml/opam/releases/download/2.1.6/opam-2.1.6-i686-linux && chmod 755 /usr/bin/opam +# taken from https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh +RUN test `sha512sum /usr/bin/opam | cut -d' ' -f1` = \ +"2b308e7a848252d831a1e046b70156cd901e8a5d95405fc03244fc69ce08222675871d3bcc35352b4448f15787f68a16491c574a6f9d5d8c9bcab81eb6d71ef8" || exit + +ENV OPAMROOT=/tmp +ENV OPAMCONFIRMLEVEL=unsafe-yes +# Pin last known-good version for reproducible builds. +# Remove this line (and the base image pin above) if you want to test with the +# latest versions. +# taken from https://github.com/ocaml/opam-repository +RUN opam init --disable-sandboxing -a --bare https://github.com/ocaml/opam-repository.git#2926702fdd0fe7cab6ee1fa26ccecd28c3c3dd95 +RUN opam switch create myswitch 4.14.2 +RUN opam exec -- opam install -y mirage opam-monorepo ocaml-solo5 +RUN opam exec -- opam install -y tls +RUN opam pin add -y https://github.com/robur-coop/miragevpn.git#0a502cafd0824888c194039fae32a9e1e65cd356 +RUN opam pin add -y https://github.com/mirage/mirage-qubes.git#6d4745eb111c84d68efc8bb14e03d4c5c761df3b +RUN mkdir /tmp/orb-build +ADD config.ml /tmp/orb-build/config.ml +WORKDIR /tmp/orb-build +CMD opam exec -- sh -exc 'mirage configure -t xen --extra-repos=\ +opam-overlays:https://github.com/dune-universe/opam-overlays.git#4e75ee36715b27550d5bdb87686bb4ae4c9e89c4,\ +mirage-overlays:https://github.com/dune-universe/mirage-opam-overlays.git#797cb363df3ff763c43c8fbec5cd44de2878757e \ +&& make depend && make build' diff --git a/build-with.sh b/build-with.sh new file mode 100755 index 0000000..f2b1f49 --- /dev/null +++ b/build-with.sh @@ -0,0 +1,24 @@ +#!/bin/sh +set -eu + +if [ $# -ne 1 ] ; then + echo "Usage: build-with.sh { docker | podman }" + exit 1 +fi + +builder=$1 +case $builder in + docker|podman) + ;; + *) + echo "You should use either docker or podman for building" + exit 2 +esac + +echo Building $builder image with dependencies.. +$builder build -t qubes-miragevpn . +echo Building MirageVPN... +$builder run --rm -i -v `pwd`:/tmp/orb-build:Z qubes-miragevpn +echo "SHA2 of build: $(sha256sum ./dist/qubes-miragevpn.xen)" +echo "SHA2 last known: $(cat qubes-miragevpn.sha256)" +echo "(hashes should match for released versions)" diff --git a/config.ml b/config.ml index 4d04a5f..2504019 100644 --- a/config.ml +++ b/config.ml @@ -29,7 +29,7 @@ let main = (random @-> mclock @-> pclock @-> time @-> qubesdb @-> stackv4v6 @-> kv_ro @-> job) let () = - register "qubes-unikernel" + register "qubes-miragevpn" [ main $ default_random $ default_monotonic_clock $ default_posix_clock $ default_time diff --git a/dao.ml b/dao.ml index 006ff41..71149fc 100644 --- a/dao.ml +++ b/dao.ml @@ -139,4 +139,4 @@ let print_network_config config = Ipaddr.V4.pp config.ip Ipaddr.V4.pp (fst config.dns) Ipaddr.V4.pp (snd config.dns)) -let set_iptables_error db = Qubes.DB.write db "/qubes-iptables-error" +let _set_iptables_error db = Qubes.DB.write db "/qubes-iptables-error" diff --git a/qubes-miragevpn.sha256 b/qubes-miragevpn.sha256 new file mode 100644 index 0000000..0311878 --- /dev/null +++ b/qubes-miragevpn.sha256 @@ -0,0 +1 @@ +c38251c9c0e72e891b0bffeba3ab4a14244360df3eaea4b87af778e299f1d2b7 ./dist/qubes-miragevpn.xen diff --git a/unikernel.ml b/unikernel.ml index 7c42366..bd7b215 100644 --- a/unikernel.ml +++ b/unikernel.ml @@ -1,5 +1,3 @@ -open Qubes - let ( let* ) = Lwt.bind let ( % ) f g = fun x -> f (g x) @@ -150,9 +148,8 @@ struct | exn -> Lwt.fail exn in Finaliser.add ~finaliser:(fun () -> Lwt.cancel listener) finalisers; - let rec transmit = + let transmit = let rec fn () = - let open Lwt.Syntax in Lwt_stream.get (fst ic) >>= function | Some packet -> (snd t.ic) (Some (vif, packet)); fn () | None -> Lwt.return_unit in @@ -214,7 +211,7 @@ struct msg Cstruct.hexdump_pp cs); Lwt.return fragments | Ok (hdr, payload) -> - let fragments, packet = Fragments.process fragments now hdr payload in + let fragments, _packet = Fragments.process fragments now hdr payload in let packet = Nat.of_ipv4 hdr payload in let packet = Option.map (Mirage_nat_lru.translate table) packet in let packet = Option.map Result.to_option packet in @@ -307,5 +304,6 @@ struct ; oc= Lwt_stream.create () ; ic= Lwt_stream.create () ; clients } in - Lwt.pick [ shutdown; wait_clients t; ovpn_loop t; ingest_private t; packets_to_clients t ] + let* () = Lwt.pick [ shutdown; wait_clients t; ovpn_loop t; ingest_private t; packets_to_clients t ] in + S.disconnect vif0 end diff --git a/vif.ml b/vif.ml index 272422b..2d90e6d 100644 --- a/vif.ml +++ b/vif.ml @@ -50,7 +50,7 @@ type t = ; ip : Client_ip.t ; domid : int } -let make backend { Dao.Client_vif.domid; device_id } ~gateway ipaddr = +let make backend { Dao.Client_vif.domid; _ } ~gateway ipaddr = let open Lwt.Syntax in let* ethernet = Client_ethernet.connect backend in let ((my_mac, your_mac) as mac) =