Skip to the content.

Network and Infrastructure Security

PuTTrY’s built-in authentication (session password, 2FA, and passkeys) protects your instance from unauthorized access at the application level. However, to reach your PuTTrY instance from a browser, your server must accept incoming connections over a network. Depending on how your server is reachable, additional infrastructure-level security measures are essential.

HTTPS vs HTTP

Always use HTTPS in production, unless your PuTTrY server lives on a completely private network with no external access:

Certificates: Self-Signed vs Official

Self-Signed Certificates

Official (CA-Signed) Certificates

Setting Up HTTPS with nginx

If your PuTTrY server runs on a machine with public IP or internal network access, use nginx as a reverse proxy to handle HTTPS:

1. Install nginx

# macOS
brew install nginx

# Ubuntu/Debian
sudo apt-get install nginx

# Other systems: see https://nginx.org/en/download.html

2. Generate a self-signed certificate (or obtain one from Let’s Encrypt)

# Self-signed cert (valid for 365 days)
openssl req -x509 -newkey rsa:4096 -keyout /etc/nginx/puttry.key -out /etc/nginx/puttry.crt -days 365 -nodes -subj "/CN=your-server-hostname"

3. Configure nginx as a reverse proxy Create /etc/nginx/sites-available/puttry:

upstream puttry {
    server 127.0.0.1:3000;  # Adjust port if PuTTrY runs on a different port
}

server {
    listen 443 ssl;
    server_name your-server-hostname;

    ssl_certificate /etc/nginx/puttry.crt;
    ssl_certificate_key /etc/nginx/puttry.key;

    # Recommended SSL settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://puttry;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        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;
    }
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name your-server-hostname;
    return 301 https://$server_name$request_uri;
}

Enable the site and restart nginx:

sudo ln -s /etc/nginx/sites-available/puttry /etc/nginx/sites-enabled/
sudo nginx -s reload

With Let’s Encrypt (Certbot) For automatic certificate management, use Certbot:

# Install Certbot
sudo apt-get install certbot python3-certbot-nginx  # Ubuntu/Debian

# Obtain and install certificate
sudo certbot certonly --standalone -d your-server-hostname

# Update nginx config to use Certbot's certificates
ssl_certificate /etc/letsencrypt/live/your-server-hostname/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-server-hostname/privkey.pem;

# Certbot auto-renews certificates before expiry

Cloud Provider HTTPS Options

Most cloud providers make HTTPS setup straightforward:

AWS (EC2 + Load Balancer)

Google Cloud (Compute Engine + Cloud Load Balancing)

Azure (App Service or Container Instances)

DigitalOcean (Droplet + App Platform)

VPN as an Alternative

Instead of exposing PuTTrY over HTTPS to the internet, you can tunnel access through a VPN:

Benefits

Options

Typical Setup

  1. Run PuTTrY on your server (no public exposure; localhost or private network only)
  2. Connect to your VPN from your device
  3. Access PuTTrY via its private IP address within the VPN
  4. Optional: still use HTTPS within the VPN for defense-in-depth

For Mobile: Install WireGuard, Tailscale, or OpenVPN on your phone, connect to your VPN, and access PuTTrY in your browser—just like from a desktop. The VPN keeps all traffic encrypted and authenticated.

Bastion Host Reverse Proxy

A bastion host (also called a jump host) is a hardened server that acts as a gatekeeper between the internet and your internal infrastructure. You can use it as a reverse proxy to shield your PuTTrY server from direct internet exposure while keeping HTTPS access available.

Architecture

Internet → Bastion Host (nginx/reverse proxy) → Internal PuTTrY Server (private network)
           (public IP, TLS termination)         (no public IP, internal only)

Benefits

Setup Steps

1. Network Configuration

2. Install and configure nginx on bastion

Modify the nginx config shown earlier, but point to your internal PuTTrY server’s private IP:

upstream puttry_internal {
    server 10.0.1.50:3000;  # Internal private IP of PuTTrY server
}

server {
    listen 443 ssl;
    server_name puttry.example.com;  # Your bastion's public domain

    ssl_certificate /etc/letsencrypt/live/puttry.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/puttry.example.com/privkey.pem;

    # Recommended SSL settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # Optional: Rate limiting and basic protection
    limit_req_zone $binary_remote_addr zone=puttry_limit:10m rate=10r/s;
    limit_req zone=puttry_limit burst=20 nodelay;

    location / {
        proxy_pass http://puttry_internal;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        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;

        # WebSocket timeouts
        proxy_read_timeout 86400;
        proxy_send_timeout 86400;
    }
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name puttry.example.com;
    return 301 https://$server_name$request_uri;
}

3. Firewall rules on PuTTrY server

# Allow only bastion to reach PuTTrY (example with iptables)
iptables -A INPUT -p tcp -s 203.0.113.10 --dport 3000 -j ACCEPT  # Bastion IP
iptables -A INPUT -p tcp --dport 3000 -j DROP  # Block all other access

# Or with ufw (Ubuntu/Debian)
sudo ufw default deny incoming
sudo ufw allow from 203.0.113.10 to any port 3000  # Bastion IP

4. Start PuTTrY normally on internal server

puttry  # Runs on localhost:3000, accessible only to bastion

5. Access from client browsers Users connect to https://puttry.example.com (bastion’s public domain), nginx reverse proxies to the internal PuTTrY server, and authentication is enforced by PuTTrY’s session password and 2FA.

Adding Extra Security Layers on Bastion

Once your bastion is set up, you can add more protections:

Rate Limiting (already shown in nginx config above)

Request Logging

access_log /var/log/nginx/puttry_access.log;
error_log /var/log/nginx/puttry_error.log;

IP Whitelist (if you have fixed IPs)

location / {
    allow 198.51.100.0/24;   # Office IP range
    allow 203.0.113.5;        # Your home IP
    deny all;

    proxy_pass http://puttry_internal;
    # ... rest of config
}

Web Application Firewall (WAF)

When to Use Bastion Reverse Proxy

Bastion vs VPN: When to Choose Each

Approach Best For Complexity Accessibility
Bastion Reverse Proxy Corporate, multi-service infrastructure Medium Browser (HTTPS), public domain
VPN Personal, cross-network tunneling Low-Medium Any IP on private network, mobile apps
Both Maximum security + ease-of-access Higher VPN + bastion double-shields PuTTrY

Summary: Choose Your Model

Scenario Model Setup Complexity
Personal, fully private network HTTP locally, no public access Low
Shared internal network HTTPS + self-signed cert + nginx Medium
Personal, internet-facing HTTPS + Let’s Encrypt + nginx Medium
Multiple users, production HTTPS + official cert + cloud load balancer Medium-High
Secure cross-network access VPN (WireGuard/Tailscale) + local HTTP Low-Medium