Para facilitar a emissão de certificados do nginx no CloudPanel, esse script ajuda listando todos os sites ativos e, se configurados corretamente, permitem a emissão de certificados para seus domínios:
__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 <<< "$raw_domains"
local unique_domains=()
local -A seen_domains
seen_domains["$primary"]=1 # Mark primary as seen so it's excluded from SANs
# 3. Filter out catch-all '_', duplicates, and the primary domain itself
local d
for d in "${all_domains_arr[@]}"; do
if [[ -z "${seen_domains[$d]}" && "$d" != "_" ]]; then
seen_domains["$d"]=1
unique_domains+=("$d")
fi
done
local sans=""
local sans_display=""
if [ ${#unique_domains[@]} -gt 0 ]; then
sans=$(IFS=','; echo "${unique_domains[*]}")
sans_display=$(IFS=', '; echo "${unique_domains[*]}")
fi
# 4. Build the clpctl command
local cmd="clpctl lets-encrypt:install:certificate --domainName=$primary"
if [ -n "$sans" ]; then
cmd="$cmd --subjectAlternativeName=$sans"
fi
DOMAIN_CMD[$count]="$cmd"
printf " [\e[1;33m%2d\e[0m] \e[1;30mPrimary:\e[0m \e[1;32m%-30s\e[0m\n" "$count" "$primary"
[ -n "$sans_display" ] && printf " \e[1;30mAliases:\e[0m %s\n" "$sans_display"
printf " \e[1;30mFile:\e[0m %s\n" "$(basename "$file")"
echo "-----------------------------------------------------------"
((count++))
fi
done
if [ $count -eq 1 ]; then
echo "No valid vhosts found."
return
fi
echo ""
while read -r -t 0.1; do :; done < /dev/tty
local choice
read -p $'\e[1;37mEnter the number to generate SSL (or press Enter to cancel):\e[0m ' choice < /dev/tty
if [[ -n "$choice" && -n "${DOMAIN_CMD[$choice]}" ]]; then
echo -e "\n\e[1;32mRunning:\e[0m ${DOMAIN_CMD[$choice]}\n"
eval "${DOMAIN_CMD[$choice]}"
else
echo -e "\n\e[1;31mCanceled or invalid selection.\e[0m"
fi
}
__run_ssl_script
unset -f __run_ssl_scriptPadrões de vhost:
Sites padrão PHP:
### 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
}Sites padrão Reverse Proxy:
### 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
}Sites padrão Estático:
### 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
}Sites padrão Wordpress:
### 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
}Feito!