Final Architecture

Browser
    ↓ HTTPS
lab.mydomain.com

Nginx

ttyd

bash

Linux shell

Step 1: DNS

Added:

lab.mydomain.com
→ 123.124.125.126

Purpose:

Convert human names into IP addresses.

Verification:

dig lab.mydomain.com

Step 2: Install ttyd

sudo apt install ttyd

Purpose:

Expose Linux terminal through browser.

Protocol:

Browser
↔ WebSocket
↔ ttyd
↔ bash

Step 3: Local-only binding

Command:

ttyd -W -i 127.0.0.1 -p 7681 /bin/bash

Breakdown:

  • -W

Enable keyboard input

  • -i 127.0.0.1

localhost only

  • -p 7681

listen on port

  • /bin/bash

launch shell


Step 4: systemd

File:

/etc/systemd/system/ttyd.service

Purpose:

Autostart and restart ttyd.

Important settings:

User=terri
 
WorkingDirectory=/home/terri
 
Restart=always

Step 5: Reverse proxy

location / {
 
proxy_pass http://127.0.0.1:7681;
 
}

Browser only sees:

https://lab.mydomain.com

Nginx forwards internally.


Step 6: WebSocket support

Required:

proxy_http_version 1.1;
 
proxy_set_header Upgrade $http_upgrade;
 
proxy_set_header Connection "upgrade";

Without websocket:

Terminal input/output breaks.


Step 7: HTTPS

Generated by:

sudo certbot --nginx -d lab.mydomain.com

Purpose:

Encrypt browser ↔ server communication.


Step 8: Basic auth

auth_basic

Adds extra authentication before terminal access.


Security model

Internet

443

Nginx

localhost-only service

shell

Advantages:

  • hides internal ports
  • HTTPS termination
  • authentication
  • future fail2ban
  • easier hardening