This repository provides a shell script and configuration reference for deploying Cockpit behind a Cloudflare Tunnel with optional LAN access through Nginx. It allows secure remote access to Cockpit while keeping local network accessibility.
- Exposes Cockpit securely via a Cloudflare Tunnel.
- Allows LAN access on a separate port.
- Configures Nginx as a reverse proxy.
- Provides safe defaults and backup of original configuration files.
- Supports unencrypted Cockpit access via
X-Forwarded-Protoheader.
- Ubuntu/Debian server
- Cockpit installed
- Nginx installed
- Cloudflared installed and authenticated with Cloudflare
- Root or sudo privileges
-
Clone this repository or download the setup script.
-
Run the script:
sudo bash setup.sh
⚠️ Please run the script via SSH and not on Cockpit.
- The script will prompt for:
- Public domain name
- Cloudflare Tunnel ID
- Cloudflare tunnel credentials JSON path
- Cloudflare origin certificate path
- LAN subnet to allow (default:
192.168.0.0/16)
- The script will:
- Backup existing configs (
cockpit.conf,config.yml, Nginx site) - Update
/etc/cockpit/cockpit.conf - Update
/etc/cloudflared/config.yml - Configure Nginx for both public and LAN access
- Restart Cockpit, Cloudflared, and Nginx
Cockpit config (/etc/cockpit/cockpit.conf):
[WebService]
TLS=false
ProtocolHeader=X-Forwarded-Proto
AllowUnencrypted=trueCloudflared config (/etc/cloudflared/config.yml):
tunnel: <TUNNEL-ID>
credentials-file: /etc/cloudflared/<TUNNEL-ID>.json
origincert: /etc/cloudflared/cert.pem
ingress:
- hostname: <your-domain>
service: http://localhost:9090
- service: http_status:404Nginx site (/etc/nginx/sites-available/cockpit):
# Public via Cloudflare
server {
listen 80;
server_name <your-domain>;
location / {
proxy_pass http://localhost:9090;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Port $server_port;
}
}
# LAN access
server {
listen 9091;
allow <LAN-SUBNET>;
deny all;
location / {
proxy_pass http://localhost:9090;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
}
}- TLS is offloaded to Cloudflare.
- Reverse proxy is separated. You're proxying through nginx for both CF and LAN.
⚠️ AllowUnencrypted=trueThis allows Cockpit to accept plaintext HTTP from Nginx/Cloudflared. Normally okay for localhost or private connections, but if misconfigured (bound to 0.0.0.0), you’d expose Cockpit unencrypted.
Mitigation: Ensure Cockpit only listens on localhost and traffic goes through Cloudflare/Nginx.
-
Nginx LAN blocklist is minimal
-
Cockpit relies on system user accounts + PAM. If those accounts are weakly secured (e.g., password-only, no MFA), it’s a potential risk.
Mitigation: Enforce SSH key logins, disable root login, enable MFA if possible.
Before you deploy this setup in production, review and apply the following security best practices:
-
Firewall Rules
-
Block direct access to Cockpit ports (
:9090,:9091) from external IPs. -
Allow these ports only from
localhostso that all external traffic passes through Nginx and Cloudflare. -
Example with UFW:
sudo ufw deny 9090 sudo ufw deny 9091 sudo ufw allow from 127.0.0.1 to any port 9090 sudo ufw allow from 127.0.0.1 to any port 9091
-
-
Cloudflared and Nginx Communication
- Ensure that
cloudflaredandnginxcan talk to each other locally. - No additional firewall rule is needed if both run on the same host.
- Ensure that
-
Unencrypted Cockpit Traffic
- The setting
AllowUnencrypted=trueis safe only if Cockpit is not exposed directly to the internet. - In this setup, Cockpit is behind Nginx and Cloudflare, so the traffic is encrypted externally.
- The setting
-
System Account Security
- Do not enable root login via Cockpit.
- Use strong passwords or SSH keys for all system accounts.
- Remove/disable unused accounts.
-
Cloudflare Zero Trust (Optional but Recommended)
- Configure Cloudflare Access rules to require identity provider login (Google, Microsoft, GitHub, etc.) before reaching Cockpit.
- This adds an additional layer of authentication beyond Cockpit’s own login system.
- LAN access is only allowed from the subnet defined during setup.
- TLS is handled by Cloudflare; Cockpit itself runs unencrypted locally.
- Original configuration files are backed up before being overwritten.
- Ensure Cloudflared service is active and running for public access.
- Verify Cockpit is running:
sudo systemctl status cockpit- Verify Cloudflared tunnel:
sudo systemctl status cloudflared- Verify Nginx configuration:
sudo nginx -t
sudo systemctl status nginx