# RDP FIDO 1.25 for Linux

Both halves of RDP FIDO run on Linux (Ubuntu 22.04/24.04, Debian, Astra Linux,
RED OS 7.3, ALT Linux p10+ and other x86-64 distributions with glibc 2.18+):

- **gate `rdpfido-gate`** on the target machine keeps the RDP port (xrdp) closed
  and opens it only to the address that presented an enrolled FIDO2 key - or,
  since 1.23, a one-time code from an authenticator app;
- **client `rdpfido` / `rdpfido-gui`** connects to Windows or Linux gates with a
  FIDO2 USB/NFC key (or the one-time code) and starts FreeRDP - or, since
  1.24, ssh and the SSH console behind the same key;
- **FIDO Stream** (low-latency video, games) works both ways: a Linux machine
  can stream its X11 desktop (`rdpfido-stream-host`, in the gate package) and
  watch a stream from Windows or Linux (`rdpfido-viewer`, in the client package);
  files travel through the stream in both directions, and several participants
  can share one session (one of them in control).

The Windows and Linux editions speak the same protocol: a Windows client
connects to a Linux gate and the other way round.

## Install

```sh
# Ubuntu / Debian / Astra Linux
sudo apt install ./rdpfido-gate_1.25.2_amd64.deb      # target machine
sudo apt install ./rdpfido-client_1.25.2_amd64.deb    # your workstation
# RED OS / RHEL-like
sudo dnf install ./rdpfido-gate-1.25.2-1.x86_64.rpm
sudo dnf install ./rdpfido-client-1.25.2-1.x86_64.rpm
# ALT Linux (apt-rpm)
sudo apt-get install ./rdpfido-gate-1.25.2-alt1.x86_64.rpm
sudo apt-get install ./rdpfido-client-1.25.2-alt1.x86_64.rpm
# anything else
tar xzf rdpfido-1.25.2-linux-x86_64.tar.gz && cd rdpfido-1.25.2-linux-x86_64
sudo ./install.sh gate     # or: client, all
```

Checksums: `SHA256SUMS` in this folder.

The gate package brings nothing else with it (since 1.25.2): on a server with
no desktop it is the only package installed. xrdp and the X libraries are
suggestions only (the RED OS package recommends xrdp where an X server is
installed). For Remote Desktop `setup --install-xrdp` installs xrdp; FIDO
Stream needs `libx11-6 libxext6 libxdamage1 libxfixes3 libxtst6 libpulse0`,
which a machine with a desktop already has.

## Set up the gate

```sh
sudo rdpfido-gate setup            # for Remote Desktop: add --install-xrdp if xrdp is missing
```

It creates the gate certificate, installs the service and a boot guard that
closes the RDP port before the network comes up, and prints a one-time
enrollment code and the gate's certificate thumbprint. The RDP port closes the
moment the first key (or account) is enrolled.

## Use the client

```sh
rdpfido add --name office --host 10.0.0.5 --user ivan --password
rdpfido enroll office CODE --fingerprint THUMBPRINT   # code and thumbprint from the gate
rdpfido connect office                                # key -> port opens -> FreeRDP
rdpfido stream office                                 # FIDO Stream instead of RDP
```

Or the window: `rdpfido-gui` ("RDP FIDO" in the applications menu).

FIDO Stream on a Linux host captures X11 sessions (log in with an "Xorg"
session; Wayland is not captured yet).

## A key or a one-time code (1.23)

A gate signs people in one way: with a FIDO key (the default) or, for teams
without keys, with a 6-digit code from any authenticator app (Google
Authenticator, Microsoft Authenticator, Aegis, 1Password...).

```sh
sudo rdpfido-gate setup --auth totp     # at setup
sudo rdpfido-gate auth                  # which way now
sudo rdpfido-gate auth totp             # switch (restarts the gate); auth fido to go back
sudo rdpfido-gate totp add "Anna"       # an account made on the gate, QR code in the terminal
sudo rdpfido-gate totp test 3 123456    # check a code from the app
```

Enrollment works as with a key: `rdpfido-gate code`, then `rdpfido enroll`
shows a QR code in the terminal (`rdpfido-gui` in a window) and the first code
from the app confirms it. When connecting, the client asks for the code; a code
is accepted once only. A code opens RDP only - xrdp or Windows still ask for
their password; FIDO Stream is off in this mode (it reaches the desktop without
a password). Clients 1.23 and newer ask for codes.

## SSH and other ports behind the same key (1.24)

The gate can guard more TCP ports of the machine - SSH, a web console - the
way it guards RDP: closed to everyone until a key (or code) confirms, then
open for the confirming address only, together with the RDP port.

```sh
sudo rdpfido-gate ports add 22       # guard SSH; several ports separated by spaces
sudo rdpfido-gate ports              # what is guarded now
sudo rdpfido-gate ports remove 22    # back to normal
rdpfido open office                  # client: key -> ports open, nothing is started
rdpfido ssh office                   # key -> ssh to the session's host
rdpfido console office               # key -> the SSH console window
```

Connections already established are not cut, so `ports add 22` is safe to run
over SSH - check from a second terminal that the key lets you in before closing
the first. A connection counts as established if the gate has seen it:
tracking starts at `setup`, so the session you ran `setup` from is covered. A
connection opened earlier that stays silent until the first key is enrolled
may hang; open it again, with the key. (Before 1.25.2 tracking started only
with the first key, and the very session the gate was installed from could
hang.) Only RDP goes through the cloud; the Windows gate does not use the list
yet.

### A server with no desktop: SSH only

The gate needs neither xrdp nor a desktop:

```sh
sudo apt install ./rdpfido-gate_1.25.2_amd64.deb   # one package, no xrdp, no X
sudo rdpfido-gate setup                            # enrollment code and thumbprint
sudo rdpfido-gate ports add 22
```

At the "RDP server" step `setup` says that none was found; on such a machine
that is fine. Until the first key is enrolled port 22 stays open as before;
with the first key it closes for everyone but an address the key has let in.

- The gate guards the RDP port (3389) here too, though nothing listens on it.
  With ufw or firewalld active it adds allows there for 3389 and for the
  stream ports (UDP 7441-7448). They open nothing: the gate's own rules stand
  in front. What was added is listed in `/var/lib/rdpfido-gate/hostfw.json`,
  and removing the package takes it back.
- ufw switched on after `setup` closes the gate's own port (7440), and no key
  can get through. Allow it yourself (`sudo ufw allow 7440/tcp`) or run
  `sudo rdpfido-gate setup` again.
- Ports published from Docker containers (`-p`) bypass the `INPUT` chain and
  are not guarded: the gate covers ports the machine itself listens on.

Tested on Debian 12 without xrdp (nftables, with and without ufw).

The SSH console (`rdpfido-console`, in the client package) is a terminal with a
side panel: saved passwords typed by a click or by themselves at their prompt
(sudo), saved commands, and an AI assistant (Claude or an OpenAI-compatible
server) with per-session prompts and conversation history; it sees the console
only when allowed. Its window needs a Chromium-family browser (otherwise the
page opens in the default browser); saved passwords need the desktop keyring.
The session's SSH port, key file and options: `rdpfido add|edit --ssh-port N
--ssh-key FILE --ssh-opt ARG`.

## The entry lock (1.25.1)

The client itself can be closed with a password or a FIDO2 key, as the Windows
client since 1.25.0. All three programs ask: `rdpfido` before any command that
works with the sessions, `rdpfido-gui` before its window appears,
`rdpfido-console` when it starts.

```sh
rdpfido lock                 # what stands now
rdpfido lock password        # set a master password, or change it
rdpfido lock key             # bind a FIDO2 key instead
rdpfido lock off             # take the lock off
rdpfido lock reset           # forgotten password, lost key
```

In the window: the "Entry lock" button.

- **A password is a master password.** Saved session passwords, the SSH
  console's passwords and the assistant's API key are encrypted before they go
  into the desktop keyring, with an AES-256 key that exists on disk only
  wrapped by that password (PBKDF2-SHA256, 600,000 iterations;
  `~/.config/rdpfido/applock.json`, mode 0600). The keyring hands an entry to
  any program of the user (`secret-tool lookup session ...`); with a master
  password what lies there is ciphertext, `rdpfido-mk1:...`. Deleting the lock
  file loses the passwords instead of freeing them.
- **A FIDO2 key guards the entry only.** It needs a PIN or a fingerprint
  sensor: its owner is verified when it is bound and at every entry. The key
  does not encrypt the saved passwords - it keeps out a person who sits down
  at your computer, not a program under your account.
- **What stays open.** The list of sessions (`sessions.json`: addresses, user
  names) is protected by file permissions only, as before.
- **Wrong passwords:** five free attempts, then a wait from 30 seconds up to
  15 minutes. **A forgotten password cannot be recovered:** `rdpfido lock
  reset` takes the lock off together with what it guarded - the saved
  passwords, the assistant's API key and its conversations; sessions, commands
  and settings stay.
- **Without a terminal** (a script, cron) the entry password is read as the
  first line of standard input; with `--password-stdin` the RDP password is
  the second line. `rdpfido console` asks once and hands the encryption key
  to the console through an inherited descriptor, not on the command line.
- The locks of Windows and Linux are separate; passwords encrypted by 1.25.1
  do not open in a 1.24 client.

## The cloud as an option

A gate without a public address can be linked to an RDP FIDO Cloud hub:
`sudo rdpfido-gate cloud link HUB:443 CODE` (the code comes from
`rdpfido-cloud code` on the hub), `cloud status`, `cloud unlink`. Clients then
reach the gate at `<id>.g.<domain>:443` without any port forwarding; RDP goes
through a tunnel ticket (port 3389 stays closed from outside), FIDO Stream
directly or through the hub's relay. A gate that is not linked makes no
outgoing connection at all. The hub `rdpfido-cloud` runs on your own VPS:
`rdpfido-cloud-1.22.0-linux-x86_64.tar.gz` in this folder (binary, relay,
`install.sh`, systemd units, web cabinet; unchanged since 1.22), described in
[README-cloud.ru.md](README-cloud.ru.md) (Russian). The Imobile cloud is a
private service: Imobile links a gate to it by arrangement, and demo access
for connecting is available to get acquainted.

## Updates

Every version works for one year from its release date (1.25.2: until
6 October 2027) and then requires an update: upgrade the packages with
`apt` / `dnf` / `apt-get`. The gate warns 30 days ahead (`rdpfido-gate status`).

Full guide (Russian): [README.ru.md](README.ru.md). Third-party components and
licences: [THIRD-PARTY.txt](THIRD-PARTY.txt).
