Cockpit via Apache Reverse Proxy

I know, this is very unsafe if your login credentials are stolen but it serves as a proof of concept!!!

1. The Goal

To provide secure, external access to the Cockpit Web Console via https://example.site/cockpit/ without opening extra ports (like 9090) on the router and without managing separate SSL certificates for the dashboard.

2. Architecture Flow

  1. User requests https://example.site/cockpit/.
  2. OpenWrt (HAProxy) receives traffic on port 443 and passes it to the Debian LXC (192.168.1.16:443).
  3. Apache (inside LXC) terminates the SSL using Let’s Encrypt certificates.
  4. Apache proxies the request internally to 127.0.0.1:9090.
  5. Cockpit processes the request and responds through the tunnel.

3. Key Configurations

A. Apache VirtualHost (/etc/apache2/sites-available/...)

We used mod_proxy and mod_rewrite to handle both standard web traffic and the persistent WebSocket connections required for the Cockpit terminal.

# WebSocket Upgrade (Fixes "Login then Blank Page" issue)
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /cockpit/(.*) ws://127.0.0.1:9090/cockpit/$1 [P,L]

# Subfolder Proxy
<Location /cockpit/>
    ProxyPass http://127.0.0.1:9090/cockpit/
    ProxyPassReverse http://127.0.0.1:9090/cockpit/
</Location>

B. Cockpit Config (/etc/cockpit/cockpit.conf)

Crucial for preventing CSRF (Cross-Site Request Forgery) security blocks and allowing the unencrypted internal “handshake.”

[WebService]
Origins = https://hissite.org
ProtocolHeader = X-Forwarded-Proto
AllowUnencrypted = true
UrlRoot = /cockpit

4. Troubleshoot Log & Fixes

  • Issue:sscg: command not found.
    • Fix: Installed sscg package to satisfy Cockpit dependencies.
  • Issue:gnutls_handshake failed: A TLS fatal alert.
    • Reason: Cockpit was expecting HTTPS but Apache was sending HTTP.
    • Fix: Added AllowUnencrypted = true and restarted cockpit.socket.
  • Issue: Blank page after login.
    • Reason: WebSockets (the “live” part of the site) were failing to tunnel through Apache.
    • Fix: Added specific RewriteRule for ws:// protocol.

5. Security Hardening Applied

  • Consolidated SSL: All traffic uses the main site’s hardened TLS 1.2/1.3 settings.
  • Internal Communication: Apache talks to Cockpit over 127.0.0.1 (local loopback), meaning no unencrypted traffic ever touches your LAN or the WAN.

6. Maintenance Commands

If Cockpit ever stops responding, run these in order:

  1. sudo systemctl restart cockpit.socket (Restarts the listener)
  2. sudo systemctl restart apache2 (Restarts the proxy)
  3. sudo journalctl -u cockpit -f (To watch live logs if a crash occurs)

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *