mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
refactor(linux-client): replace client-tunnel with headless-client which is the same thing (#4516)
Unfortunately I had to keep `linux-client` to get the compatibility tests to pass. #4578 aims to remove that package. Please add to this list if you think of anything: ```[tasklist] # Things that may break that CI/CD won't catch - [ ] Github release artifacts - [ ] Knowledge base - [ ] Docker images - [ ] Docker containers - [ ] Existing `linux-client` users - [ ] Anything that downloads ghcr artifacts - [ ] Nix (Not sure if it's built in CI. It had a merge conflict) ``` Refs #4515, and #3712, #3782 I think this is what Thomas and I agreed on in Slack / Github --------- Signed-off-by: Reactor Scram <ReactorScram@users.noreply.github.com> Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
This commit is contained in:
2
.github/actions/setup-rust/action.yml
vendored
2
.github/actions/setup-rust/action.yml
vendored
@@ -22,7 +22,7 @@ outputs:
|
||||
value: ${{
|
||||
(runner.os == 'Linux' && '--workspace') ||
|
||||
(runner.os == 'macOS' && '-p connlib-client-apple -p connlib-client-shared -p firezone-tunnel -p snownet') ||
|
||||
(runner.os == 'Windows' && '-p connlib-client-shared -p firezone-client-tunnel -p firezone-gui-client -p firezone-tunnel -p snownet') }}
|
||||
(runner.os == 'Windows' && '-p connlib-client-shared -p firezone-headless-client -p firezone-gui-client -p firezone-tunnel -p snownet') }}
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
|
||||
4
.github/workflows/e2e.yml
vendored
4
.github/workflows/e2e.yml
vendored
@@ -151,10 +151,10 @@ jobs:
|
||||
sccache_enabled: false
|
||||
targets: x86_64-unknown-linux-gnu
|
||||
- run: |
|
||||
cargo build --package firezone-linux-client
|
||||
cargo build --package firezone-headless-client
|
||||
|
||||
# TODO Run tests
|
||||
# ./target/debug/firezone-linux-client
|
||||
# ./target/debug/firezone-headless-client
|
||||
|
||||
android:
|
||||
needs: setup
|
||||
|
||||
@@ -295,6 +295,7 @@ services:
|
||||
cache_from:
|
||||
- type=registry,ref=us-east1-docker.pkg.dev/firezone-staging/cache/client:main
|
||||
args:
|
||||
# TODO: Fix after #4516 lands
|
||||
PACKAGE: firezone-linux-client
|
||||
image: ${CLIENT_IMAGE:-us-east1-docker.pkg.dev/firezone-staging/firezone/dev/client}:${CLIENT_TAG:-main}
|
||||
cap_add:
|
||||
|
||||
@@ -97,7 +97,7 @@ product documentation, organized as follows:
|
||||
and deployed to your infrastructure.
|
||||
- [rust/relay](../rust/relay): Relay - STUN/TURN server to facilitate
|
||||
holepunching.
|
||||
- [rust/linux-client](../rust/linux-client): Linux CLI client.
|
||||
- [rust/headless-client](../rust/headless-client): Cross-platform CLI client.
|
||||
- [rust/gui-client](../rust/gui-client): Cross-platform GUI client.
|
||||
- [swift/](../swift/apple): macOS / iOS clients.
|
||||
- [kotlin/](../kotlin/android): Android / ChromeOS clients.
|
||||
|
||||
46
rust/Cargo.lock
generated
46
rust/Cargo.lock
generated
@@ -1848,27 +1848,6 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "firezone-client-tunnel"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"connlib-client-shared",
|
||||
"connlib-shared",
|
||||
"dirs",
|
||||
"firezone-cli-utils",
|
||||
"humantime",
|
||||
"nix 0.28.0",
|
||||
"resolv-conf",
|
||||
"secrecy",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "firezone-gateway"
|
||||
version = "1.0.0"
|
||||
@@ -1915,7 +1894,7 @@ dependencies = [
|
||||
"connlib-shared",
|
||||
"crash-handler",
|
||||
"dirs",
|
||||
"firezone-client-tunnel",
|
||||
"firezone-headless-client",
|
||||
"futures",
|
||||
"git-version",
|
||||
"hex",
|
||||
@@ -1954,12 +1933,33 @@ dependencies = [
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "firezone-headless-client"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"connlib-client-shared",
|
||||
"connlib-shared",
|
||||
"dirs",
|
||||
"firezone-cli-utils",
|
||||
"humantime",
|
||||
"nix 0.28.0",
|
||||
"resolv-conf",
|
||||
"secrecy",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "firezone-linux-client"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"firezone-client-tunnel",
|
||||
"firezone-headless-client",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[workspace]
|
||||
members = [
|
||||
"client-tunnel",
|
||||
"connlib/clients/android",
|
||||
"connlib/clients/apple",
|
||||
"connlib/clients/shared",
|
||||
@@ -8,8 +7,9 @@ members = [
|
||||
"connlib/tunnel",
|
||||
"connlib/snownet",
|
||||
"gateway",
|
||||
"linux-client",
|
||||
"firezone-cli-utils",
|
||||
"headless-client",
|
||||
"linux-client",
|
||||
"snownet-tests",
|
||||
"phoenix-channel",
|
||||
"relay",
|
||||
@@ -39,9 +39,8 @@ rtnetlink = { version = "0.14.1", default-features = false, features = ["tokio_s
|
||||
connlib-client-android = { path = "connlib/clients/android"}
|
||||
connlib-client-apple = { path = "connlib/clients/apple"}
|
||||
connlib-client-shared = { path = "connlib/clients/shared"}
|
||||
firezone-client-tunnel = { path = "client-tunnel" }
|
||||
firezone-gateway = { path = "gateway"}
|
||||
firezone-linux-client = { path = "linux-client"}
|
||||
firezone-headless-client = { path = "headless-client"}
|
||||
firezone-gui-client = { path = "gui-client/src-tauri"}
|
||||
firezone-cli-utils = { path = "firezone-cli-utils"}
|
||||
snownet = { path = "connlib/snownet"}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# firezone-client-tunnel
|
||||
|
||||
A privileged tunnel process that can communicate with the Linux GUI Client (and eventually Windows)
|
||||
|
||||
## Files
|
||||
|
||||
- `/etc/dev.firezone.client/token` - The service account token, provided by the human administrator. Must be owned by root and have 600 permissions (r/w by owner, nobody else can read) If present, the tunnel will ignore any GUI Client and run as a headless Client. If absent, the tunnel will wait for commands from a GUI Client
|
||||
- `/usr/bin/firezone-client-tunnel` - The tunnel binary. This must run as root so it can modify the system's DNS settings. If DNS is not needed, it only needs CAP_NET_ADMIN.
|
||||
- `/usr/lib/systemd/system/firezone-client-tunnel.service` - A systemd service unit, installed by the deb package.
|
||||
- `/var/lib/dev.firezone.client/config/firezone-id` - The device ID, unique across an organization. The tunnel will generate this if it's not present.
|
||||
@@ -4,7 +4,7 @@ services:
|
||||
build:
|
||||
target: test
|
||||
volumes:
|
||||
- ./rust/target/x86_64-unknown-linux-musl/debug/firezone-linux-client:/bin/firezone-linux-client
|
||||
- ./rust/target/x86_64-unknown-linux-musl/debug/firezone-headless-client:/bin/firezone-headless-client
|
||||
|
||||
gateway:
|
||||
build:
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
(TODO: Change "client-tunnel" to "headless-client")
|
||||
|
||||
# Process split
|
||||
|
||||
This is meant for Linux, but it will be similar on Windows.
|
||||
|
||||
@@ -20,7 +20,7 @@ clap = { version = "4.5", features = ["derive", "env"] }
|
||||
connlib-client-shared = { workspace = true }
|
||||
connlib-shared = { workspace = true }
|
||||
crash-handler = "0.6.1"
|
||||
firezone-client-tunnel = { path = "../../client-tunnel" }
|
||||
firezone-headless-client = { path = "../../headless-client" }
|
||||
git-version = "0.3.9"
|
||||
hex = "0.4.3"
|
||||
# Same crate Hickory uses
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
firezone_client_tunnel::run().await
|
||||
firezone_headless_client::run().await
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
[package]
|
||||
name = "firezone-client-tunnel"
|
||||
version = "0.1.0"
|
||||
name = "firezone-headless-client"
|
||||
# mark:automatic-version
|
||||
version = "1.0.0"
|
||||
edition = "2021"
|
||||
authors = ["Firezone, Inc."]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
65
rust/headless-client/README.md
Normal file
65
rust/headless-client/README.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# headless-client
|
||||
|
||||
This crate acts as the CLI / headless Client, and the privileged tunnel service for the GUI Client, for both Linux and Windows.
|
||||
|
||||
It is built as:
|
||||
- `linux-client` to act as the Linux headless Client
|
||||
- `firezone-headless-client` to act as the Linux tunnel service, Windows headless Client, or Windows tunnel service
|
||||
|
||||
In general, the brand name should be part of the file name, but the OS name should not be.
|
||||
|
||||
## Running
|
||||
|
||||
To run the headless Client:
|
||||
|
||||
1. Generate a new Service account token from the "Actors -> Service Accounts"
|
||||
section of the admin portal and save it in your secrets manager. The Firezone
|
||||
Linux client requires a service account at this time.
|
||||
1. Ensure `/etc/dev.firezone.client/token` is only readable by root (i.e. `chmod 400`)
|
||||
1. Ensure `/etc/dev.firezone.client/token` contains the Service account token. The Client needs this before it can start
|
||||
1. Set `FIREZONE_ID` to a unique string to identify this client in the portal,
|
||||
e.g. `export FIREZONE_ID=$(uuidgen)`. The client requires this variable at
|
||||
startup.
|
||||
1. Set `LOG_DIR` to a suitable directory for writing logs
|
||||
```
|
||||
export LOG_DIR=/tmp/firezone-logs
|
||||
mkdir $LOG_DIR
|
||||
```
|
||||
1. Now, you can start the client with:
|
||||
|
||||
```
|
||||
./firezone-headless-client
|
||||
```
|
||||
|
||||
If you're running as an unprivileged user, you'll need the `CAP_NET_ADMIN`
|
||||
capability to open `/dev/net/tun`. You can add this to the client binary with:
|
||||
|
||||
```
|
||||
sudo setcap 'cap_net_admin+eip' /path/to/firezone-headless-client
|
||||
```
|
||||
|
||||
|
||||
## Building
|
||||
|
||||
Assuming you have Rust installed, you can build the headless Client with:
|
||||
|
||||
```
|
||||
cargo build --release -p firezone-headless-client
|
||||
```
|
||||
|
||||
The binary will be in `target/release/firezone-headless-client`
|
||||
|
||||
The release on Github are built with musl. To build this way, use:
|
||||
|
||||
```bash
|
||||
rustup target add x86_64-unknown-linux-musl
|
||||
sudo apt-get install musl-tools
|
||||
cargo build --release -p headless-client --target x86_64-unknown-linux-musl
|
||||
```
|
||||
|
||||
## Files
|
||||
|
||||
- `/etc/dev.firezone.client/token` - The service account token, provided by the human administrator. Must be owned by root and have 600 permissions (r/w by owner, nobody else can read) If present, the tunnel will ignore any GUI Client and run as a headless Client. If absent, the tunnel will wait for commands from a GUI Client
|
||||
- `/usr/bin/firezone-headless-client` - The tunnel binary. This must run as root so it can modify the system's DNS settings. If DNS is not needed, it only needs CAP_NET_ADMIN.
|
||||
- `/usr/lib/systemd/system/firezone-headless-client.service` - A systemd service unit, installed by the deb package.
|
||||
- `/var/lib/dev.firezone.client/config/firezone-id` - The device ID, unique across an organization. The tunnel will generate this if it's not present.
|
||||
4
rust/headless-client/src/main.rs
Normal file
4
rust/headless-client/src/main.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
firezone_headless_client::run().await
|
||||
}
|
||||
@@ -3,13 +3,14 @@ name = "firezone-linux-client"
|
||||
# mark:automatic-version
|
||||
version = "1.0.0"
|
||||
edition = "2021"
|
||||
authors = ["Firezone, Inc."]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = { version = "1.0" }
|
||||
firezone-client-tunnel = { workspace = true }
|
||||
tokio = { version = "1.36", default-features = false, features = ["rt", "macros"] }
|
||||
firezone-headless-client = { path = "../headless-client" }
|
||||
tokio = { version = "1.36.0", features = ["macros", "signal"] }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
@@ -1,53 +1 @@
|
||||
# linux-client
|
||||
|
||||
This crate houses the Firezone linux client.
|
||||
|
||||
## Building
|
||||
|
||||
Assuming you have Rust installed, you can build the Linux client from a Linux
|
||||
host with:
|
||||
|
||||
```
|
||||
cargo build --release --bin firezone-linux-client
|
||||
```
|
||||
|
||||
You should then find a binary in `target/release/firezone-linux-client`.
|
||||
|
||||
The releases on Github are built with musl. To build this way, use:
|
||||
|
||||
```bash
|
||||
rustup target add x86_64-unknown-linux-musl
|
||||
sudo apt-get install musl-tools
|
||||
cargo build --release --bin firezone-linux-client --target x86_64-unknown-linux-musl
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
To run the Linux client:
|
||||
|
||||
1. Generate a new Service account token from the "Actors -> Service Accounts"
|
||||
section of the admin portal and save it in your secrets manager. The Firezone
|
||||
Linux client requires a service account at this time.
|
||||
1. Ensure the `FIREZONE_TOKEN=<service_account_token>` environment variable is
|
||||
set securely in your client's shell environment. The client requires this
|
||||
variable at startup.
|
||||
1. Set `FIREZONE_ID` to a unique string to identify this client in the portal,
|
||||
e.g. `export FIREZONE_ID=$(uuidgen)`. The client requires this variable at
|
||||
startup.
|
||||
1. Set `LOG_DIR` to a suitable directory for writing logs
|
||||
```
|
||||
export LOG_DIR=/tmp/firezone-logs
|
||||
mkdir $LOG_DIR
|
||||
```
|
||||
1. Now, you can start the client with:
|
||||
|
||||
```
|
||||
./firezone-linux-client
|
||||
```
|
||||
|
||||
If you're running as an unprivileged user, you'll need the `CAP_NET_ADMIN`
|
||||
capability to open `/dev/net/tun`. You can add this to the client binary with:
|
||||
|
||||
```
|
||||
sudo setcap 'cap_net_admin+eip' /path/to/firezone-linux-client
|
||||
```
|
||||
This is a stub to fix a build issue in CI. Remove it once PR #4516 is merged into main.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
firezone_client_tunnel::run().await
|
||||
firezone_headless_client::run().await
|
||||
}
|
||||
|
||||
@@ -63,9 +63,9 @@
|
||||
};
|
||||
in
|
||||
{
|
||||
packages.firezone-linux-client = naersk.buildPackage {
|
||||
packages.firezone-headless-client = naersk.buildPackage {
|
||||
name = "foo";
|
||||
src = ../../rust/linux-client;
|
||||
src = ../../rust/headless-client;
|
||||
};
|
||||
|
||||
devShells.default = mkShellWithRustVersion [
|
||||
|
||||
@@ -5,7 +5,7 @@ set -euo pipefail
|
||||
|
||||
BINARY_NAME=firezone-linux-client
|
||||
|
||||
docker compose exec client cat firezone-linux-client >"$BINARY_NAME"
|
||||
docker compose exec client cat firezone-linux-client > "$BINARY_NAME"
|
||||
chmod u+x "$BINARY_NAME"
|
||||
sudo mv "$BINARY_NAME" "/usr/bin/$BINARY_NAME"
|
||||
# TODO: Check whether this is redundant with the systemd service file
|
||||
|
||||
Reference in New Issue
Block a user