From 1063d10ac9d4c8e8d1259c2662a601dfe63a1a51 Mon Sep 17 00:00:00 2001 From: Laurence Date: Wed, 1 Apr 2026 15:52:55 +0100 Subject: [PATCH 1/2] Improve SSH access docs and document Newt auth env vars --- manage/sites/configure-site.mdx | 10 ++ manage/ssh.mdx | 277 ++++++++++++++------------------ 2 files changed, 127 insertions(+), 160 deletions(-) diff --git a/manage/sites/configure-site.mdx b/manage/sites/configure-site.mdx index b4a3a2c..779ee17 100644 --- a/manage/sites/configure-site.mdx +++ b/manage/sites/configure-site.mdx @@ -205,6 +205,16 @@ When both environment variables and CLI arguments are provided, CLI arguments ta Newt secret for authentication (equivalent to `--secret`) + + Enable Newt's built-in auth daemon mode (equivalent to `--auth-daemon`). + + **Default**: `false` + + + + Pre-shared key used to authenticate external auth daemons to Newt (equivalent to `--ad-pre-shared-key`) + + Port for the peers to connect to Newt on (equivalent to `--port`) diff --git a/manage/ssh.mdx b/manage/ssh.mdx index 809d7b4..d10d58a 100644 --- a/manage/ssh.mdx +++ b/manage/ssh.mdx @@ -27,32 +27,16 @@ Pangolin includes a built-in SSH client so you can connect to remote servers and You can SSH into any Pangolin site or private resource. Two components handle SSH on the server side: - + Runs as a daemon and handles SSH for the host it runs on. Use this when the machine you want to SSH into is the same server running Newt. - + Handles SSH for other servers on the same network. Run the auth daemon on each target host; Newt on a bastion proxies connections to them. You connect using the Pangolin CLI as the SSH client. The tunnel can be provided by the CLI or by another Pangolin client (e.g. the macOS app); you can run the GUI for the tunnel and use the CLI only for SSH if you prefer. -## Quick start: connecting via SSH - -From a machine where the Pangolin tunnel is already running (CLI or another client), run: - -```bash -pangolin ssh vm-01.prod.example.com -``` - -Here, `vm-01.prod.example.com` is the **internal alias** of the Pangolin resource (the host you want to SSH into). Pangolin uses your identity to obtain a short-lived certificate and establish the SSH session. - -You can also use the resource identifier instead of the alias: - -```bash -pangolin ssh elaborate-western-whiptail -``` - ## How certificates work Each organization has a **certificate authority (CA)** used to sign temporary SSH keys. @@ -68,133 +52,101 @@ This gives short-lived, auditable access without long-lived keys on the server. Users are provisioned **just in time** on the remote system. When you connect, Pangolin ensures an account exists for you with the right permissions before the SSH session starts. Your Pangolin identity is mapped to a local username (derived from the part before `@` in your identity; if needed, a suffix is added for uniqueness). The account is created with a home directory and can be granted sudo access as configured. -## Setup: choose your architecture +## Setup: choose your SSH layout -You can enable SSH in two ways: +Newt can provide SSH access for its own host, for other hosts behind it, or for both at the same time. -| Scenario | Approach | -|----------|----------| -| SSH into the **same server** that runs Newt | **Option 1**: Run Newt with auth-daemon support (built-in). | -| SSH into **other servers** on the same network as Newt | **Option 2**: Run Newt on one host (e.g. bastion) and run the auth daemon on each server you want to SSH into. | +Before you begin: + +- Install Newt on the host that will run the site connector. See [Install Site](/manage/sites/install-site). +- Install the Pangolin CLI on any machine that will initiate `pangolin ssh` sessions. See [Install Clients](/manage/clients/install-client#quick-install-recommended-—-linux-and-macos). + +| Layout | Use this when | Newt flags | +|--------|---------------|------------| +| **Newt host only** | Users only need SSH access to the server running Newt | `--auth-daemon` | +| **Hosts behind Newt only** | Users only need SSH access to other servers on the same network as Newt | `--ad-pre-shared-key ` | +| **Mixed deployment** | Users need SSH access to the Newt host **and** to other servers behind it | `--auth-daemon --ad-pre-shared-key ` | -A single Newt instance cannot run as the auth daemon for its own host **and** use external auth daemons. You must choose one mode: either Option 1 (built-in auth daemon on this host) or Option 2 (external auth daemons on other hosts). +You do not need to choose a single site-wide SSH mode. A single Newt instance can run its built-in auth daemon for the Newt host and also authenticate external auth daemons for other target hosts. -Both options require the SSH server on each target host to be configured to trust the Pangolin CA and to use the auth daemon for principals (see [Configure the SSH server](#configure-the-ssh-server-on-the-host) below). You also need a **private resource** on the site for each host you want to SSH into (see below). +## Understand the model -## Create a private resource (required) +The easiest way to think about SSH in Pangolin is: -SSH access in both Option 1 and Option 2 is scoped to a private resource. You must create a private resource on the site for the host (or each host) you want to SSH into, then grant access and allow TCP 22. +1. Each SSH target gets its own **private resource**. +2. That resource decides **how Pangolin reaches that host**. +3. The host itself must be configured to match that resource. -1. **Create a private resource** on the site in the Pangolin dashboard. The resource should target the host that will run Newt (Option 1) or the host that will run the auth daemon (Option 2). Give it a destination (IP or FQDN of the server). You can use an [alias](/manage/resources/private/alias) (e.g. `vm-01.prod.example.com`) so users connect with a friendly name: `pangolin ssh vm-01.prod.example.com`. +In a mixed deployment, you will create one resource for the Newt host and separate resources for each host behind Newt. -2. **Grant access** to the resource by assigning **users** or **roles** in the resource’s access settings. Only users or roles with access can obtain SSH certificates and connect. +## Start Newt for your layout -3. **Allow TCP 22 in port restrictions.** In the private resource’s port restrictions, ensure **TCP 22** is allowed so SSH traffic is permitted through the tunnel. Without this, SSH connections to the resource will be blocked. +With Newt [installed](/manage/sites/install-site), start it with the flags that match your layout: - -If TCP 22 is not allowed in the resource’s port restrictions, users will not be able to establish SSH sessions to that resource even when the rest of the setup is correct. - +| Layout | Command | +|--------|---------| +| Newt host only | `sudo newt --id --secret --endpoint --auth-daemon` | +| Hosts behind Newt only | `sudo newt --id --secret --endpoint --ad-pre-shared-key ` | +| Mixed deployment | `sudo newt --id --secret --endpoint --auth-daemon --ad-pre-shared-key ` | -After the resource exists and access is granted, proceed with [Option 1](#option-1-newt-as-the-auth-daemon-same-host) or [Option 2](#option-2-external-auth-daemon-different-servers) below. +Relevant environment variables: -## Option 1: Newt as the auth daemon (same host) +| Flag | Environment variable | +|------|----------------------| +| `--id` | `NEWT_ID` | +| `--secret` | `NEWT_SECRET` | +| `--endpoint` | `PANGOLIN_ENDPOINT` | +| `--auth-daemon` | `AUTH_DAEMON_ENABLED=true` | +| `--ad-pre-shared-key` | `AD_KEY` | -Use this when the machine you want to SSH into **is** the machine running Newt (e.g. the site connector and SSH are on the same server). - -```mermaid -flowchart LR - subgraph client["User machine"] - CLI[Pangolin CLI] - end - - subgraph cloud["Pangolin Cloud"] - CA[Sign certificate] - end - - subgraph server["Single server (site)"] - direction TB - Newt[Newt + auth-daemon] - SSHD[SSH server] - Newt --> SSHD - end - - CLI -->|Request signed cert| CA - CLI -->|SSH port 22| SSHD -``` - -### Run Newt with auth-daemon enabled - -With Newt [installed](/manage/sites/install-site), run it in auth-daemon mode so it can handle SSH on this host: - -```bash -sudo newt --id --secret --endpoint --auth-daemon -``` +See [more environment variables](/manage/sites/configure-site#environment-variables). Replace ``, ``, and `` with the values from your site configuration in the Pangolin dashboard. - - -Then configure the SSH server on this host as described in [Configure the SSH server on the host](#configure-the-ssh-server-on-the-host). - -## Option 2: External auth daemon (SSH on another server that doesn't run Newt) - -Use this when you want to SSH into servers that **do not** run Newt. One host runs Newt (e.g. as a bastion); each target server runs the Pangolin auth daemon as an extension of Newt. The client connects to the target by going **through** Newt—Newt proxies the SSH connection to the auth daemon and SSH server on each target. - -```mermaid -flowchart LR - subgraph client["User machine"] - CLI[Pangolin CLI] - end - - subgraph cloud["Pangolin Cloud"] - CA[Sign certificate] - end - - subgraph bastion["Bastion / site host"] - Newt[Newt] - end - - subgraph target["Target server"] - direction TB - AuthDaemon[Auth daemon] - SSHD[SSH server] - AuthDaemon --> SSHD - end - - CLI -->|Request signed cert| CA - CLI -->|SSH port 22| Newt - Newt -->|SSH to target| SSHD - Newt <-->|Extension, port 22123| AuthDaemon -``` - -### Prerequisites - -- **Newt** running on one host (the “site” / bastion) with auth-daemon support and a pre-shared key for external auth daemons. -- **Pangolin CLI** installed on each server where you will run the auth daemon. See [Install Clients — Quick Install (Recommended)](/manage/clients/install-client#quick-install-recommended). - -### Step 1: On the server running Newt - -Start Newt with a **pre-shared key** so external auth daemons can authenticate to it: +If you use ``, choose a strong random value and reuse the same value on each target host running `pangolin auth-daemon`. +For example, you can generate one with: ```bash -sudo newt --id --secret --endpoint --ad-pre-shared-key +openssl rand -hex 32 ``` - - -Choose a strong, random value for `` and use the same value when starting the auth daemon on each target server. -### Step 2: On each server you want to SSH into +## Configure SSH on the Newt host -On every host that should accept Pangolin SSH (and is not running Newt), run the auth daemon with the same pre-shared key: +If you want SSH access to the Newt host itself, run the `newt` binary directly on that host. +Do not treat this as a normal container use case. Newt needs to work with the host's own SSH configuration and local auth-daemon state, so a standard container deployment is not suitable for this path. + +Add or adjust these lines in `/etc/ssh/sshd_config`: + +```ini title="/etc/ssh/sshd_config" +TrustedUserCAKeys /etc/ssh/ca.pem +AuthorizedPrincipalsCommand /usr/local/bin/newt auth-daemon principals --username %u +AuthorizedPrincipalsCommandUser root +``` + +Restart the SSH server: + +```bash +sudo systemctl restart ssh +``` + +## Configure SSH on hosts behind Newt + +Do this on every target server behind Newt that should accept SSH. + +These hosts need the Pangolin CLI installed because the remote-side SSH integration is provided by `pangolin auth-daemon`. See [Install Clients](/manage/clients/install-client#quick-install-recommended-—-linux-and-macos). + +### Step 1: Start the auth daemon + +Run the auth daemon with the same pre-shared key used on Newt: ```bash sudo pangolin auth-daemon --pre-shared-key ``` -To use a non-default port, add `--port ` and set the same port in the resource’s SSH settings in the dashboard. +To use a non-default port, add `--port `. When you create the dashboard resource later, set the same daemon port in that resource's `SSH Access` settings. If you do not set a custom port, the default is **22123**. #### Run as a systemd service @@ -214,7 +166,7 @@ User=root WantedBy=multi-user.target ``` -Replace `` with the same value used on Newt. If you use a custom port (set in the resource’s SSH settings), add `--port ` to `ExecStart`. Then: +Replace `` with the same value used on Newt. If you use a custom port (set in the resource's SSH settings), add `--port ` to `ExecStart`. Then: ```bash sudo systemctl daemon-reload @@ -223,68 +175,73 @@ sudo systemctl start pangolin-auth-daemon sudo systemctl status pangolin-auth-daemon ``` - -Ensure the Pangolin CLI binary is at `/usr/local/bin/pangolin` (or update `ExecStart` to its path) before creating the service. - +Ensure the Pangolin CLI binary is at `/usr/local/bin/pangolin`, or update `ExecStart` to the correct path. -### Step 3: Configure the SSH server on each target host - -On each of these hosts, configure the SSH server as in [Configure the SSH server on the host](#configure-the-ssh-server-on-the-host). Use the `pangolin auth-daemon principals` command in `AuthorizedPrincipalsCommand` (see that section for the exact line). - -### Step 4: Ensure network connectivity - -- **Newt → auth daemon:** Newt must be able to reach the auth daemon port on each target server (default **TCP 22123**; configurable in the resource’s SSH settings and via the auth daemon’s `--port` flag). -- **Clients → SSH:** Port **22** must be open for SSH to each target server (from wherever your users connect—often only within your private network). - - -To change the auth daemon port from the default 22123, configure the port in the resource’s SSH settings in Pangolin and pass the same port with `--port` when starting the auth daemon. - - - -These ports do not need to be exposed to the public internet. They only need to be reachable within the network where Newt and the target servers live. - - -## Configure the SSH server on the host - -For both Option 1 and Option 2, the host’s SSH server must trust the Pangolin CA and use the auth daemon to resolve principals. Do the following on **every** host that will accept Pangolin SSH (the host running Newt in Option 1, or each host running the external auth daemon in Option 2). - -### 1. Update `sshd_config` +### Step 2: Configure `sshd` Add or adjust these lines in `/etc/ssh/sshd_config`: -- **Option 1 (Newt on this host):** use `newt auth-daemon principals` in the command. -- **Option 2 (external auth daemon on this host):** use `pangolin auth-daemon principals` in the command. - -Example for **Option 1** (Newt on same host): - -```ini title="/etc/ssh/sshd_config" -TrustedUserCAKeys /etc/ssh/ca.pem -AuthorizedPrincipalsCommand /usr/local/bin/newt auth-daemon principals --username %u -AuthorizedPrincipalsCommandUser root -``` - -Example for **Option 2** (external auth daemon on this host): - ```ini title="/etc/ssh/sshd_config" TrustedUserCAKeys /etc/ssh/ca.pem AuthorizedPrincipalsCommand /usr/local/bin/pangolin auth-daemon principals --username %u AuthorizedPrincipalsCommandUser root ``` -### 2. Restart the SSH server +Restart the SSH server: ```bash sudo systemctl restart ssh ``` -After this, users with access to the resource in Pangolin can run `pangolin ssh ` to connect. +### Step 3: Ensure network connectivity + +- **Newt → auth daemon:** Newt must be able to reach the auth daemon port on each target server (default **TCP 22123**; configurable in the resource's SSH settings and via the auth daemon's `--port` flag). +- **Clients → SSH:** Port **22** must be open for SSH to each target server from wherever your users connect. + + +To change the auth daemon port from the default 22123, configure the same port in the resource's `SSH Access` settings in Pangolin and pass it with `--port` when starting the auth daemon. +The auth-daemon port only needs to be reachable by Newt inside your network. It does not need to be exposed publicly, so restrict it with a firewall or network policy as appropriate for your environment. + + +## Configure resources in the dashboard + +After the host-side services are running, create the corresponding private resources in Pangolin. + +| Resource type | Destination | Recommended alias | SSH access policy | +|---------------|-------------|-------------------|-------------------| +| Newt host | Usually `127.0.0.1` or `localhost` on the server running Newt | `ssh..internal`, for example `ssh.prod.internal` | The policy for the **Newt host / built-in auth daemon** | +| Host behind Newt | The target server | `..internal`, for example `db-01.prod.internal` | In `SSH Access`, choose **Remote Host** | + +For each resource: + +1. Set the destination to the IP or FQDN of the correct host. For the Newt host itself, this is typically `127.0.0.1` or `localhost`. +2. Set an [alias](/manage/resources/private/alias) using the recommended pattern above. +3. In the resource's SSH settings, choose the SSH access policy that matches that host's backend. +4. If the resource points to a host behind Newt, open `SSH Access`, set it to **Remote Host**, and set the daemon port to match that host's auth daemon. Use **22123** unless you changed it with `pangolin auth-daemon --port `. +5. Grant access to the required users or roles. +6. In port restrictions, allow the host's SSH port: **TCP 22** by default, or a custom SSH port if your server uses one. + + +Two ports matter here: + +- The **SSH port** is the port users connect to on the target host. This is usually `22`, and it must be allowed in the resource's port restrictions. +- The **daemon port** is the port Newt uses to reach `pangolin auth-daemon` on hosts behind Newt. This is `22123` by default, or whatever you set with `--port`. + + +## Connect + +Once the resources and host-side SSH integrations match, users can connect with the alias or resource identifier for the specific host they want: + +```bash +pangolin ssh db-01.prod.internal +``` ## Signing keys for other applications You can ask Pangolin to sign a key for a resource without starting an interactive SSH session. Useful for scripts or tools that use SSH with a specific key: ```bash -pangolin ssh sign vm-01.prod.example.com --key-file /path/to/public/key.pub +pangolin ssh sign db-01.prod.internal --key-file /path/to/public/key.pub ``` ## Generating passwords for users @@ -305,9 +262,9 @@ When the client requests a signed key from the Pangolin server, the certificate ### Is the SSH connection proxied through Newt? -**Option 1 (same host):** No. Your client connects directly to the server that runs Newt; SSH traffic does not go through another hop. +If the resource points to the **Newt host itself**, no. Your client connects directly to the server running Newt. -**Option 2 (external auth daemon):** Yes. Your client connects to Newt, and Newt proxies the SSH session to the target server. The auth daemon on each target is an extension of Newt and works with it to complete the connection. +If the resource points to a **host behind Newt**, yes. Your client connects to Newt, and Newt proxies the SSH session to the target server. In a mixed deployment, both behaviors can exist at the same time depending on which resource the user selects. ### How are usernames created on the remote server? From 138a561e5c0f34655c0dab7c32c3d0a75a9f7205 Mon Sep 17 00:00:00 2001 From: Laurence Date: Wed, 1 Apr 2026 16:07:33 +0100 Subject: [PATCH 2/2] Refine SSH access doc structure and UI wording --- manage/ssh.mdx | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/manage/ssh.mdx b/manage/ssh.mdx index d10d58a..aaab4fb 100644 --- a/manage/ssh.mdx +++ b/manage/ssh.mdx @@ -52,7 +52,7 @@ This gives short-lived, auditable access without long-lived keys on the server. Users are provisioned **just in time** on the remote system. When you connect, Pangolin ensures an account exists for you with the right permissions before the SSH session starts. Your Pangolin identity is mapped to a local username (derived from the part before `@` in your identity; if needed, a suffix is added for uniqueness). The account is created with a home directory and can be granted sudo access as configured. -## Setup: choose your SSH layout +## Setup: choose your architecture Newt can provide SSH access for its own host, for other hosts behind it, or for both at the same time. @@ -68,7 +68,7 @@ Before you begin: | **Mixed deployment** | Users need SSH access to the Newt host **and** to other servers behind it | `--auth-daemon --ad-pre-shared-key ` | -You do not need to choose a single site-wide SSH mode. A single Newt instance can run its built-in auth daemon for the Newt host and also authenticate external auth daemons for other target hosts. +You do not need to choose a single site-wide SSH mode. A single Newt instance can handle **On Site** SSH access for the Newt host and also authenticate **Remote Host** SSH access for other target hosts. ## Understand the model @@ -146,7 +146,7 @@ Run the auth daemon with the same pre-shared key used on Newt: sudo pangolin auth-daemon --pre-shared-key ``` -To use a non-default port, add `--port `. When you create the dashboard resource later, set the same daemon port in that resource's `SSH Access` settings. If you do not set a custom port, the default is **22123**. +To use a non-default port, add `--port `. When you create the dashboard resource later, set the same daemon port in that resource's `SSH Access` tab. If you do not set a custom port, the default is **22123**. #### Run as a systemd service @@ -166,7 +166,7 @@ User=root WantedBy=multi-user.target ``` -Replace `` with the same value used on Newt. If you use a custom port (set in the resource's SSH settings), add `--port ` to `ExecStart`. Then: +Replace `` with the same value used on Newt. If you use a custom port (set in the resource's `SSH Access` tab), add `--port ` to `ExecStart`. Then: ```bash sudo systemctl daemon-reload @@ -195,11 +195,11 @@ sudo systemctl restart ssh ### Step 3: Ensure network connectivity -- **Newt → auth daemon:** Newt must be able to reach the auth daemon port on each target server (default **TCP 22123**; configurable in the resource's SSH settings and via the auth daemon's `--port` flag). +- **Newt → auth daemon:** Newt must be able to reach the auth daemon port on each target server (default **TCP 22123**; configurable in the resource's `SSH Access` tab and via the auth daemon's `--port` flag). - **Clients → SSH:** Port **22** must be open for SSH to each target server from wherever your users connect. -To change the auth daemon port from the default 22123, configure the same port in the resource's `SSH Access` settings in Pangolin and pass it with `--port` when starting the auth daemon. +To change the auth daemon port from the default 22123, configure the same port in the resource's `SSH Access` tab in Pangolin and pass it with `--port` when starting the auth daemon. The auth-daemon port only needs to be reachable by Newt inside your network. It does not need to be exposed publicly, so restrict it with a firewall or network policy as appropriate for your environment. @@ -209,15 +209,16 @@ After the host-side services are running, create the corresponding private resou | Resource type | Destination | Recommended alias | SSH access policy | |---------------|-------------|-------------------|-------------------| -| Newt host | Usually `127.0.0.1` or `localhost` on the server running Newt | `ssh..internal`, for example `ssh.prod.internal` | The policy for the **Newt host / built-in auth daemon** | -| Host behind Newt | The target server | `..internal`, for example `db-01.prod.internal` | In `SSH Access`, choose **Remote Host** | +| Newt host | Usually `127.0.0.1` or `localhost` on the server running Newt | `ssh..internal`, for example `ssh.prod.internal` | In `SSH Access`, set **SSH Auth Daemon Location** to **On Site** | +| Host behind Newt | The target server | `..internal`, for example `db-01.prod.internal` | In `SSH Access`, set **SSH Auth Daemon Location** to **Remote Host** | For each resource: 1. Set the destination to the IP or FQDN of the correct host. For the Newt host itself, this is typically `127.0.0.1` or `localhost`. 2. Set an [alias](/manage/resources/private/alias) using the recommended pattern above. -3. In the resource's SSH settings, choose the SSH access policy that matches that host's backend. -4. If the resource points to a host behind Newt, open `SSH Access`, set it to **Remote Host**, and set the daemon port to match that host's auth daemon. Use **22123** unless you changed it with `pangolin auth-daemon --port `. +3. Open the resource's `SSH Access` tab and set **SSH Auth Daemon Location** to match that host: + `On Site` for the Newt host, or `Remote Host` for a host behind Newt. +4. If the resource points to a host behind Newt, set the daemon port to match that host's auth daemon. Use **22123** unless you changed it with `pangolin auth-daemon --port `. 5. Grant access to the required users or roles. 6. In port restrictions, allow the host's SSH port: **TCP 22** by default, or a custom SSH port if your server uses one.