Files
cdn-setup-varnish-nginx/setup-cdn.sh
2025-02-23 13:55:35 +00:00

199 lines
5.5 KiB
Bash

#!/bin/bash
# Ensure the script is run as root
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root. Use sudo."
exit 1
fi
# Function to generate a random alphanumeric string
generate_random_string() {
tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 10 | head -n 1
}
# Function to install CDN setup
install_cdn() {
if ! command -v varnishd &> /dev/null || ! command -v nginx &> /dev/null; then
echo "Varnish and/or Nginx are not installed. Please install them first."
exit 1
fi
read -p "Enter your domain (e.g. domain.com): " domain
read -p "Enter your subdomain (e.g. cdn): " subdomain
cdn_subdomain="${subdomain}.${domain}"
if ! (host "${domain}" > /dev/null 2>&1); then
echo "Invalid domain or not reachable. Please check your domain."
exit 1
fi
subdomain_ip=$(dig +short "${cdn_subdomain}")
server_ip=$(curl -s ifconfig.me)
if [[ "${subdomain_ip}" != "${server_ip}" ]]; then
echo "The subdomain's IP address does not match the server's IP address. Update the DNS record for ${cdn_subdomain}."
exit 1
fi
read -p "Does the source domain (${domain}) use SSL (HTTPS)? (yes/no): " use_ssl
if [[ "${use_ssl,,}" == "yes" ]]; then
backend_port="443"
backend_proto="https"
else
backend_port="80"
backend_proto="http"
fi
read -p "Enter the cache time in hours (e.g. 24): " cache_time
cache_time_seconds=$((cache_time * 3600))
purge_subdomain="$(generate_random_string).${cdn_subdomain}"
cat > /etc/varnish/${domain}.vcl << EOF
vcl 4.0;
backend default {
.host = "${domain}";
.port = "${backend_port}";
.ssl = ${backend_proto} == "https";
}
sub vcl_recv {
if (req.url ~ "\\.(jpg|jpeg|png|gif)$") {
unset req.http.cookie;
} else {
return (pass);
}
if (req.method == "PURGE" && req.http.host == "${purge_subdomain}") {
return (purge);
}
}
sub vcl_backend_response {
if (bereq.url ~ "\\.(jpg|jpeg|png|gif)$") {
set beresp.ttl = ${cache_time_seconds}s;
set beresp.http.Cache-Control = "public, max-age=${cache_time_seconds}";
}
}
sub vcl_deliver {
unset resp.http.X-Varnish;
}
EOF
include_line="include \"/etc/varnish/${domain}.vcl\";"
if ! grep -Fxq "$include_line" /etc/varnish/default.vcl; then
echo "$include_line" >> /etc/varnish/default.vcl
fi
cat > /etc/nginx/sites-available/${cdn_subdomain} << EOF
server {
listen 80;
server_name ${cdn_subdomain};
location / {
proxy_pass http://127.0.0.1:8080;
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;
}
}
server {
listen 80;
server_name ${purge_subdomain};
location / {
proxy_pass http://127.0.0.1:8080;
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;
}
}
EOF
ln -sf /etc/nginx/sites-available/${cdn_subdomain} /etc/nginx/sites-enabled/
systemctl restart varnish || { echo "Failed to restart Varnish."; exit 1; }
systemctl restart nginx || { echo "Failed to restart Nginx."; exit 1; }
read -p "Enter your email for Let's Encrypt notifications: " email
read -p "Press enter to continue once the DNS record is set up and propagated..."
certbot certonly --nginx -d ${cdn_subdomain} --agree-tos --no-eff-email --email ${email} || { echo "Certbot failed."; exit 1; }
cat > /etc/nginx/sites-available/${cdn_subdomain} << EOF
server {
listen 80;
server_name ${cdn_subdomain};
return 301 https://\\$host\\$request_uri;
}
server {
listen 443 ssl;
server_name ${cdn_subdomain};
ssl_certificate /etc/letsencrypt/live/${cdn_subdomain}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${cdn_subdomain}/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
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;
}
}
server {
listen 80;
server_name ${purge_subdomain};
location / {
proxy_pass http://127.0.0.1:8080;
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;
}
}
EOF
systemctl reload nginx || { echo "Failed to reload Nginx."; exit 1; }
echo "CDN setup for ${cdn_subdomain} is complete."
echo "Purge subdomain: ${purge_subdomain}"
}
uninstall_cdn() {
read -p "Enter the domain to uninstall (e.g. domain.com): " domain
read -p "Enter the subdomain to uninstall (e.g. cdn): " subdomain
cdn_subdomain="${subdomain}.${domain}"
rm -f /etc/nginx/sites-available/${cdn_subdomain}
rm -f /etc/nginx/sites-enabled/${cdn_subdomain}
rm -f /etc/varnish/${domain}.vcl
sed -i "/include \\\"\\/etc\\/varnish\\/${domain}\\.vcl\\";/d" /etc/varnish/default.vcl || { echo "Failed to update Varnish config."; exit 1; }
systemctl restart nginx || { echo "Failed to restart Nginx."; exit 1; }
systemctl restart varnish || { echo "Failed to restart Varnish."; exit 1; }
echo "CDN setup for ${cdn_subdomain} has been removed."
}
case "$1" in
-i|--install)
install_cdn
;;
-u|--uninstall)
uninstall_cdn
;;
*)
echo "Usage: $0 {-i|--install} | {-u|--uninstall}"
exit 1
;;
esac