To facilitate the issuance of nginx certificates in CloudPanel, this script helps by listing all active sites and, if properly configured, allows certificate issuance for your domains:
__run_ssl_script() {
local VHOST_DIR="/etc/nginx/sites-enabled"
local files=("${VHOST_DIR}"/*.conf)
local count=1
local -A DOMAIN_CMD
clear
echo -e "\n\e[1;34mScanning $VHOST_DIR for vhosts...\e[0m"
echo "==========================================================="
for file in "${files[@]}"; do
[ -e "$file" ] || continue
# 1. Primary domain MUST match the CloudPanel site name (filename without .conf)
local primary
primary=$(basename "$file" .conf)
# Ignore default configs or non-domain files
if [[ "$primary" == "default" || "$primary" == "custom-domain" ]]; then
continue
fi
# 2. Grab ALL server_name lines from the file
local raw_domains
raw_domains=$(awk '/^[ \t]*server_name[ \t]/ {gsub(/;/, ""); gsub(/\r/, ""); gsub(/^[ \t]*server_name[ \t]+/, ""); printf "%s ", $0}' "$file")
if [ -n "$raw_domains" ]; then
local all_domains_arr
read -ra all_domains_arr Vhost Patterns:
Default PHP sites:
### BEGIN Only needed for environment with more than one server_name
server {
listen 443 quic;
listen 443 ssl;
listen [::]:443 quic;
listen [::]:443 ssl;
http2 on;
http3 on;
{{ssl_certificate_key}}
{{ssl_certificate}}
server_name www.-default-php.example;
return 301 https://-default-php.example$request_uri;
}
### END Only needed for environment with more than one server_name
server {
listen 443 quic;
listen 443 ssl;
listen [::]:443 quic;
listen [::]:443 ssl;
http2 on;
http3 on;
server_name -default-php.example;
{{ssl_certificate_key}}
{{ssl_certificate}}
{{root}}
{{nginx_access_log}}
{{nginx_error_log}}
{{settings}}
index index.php index.html index.htm;
### BEGIN Includes global security headers and specific .well-known endpoints
include /etc/nginx/global_settings;
### END Includes global security headers and specific .well-known endpoints
### BEGIN Fix to improve app capabilities if needed
# add_header Cache-Control no-transform;
# client_max_body_size 256M;
### END Fix to improve app capabilities if needed
### BEGIN General .well-known handling
location /.well-known/ {
auth_basic off;
allow all;
}
### END General .well-known handling
### BEGIN Optional: Prevent PHP execution in custom upload folders
# location ~* ^/(uploads|storage|media)/.*\.php$ {
# deny all;
# }
### END Optional upload security
### BEGIN Main Front Controller
location / {
try_files $uri $uri/ /index.php?$args;
}
### END Main Front Controller
### BEGIN Static Assets Processing & Caching
location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|woff2|eot|mp4|ogg|ogv|webm|webp|zip|swf|map)$ {
include /etc/nginx/security_headers;
add_header Access-Control-Allow-Origin "*" always;
add_header Cache-Control "max-age=2592000, public, no-transform" always;
access_log off;
log_not_found off;
expires 30d;
}
### END Static Assets Processing & Caching
### BEGIN General PHP Processing
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS "on";
fastcgi_param SERVER_PORT 443;
fastcgi_read_timeout 300;
fastcgi_send_timeout 300;
fastcgi_pass 127.0.0.1:{{php_fpm_port}};
fastcgi_param PHP_VALUE "{{php_settings}}";
}
### END General PHP Processing
}Default Reverse Proxy sites:
### BEGIN Only needed for environment with more than one server_name
server {
listen 443 quic;
listen 443 ssl;
listen [::]:443 quic;
listen [::]:443 ssl;
http2 on;
http3 on;
{{ssl_certificate_key}}
{{ssl_certificate}}
server_name www.-default-reverse.example;
return 301 https://-default-reverse.example$request_uri;
}
### END Only needed for environment with more than one server_name
server {
listen 443 quic;
listen 443 ssl;
listen [::]:443 quic;
listen [::]:443 ssl;
http2 on;
http3 on;
server_name -default-reverse.example;
{{ssl_certificate_key}}
{{ssl_certificate}}
{{root}}
{{nginx_access_log}}
{{nginx_error_log}}
{{settings}}
### BEGIN Includes global security headers and specific .well-known endpoints
include /etc/nginx/global_settings;
### END Includes global security headers and specific .well-known endpoints
### BEGIN Fix to improve reversed app capabilities if needed
# add_header Cache-Control no-transform;
# client_max_body_size 256M;
### END Fix to improve reversed app capabilities if needed
### BEGIN General .well-known handling
location /.well-known/ {
auth_basic off;
allow all;
try_files $uri @reverse_proxy;
}
### END General .well-known handling
### BEGIN Main Front Controller
location / {
try_files $uri @reverse_proxy;
}
### END Main Front Controller
### BEGIN General Reverse Proxy Destination
location @reverse_proxy {
proxy_pass {{reverse_proxy_url}};
proxy_http_version 1.1;
# Standard Proxy Headers
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 X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
# WebSocket Support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Upstream SSL SNI support
proxy_ssl_server_name on;
proxy_ssl_name $host;
proxy_pass_request_headers on;
# Long Execution Timeouts
proxy_connect_timeout 900;
proxy_send_timeout 900;
proxy_read_timeout 900;
# Real-Time SSE & Streaming Fixes (uncomment them for SSE, Real-Time Streaming apps)
# proxy_buffering off;
# proxy_cache off;
# proxy_max_temp_file_size 0;
# chunked_transfer_encoding on;
# gzip off;
}
### END General Reverse Proxy Destination
}Default Static sites:
### BEGIN Only needed for environment with more than one server_name
server {
listen 443 quic;
listen 443 ssl;
listen [::]:443 quic;
listen [::]:443 ssl;
http2 on;
http3 on;
{{ssl_certificate_key}}
{{ssl_certificate}}
server_name www.-default-static.example;
return 301 https://-default-static.example$request_uri;
}
### END Only needed for environment with more than one server_name
server {
listen 443 quic;
listen 443 ssl;
listen [::]:443 quic;
listen [::]:443 ssl;
http2 on;
http3 on;
server_name -default-static.example;
{{ssl_certificate_key}}
{{ssl_certificate}}
{{root}}
{{nginx_access_log}}
{{nginx_error_log}}
{{settings}}
index index.html index.htm;
### BEGIN Includes global security headers and specific .well-known endpoints
include /etc/nginx/global_settings;
### END Includes global security headers and specific .well-known endpoints
### BEGIN General .well-known handling
location /.well-known/ {
auth_basic off;
allow all;
}
### END General .well-known handling
### BEGIN Main Routing
location / {
# Standard static site behavior (returns 404 if file or directory does not exist):
try_files $uri $uri/ =404;
# FOR SPAs (React, Vue, Angular, Svelte) - Uncomment the line below & comment the one above:
# try_files $uri $uri/ /index.html;
}
### END Main Routing
### BEGIN Static Assets Processing & Caching
location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|woff2|eot|mp4|ogg|ogv|webm|webp|zip|swf|map|html|htm)$ {
include /etc/nginx/security_headers;
add_header Access-Control-Allow-Origin "*" always;
add_header Cache-Control "max-age=2592000, public, no-transform" always;
access_log off;
log_not_found off;
expires 30d;
}
### END Static Assets Processing & Caching
### BEGIN Security: Explicitly block any accidental PHP file execution
location ~ \.php$ {
return 404;
}
### END Security
}Default Wordpress sites:
### BEGIN Only needed for environment with more than one server_name
server {
listen 443 quic;
listen 443 ssl;
listen [::]:443 quic;
listen [::]:443 ssl;
http2 on;
http3 on;
{{ssl_certificate_key}}
{{ssl_certificate}}
server_name www.-default-wordpress.example;
return 301 https://-default-wordpress.example$request_uri;
}
### END Only needed for environment with more than one server_name
server {
listen 443 quic;
listen 443 ssl;
listen [::]:443 quic;
listen [::]:443 ssl;
http2 on;
http3 on;
server_name -default-wordpress.example;
{{ssl_certificate_key}}
{{ssl_certificate}}
{{root}}
{{nginx_access_log}}
{{nginx_error_log}}
{{settings}}
index index.php index.html;
### BEGIN Includes global security headers and specific .well-known endpoints
include /etc/nginx/global_settings;
### END Includes global security headers and specific .well-known endpoints
### BEGIN Fix to improve app capabilities if needed
# add_header Cache-Control no-transform;
# client_max_body_size 256M;
### END Fix to improve app capabilities if needed
### BEGIN General .well-known handling for this proxy site
location /.well-known/ {
auth_basic off;
allow all;
}
### END General .well-known handling for this proxy site
### BEGIN Prevent PHP execution in uploads directory (Security Hardening)
location ~* ^/wp-content/uploads/.*\.php$ {
deny all;
}
### END Prevent PHP execution in uploads directory
### BEGIN WordPress Multisite Subdirectory Rewrites (uncomment to use MU Subdirectory)
# if (!-e $request_filename) {
# rewrite /wp-admin$ $scheme://$host$uri/ permanent;
# rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last;
# rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last;
# }
### END WordPress Multisite Subdirectory Rewrites
### BEGIN Main Front Controller
location / {
try_files $uri $uri/ /index.php?$args;
}
### END Main Front Controller
### BEGIN Static Assets Processing & Caching
location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|woff2|eot|mp4|ogg|ogv|webm|webp|zip|swf|map)$ {
# Subdirectory multisite static path (uncomment to use MU Subdirectory)
# rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 break;
# Re-include global security headers to avoid Nginx header inheritance wiping
include /etc/nginx/security_headers;
add_header Access-Control-Allow-Origin "*" always;
add_header Cache-Control "max-age=2592000, public, no-transform" always;
access_log off;
log_not_found off;
expires 30d;
}
### END Static Assets Processing & Caching
### BEGIN WP-Admin & Login PHP (Extended 1-hour timeout for heavy tasks/updates)
location ~* ^/(wp-admin/.*\.php|wp-login\.php)$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS "on";
fastcgi_param SERVER_PORT 443;
fastcgi_read_timeout 3600;
fastcgi_send_timeout 3600;
fastcgi_pass 127.0.0.1:{{php_fpm_port}};
fastcgi_param PHP_VALUE "{{php_settings}}";
}
### END WP-Admin & Login PHP
### BEGIN General PHP Processing (5-minute timeout)
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS "on";
fastcgi_param SERVER_PORT 443;
fastcgi_read_timeout 300;
fastcgi_send_timeout 300;
fastcgi_pass 127.0.0.1:{{php_fpm_port}};
fastcgi_param PHP_VALUE "{{php_settings}}";
}
### END General PHP Processing
}Done!