Skip to content

Instantly share code, notes, and snippets.

@Dviros
Last active October 21, 2024 06:32
Show Gist options
  • Select an option

  • Save Dviros/c2beb7fbcf80c3a1c2374bb24da1b5b6 to your computer and use it in GitHub Desktop.

Select an option

Save Dviros/c2beb7fbcf80c3a1c2374bb24da1b5b6 to your computer and use it in GitHub Desktop.
Homeassistant and Cloudflared tunnel!
#!/bin/bash
# motivation for this script came after I found out that the official add in is not supported in Docker based installations, such as Core.
# after a long time of making it work, I created this script that will allow anyone with a Cloudflare managed domain to have this setup as well.
# please review the IP's and domains mentioned for your own setup, make the relevant adjustments if needed.
# feedback and ideas are highly appreciated
# Exit on any error
set -e
# Function to check if a command was successful
check_success() {
if [ $? -ne 0 ]; then
echo "Error: $1"
exit 1
fi
}
# Update and install cloudflared and nginx
sudo apt update
sudo apt install -y cloudflared nginx
check_success "Failed to install cloudflared and nginx"
# Cloudflared login (this step might require manual intervention)
cloudflared login
check_success "Failed to login to cloudflared"
# Create tunnel and set DNS
TUNNEL_NAME="homeassistant-tunnel"
DOMAIN="ha.mydomain.com" # Replace with your actual domain
TUNNEL_OUTPUT=$(cloudflared tunnel create $TUNNEL_NAME)
TUNNEL_ID=$(echo "$TUNNEL_OUTPUT" | grep -oP 'Created tunnel \K[a-z0-9-]+')
check_success "Failed to create tunnel"
cloudflared tunnel route dns $TUNNEL_ID $DOMAIN
check_success "Failed to set DNS route"
# Create Cloudflared config
cat << EOF > ~/.cloudflared/config.yml
tunnel: $TUNNEL_ID
credentials-file: /home/user/.cloudflared/$TUNNEL_ID.json
ingress:
- hostname: $DOMAIN
service: http://localhost:80
- service: http_status:404
EOF
# Update Home Assistant configuration
HA_CONFIG="/home/homeassistant/.homeassistant/configuration.yaml"
cat << EOF >> $HA_CONFIG
http:
server_port: 8443
ssl_certificate: /ssl/selfsigned.crt
ssl_key: /ssl/selfsigned.key
server_host: 127.0.0.1
use_x_forwarded_for: true
trusted_proxies:
- 127.0.0.1
- ::1
- 10.10.12.9
- 173.245.48.0/20
- 103.21.244.0/22
- 103.22.200.0/22
- 103.31.4.0/22
- 141.101.64.0/18
- 108.162.192.0/18
- 190.93.240.0/20
- 188.114.96.0/20
- 197.234.240.0/22
- 198.41.128.0/17
- 162.158.0.0/15
- 104.16.0.0/13
- 104.24.0.0/14
- 172.64.0.0/13
- 131.0.72.0/22
- 2400:cb00::/32
- 2606:4700::/32
- 2803:f800::/32
- 2405:b500::/32
- 2405:8100::/32
- 2a06:98c0::/29
- 2c0f:f248::/32
EOF
# Create OpenSSL config
cat << EOF > /home/user/openssl.cnf
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
CN = $DOMAIN
[v3_req]
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = $DOMAIN
DNS.2 = localhost
IP.1 = 127.0.0.1
IP.2 = <change to your lan IP>
EOF
# Generate self-signed certificate
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /home/user/.cloudflared/selfsigned.key \
-out /home/user/.cloudflared/selfsigned.crt \
-config /home/user/openssl.cnf
# Set correct permissions
sudo chmod 644 /home/user/.cloudflared/selfsigned.crt
sudo chmod 600 /home/user/.cloudflared/selfsigned.key
# Copy certificate to system-wide location
sudo cp /home/user/.cloudflared/selfsigned.crt /etc/ssl/certs/ha_legit_place.crt
# Update Cloudflared service
CLOUDFLARED_SERVICE="/etc/systemd/system/cloudflared.service"
if [ -f "$CLOUDFLARED_SERVICE" ]; then
sudo sed -i '/^\[Service\]/a Environment="GODEBUG=x509ignoreCN=0"\nEnvironment="SSL_CERT_FILE=/etc/ssl/certs/ha_legit_place.crt"' $CLOUDFLARED_SERVICE
else
echo "Cloudflared service file not found. Please create it manually."
fi
# Create Nginx configuration for Home Assistant
cat << EOF | sudo tee /etc/nginx/sites-available/home-assistant
server {
listen 80;
server_name ha.local;
location / {
proxy_pass https://127.0.0.1:8443;
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;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
}
location /api/websocket {
proxy_pass https://127.0.0.1:8443/api/websocket;
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 Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
}
}
EOF
# Enable the Nginx configuration
sudo ln -s /etc/nginx/sites-available/home-assistant /etc/nginx/sites-enabled/
# Remove default Nginx site
sudo rm -f /etc/nginx/sites-enabled/default
# Test Nginx configuration
sudo nginx -t
check_success "Nginx configuration test failed"
# Restart services
sudo systemctl daemon-reload
sudo systemctl restart cloudflared
sudo systemctl restart nginx
sudo systemctl restart home-assistant
echo "Setup completed successfully!"
echo "Please add the following line to your local machine's /etc/hosts file:"
echo "<IP ADDRESS> ha.local # Replace with your Raspberry Pi's IP if different"
echo "Then, you should be able to access Home Assistant at http://ha.local"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment