# Install Psono Gateway
Psono Gateway provides browser-based SSH, RDP, and VNC sessions for connection entries stored in Psono.
WARNING
Psono Gateway is available only with Psono Enterprise Edition and requires a valid Enterprise Edition licence. It cannot be used with the Community Edition server.
# Preamble
This guide assumes that Psono Enterprise Edition, the webclient, and the Admin Portal are already running. It uses the following addresses:
https://psono.example.comfor Psonohttps://psono.example.com/serverfor the Psono Enterprise Server APIhttps://gateway.example.com/for Psono Gateway
Psono Gateway is based on Apache Guacamole. The container includes the web application and a bundled guacd daemon with
SSH, RDP, and VNC support. A browser connects to the Gateway over HTTPS. The Gateway then opens the SSH, RDP, or VNC
connection from its own network to the target system.
Connection credentials are encrypted by the webclient for a one-time launch. The server selects an active Gateway from the chosen cluster, and the Gateway atomically exchanges the short-lived launch code for the encrypted connection details. The launch cannot be reused.
WARNING
The Gateway handles decrypted connection credentials and remote sessions in memory. Run it on a trusted, maintained host and restrict its network access to the Psono server and intended target systems.
# Cluster configuration
A Gateway cluster groups one or more Gateway instances and controls which users may launch sessions through them. Multiple instances registered with the same cluster provide high availability; the server randomly selects one of the active instances for each launch.
Enable the Gateway API on the Psono Enterprise Server.
You can enable the API explicitly in the server's
settings.yaml:GATEWAY_HANDLER_ENABLED: TrueRestart the Psono Enterprise Server after changing this setting.
Create a Gateway cluster.
Sign in to the Admin Portal, open Gateway Management, select Clusters, and create a cluster. Give the cluster a title that helps users identify its location or purpose.
Configure access.
Allow all users is enabled by default. Disable it if only selected users or groups should be able to use the cluster, then map the permitted users and groups on the cluster page. Accepted members of a mapped group receive access.
Generate the cluster configuration.
On the cluster page, select Generate Gateway Configuration. The generated configuration contains the server URL, server public key, cluster ID, and cluster private key.
WARNING
The cluster private key allows a Gateway to register as a member of the cluster. Store the generated configuration as a secret and do not expose it to users or include it in source control.
# Command-line alternative
You can create the cluster and generate its configuration on the Psono Enterprise Server instead:
docker run --rm \
-v /opt/docker/psono/settings.yaml:/root/.psono_server/settings.yaml \
-ti psono/psono-combo-enterprise:latest \
python3 ./psono/manage.py gatewayclustercreate "Production gateways"
Use the cluster ID returned by the first command:
docker run --rm \
-v /opt/docker/psono/settings.yaml:/root/.psono_server/settings.yaml \
-ti psono/psono-combo-enterprise:latest \
python3 ./psono/manage.py gatewayclustershowconfig YOUR_CLUSTER_ID
Clusters created with the command line initially allow all users. Use the Admin Portal to change the access policy and map users or groups.
# Gateway configuration
Create the configuration directory:
mkdir -p /opt/docker/psono-gatewaySave the generated configuration as
/opt/docker/psono-gateway/settings.yamland add the public Gateway URL:SERVER_URL: 'https://psono.example.com/server' SERVER_PUBLIC_KEY: '<server-public-key>' CLUSTER_ID: '<cluster-id>' CLUSTER_PRIVATE_KEY: '<cluster-private-key>' HOST_URL: 'https://gateway.example.com/'HOST_URLmust be the public URL that users' browsers can reach. HTTPS is mandatory except for loopback development. Keep the trailing slash when the Gateway is served at the domain root.Restrict access to the settings file:
chown 1001:1001 /opt/docker/psono-gateway/settings.yaml chmod 600 /opt/docker/psono-gateway/settings.yamlThe Gateway application runs as UID/GID
1001inside the container. Adjust the ownership strategy if your container platform remaps user IDs.
# Optional settings
The defaults are suitable for most installations:
SERVER_URL_VERIFY_SSL: True
ALIVE_INTERVAL_SECONDS: 10
LAUNCH_CONNECT_TIMEOUT_SECONDS: 10
LAUNCH_READ_TIMEOUT_SECONDS: 10
LAUNCH_ABSOLUTE_TIMEOUT_SECONDS: 28800
LAUNCH_VALIDATION_INTERVAL_SECONDS: 30
SERVER_URL_VERIFY_SSLcontrols certificate verification for connections to the Psono server. Do not disable it in production.ALIVE_INTERVAL_SECONDScontrols how often the Gateway renews its server registration. It must be lower than the server'sGATEWAY_ALIVE_TIMEOUT, which defaults to 30 seconds.LAUNCH_CONNECT_TIMEOUT_SECONDSandLAUNCH_READ_TIMEOUT_SECONDScontrol requests from the Gateway to the Psono server.LAUNCH_ABSOLUTE_TIMEOUT_SECONDSlimits the total life of a launched session. The default is eight hours.LAUNCH_VALIDATION_INTERVAL_SECONDScontrols how often active launches are revalidated with the Psono server.
Set PSONO_GATEWAY_CONFIG to load a different YAML file. Each setting can alternatively be supplied as an environment
variable prefixed with PSONO_GATEWAY_; for example, PSONO_GATEWAY_SERVER_URL. Environment variables override YAML
values. Quote hexadecimal keys in YAML so they are parsed as strings.
# Installation
Run the Gateway container and bind it only to the local reverse proxy:
docker run --name psono-gateway \
--sysctl net.core.somaxconn=65535 \
-v /opt/docker/psono-gateway/settings.yaml:/home/psono/.psono_gateway/settings.yaml:ro \
-d --restart=unless-stopped \
-p 10500:8080 \
psono/psono-gateway:latest
The bundled guacd daemon listens only on the container's loopback interface. The image health check verifies both the
Gateway web application and guacd. Check that the container becomes healthy:
docker ps --filter name=psono-gateway
docker logs psono-gateway
TIP
For stronger process isolation, you can disable the bundled daemon with BUNDLED_GUACD_ENABLED=false and configure an
external daemon with GUACD_HOSTNAME and GUACD_PORT. The external guacd must be able to reach all intended target
systems.
# Reverse proxy
Psono Gateway requires a reverse proxy for TLS termination and WebSocket forwarding. The following example uses Nginx.
Install Nginx
sudo apt-get install nginxCreate nginx config
Create
gateway.example.com.confin/etc/nginx/sites-available/with the following content:server { listen 80; server_name gateway.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name fs01.example.com; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; ssl_session_timeout 1d; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; # Comment this in if you know what you are doing # add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; add_header Referrer-Policy same-origin; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; ssl_certificate /etc/ssl/fullchain.pem; ssl_certificate_key /etc/ssl/privkey.pem; root /var/www/html; location / { proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://127.0.0.1:10500/; proxy_read_timeout 90; proxy_buffering off; proxy_redirect http://127.0.0.1:10500 https://gateway.chickahoona.com/; } }Enable and test the configuration, then reload Nginx:
ln -s /etc/nginx/sites-available/gateway.example.com.conf /etc/nginx/sites-enabled/ nginx -t systemctl reload nginx
Opening https://gateway.example.com/ should display the Psono Gateway page. Direct sign-in is intentionally unavailable;
sessions must be launched from Psono.
# Validation
- Open Gateway Management in the Admin Portal and select Gateways. The new instance should appear as active with the expected hostname, cluster, version, and public URL.
- In the Psono webclient, create or open an SSH, RDP, or VNC connection entry with valid credentials.
- Select Launch. If you have access to multiple active clusters, select one from the dialog. With one cluster, Psono launches it directly.
- Allow popups for the Psono webclient if the browser blocks the new session tab.
The launch button is available only while the client is online and the user has read access to the connection entry.
# High availability
Run multiple Gateway containers with the same cluster configuration and a unique HOST_URL for each instance. Every
instance registers independently. The Psono server advertises the cluster while at least one member is active and selects
an active member for each launch.
A Gateway restart ends sessions running on that instance. Active sessions are intentionally not recoverable after a restart, so schedule or announce maintenance before restarting Gateway instances.
# Firewall rules
Allow the following traffic:
- Incoming TCP 443 from users' browsers to the Gateway reverse proxy.
- Outgoing TCP 443 from the Gateway to the Psono Enterprise Server.
- Outgoing traffic from
guacdto the configured targets, usually TCP 22 for SSH, TCP 3389 for RDP, and TCP 5900 for VNC. - DNS and time synchronization traffic required by the host. The Gateway and Psono server clocks must be synchronized for registration replay protection.
The Psono server does not need to initiate a connection to the Gateway or to the remote target systems.