Files
firezone/rust/headless-client
Reactor Scram 1ef775dee1 feat(windows-client): run the GUI and tunnel in separate processes (#4978)
Ready for review.

Closes #3712.
Supersedes #4940.
Refs #4963.

I haven't figured out if it needs any new automated tests (unit,
integration, etc.) but the code itself is ready for review. There is
more refactoring that could be done, or could be left for later.

```[tasklist]
- [x] Move wintun setup from GUI to IPC service / headless client
- [x] Make sure the device ID is in a sensible place
- [x] Export IPC service logs in the zips
- [x] Test GUI + SC IPC service on Windows (f4db808919a passed)
- [x] Make sure IPC service does not busy-loop
- [x] Test un-install checklist for Windows
- [x] Test upgrade checklist for Windows
- [x] Test GUI + systemd IPC service on Linux (c4ab7e7 passed)
- [x] Test upgrade checklist for Linux
- [x] Test un-install checklist for Linux
- [x] Make sure the IPC service logs out and deactivates DNS control if the GUI crashes
- [x] Test network changing
- [x] (it's intended behavior) ~~Look into spurious `on_update_resources` (fad86babd7)~~
- [x] ~~Test max partition time on offline laptop~~ (I ended up just setting a 30-day default in the code)
- [x] Make sure headless Client does not busy-loop
- [x] Test standalone headless on Linux
- [ ] Add unit / integration tests
- [ ] Think about security a bit #3971
```

---------

Signed-off-by: Reactor Scram <ReactorScram@users.noreply.github.com>
Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
2024-05-20 21:37:29 +00:00
..

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:

  • headless-client to act as the Linux / Windows 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.
  2. Ensure /etc/dev.firezone.client/token is only readable by root (i.e. chmod 400)
  3. Ensure /etc/dev.firezone.client/token contains the Service account token. The Client needs this before it can start
  4. 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.
  5. Set LOG_DIR to a suitable directory for writing logs
    export LOG_DIR=/tmp/firezone-logs
    mkdir $LOG_DIR
    
  6. Now, you can start the client with:
./firezone-headless-client standalone

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:

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.