SSH Access

openZro provides SSH access to peers through its built-in SSH server. Unlike traditional SSH setups that require exposing port 22 to the internet, openZro SSH operates entirely over your private network. You can connect using either the openzro ssh command or native OpenSSH clients.

openZro SSH supports fine-grained access control, allowing you to specify which openZro users can access which local OS users on target machines.

Concepts

SSH Server

Each openZro peer can run an embedded SSH server by enabling --allow-server-ssh. From the peer's perspective the session arrives on its normal port (TCP 22); internally it's re-routed to the openZro client on port 22022.

Management may automatically ensure the mesh access policy permits 22022 for a peer when the policy explicitly allows port 22 (or a range containing 22) and the peer advertises native SSH support (openZro v0.60.0+). That access policy is distributed by the management plane; enforcement and forwarding are performed by the openZro client on the peer.

Authentication Methods

  • JWT Authentication (default): Maps SSH sessions to user identities via your configured Identity Provider (OIDC). Each new session will require completing the OIDC flow to mint the JWT used for SSH authentication (unless JWT caching is enabled, in which case JWT tokens are cached for a configurable duration). Combined with fine-grained access control, this allows you to control exactly which authenticated users can access which local OS users on the target machine.
  • Machine Identity (--disable-ssh-auth): When SSH auth is disabled, SSH access is governed by openZro network ACLs (machine-level access) rather than per-user JWT identity.

OpenSSH Integration

openZro can provide configuration so the remote peer's OpenSSH clients behave transparently. The remote peer's openZro client performs interception and JWT handling; openZro may install OpenSSH configuration snippets on the client to simplify usage. The interception and forwarding logic lives in the remote peer's openZro client, not the management server.

Port 22 Redirection

The management server does not edit your host OS firewall or perform OS-level port redirects. The model is:

  • 22 - the standard SSH port used by SSH clients and the local SSH daemon.
  • 22022 - the openZro-native endpoint used by the openZro client on remote peers. When openZro SSH is enabled for a peer, standard SSH traffic is redirected here.

Behavior:

  • A modern openZro client can intercept an ssh user@remote (which targets remote:22) and redirect the SSH stream to the openZro client on port 22022.
  • Management will auto-add a openZro access-policy rule for 22022 when a policy allows 22 (or a range containing 22) and the peer supports native SSH (v0.60.0+) and SSH is enabled on the peer in the openZro dashboard.

Requirements

To use SSH access through openZro, you need:

  1. openZro v0.61.0 or later on all peers using SSH (both clients and servers). For fine-grained access control features, v0.61.0 is required.
  2. SSH enabled on target peer - the peer must run with --allow-server-ssh.
  3. Access Control Policy - A openZro SSH policy configured in the dashboard
  4. (Optional) For JWT authentication: an Identity Provider configured in openZro.

Enabling SSH

Step 1: Enable SSH Server on Target Peer

On the machine you want to access via SSH, enable the openZro SSH server.

Using the GUI:

  1. Click on the openZro tray icon
  2. Navigate to Settings
  3. Click on Allow SSH to enable the SSH server

openzro ssh client

Using the CLI:

openzro down  # if openZro is already running
openzro up --allow-server-ssh

For additional SSH server features, use these flags:

openzro up --allow-server-ssh \
  --enable-ssh-local-port-forwarding \
  --enable-ssh-remote-port-forwarding \
  --enable-ssh-sftp \
  --enable-ssh-root

Flag Reference:

  • --allow-server-ssh: Enable the SSH server
  • --enable-ssh-local-port-forwarding: Allow clients to forward local ports through the server
  • --enable-ssh-remote-port-forwarding: Allow clients to request remote port forwarding
  • --enable-ssh-sftp: Enable SFTP subsystem for file transfers
  • --enable-ssh-root: Allow root user login (use with caution)
  • --disable-ssh-auth: Disable JWT authentication (allows any peer with network access)
  • --ssh-jwt-cache-ttl <seconds>: Enable JWT token caching with specified TTL in seconds (default: 0, disabled)

Step 2: Create Access Control Policy

Create an ACL policy to allow SSH access:

  1. Log in to your openZro Dashboard
  2. Navigate to Access Control
  3. Create a new policy:
  • Source: Select the peers or groups that will connect via SSH
  • Destination: Select the peers or groups running the SSH server
  • Protocol: Select openZro SSH for SSH-specific policies with fine-grained access control, or use TCP with port 22 for basic network-level SSH access
  • Authorized Groups (when using openZro SSH protocol): Configure which user groups can access which local OS users on the destination machines
  1. Save the policy

openzro ssh access policy

Using openZro SSH

openZro CLI Client

The simplest way to connect is using the openzro ssh command:

openzro ssh user@100.119.230.104

Execute a single command:

openzro ssh user@100.119.230.104 "uptime"

Port forwarding:

# Local port forwarding: forward local port 8080 to remote port 80
openzro ssh -L 8080:localhost:80 user@100.119.230.104

# Remote port forwarding: forward remote port 8080 to local port 3000
openzro ssh -R 8080:localhost:3000 user@100.119.230.104

For detailed CLI usage, see the CLI documentation.

Native SSH Clients (OpenSSH)

openZro automatically configures OpenSSH through a drop-in configuration file.

Prerequisites:

openZro creates /etc/ssh/ssh_config.d/99-openzro.conf (or equivalent on your OS) which automatically:

  1. Detects if the target is a openZro SSH server
  2. Handles JWT authentication transparently
  3. Handles server host key verification

Using OpenSSH:

# Connect using standard SSH
ssh user@100.119.230.104

# Port forwarding
ssh -L 8080:localhost:80 user@100.119.230.104

# SFTP
sftp user@100.119.230.104

# SCP
scp file.txt user@100.119.230.104:/path/to/destination

How it works:

When you run ssh user@<openzro-peer>:

  1. OpenSSH reads the openZro configuration from 99-openzro.conf
  2. openZro detects if the target is a openZro SSH server
  3. If detected, openZro handles JWT authentication automatically (OIDC flow if needed)
  4. The SSH connection is established with your user identity

Authentication

JWT Authentication (Default)

By default, openZro SSH uses JWT-based authentication with the configured Identity Provider. This provides user identity verification instead of machine identity.

openZro supports fine-grained user mapping, allowing you to specify which OIDC users or groups can connect to which local OS users on the target system. See Fine-Grained Access Control for details.

How it works:

  1. When you connect via SSH, the openZro client requests a JWT token
  2. If no cached token exists or the token is expired:
  • openZro initiates an OIDC flow
  • A URL is displayed that you must open in your browser to authenticate with the IdP
  • After successful login, openZro receives and caches the JWT token
  1. The client sends the JWT to the SSH server
  2. The server validates the JWT using the JWKS endpoint configured in the management server
  3. If valid, the SSH session is established with the user identity from the JWT

Benefits:

  • User identity: SSH sessions are associated with actual users, not machines
  • Centralized auth: Leverage the configured IdP (Okta, Google, Microsoft, etc.)
  • Audit trail: Know exactly which user accessed which machine
  • Token expiration: Automatic re-authentication when tokens expire

Token caching:

By default, JWT tokens are not cached, meaning you'll need to authenticate for each new SSH connection. To enable token caching and reduce authentication prompts on the SSH client machine, use the --ssh-jwt-cache-ttl flag:

# On the SSH client: enable caching with 1-hour TTL
openzro up --ssh-jwt-cache-ttl 3600

# On the SSH client: disable caching (default)
openzro up --ssh-jwt-cache-ttl 0

When caching is disabled (default):

  • You'll authenticate via OIDC for each new SSH connection
  • More secure but less convenient
  • Recommended for high-security environments

When caching is enabled:

  • JWT tokens are cached on the client for the specified TTL in seconds
  • Reduces repeated authentication prompts
  • Cached tokens expire after the configured TTL or when the openZro daemon is restarted

Machine Identity (--disable-ssh-auth)

If you prefer to allow SSH access from any peer with network access (similar to pre-0.60 behavior), you can disable JWT authentication:

openzro up --allow-server-ssh --disable-ssh-auth

Important considerations:

  • Less secure: Any peer with network access (ACL policy) can connect
  • Machine identity: Connections are identified by peer/machine, not by user
  • No audit trail: You cannot track which user accessed the system
  • Use cases: Automated scripts, service accounts, environments without IdP

Fine-Grained Access Control

openZro SSH allows you to configure granular access control that maps openZro users to specific local OS users on target machines. This provides precise control over who can access what on your infrastructure.

How It Works

When you create an SSH policy with the openZro SSH protocol, you can configure Authorized Groups that define:

  1. Source User Groups: Which openZro user groups are allowed to connect
  2. Local User Mapping: Which local OS users each group can access on the destination machines

For example, you can configure:

  • Members of the "Developers" group can SSH as developer or deploy users
  • Members of the "DBAs" group can SSH as postgres user
  • Members of the "SysAdmins" group can SSH as root user

Configuring Fine-Grained Access Control

When creating or editing an SSH policy in the Dashboard:

  1. Navigate to Access Control and click Create Policy
  2. Select openZro SSH as the protocol
  3. Configure the Source - select the user groups that will connect via SSH
  4. Configure the Destination - select the peers or groups running the SSH server
  5. Under SSH Access, choose the access level:
    • Full Access: Allow SSH as any local user on the destination machines
    • Limited Access: Specify which local users each source group can access
  6. If you selected Limited Access, configure the user mappings:
    • For each source group, specify which local OS users they are allowed to SSH as
    • Add multiple local users per group as needed (e.g., ashley, root)
  7. Enable the policy and click Continue

openzro ssh fine grained access policy

Example configuration:

Source GroupAllowed Local Users
Developersdeveloper, deploy
DBAspostgres
SysAdminsroot, admin

Authorization Flow

When a user attempts to SSH into a peer:

  1. The user authenticates via OIDC to obtain a JWT token
  2. The JWT contains the user's identity (user ID from the sub claim by default)
  3. openZro checks if the user's ID is in the list of authorized users for this peer
  4. openZro verifies the user is allowed to access the requested local OS user based on the policy's authorized groups configuration
  5. If authorized, the SSH session is established as the specified local user

Security Considerations

  • Fail-closed: If no mapping exists for an OS user, access is denied by default
  • User identity verification: Access decisions are based on the authenticated OIDC user identity
  • Audit trail: All SSH access attempts are logged with the authenticated user's identity
  • Least privilege: Configure the minimum necessary local user access for each group

Advanced Features

Port Forwarding

openZro SSH supports both local and remote port forwarding, allowing you to create secure tunnels through the SSH connection.

Local Port Forwarding:

Forward a local port on your machine to a remote address through the SSH server:

# Forward local port 8080 to remote localhost:80
openzro ssh -L 8080:localhost:80 user@100.119.230.104

# Forward local port 5432 to a database accessible from the remote peer
openzro ssh -L 5432:database.internal:5432 user@100.119.230.104

Use case: Access a web service or database running on the remote peer or in its network.

Remote Port Forwarding:

Forward a port on the remote SSH server to your local machine:

# Forward remote port 8080 to local port 3000
openzro ssh -R 8080:localhost:3000 user@100.119.230.104

Use case: Allow the remote peer to access a service running on your local machine.

SFTP and SCP

Transfer files securely using native SFTP or SCP clients:

SFTP:

sftp user@100.119.230.104

SCP:

# Upload file
scp file.txt user@100.119.230.104:/path/to/destination

# Download file
scp user@100.119.230.104:/path/to/file.txt .

# Copy directory
scp -r directory/ user@100.119.230.104:/path/to/destination

Non-interactive Command Execution

Execute commands on remote peers without an interactive shell:

openzro ssh user@100.119.230.104 "uptime"

Platform Support & Limitations

Supported Platforms

openZro SSH is supported on the following platforms:

  • Linux: Full support (all features)
  • macOS: Full support (all features)
  • Windows: Full support with platform-specific considerations (see below)
  • FreeBSD: Full support (all features)
  • Android: Server-only support (SSH client not available)

Platform-Specific Considerations

Windows

  • Port forwarding not supported: SSH servers on Windows cannot accept port forwarding requests
  • Other features supported: SFTP, non-interactive commands fully functional

Linux/Unix

  • User Switching: Available when running as root
  • The SSH server can switch to any user when running with root privileges
  • Non-root openZro (e.g., rootless containers) will run sessions under the given account
  • All features supported: Full feature parity across these platforms

Android

  • Server-only: SSH client functionality not available
  • Server features: Can run openZro SSH server (configured via GUI)

Known Limitations

Port Forwarding

Port forwarding has the following limitations:

  • Not supported with native SSH clients: Port forwarding (both local -L and remote -R) is only available when using the openzro ssh command directly
  • Native OpenSSH clients cannot use port forwarding
  • This is a current implementation limitation
  • Use openzro ssh -L or openzro ssh -R instead of ssh -L or ssh -R
  • Not supported on Windows servers: SSH servers running on Windows cannot accept port forwarding requests
  • No user switching with port forwarding: Port forwarding only works when connecting as the user running the openZro process

User Mapping

openZro now supports fine-grained user mapping through the openZro SSH protocol and Authorized Groups configuration. See Fine-Grained Access Control for details.

Requirements for user switching:

  • The openZro SSH server must run with root/administrator privileges to switch between local users
  • Non-root openZro installations (e.g., rootless containers) will run all sessions under the openZro process account
  • On Windows, sessions connect as Administrator-equivalent users

Feature Availability

Some features require specific flags to be enabled on the SSH server:

  • SFTP: Requires --enable-ssh-sftp
  • Local port forwarding: Requires --enable-ssh-local-port-forwarding
  • Remote port forwarding: Requires --enable-ssh-remote-port-forwarding
  • Root login: Requires --enable-ssh-root (use with caution)

Security Considerations

Access Control

SSH access is controlled by multiple layers:

  1. Network ACL policies: Control which peers can access SSH with dedicated 'openZro SSH' protocol policies
  2. JWT authentication (if enabled): User identity verification via IdP
  3. Fine-grained access control (when using openZro SSH protocol): Controls which authenticated users can access which local OS users on the target machine

Disable SSH server

To disable the openZro SSH server run openzro down && openzro up --allow-server-ssh=false

Troubleshooting

Connection Issues

"SSH server not detected" or "Permission denied (publickey)" or "No more authentication methods available"

  • Ensure the target peer is running with --allow-server-ssh
  • Verify SSH is enabled in the dashboard for the target peer
  • Check that the target peer is online and connected

"Authentication failed" (JWT authentication)

  • Complete the OIDC flow when prompted
  • Verify the IdP is properly configured
  • Check if your JWT token is expired (openZro will request a new one)
  • Ensure the SSH server's system clock is synchronized (time skew causes JWT validation failures)
  • For --disable-ssh-auth: Ensure ACL policy allows access

"Connection timeout"

  • Verify ACL policy allows SSH access
  • Check if peers are connected to each other: openzro status -d
  • Test basic connectivity: ping <peer-ip>

Port Forwarding Issues

"Port forwarding not available"

  • Ensure the SSH server was started with appropriate flags:
  • --enable-ssh-local-port-forwarding for local forwarding
  • --enable-ssh-remote-port-forwarding for remote forwarding

"Cannot bind to port"

  • For local forwarding: Ensure the local port is not already in use
  • For remote forwarding: Ensure the remote port is available

SFTP Issues

"SFTP subsystem not available"

  • Ensure the SSH server was started with --enable-ssh-sftp

"Permission denied"

  • Check file system permissions on the target peer
  • Verify you're connecting with the correct user

Fine-Grained Access Control Issues

"User is not authorized to access this peer"

  • Verify the user's group is included in the SSH policy's source groups
  • Check that the policy uses the openZro SSH protocol
  • Ensure the user has authenticated via OIDC

"User is not authorized to login as OS user"

  • Check the Authorized Groups configuration in the SSH policy
  • Verify the user's group is mapped to the requested local OS user
  • Ensure the local OS user exists on the target machine

"No authorization mapping for OS user"

  • The requested local OS user is not configured in any Authorized Groups mapping
  • Add the local OS user to the appropriate group's allowed users list in the policy

CLI Reference

For complete CLI command reference, including all SSH-related commands and flags, see the CLI documentation.

Version History

v0.61.0

Version 0.61.0 introduces fine-grained SSH access control.

New Capabilities

  • openZro SSH protocol: New protocol type in policies specifically for SSH access control
  • Fine-grained user mapping: Map openZro user groups to specific local OS users
  • Authorized Groups: Configure which users can access which local accounts per policy
  • Full Access vs Limited Access: Choose between unrestricted local user access or granular per-group mappings
  • Enhanced security: Fail-closed authorization model with granular audit trail

Breaking Changes

  • Peers running versions older than v0.61.0 will lose SSH functionality when the management server is upgraded to v0.61.0

Upgrade Steps

  1. Update SSH servers (peers running --allow-server-ssh)

  2. Update SSH clients (peers using openzro ssh)

  3. Update the management server to v0.61.0

  4. Update the dashboard to v0.61.0

  5. Create openZro SSH policy:

    • Source: SSH client user groups
    • Destination: SSH server peers/groups
    • Protocol: openZro SSH
    • SSH Access: Full Access or Limited Access
    • If Limited Access: configure local user mappings per source group

v0.60.0

Version 0.60.0 is a complete rewrite of openZro SSH with breaking changes.

New Capabilities

  • OpenSSH client support via automatic proxy configuration
  • Windows client and server support
  • SFTP subsystem for file transfers
  • Local and remote port forwarding (openzro ssh only)
  • Non-interactive command execution
  • Configurable JWT token caching

Breaking Changes

  • Server port changed from 44338 to 22 (22022 internally)
  • Authentication changed from machine public keys to JWT tokens (user identity)
  • Port 22 automatically redirects to 22022 for openZro traffic
  • Old implicit firewall rule removed - explicit ACL policy required for port 22
  • Client no longer requires sudo for authentication
  • Not backward compatible: v0.60.0+ clients cannot connect to older servers and vice versa

Upgrade Steps

  1. Update management server to v0.60.0 or later

    • Verify server is running correctly
    • Confirm JWKS endpoint is accessible
  2. Update dashboard (optional)

    • Only needed if you use the browser-based SSH client
  3. Create ACL policy for port 22:

    • Source: SSH client peers/groups
    • Destination: SSH server peers/groups
    • Protocol: TCP
    • Port: 22
  4. Update SSH servers first (peers running --allow-server-ssh)

    • Start with non-critical peers for testing
  5. Update SSH clients last (peers using openzro ssh)

    • Updated clients cannot connect to old servers

Optional Configuration

Disable JWT authentication on SSH servers (allows network-level access without user auth):

openzro up --allow-server-ssh --disable-ssh-auth

Enable JWT token caching on SSH clients (reduces auth prompts):

openzro up --ssh-jwt-cache-ttl 3600  # 1 hour

Get started