From 1be77d4e2dd4e5a992458e128e3fa75d393b7717 Mon Sep 17 00:00:00 2001 From: Jamil Date: Wed, 8 May 2024 14:09:50 -0700 Subject: [PATCH] chore: Bump versions to link 1.0.3 packages (#4924) Link to latest binaries Generated with `make -f scripts/Makefile`. Just need a rubber-stamp, changes should be GTG --- .github/workflows/_build_artifacts.yml | 4 +- .github/workflows/_deploy_production.yml | 2 +- .github/workflows/_tauri.yml | 18 +- .github/workflows/_terraform.yml | 2 +- .github/workflows/cd.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/publish.yml | 2 +- elixir/VERSION | 2 +- rust/Cargo.lock | 34 +-- rust/connlib/clients/android/Cargo.toml | 2 +- rust/connlib/clients/apple/Cargo.toml | 2 +- rust/connlib/clients/shared/Cargo.toml | 2 +- rust/connlib/shared/Cargo.toml | 2 +- rust/connlib/snownet/Cargo.toml | 2 +- rust/connlib/tunnel/Cargo.toml | 2 +- rust/firezone-cli-utils/Cargo.toml | 2 +- rust/gateway/Cargo.toml | 2 +- rust/gui-client/src-tauri/Cargo.toml | 2 +- rust/headless-client/Cargo.toml | 2 +- rust/http-health-check/Cargo.toml | 2 +- rust/http-test-server/Cargo.toml | 2 +- rust/ip-packet/Cargo.toml | 2 +- rust/linux-client/Cargo.toml | 2 +- rust/phoenix-channel/Cargo.toml | 2 +- rust/relay/Cargo.toml | 2 +- rust/snownet-tests/Cargo.toml | 2 +- scripts/Makefile | 15 +- .../may-2024-update/traffic-restriction.png | Bin 0 -> 59618 bytes website/redirects.js | 18 +- .../src/app/blog/may-2024-update/_page.tsx | 17 ++ website/src/app/blog/may-2024-update/page.tsx | 11 + .../src/app/blog/may-2024-update/readme.mdx | 270 ++++++++++++++++++ 32 files changed, 369 insertions(+), 64 deletions(-) create mode 100644 website/public/images/blog/may-2024-update/traffic-restriction.png create mode 100644 website/src/app/blog/may-2024-update/_page.tsx create mode 100644 website/src/app/blog/may-2024-update/page.tsx create mode 100644 website/src/app/blog/may-2024-update/readme.mdx diff --git a/.github/workflows/_build_artifacts.yml b/.github/workflows/_build_artifacts.yml index 4fa905a88..3cef7a4a5 100644 --- a/.github/workflows/_build_artifacts.yml +++ b/.github/workflows/_build_artifacts.yml @@ -40,7 +40,7 @@ on: env: # mark:automatic-version - VERSION: "1.0.3" + VERSION: "1.0.4" permissions: # write permission is required to create a github release @@ -175,7 +175,7 @@ jobs: image_name: http-test-server env: # mark:automatic-version - BINARY_DEST_PATH: ${{ matrix.name.artifact }}_1.0.3_${{ matrix.arch.shortname }} + BINARY_DEST_PATH: ${{ matrix.name.artifact }}_1.0.4_${{ matrix.arch.shortname }} outputs: client_image: ${{ steps.image-name.outputs.client_image }} relay_image: ${{ steps.image-name.outputs.relay_image }} diff --git a/.github/workflows/_deploy_production.yml b/.github/workflows/_deploy_production.yml index 22899be07..7da4896ee 100644 --- a/.github/workflows/_deploy_production.yml +++ b/.github/workflows/_deploy_production.yml @@ -11,7 +11,7 @@ on: env: # mark:automatic-version - VERSION: "1.0.3" + VERSION: "1.0.4" concurrency: group: "production-deploy" diff --git a/.github/workflows/_tauri.yml b/.github/workflows/_tauri.yml index ccc35629e..be7533de2 100644 --- a/.github/workflows/_tauri.yml +++ b/.github/workflows/_tauri.yml @@ -14,7 +14,7 @@ permissions: env: # mark:automatic-version - VERSION: "1.0.3" + VERSION: "1.0.4" defaults: run: @@ -30,26 +30,26 @@ jobs: include: - runs-on: ubuntu-20.04 # mark:automatic-version - binary-dest-path: firezone-client-gui-linux_1.0.3_x86_64 + binary-dest-path: firezone-client-gui-linux_1.0.4_x86_64 rename-script: ../../scripts/build/tauri-rename-ubuntu.sh upload-script: ../../scripts/build/tauri-upload-ubuntu.sh # mark:automatic-version - exe-artifact: rust/gui-client/firezone-client-gui-linux_1.0.3_x86_64 + exe-artifact: rust/gui-client/firezone-client-gui-linux_1.0.4_x86_64 # mark:automatic-version - syms-artifact: rust/gui-client/firezone-client-gui-linux_1.0.3_x86_64.dwp + syms-artifact: rust/gui-client/firezone-client-gui-linux_1.0.4_x86_64.dwp # mark:automatic-version - pkg-artifact: rust/gui-client/firezone-client-gui-linux_1.0.3_x86_64.deb + pkg-artifact: rust/gui-client/firezone-client-gui-linux_1.0.4_x86_64.deb - runs-on: windows-2019 # mark:automatic-version - binary-dest-path: firezone-client-gui-windows_1.0.3_x86_64 + binary-dest-path: firezone-client-gui-windows_1.0.4_x86_64 rename-script: ../../scripts/build/tauri-rename-windows.sh upload-script: ../../scripts/build/tauri-upload-windows.sh # mark:automatic-version - exe-artifact: rust/gui-client/firezone-client-gui-windows_1.0.3_x86_64.exe + exe-artifact: rust/gui-client/firezone-client-gui-windows_1.0.4_x86_64.exe # mark:automatic-version - syms-artifact: rust/gui-client/firezone-client-gui-windows_1.0.3_x86_64.pdb + syms-artifact: rust/gui-client/firezone-client-gui-windows_1.0.4_x86_64.pdb # mark:automatic-version - pkg-artifact: rust/gui-client/firezone-client-gui-windows_1.0.3_x86_64.msi + pkg-artifact: rust/gui-client/firezone-client-gui-windows_1.0.4_x86_64.msi env: BINARY_DEST_PATH: ${{ matrix.binary-dest-path }} AZURE_KEY_VAULT_URI: ${{ secrets.AZURE_KEY_VAULT_URI }} diff --git a/.github/workflows/_terraform.yml b/.github/workflows/_terraform.yml index d901ccc01..9f1acf924 100644 --- a/.github/workflows/_terraform.yml +++ b/.github/workflows/_terraform.yml @@ -4,7 +4,7 @@ on: env: # mark:automatic-version - VERSION: "1.0.3" + VERSION: "1.0.4" jobs: plan-deploy: diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 87115164d..68d5dcdd7 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -14,7 +14,7 @@ on: env: # mark:automatic-version - VERSION: "1.0.3" + VERSION: "1.0.4" jobs: # Builds images that match what's default in docker-compose.yml for diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f898514e2..6c5120044 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ on: env: # mark:automatic-version - VERSION: "1.0.3" + VERSION: "1.0.4" # Cancel old workflow runs if new code is pushed concurrency: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8b15d0abc..b6e2797e0 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,7 +7,7 @@ on: env: # mark:automatic-version - VERSION: "1.0.3" + VERSION: "1.0.4" concurrency: group: "publish-production-${{ github.event_name }}-${{ github.workflow }}-${{ github.ref }}" diff --git a/elixir/VERSION b/elixir/VERSION index 21e8796a0..ee90284c2 100644 --- a/elixir/VERSION +++ b/elixir/VERSION @@ -1 +1 @@ -1.0.3 +1.0.4 diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 5b6cc463d..d313b5233 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -1088,7 +1088,7 @@ dependencies = [ [[package]] name = "connlib-client-android" -version = "1.0.3" +version = "1.0.4" dependencies = [ "connlib-client-shared", "ip_network", @@ -1107,7 +1107,7 @@ dependencies = [ [[package]] name = "connlib-client-apple" -version = "1.0.3" +version = "1.0.4" dependencies = [ "connlib-client-shared", "ip_network", @@ -1126,7 +1126,7 @@ dependencies = [ [[package]] name = "connlib-client-shared" -version = "1.0.3" +version = "1.0.4" dependencies = [ "anyhow", "async-trait", @@ -1153,7 +1153,7 @@ dependencies = [ [[package]] name = "connlib-shared" -version = "1.0.3" +version = "1.0.4" dependencies = [ "anyhow", "atomicwrites", @@ -1845,7 +1845,7 @@ dependencies = [ [[package]] name = "firezone-cli-utils" -version = "1.0.3" +version = "1.0.4" dependencies = [ "clap", "tracing", @@ -1856,7 +1856,7 @@ dependencies = [ [[package]] name = "firezone-gateway" -version = "1.0.3" +version = "1.0.4" dependencies = [ "anyhow", "async-trait", @@ -1889,7 +1889,7 @@ dependencies = [ [[package]] name = "firezone-gui-client" -version = "1.0.3" +version = "1.0.4" dependencies = [ "anyhow", "arboard", @@ -1943,7 +1943,7 @@ dependencies = [ [[package]] name = "firezone-headless-client" -version = "1.0.3" +version = "1.0.4" dependencies = [ "anyhow", "clap", @@ -1969,7 +1969,7 @@ dependencies = [ [[package]] name = "firezone-linux-client" -version = "1.0.3" +version = "1.0.4" dependencies = [ "anyhow", "firezone-headless-client", @@ -1977,7 +1977,7 @@ dependencies = [ [[package]] name = "firezone-relay" -version = "1.0.3" +version = "1.0.4" dependencies = [ "anyhow", "backoff", @@ -2018,7 +2018,7 @@ dependencies = [ [[package]] name = "firezone-tunnel" -version = "1.0.3" +version = "1.0.4" dependencies = [ "async-trait", "bimap", @@ -2849,7 +2849,7 @@ dependencies = [ [[package]] name = "http-health-check" -version = "1.0.3" +version = "1.0.4" dependencies = [ "axum 0.7.5", "clap", @@ -2864,7 +2864,7 @@ checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" [[package]] name = "http-test-server" -version = "1.0.3" +version = "1.0.4" dependencies = [ "anyhow", "axum 0.7.5", @@ -3123,7 +3123,7 @@ dependencies = [ [[package]] name = "ip-packet" -version = "1.0.3" +version = "1.0.4" dependencies = [ "pnet_packet", ] @@ -4458,7 +4458,7 @@ dependencies = [ [[package]] name = "phoenix-channel" -version = "1.0.3" +version = "1.0.4" dependencies = [ "backoff", "base64 0.22.0", @@ -5722,7 +5722,7 @@ dependencies = [ [[package]] name = "snownet" -version = "1.0.3" +version = "1.0.4" dependencies = [ "backoff", "boringtun", @@ -5743,7 +5743,7 @@ dependencies = [ [[package]] name = "snownet-tests" -version = "1.0.3" +version = "1.0.4" dependencies = [ "anyhow", "boringtun", diff --git a/rust/connlib/clients/android/Cargo.toml b/rust/connlib/clients/android/Cargo.toml index a252165f6..fe2b60662 100644 --- a/rust/connlib/clients/android/Cargo.toml +++ b/rust/connlib/clients/android/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "connlib-client-android" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" [lib] diff --git a/rust/connlib/clients/apple/Cargo.toml b/rust/connlib/clients/apple/Cargo.toml index deb1ffb45..8b646ea3a 100644 --- a/rust/connlib/clients/apple/Cargo.toml +++ b/rust/connlib/clients/apple/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "connlib-client-apple" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" [features] diff --git a/rust/connlib/clients/shared/Cargo.toml b/rust/connlib/clients/shared/Cargo.toml index 55df16a84..7af7f0949 100644 --- a/rust/connlib/clients/shared/Cargo.toml +++ b/rust/connlib/clients/shared/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "connlib-client-shared" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" [features] diff --git a/rust/connlib/shared/Cargo.toml b/rust/connlib/shared/Cargo.toml index 22ae16b94..92e68db9b 100644 --- a/rust/connlib/shared/Cargo.toml +++ b/rust/connlib/shared/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "connlib-shared" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/rust/connlib/snownet/Cargo.toml b/rust/connlib/snownet/Cargo.toml index c7669b964..5785af34f 100644 --- a/rust/connlib/snownet/Cargo.toml +++ b/rust/connlib/snownet/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snownet" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" [dependencies] diff --git a/rust/connlib/tunnel/Cargo.toml b/rust/connlib/tunnel/Cargo.toml index 842c836ec..ca5dbd391 100644 --- a/rust/connlib/tunnel/Cargo.toml +++ b/rust/connlib/tunnel/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "firezone-tunnel" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" [dependencies] diff --git a/rust/firezone-cli-utils/Cargo.toml b/rust/firezone-cli-utils/Cargo.toml index 9b416b74a..bbeac73ea 100644 --- a/rust/firezone-cli-utils/Cargo.toml +++ b/rust/firezone-cli-utils/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "firezone-cli-utils" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/rust/gateway/Cargo.toml b/rust/gateway/Cargo.toml index 631ada17f..b9f8dfb66 100644 --- a/rust/gateway/Cargo.toml +++ b/rust/gateway/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "firezone-gateway" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/rust/gui-client/src-tauri/Cargo.toml b/rust/gui-client/src-tauri/Cargo.toml index fa62cab69..3ab121bd5 100644 --- a/rust/gui-client/src-tauri/Cargo.toml +++ b/rust/gui-client/src-tauri/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "firezone-gui-client" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" description = "Firezone" edition = "2021" default-run = "firezone-gui-client" diff --git a/rust/headless-client/Cargo.toml b/rust/headless-client/Cargo.toml index 239f20652..62a226b93 100644 --- a/rust/headless-client/Cargo.toml +++ b/rust/headless-client/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "firezone-headless-client" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" authors = ["Firezone, Inc."] diff --git a/rust/http-health-check/Cargo.toml b/rust/http-health-check/Cargo.toml index 41dc68bd0..7a40404bc 100644 --- a/rust/http-health-check/Cargo.toml +++ b/rust/http-health-check/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "http-health-check" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/rust/http-test-server/Cargo.toml b/rust/http-test-server/Cargo.toml index 968fddd08..fa60af100 100644 --- a/rust/http-test-server/Cargo.toml +++ b/rust/http-test-server/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "http-test-server" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/rust/ip-packet/Cargo.toml b/rust/ip-packet/Cargo.toml index ca15bb4a7..0fd12d448 100644 --- a/rust/ip-packet/Cargo.toml +++ b/rust/ip-packet/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ip-packet" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" authors = ["Firezone, Inc."] publish = false diff --git a/rust/linux-client/Cargo.toml b/rust/linux-client/Cargo.toml index 2bdd4dafe..874a52ea1 100644 --- a/rust/linux-client/Cargo.toml +++ b/rust/linux-client/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "firezone-linux-client" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" authors = ["Firezone, Inc."] diff --git a/rust/phoenix-channel/Cargo.toml b/rust/phoenix-channel/Cargo.toml index e6e3d5a58..71cc1340f 100644 --- a/rust/phoenix-channel/Cargo.toml +++ b/rust/phoenix-channel/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "phoenix-channel" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/rust/relay/Cargo.toml b/rust/relay/Cargo.toml index 8356ec3b4..263adf3ee 100644 --- a/rust/relay/Cargo.toml +++ b/rust/relay/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "firezone-relay" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" [dependencies] diff --git a/rust/snownet-tests/Cargo.toml b/rust/snownet-tests/Cargo.toml index e8a4d1542..a16d63823 100644 --- a/rust/snownet-tests/Cargo.toml +++ b/rust/snownet-tests/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snownet-tests" # mark:automatic-version -version = "1.0.3" +version = "1.0.4" edition = "2021" [dependencies] diff --git a/scripts/Makefile b/scripts/Makefile index af48d6fbd..69a3c267d 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -1,12 +1,19 @@ # Format: Semver # See discussion here: https://github.com/firezone/firezone/issues/2041 # and PR changing it here: https://github.com/firezone/firezone/pull/2949 + +# These should track the upcoming release for Apple/Android apple-version = 1.0.5 android-version = 1.0.3 -cargo-version = 1.0.3 -website-version = 1.0.2 -elixir-version = 1.0.3 -ci-version = 1.0.3 + +# Set this to the current latest published release for the Windows/Linux/Gateway packages so +# that links from the website will work +website-version = 1.0.3 + +# Set this to the upcoming release for the Windows/Linux/Gateway packages +cargo-version = 1.0.4 +elixir-version = 1.0.4 +ci-version = 1.0.4 .PHONY: version apple-version android-version cargo-version ci-version elixir-version diff --git a/website/public/images/blog/may-2024-update/traffic-restriction.png b/website/public/images/blog/may-2024-update/traffic-restriction.png new file mode 100644 index 0000000000000000000000000000000000000000..4448bc42c649a3d2ef8b6bf1075a4b69f107aa01 GIT binary patch literal 59618 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 literal 0 HcmV?d00001 diff --git a/website/redirects.js b/website/redirects.js index ee8e20090..04da1270d 100644 --- a/website/redirects.js +++ b/website/redirects.js @@ -11,7 +11,7 @@ module.exports = [ source: "/dl/firezone-client-gui-windows/latest/x86_64", destination: // mark:automatic-version - "https://www.github.com/firezone/firezone/releases/download/1.0.2/firezone-client-gui-windows_1.0.2_x86_64.msi", + "https://www.github.com/firezone/firezone/releases/download/1.0.3/firezone-client-gui-windows_1.0.3_x86_64.msi", permanent: false, }, // versioned @@ -31,35 +31,35 @@ module.exports = [ source: "/dl/firezone-client-gui-linux/latest/x86_64", destination: // mark:automatic-version - "https://www.github.com/firezone/firezone/releases/download/1.0.2/firezone-client-gui-linux_1.0.2_x86_64.deb", + "https://www.github.com/firezone/firezone/releases/download/1.0.3/firezone-client-gui-linux_1.0.3_x86_64.deb", permanent: false, }, { source: "/dl/firezone-client-gui-linux/latest/aarch64", destination: // mark:automatic-version - "https://www.github.com/firezone/firezone/releases/download/1.0.2/firezone-client-gui-linux_1.0.2_aarch64.deb", + "https://www.github.com/firezone/firezone/releases/download/1.0.3/firezone-client-gui-linux_1.0.3_aarch64.deb", permanent: false, }, { source: "/dl/firezone-client-headless-linux/latest/x86_64", destination: // mark:automatic-version - "https://www.github.com/firezone/firezone/releases/download/1.0.2/firezone-client-headless-linux_1.0.2_x86_64", + "https://www.github.com/firezone/firezone/releases/download/1.0.3/firezone-client-headless-linux_1.0.3_x86_64", permanent: false, }, { source: "/dl/firezone-client-headless-linux/latest/aarch64", destination: // mark:automatic-version - "https://www.github.com/firezone/firezone/releases/download/1.0.2/firezone-client-headless-linux_1.0.2_aarch64", + "https://www.github.com/firezone/firezone/releases/download/1.0.3/firezone-client-headless-linux_1.0.3_aarch64", permanent: false, }, { source: "/dl/firezone-client-headless-linux/latest/armv7", destination: // mark:automatic-version - "https://www.github.com/firezone/firezone/releases/download/1.0.2/firezone-client-headless-linux_1.0.2_armv7", + "https://www.github.com/firezone/firezone/releases/download/1.0.3/firezone-client-headless-linux_1.0.3_armv7", permanent: false, }, // versioned @@ -103,21 +103,21 @@ module.exports = [ source: "/dl/firezone-gateway/latest/x86_64", destination: // mark:automatic-version - "https://www.github.com/firezone/firezone/releases/download/1.0.2/firezone-gateway_1.0.2_x86_64", + "https://www.github.com/firezone/firezone/releases/download/1.0.3/firezone-gateway_1.0.3_x86_64", permanent: false, }, { source: "/dl/firezone-gateway/latest/aarch64", destination: // mark:automatic-version - "https://www.github.com/firezone/firezone/releases/download/1.0.2/firezone-gateway_1.0.2_aarch64", + "https://www.github.com/firezone/firezone/releases/download/1.0.3/firezone-gateway_1.0.3_aarch64", permanent: false, }, { source: "/dl/firezone-gateway/latest/armv7", destination: // mark:automatic-version - "https://www.github.com/firezone/firezone/releases/download/1.0.2/firezone-gateway_1.0.2_armv7", + "https://www.github.com/firezone/firezone/releases/download/1.0.3/firezone-gateway_1.0.3_armv7", permanent: false, }, // versioned diff --git a/website/src/app/blog/may-2024-update/_page.tsx b/website/src/app/blog/may-2024-update/_page.tsx new file mode 100644 index 000000000..f3b75743c --- /dev/null +++ b/website/src/app/blog/may-2024-update/_page.tsx @@ -0,0 +1,17 @@ +"use client"; +import Post from "@/components/Blog/Post"; +import Content from "./readme.mdx"; + +export default function _Page() { + return ( + + + + ); +} diff --git a/website/src/app/blog/may-2024-update/page.tsx b/website/src/app/blog/may-2024-update/page.tsx new file mode 100644 index 000000000..3f704c4e3 --- /dev/null +++ b/website/src/app/blog/may-2024-update/page.tsx @@ -0,0 +1,11 @@ +import { Metadata } from "next"; +import _Page from "./_page"; + +export const metadata: Metadata = { + title: "May 2024 Update • Firezone Blog", + description: "May 2024 Update: GA", +}; + +export default function Page() { + return <_Page />; +} diff --git a/website/src/app/blog/may-2024-update/readme.mdx b/website/src/app/blog/may-2024-update/readme.mdx new file mode 100644 index 000000000..4c1c58fc8 --- /dev/null +++ b/website/src/app/blog/may-2024-update/readme.mdx @@ -0,0 +1,270 @@ +import Image from "next/image"; + +Traffic restrictions + +--- + +## In this update: + +- Restrict access to specific ports and protocols + +### Firezone 1.0 GA + +After months of beta testing with our early adopters, today we're announcing +that Firezone 1.0 is now generally available. We couldn't be more excited for +you to try it. + +[Sign up now](https://app.firezone.dev/sign_up) to get started. + +#### The road to 1.0 + +This release marks a significant milestone for Firezone. + +When we [announced](/blog/firezone-1-0) Firezone 1.0 was coming last July, we +knew we had our work cut out for us. Until that point, Firezone was a simple web +app into a single Docker image. Although a great fit for homelabbers and small +groups, it wasn't suited to address the remote access needs of larger +organizations. + +It was easy to get up and running quickly with Firezone, but as the number of +users, devices, and networks to protect grew within an organization, so did the +complexity of managing it all. + +So we went back to the whiteboard to reimagine how Firezone would look if we +rebuilt it from the ground up The Right Way™ -- with scalability and ease of +use in mind. + +
+ Whiteboard 1 + Whiteboard 2 +
+ +{/* Wrapping in JSX to avoid MDX from inserting p tags */} + +{(
+ + + We don't always work together IRL, but when we do, we rearchitect + everything. + +
)} + +We spent the next several months prototyping, testing, and iterating on a new +architecture that would allow Firezone to scale to hundreds of thousands of +users and millions of devices. + +#### The stack + +We weren't going to squander a good opportunity to rethink our stack choice, but +it remained largely the same: the new Firezone would be built with Elixir for +the control plane and Rust for the data plane. + +Why? + +Elixir has been getting lots of acclaim in recent years for its concurrency +model and fault-tolerance features. And for good reason: it runs on Erlang's +BEAM VM, the same technology that powers the telecom industry's most reliable +systems. There's a good chance the device you're reading this on has an IP +address handed out by an Erlang-powered telecom switch. + +As it turns out, managing connections for a remote access product is _a lot_ +like managing messages across a telecom network: + +``` +1. Peer A wants to connect to Peer B. +2. Is it allowed? + Yes: here are their addresses and keys to secure the connection. + No: drop the connection. +``` + +And Elixir's concurrency model makes it easy to manage thousands of these +connection "intents" on very little hardware -- just a few tiny VMs orchestrate +all connections across all our customers, globally. + +And what about the data plane? For that, we turned to Rust. + +Rust forms the network backbone of Firezone, handling all the heavy lifting of +encrypting and decrypting packets as they flow between Clients and Gateways. As +far as systems languages go, Rust couldn't be a better fit for the job. Its +memory safety guarantees eliminate entire classes of bugs that plague other +systems languages, making it a great choice for a security-critical application +like Firezone. + +And it has build targets for just about every platform under the sun. Our +[core connectivity library](https://github.com/firezone/firezone/tree/main/rust/connlib), +for example, runs reliably on iOS, Android, Windows, Linux, and macOS. + +We'll be sharing more about our stack choices in future blog posts, but suffice +to say, we're very happy with the results so far. + +### What's unique about Firezone? + +There are a lot of remote access solutions out there, so what makes Firezone +different? + +For starters, Firezone uses [WireGuard®](https://www.wireguard.com/) under the +hood -- a new VPN protocol that's +[faster](https://www.wireguard.com/performance) and +[more secure](https://www.wireguard.com/formal-verification/) than traditional +VPNs. But that's just the start. + +We learned from Firezone 0.x that organizations grappling with remote access at +scale needed things like integrations with identity providers that keep +directory information in sync, high availability features, and an easier way to +manage access policies that don't require a PhD in network security. + +Firezone 1.0 delivers on all of that and more. + +#### Core concepts in 1.0 + +Before we dive into the new features, let's first cover some core concepts new +to Firezone: + +- **Resource**: A [Resource](/kb/deploy/resources) is any DNS name, IP, or + network (CIDR range) you wish to manage access for. DNS-based Resources can be + used to manage access to internal or external applications and optionally be + configured to match all subdomains as well. CIDR-based Resources can be used + to manage access for an entire subnets, similar to a traditional VPN. +- **Gateway**: [Gateways](/kb/deploy/gateways) are Firezone servers that run on + your infrastructure. Gateways must be defined within a Site, and any traffic + to/from Resources associated with a Site will pass through one of that Site’s + Gateways. Gateways are designed to be lightweight and don't require persistent + storage to function. +- **Site**: [Sites](/kb/deploy/sites) are user-created environments where admins + can manage Resources and the Gateways that enable access to those Resources. A + typical Site name might be `SJC lab 1`, `Chicago office`, or + `Testbench subnet`. All Gateways and Resources in a Site are assumed to be + able to reach each other in a shared network context such as a VPC or LAN. + +For a more detailed overview of these concepts, check out the +[FAQ](/kb/reference/faq) and [glossary](/kb/reference/glossary) sections of our +documentation. + +#### High availability + +The first major feature in 1.0 we should discuss is high availability. Firezone +achieves high availability by allowing you to deploy multiple Gateways within a +given Site. + +Each Firezone Gateway is a tiny, self-contained binary that needs +[only a single environment](/kb/deploy/gateways) variable to function. Throw it +in a VM, a container, or on an IoT device -- it's lightweight enough to run +everywhere. Its sole purpose is to shuttle encrypted packets between Clients and +Resources. + +After you [create a Site](/kb/deploy/sites), you can deploy as many Gateways +into that Site as you'd like. All Gateways in the Site will work in unison to +provide load balancing and automatic failover for all connections to Resources +in the Site. + +If a Gateway goes offline or becomes overloaded, any Clients connected to it +will automatically migrate their connections to a healthy Gateway in the Site. +This process is completely transparent to the user and happens in most cases +within a few seconds. + +Armed with this ability, admins can now enjoy a simple maintenance process: (1) +take a Gateway down, (2) upgrade it, and (3) bring it back up. _That's it_. No +more lengthy maintenance windows, backing up configurations, or worrying about +extended downtime. + +A nice side effect of this architecture is that it provides near infinite +horizontal scalability, which works as follows: + +When a Client wants to connect to a protected resource, it sends a connection +intent message to the control plane API. If the intent is approved, the control +plane responds with a healthy Gateway to connect to. If there are multiple +healthy Gateways, the control plane will round-robin between them, effectively +splitting the load across all Gateways in the Site. + +Need more throughput? Simple: deploy more Gateways. The control plane will +automatically distribute the load across all of them. + +We think high availability is such a core feature in a remote access solution +that we made failover and load balancing available **on all plans**, including +the Starter tier. [Read more](/kb/deploy/gateways) about how it works in our +documentation. + +#### Firewall hole-punching + +You know what's not fun? Configuring firewalls. + +More precisely, configuring your organization's cloud or corporate firewalls to +allow incoming connections from the internet. Not only is it a pain to manage at +scale, it also exposes your organization to all kinds of security risks. + +So we rearchitected Firezone to include the same NAT traversal techniques that +WebRTC applications have enjoyed for years now: +[STUN](https://www.rfc-editor.org/rfc/rfc8489.html) and +[TURN](https://www.rfc-editor.org/rfc/rfc8553), known collectively as +[ICE](https://datatracker.ietf.org/doc/html/rfc8445). + +As you can probably surmise from the above links, these are well-established +standards for doing reliable NAT traversal. These have been battle-tested in the +field for years across all kinds of products -- Firezone is only the latest to +benefit from them. + +What does this mean for you? It means you can deploy Firezone without touching a +single firewall configuration and still enjoy the same level of performance as +if you did. Attack surface is minimized and connections are direct. It's a +win-win. + +For the curious readers, you can find our implementation of ICE, aptly named +"snownet", in our repository +[here](https://github.com/firezone/firezone/tree/main/rust/connlib/snownet). + +#### Directory sync + +The last feature we want to highlight in this announcement is directory sync. +Firezone currently supports directory sync for [Okta](https://www.okta.com/), +[Entra ID](https://azure.microsoft.com/en-us/services/active-directory/), and +[Google Workspace](https://workspace.google.com/), with more providers on the +way. + +Anyone who's ever managed a large organization knows the pain of keeping user +and group information in sync across multiple systems. It's a nightmare to +manage manually. And it's error-prone, leading to security risks and compliance +issues. + +Experienced admins will now be thinking, "But what about +[SCIM](https://datatracker.ietf.org/doc/html/rfc7644)? Doesn't that make this +easy?". Sadly, SCIM today is one of those standards that isn't. Entire +[business models](https://www.workos.com) have been optimized to leverage +inconsistencies in SCIM implementations across different identity providers. + +So Firezone doesn't use SCIM. Instead, we +[built our very own directory sync engine](https://github.com/firezone/firezone/tree/main/elixir/apps/domain/lib/domain/auth) +that can be extended to virtually any source of identity data, regardless of +whether they support SCIM. If it has a REST API, we can probably sync with it. + +Directory sync is available only for the Enterprise plan so we can be sure it'll +work reliably for your organization. +[Read more](/kb/authenticate/directory-sync) about how it works or +[contact sales](/contact/sales) if you'd like a first-hand demo. + +### What's next? + +We covered only a fraction of what's new in Firezone in this post. Go +[sign up](https://app.firezone.dev/sign_up) and see what else is new for +yourself, or [request a demo](/contact/sales) if you'd like to better understand +how Firezone can help your organization. + +We have more to announce in the coming weeks, so +[subscribe to our newsletter](/product/newsletter) below to stay in the loop.