From dd67baf6294b0b84dcb4825da51a00b8ca97f681 Mon Sep 17 00:00:00 2001 From: Jamil Date: Thu, 29 Sep 2022 08:20:32 -0500 Subject: [PATCH] Build docker image in build workflow; Update automatic install to use Docker (#983) * Test docker prod build in CI * Need uses * Set build-args * Split builds * Fix build-args format * wtf * hmmm * Jeebus * build version based on drafted release * Build multi-platform images * Only build for supported platforms * Use newer OTP fingers crossed * Use OTP 24 for arm64 * Finalize test build of Docker image * Update comment * Bump to OTP 25.1 * Use proper ver * D'oh proper sha * Use OTP 24 and install python for node build * Use new Docker base * Use python3 * Use newly-built base images with other platform support * Don't build for ppc64le and s390x * Build only for amd64/arm64 * Don't rebuild on publish; simply copy * See where the image is being pushed * Remove echo * Add docker updates * Match platforms from base image * Use docker-compose over docker compose * Use our own base * we need python3 * use consistent service name * trim trailing slash from external_url * Build for latest tag in staging --- .devcontainer/Caddyfile | 2 +- .devcontainer/docker-compose.yml | 4 +- .devcontainer/wg0.client.conf | 2 +- .github/workflows/docker_build.yml | 67 +++++++ .github/workflows/docker_publish.yml | 34 ++++ .../{build.yml => omnibus_build.yml} | 4 +- .../{publish.yml => omnibus_publish.yml} | 2 +- .github/workflows/publish-image.yml | 34 ---- .tool-versions | 2 +- Dockerfile.dev | 36 ++-- Dockerfile.prod | 10 +- docker-compose.prod.yml | 6 +- docker-compose.yml | 4 +- omnibus/config/software/erlang.rb | 4 +- .../cookbooks/firezone/libraries/config.rb | 2 +- rel/overlays/bin/gen-env | 6 +- scripts/dev_start.sh | 2 +- scripts/install.sh | 176 ++++++++++-------- scripts/omnibus_install.sh | 169 +++++++++++++++++ 19 files changed, 413 insertions(+), 153 deletions(-) create mode 100644 .github/workflows/docker_build.yml create mode 100644 .github/workflows/docker_publish.yml rename .github/workflows/{build.yml => omnibus_build.yml} (98%) rename .github/workflows/{publish.yml => omnibus_publish.yml} (99%) delete mode 100644 .github/workflows/publish-image.yml create mode 100755 scripts/omnibus_install.sh diff --git a/.devcontainer/Caddyfile b/.devcontainer/Caddyfile index 4077ff28c..6f1e3ac24 100644 --- a/.devcontainer/Caddyfile +++ b/.devcontainer/Caddyfile @@ -1,7 +1,7 @@ localhost { log - reverse_proxy * elixir:4000 + reverse_proxy * firezone:4000 encode gzip diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index ca107a9b6..15e276f95 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -5,9 +5,9 @@ services: image: caddy:2 volumes: - ./Caddyfile:/etc/caddy/Caddyfile - network_mode: service:elixir + network_mode: service:firezone - elixir: + firezone: build: context: . dockerfile: Dockerfile diff --git a/.devcontainer/wg0.client.conf b/.devcontainer/wg0.client.conf index a3568b970..247f09b53 100644 --- a/.devcontainer/wg0.client.conf +++ b/.devcontainer/wg0.client.conf @@ -11,4 +11,4 @@ PublicKey = is+0ov0/SZ9I+qyDD+adVoH9LreWHa85QQgpt6RUtA4= PresharedKey = C+Tte1echarIObr6rq+nFeYQ1QO5xo5N29ygDjMlpS8= PersistentKeepalive = 25 AllowedIPs = 0.0.0.0/0,::/0 -Endpoint = elixir:51820 +Endpoint = firezone:51820 diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml new file mode 100644 index 000000000..ea61ccb61 --- /dev/null +++ b/.github/workflows/docker_build.yml @@ -0,0 +1,67 @@ +name: Docker Build +on: + push: + branches: + - master + - 'build/**' + +jobs: + draft-release: + runs-on: ubuntu-latest + outputs: + tag_name: ${{ steps.release_drafter.outputs.tag_name }} + steps: + - uses: release-drafter/release-drafter@v5 + id: release_drafter + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + docker: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + needs: draft-release + env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + steps: + - uses: actions/checkout@v3 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Log in to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=schedule + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha + type=raw,${{ needs.draft-release.outputs.tag_name }} + type=raw,latest + # Push to GHCR; our registry for testing / dev builds. Publish will + # make these public via Docker Hub in the docker_publish workflow. + - name: Build and push Docker image + uses: docker/build-push-action@v3 + with: + platforms: linux/amd64,linux/arm64 + build-args: | + VERSION=${{ needs.draft-release.outputs.tag_name }} + file: Dockerfile.prod + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/docker_publish.yml b/.github/workflows/docker_publish.yml new file mode 100644 index 000000000..a8b14691a --- /dev/null +++ b/.github/workflows/docker_publish.yml @@ -0,0 +1,34 @@ +name: Publish image to Docker Hub + +on: + release: + types: [published] + +jobs: + deploy-app: + env: + DOCKERHUB_REGISTRY: docker.io + GITHUB_REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + runs-on: ubuntu-latest + steps: + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Log in to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.GITHUB_REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Copy image from Github (staging) to Docker (production) + uses: akhilerm/tag-push-action@v2.0.0 + with: + src: ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME}}:${{ github.ref_name }} + dst: | + ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME}}:latest + ${{ env.DOCKERHUB_REGISTRY }}/${{ env.IMAGE_NAME}}:${{ github.ref_name }} diff --git a/.github/workflows/build.yml b/.github/workflows/omnibus_build.yml similarity index 98% rename from .github/workflows/build.yml rename to .github/workflows/omnibus_build.yml index 499a19ef7..1fe3d5d64 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/omnibus_build.yml @@ -2,7 +2,7 @@ # time. concurrency: build -name: Build +name: Omnibus Build on: push: branches: @@ -11,7 +11,7 @@ on: jobs: draft-release: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest outputs: tag_name: ${{ steps.release_drafter.outputs.tag_name }} steps: diff --git a/.github/workflows/publish.yml b/.github/workflows/omnibus_publish.yml similarity index 99% rename from .github/workflows/publish.yml rename to .github/workflows/omnibus_publish.yml index d8ca0a3da..c712b8dcb 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/omnibus_publish.yml @@ -168,7 +168,7 @@ jobs: republish: 'true' file: firezone_${{ github.ref_name }}-${{ matrix.platform }}.rpm - - name: Pubslih DEB + - name: Publish DEB uses: cloudsmith-io/action@master if: steps.check_deb.outputs.files_exists == 'true' with: diff --git a/.github/workflows/publish-image.yml b/.github/workflows/publish-image.yml deleted file mode 100644 index 00d279b46..000000000 --- a/.github/workflows/publish-image.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Publish image to Docker Hub - -on: - release: - types: [published] - -jobs: - deploy-app: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Login to DockerHub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push App - uses: docker/build-push-action@v3 - with: - push: true - file: Dockerfile.prod - build-args: | - VERSION=${{ github.ref_name }} - tags: ${{ secrets.DOCKERHUB_USERNAME }}/firezone:${{ github.ref_name }} - cache-from: type=gha - cache-to: type=gha,mode=max diff --git a/.tool-versions b/.tool-versions index 3b2886957..8a7e5eb46 100644 --- a/.tool-versions +++ b/.tool-versions @@ -2,7 +2,7 @@ # This should match the versions used in the built product. nodejs 16.17.0 elixir 1.14.0-otp-25 -erlang 25.0.4 +erlang 25.1 # Used for static analysis ruby 2.7.6 diff --git a/Dockerfile.dev b/Dockerfile.dev index 69fafd9e1..4b771e4c2 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -1,26 +1,22 @@ # This Dockerfile builds a development image to use for local development work -FROM hexpm/elixir:1.14.0-erlang-25.0.4-ubuntu-jammy-20220428 +FROM firezone/elixir:1.14.0-otp-25.1 -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/* +# Install dev dependencies / convenience tools +RUN apk add \ +nodejs \ +npm \ +build-base \ +git \ +python3 \ +curl \ +net-tools \ +iproute2 \ +nftables \ +inotify-tools \ +ca-certificates \ +sudo \ +nodejs WORKDIR /var/app diff --git a/Dockerfile.prod b/Dockerfile.prod index af6c5a26e..6f1b4cf93 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -1,14 +1,14 @@ ARG ELIXIR_VERSION=1.14.0 -ARG OTP_VERSION=25.0.4 -ARG ALPINE_VERSION=3.16.1 +ARG OTP_VERSION=25.1 +ARG ALPINE_VERSION=3.16.2 -ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-alpine-${ALPINE_VERSION}" +ARG BUILDER_IMAGE="firezone/elixir:${ELIXIR_VERSION}-otp-${OTP_VERSION}" ARG RUNNER_IMAGE="alpine:${ALPINE_VERSION}" FROM ${BUILDER_IMAGE} as builder # install build dependencies -RUN apk add nodejs npm build-base git +RUN apk add nodejs npm build-base git python3 # prepare build dir WORKDIR /app @@ -104,7 +104,7 @@ ENV MIX_ENV="prod" \ ALLOW_UNPRIVILEGED_DEVICE_CONFIGURATION='true' \ DISABLE_VPN_ON_OIDC_ERROR='false' \ AUTO_CREATE_OIDC_USERS='true' \ - AUTH_OIDC='{}' \ + AUTH_OIDC_JSON='{}' \ MAX_DEVICES_PER_USER='10' \ CONNECTIVITY_CHECKS_ENABLED='true' \ CONNECTIVITY_CHECKS_INTERVAL='3600' \ diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 2f4426ff7..6679f6e78 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -57,7 +57,7 @@ services: # WIREGUARD_INTERFACE_NAME: 'wg-firezone' # WIREGUARD_PORT: '51820' # WIREGUARD_MTU: '1280' - WIREGUARD_ENDPOINT: ${WIREGUARD_ENDPOINT:?err} + # WIREGUARD_ENDPOINT: # WIREGUARD_ALLOWED_IPS: '0.0.0.0/0, ::/0' # WIREGUARD_DNS: '1.1.1.1, 1.0.0.1' # WIREGUARD_PERSISTENT_KEEPALIVE: 0 @@ -88,11 +88,11 @@ services: # ALLOW_UNPRIVILEGED_DEVICE_CONFIGURATION: 'true' # DISABLE_VPN_ON_OIDC_ERROR: 'false' # AUTO_CREATE_OIDC_USERS: 'true' - # AUTH_OIDC: '{}' + # AUTH_OIDC_JSON: '{}' # MAX_DEVICES_PER_USER: '10' # CONNECTIVITY_CHECKS_ENABLED: 'true' # CONNECTIVITY_CHECKS_INTERVAL: '3600' - # TELEMETRY_ENABLED: 'false' + # TELEMETRY_ENABLED: 'true' cap_add: - NET_ADMIN diff --git a/docker-compose.yml b/docker-compose.yml index e8b8fca01..4a589ae6d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,7 @@ services: ipv4_address: 172.28.0.99 ipv6_address: 2001:3990:3990::99 - elixir: + firezone: build: context: . dockerfile: Dockerfile.dev @@ -78,7 +78,7 @@ services: client: depends_on: - - elixir + - firezone image: linuxserver/wireguard:latest environment: - PUID=1000 diff --git a/omnibus/config/software/erlang.rb b/omnibus/config/software/erlang.rb index 5ea1a65d5..a1f8ab405 100644 --- a/omnibus/config/software/erlang.rb +++ b/omnibus/config/software/erlang.rb @@ -19,8 +19,7 @@ name 'erlang' -# Erlang 25 has SSL issues -- HTTPoison times out to some servers, e.g. Azure https://login.microsoftonline.com -default_version '25.0.4' +default_version '25.1' license 'Apache-2.0' license_file 'LICENSE.txt' @@ -38,6 +37,7 @@ source url: "https://github.com/erlang/otp/archive/OTP-#{version}.tar.gz" relative_path "otp-OTP-#{version}" # versions_list: https://github.com/erlang/otp/tags filter=*.tar.gz +version('25.1') { source sha256: 'e00b2e02350688ee4ac83c41ec25c210774fe73b7f806860c46b185457ae135e' } version('25.0.4') { source sha256: '05878cb51a64b33c86836b12a21903075c300409b609ad5e941ddb0feb8c2120' } version('25.0.3') { source sha256: 'e8eca69b6bdaac9cc8f3e3177dd2913920513495ee83bdecf73af546768febd6' } version('25.0.2') { source sha256: 'f78764c6fd504f7b264c47e469c0fcb86a01c92344dc9d625dfd42f6c3ed8224' } diff --git a/omnibus/cookbooks/firezone/libraries/config.rb b/omnibus/cookbooks/firezone/libraries/config.rb index 9f0f5a407..0fa112bf1 100644 --- a/omnibus/cookbooks/firezone/libraries/config.rb +++ b/omnibus/cookbooks/firezone/libraries/config.rb @@ -271,7 +271,7 @@ class Firezone 'AUTO_CREATE_OIDC_USERS' => attributes['authentication']['auto_create_oidc_users'].to_s, # OpenID Connect auth settings are serialized to json for consumption by fz_http - 'AUTH_OIDC' => attributes['authentication']['oidc'].to_json, + 'AUTH_OIDC_JSON' => attributes['authentication']['oidc'].to_json, # secrets 'GUARDIAN_SECRET_KEY' => attributes['guardian_secret_key'], diff --git a/rel/overlays/bin/gen-env b/rel/overlays/bin/gen-env index 535758124..92f315280 100755 --- a/rel/overlays/bin/gen-env +++ b/rel/overlays/bin/gen-env @@ -1,9 +1,8 @@ #!/bin/sh cat <<-EOF -EXTERNAL_URL=https://change-me.site -WIREGUARD_ENDPOINT=change-me.site -ADMIN_EMAIL=admin@change-me.site +EXTERNAL_URL=_CHANGE_ME_ +ADMIN_EMAIL=_CHANGE_ME_ DEFAULT_ADMIN_PASSWORD=$(openssl rand -base64 12) GUARDIAN_SECRET_KEY=$(openssl rand -base64 48) SECRET_KEY_BASE=$(openssl rand -base64 48) @@ -12,4 +11,5 @@ COOKIE_SIGNING_SALT=$(openssl rand -base64 6) COOKIE_ENCRYPTION_SALT=$(openssl rand -base64 6) DATABASE_ENCRYPTION_KEY=$(openssl rand -base64 32) DATABASE_PASSWORD=$(openssl rand -base64 12) +TELEMETRY_ID=$(od -vN "8" -An -tx1 /dev/urandom | tr -d " \n" ; echo) EOF diff --git a/scripts/dev_start.sh b/scripts/dev_start.sh index 09f7c9505..5770fbab8 100755 --- a/scripts/dev_start.sh +++ b/scripts/dev_start.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh ip link add dev wg-firezone type wireguard ip address replace dev wg-firezone 10.3.2.1/24 diff --git a/scripts/install.sh b/scripts/install.sh index 14d354499..61b3eead5 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -9,6 +9,13 @@ osCheck () { fi } +dockerCheck () { + if ! type docker > /dev/null; then + echo 'docker not found. Please install docker and try again.' + exit + fi +} + curlCheck () { if ! type curl > /dev/null; then echo 'curl not found. Please install curl to use this script.' @@ -35,9 +42,25 @@ capture () { fi fi } + +promptInstallDir() { + read -p "$1" installDir + if [ -z "$installDir" ]; then + installDir=$defaultInstallDir + fi +} + +promptExternalUrl() { + read -p "$1" externalUrl + # Remove trailing slash if present + externalUrl=$(echo $externalUrl | sed 's:/*$::') + if [ -z "$externalUrl" ]; then + externalUrl=$defaultExternalUrl + fi +} + promptEmail() { - echo $1 - read adminEmail + read -p "$1" adminEmail case $adminEmail in *@*) adminUser=$adminEmail;; *) promptEmail "Please provide a valid email: " @@ -45,8 +68,7 @@ promptEmail() { } promptContact() { - echo "Could we email you to ask for product feedback? Firezone depends heavily on input from users like you to steer development. (Y/n): " - read contact + read -p 'Could we email you to ask for product feedback? Firezone depends heavily on input from users like you to steer development. (Y/n): ' contact case $contact in n|N);; *) capture "contactOk" $adminUser @@ -78,87 +100,93 @@ kernelCheck() { fi } -# determines distro and sets up and installs from cloudsmith repo -# aborts if it can't detect or is not supported -setupCloudsmithRepoAndInstall() { - hostinfo=`hostnamectl | egrep -i 'opera'` - if [[ "$hostinfo" =~ .*"Debian GNU/Linux 10".* || \ - "$hostinfo" =~ .*"Debian GNU/Linux 11".* || \ - "$hostinfo" =~ .*"Ubuntu 18.04".* || \ - "$hostinfo" =~ .*"Ubuntu 2"(0|1|2)".04".* - ]] - then - if [ ! -f /etc/apt/sources.list.d/firezone-firezone.list ]; then - apt-get -qqy update - apt-get -qqy install apt-transport-https gnupg - setupCloudsmithRepo "deb" - else - apt-get -qqy update - fi - - apt-get install -y firezone - elif [[ "$hostinfo" =~ .*"Amazon Linux 2".* || \ - "$hostinfo" =~ .*"Fedora 33".* || \ - "$hostinfo" =~ .*"Fedora 34".* || \ - "$hostinfo" =~ .*"Fedora Linux 3"(5|6).* || \ - "$hostinfo" =~ .*"CentOS Linux 7".* || \ - "$hostinfo" =~ .*"CentOS Stream 8".* || \ - "$hostinfo" =~ .*"CentOS Linux 8".* || \ - "$hostinfo" =~ .*"CentOS Stream 9".* || \ - "$hostinfo" =~ .*"Oracle Linux Server "(7|8|9).* || \ - "$hostinfo" =~ .*"Red Hat Enterprise Linux "(7|8|9).* || \ - "$hostinfo" =~ .*"Rocky Linux 8".* || \ - "$hostinfo" =~ .*"AlmaLinux 8".* || \ - "$hostinfo" =~ .*"VzLinux 8".* - ]] - then - if [ ! -f /etc/yum.repos.d/firezone-firezone.repo ]; then - setupCloudsmithRepo "rpm" - fi - - yum install -y firezone - elif [[ "$hostinfo" =~ .*"openSUSE Leap 15".* ]] - then - if ! zypper lr | grep firezone-firezone; then - setupCloudsmithRepo "rpm" - else - zypper --non-interactive --quiet ref firezone-firezone - fi - - zypper --non-interactive install -y firezone - else - echo "Did not detect a supported Linux distribution. Try using the manual installation method using a release package from a similar distribution. Aborting." - exit - fi -} - -setupCloudsmithRepo() { - curl -1sLf \ - "https://dl.cloudsmith.io/public/firezone/firezone/setup.$1.sh" \ - | bash -} - firezoneSetup() { - conf="/opt/firezone/embedded/cookbooks/firezone/attributes/default.rb" - sed -i "s/firezone@localhost/$1/" $conf - sed -i "s/default\['firezone']\['external_url'].*/default['firezone']['external_url'] = 'https:\/\/$public_ip'/" $conf - firezone-ctl reconfigure - firezone-ctl create-or-reset-admin + cd $installDir + curl -fsSL https://raw.githubusercontent.com/firezone/firezone/master/docker-compose.prod.yml -o docker-compose.yml + docker run --rm firezone/firezone bin/gen-env > .env + sed -i "s/ADMIN_EMAIL=_CHANGE_ME_/ADMIN_EMAIL=$1/" .env + sed -i "s~EXTERNAL_URL=_CHANGE_ME_~EXTERNAL_URL=$2~" .env + sed -i "s/TELEMETRY_ID=.*/TELEMETRY_ID=$telemetry_id/" .env + docker-compose up -d + docker-compose exec firezone bin/create-or-reset-admin + + displayLogo + +cat << EOF +Installation complete! + +You should now be able to log into the Web UI at $externalUrl with the +following credentials: + +`grep ADMIN_EMAIL .env` +`grep DEFAULT_ADMIN_PASSWORD .env` + +EOF + + cd - } +displayLogo() { +cat << EOF + + + + + + + :: + !!: + .??^ + ~J?^ + :???. + .??J^ + .??J! + .??J! + ^J?J~ + !???: + .???? :: + ^J?J! :~: + 7???: :~~ + .???7 ~~~. + :??J^ :~~^ + :???..~~~: + ............. .?J7 ^~~~ .... + .. ......::.... ~J!.~~~^ ::.. + ...:::.... !7^~~~^ .^: . + ...:::.... ~~~~~~:. .:~^ . + ....:::.... .~~~~~~~~~:.. + ...::::.... .::^^^^:... + .....:::............. + .......:::..... + + + + + + + + +EOF +} + + main() { + defaultInstallDir=`pwd` + defaultExternalUrl="https://$public_ip" adminUser='' + externalUrl='' kernelCheck wireguardCheck - promptEmail "Enter the administrator email you'd like to use for logging into this Firezone instance:" + promptEmail "Enter the administrator email you'd like to use for logging into this Firezone instance: " + promptInstallDir "Enter the desired installation directory ($defaultInstallDir): " + promptExternalUrl "Enter the external URL that will be used to access this instance ($defaultExternalUrl): " promptContact - echo "Press to install or Ctrl-C to abort." - read - setupCloudsmithRepoAndInstall - firezoneSetup $adminUser + read -p "Press to install or Ctrl-C to abort." + firezoneSetup $adminUser $externalUrl } osCheck +dockerCheck curlCheck telemetry_id=`od -vN "8" -An -tx1 /dev/urandom | tr -d " \n" ; echo` diff --git a/scripts/omnibus_install.sh b/scripts/omnibus_install.sh new file mode 100755 index 000000000..14d354499 --- /dev/null +++ b/scripts/omnibus_install.sh @@ -0,0 +1,169 @@ +#!/bin/bash +set -e + +osCheck () { + os=`uname -s` + if [ ! $os = "Linux" ]; then + echo "Please ensure you're running this script on Linux and try again." + exit + fi +} + +curlCheck () { + if ! type curl > /dev/null; then + echo 'curl not found. Please install curl to use this script.' + exit + fi +} + +capture () { + if type curl > /dev/null; then + if [ ! -z "$telemetry_id" ]; then + curl -s -XPOST \ + -m 5 \ + -H 'Content-Type: application/json' \ + -d "{ + \"api_key\": \"phc_ubuPhiqqjMdedpmbWpG2Ak3axqv5eMVhFDNBaXl9UZK\", + \"event\": \"$1\", + \"properties\": { + \"distinct_id\": \"$telemetry_id\", + \"email\": \"$2\" + } + }" \ + https://telemetry.firez.one/capture/ > /dev/null \ + || true + fi + fi +} +promptEmail() { + echo $1 + read adminEmail + case $adminEmail in + *@*) adminUser=$adminEmail;; + *) promptEmail "Please provide a valid email: " + esac +} + +promptContact() { + echo "Could we email you to ask for product feedback? Firezone depends heavily on input from users like you to steer development. (Y/n): " + read contact + case $contact in + n|N);; + *) capture "contactOk" $adminUser + esac +} + +wireguardCheck() { + if ! test -f /sys/module/wireguard/version; then + if test -d /lib/modules/$(uname -r) && test -f `find /lib/modules/$(uname -r) -type f -name 'wireguard.ko'`; then + echo "WireGuard kernel module found, but not loaded. Load it now? (Y/n): " + read load_wgmod + case $load_wgmod in + n|N) echo "Load it with 'sudo modprobe wireguard' and run this install script again"; exit;; + *) modprobe wireguard + esac + else + echo "Error! WireGuard not detected. Please upgrade your kernel to at least 5.6 or install the WireGuard kernel module." + echo "See more at https://www.wireguard.com/install/" + exit + fi + fi +} + +kernelCheck() { + major=`uname -r | cut -d'.' -f1` + if [ "$major" -lt "5" ]; then + echo "Kernel version `uname -r ` is not supported. Please upgrade to 5.0 or higher." + exit + fi +} + +# determines distro and sets up and installs from cloudsmith repo +# aborts if it can't detect or is not supported +setupCloudsmithRepoAndInstall() { + hostinfo=`hostnamectl | egrep -i 'opera'` + if [[ "$hostinfo" =~ .*"Debian GNU/Linux 10".* || \ + "$hostinfo" =~ .*"Debian GNU/Linux 11".* || \ + "$hostinfo" =~ .*"Ubuntu 18.04".* || \ + "$hostinfo" =~ .*"Ubuntu 2"(0|1|2)".04".* + ]] + then + if [ ! -f /etc/apt/sources.list.d/firezone-firezone.list ]; then + apt-get -qqy update + apt-get -qqy install apt-transport-https gnupg + setupCloudsmithRepo "deb" + else + apt-get -qqy update + fi + + apt-get install -y firezone + elif [[ "$hostinfo" =~ .*"Amazon Linux 2".* || \ + "$hostinfo" =~ .*"Fedora 33".* || \ + "$hostinfo" =~ .*"Fedora 34".* || \ + "$hostinfo" =~ .*"Fedora Linux 3"(5|6).* || \ + "$hostinfo" =~ .*"CentOS Linux 7".* || \ + "$hostinfo" =~ .*"CentOS Stream 8".* || \ + "$hostinfo" =~ .*"CentOS Linux 8".* || \ + "$hostinfo" =~ .*"CentOS Stream 9".* || \ + "$hostinfo" =~ .*"Oracle Linux Server "(7|8|9).* || \ + "$hostinfo" =~ .*"Red Hat Enterprise Linux "(7|8|9).* || \ + "$hostinfo" =~ .*"Rocky Linux 8".* || \ + "$hostinfo" =~ .*"AlmaLinux 8".* || \ + "$hostinfo" =~ .*"VzLinux 8".* + ]] + then + if [ ! -f /etc/yum.repos.d/firezone-firezone.repo ]; then + setupCloudsmithRepo "rpm" + fi + + yum install -y firezone + elif [[ "$hostinfo" =~ .*"openSUSE Leap 15".* ]] + then + if ! zypper lr | grep firezone-firezone; then + setupCloudsmithRepo "rpm" + else + zypper --non-interactive --quiet ref firezone-firezone + fi + + zypper --non-interactive install -y firezone + else + echo "Did not detect a supported Linux distribution. Try using the manual installation method using a release package from a similar distribution. Aborting." + exit + fi +} + +setupCloudsmithRepo() { + curl -1sLf \ + "https://dl.cloudsmith.io/public/firezone/firezone/setup.$1.sh" \ + | bash +} + +firezoneSetup() { + conf="/opt/firezone/embedded/cookbooks/firezone/attributes/default.rb" + sed -i "s/firezone@localhost/$1/" $conf + sed -i "s/default\['firezone']\['external_url'].*/default['firezone']['external_url'] = 'https:\/\/$public_ip'/" $conf + firezone-ctl reconfigure + firezone-ctl create-or-reset-admin +} + +main() { + adminUser='' + kernelCheck + wireguardCheck + promptEmail "Enter the administrator email you'd like to use for logging into this Firezone instance:" + promptContact + echo "Press to install or Ctrl-C to abort." + read + setupCloudsmithRepoAndInstall + firezoneSetup $adminUser +} + +osCheck +curlCheck + +telemetry_id=`od -vN "8" -An -tx1 /dev/urandom | tr -d " \n" ; echo` +public_ip=`curl -m 5 --silent ifconfig.me` + +capture "install" "email-not-collected@dummy.domain" + +main