From 3225e8cbea0a10b4b32d20fe5c272da8df94ae73 Mon Sep 17 00:00:00 2001 From: Alexey Berezhok Date: Mon, 7 Oct 2024 23:21:17 +0300 Subject: [PATCH] Added proxy template for support proxy request from nginx to another service --- bin/v-add-web-domain-proxy | 14 +++-- bin/v-change-web-domain-proxy-tpl | 14 +++-- bin/v-list-web-domain | 16 +++-- bin/v-list-web-domains | 11 +++- func/domain.sh | 22 +++++++ install/rpm/templates/web/nginx/srvproxy.stpl | 60 +++++++++++++++++++ install/rpm/templates/web/nginx/srvproxy.tpl | 48 +++++++++++++++ web/edit/web/index.php | 15 ++++- web/js/src/editWebListeners.js | 13 ++++ web/templates/pages/edit_web.php | 13 ++++ 10 files changed, 206 insertions(+), 20 deletions(-) create mode 100644 install/rpm/templates/web/nginx/srvproxy.stpl create mode 100644 install/rpm/templates/web/nginx/srvproxy.tpl diff --git a/bin/v-add-web-domain-proxy b/bin/v-add-web-domain-proxy index 743f8ca..ffed9f3 100755 --- a/bin/v-add-web-domain-proxy +++ b/bin/v-add-web-domain-proxy @@ -1,6 +1,6 @@ #!/bin/bash # info: add webdomain proxy support -# options: USER DOMAIN [TEMPLATE] [EXTENTIONS] [RESTART] +# options: USER DOMAIN [TEMPLATE] [EXTENTIONS] [RESTART] [PORT] # # example: v-add-web-domain-proxy admin example.com # @@ -19,6 +19,7 @@ default_extentions="jpg,jpeg,gif,png,webp,ico,svg,css,zip,tgz,gz,rar,bz2,doc,xls exe,pdf,ppt,txt,odt,ods,odp,odf,tar,wav,bmp,rtf,js,mp3,avi,mpeg,flv,html,htm" extentions=${4-$default_extentions} restart="$5" +proxy_port_internal=${6-"0"} # Includes # shellcheck source=/etc/hestiacp/hestia.conf @@ -36,7 +37,7 @@ source_conf "$HESTIA/conf/hestia.conf" # Verifications # #----------------------------------------------------------# -check_args '2' "$#" 'USER DOMAIN [TEMPLATE] [EXTENTIONS] [RESTART]' +check_args '2' "$#" 'USER DOMAIN [TEMPLATE] [EXTENTIONS] [RESTART] [PORT]' is_format_valid 'user' 'domain' 'extentions' is_system_enabled "$PROXY_SYSTEM" 'PROXY_SYSTEM' is_object_valid 'user' 'USER' "$user" @@ -63,11 +64,12 @@ local_ip=$(get_real_ip "$IP") # Preparing domain values for the template substitution PROXY_EXT="$extentions" -add_web_config "$PROXY_SYSTEM" "$template.tpl" +PROXY_PORT_INTERNAL="$proxy_port_internal" +add_web_config "$PROXY_SYSTEM" "$template.tpl" "$PROXY_PORT_INTERNAL" # Adding proxy for ssl if [ "$SSL" = 'yes' ]; then - add_web_config "$PROXY_SYSTEM" "$template.stpl" + add_web_config "$PROXY_SYSTEM" "$template.stpl" "$PROXY_PORT_INTERNAL" fi #----------------------------------------------------------# @@ -77,12 +79,14 @@ fi # Update config update_object_value 'web' 'DOMAIN' "$domain" '$PROXY' "$template" update_object_value 'web' 'DOMAIN' "$domain" '$PROXY_EXT' "$extentions" +[ -z "$PROXY_PORT_INTERNAL" ] && add_object_key 'web' 'DOMAIN' "$domain" 'PROXY_PORT_INTERNAL' 'PROXY' +update_object_value 'web' 'DOMAIN' "$domain" '$PROXY_PORT_INTERNAL' "$proxy_port_internal" # Restarting web server $BIN/v-restart-proxy "$restart" check_result $? "Proxy restart failed" > /dev/null -$BIN/v-log-action "$user" "Info" "Web" "Proxy enabled (Domain: $domain)." +$BIN/v-log-action "$user" "Info" "Web" "Proxy enabled (Domain: $domain, Port: $proxy_port_internal)." log_event "$OK" "$ARGUMENTS" exit diff --git a/bin/v-change-web-domain-proxy-tpl b/bin/v-change-web-domain-proxy-tpl index ef2cee3..ef61b6e 100755 --- a/bin/v-change-web-domain-proxy-tpl +++ b/bin/v-change-web-domain-proxy-tpl @@ -1,6 +1,6 @@ #!/bin/bash # info: change web domain proxy template -# options: USER DOMAIN TEMPLATE [EXTENTIONS] [RESTART] +# options: USER DOMAIN TEMPLATE [EXTENTIONS] [RESTART] [PORT] # # example: v-change-web-domain-proxy-tpl admin domain.tld hosting # @@ -19,6 +19,7 @@ default_extentions="jpg,jpeg,gif,png,ico,svg,css,zip,tgz,gz,rar,bz2,doc,xls,\ exe,pdf,ppt,txt,odt,ods,odp,odf,tar,wav,bmp,rtf,js,mp3,avi,mpeg,flv,html,htm" extentions=${4-$default_extentions} restart="$5" +proxy_port_internal=${6-"0"} # Includes # shellcheck source=/etc/hestiacp/hestia.conf @@ -41,7 +42,7 @@ format_domain_idn # Verifications # #----------------------------------------------------------# -check_args '3' "$#" 'USER DOMAIN TEMPLATE [EXTENTIONS] [RESTART]' +check_args '3' "$#" 'USER DOMAIN TEMPLATE [EXTENTIONS] [RESTART] [PORT]' is_format_valid 'user' 'domain' 'template' is_system_enabled "$PROXY_SYSTEM" 'PROXY_SYSTEM' is_object_valid 'user' 'USER' "$user" @@ -71,11 +72,12 @@ fi # Add new vhost PROXY="$template" PROXY_EXT="$extentions" +PROXY_PORT_INTERNAL="$proxy_port_internal" prepare_web_domain_values -add_web_config "$PROXY_SYSTEM" "$PROXY.tpl" +add_web_config "$PROXY_SYSTEM" "$PROXY.tpl" "$PROXY_PORT_INTERNAL" if [ "$SSL" = 'yes' ]; then - add_web_config "$PROXY_SYSTEM" "$PROXY.stpl" + add_web_config "$PROXY_SYSTEM" "$PROXY.stpl" "$PROXY_PORT_INTERNAL" fi #----------------------------------------------------------# @@ -85,13 +87,15 @@ fi # Updating config update_object_value 'web' 'DOMAIN' "$domain" '$PROXY' "$PROXY" update_object_value 'web' 'DOMAIN' "$domain" '$PROXY_EXT' "$extentions" +[ -z "$PROXY_PORT_INTERNAL" ] && add_object_key 'web' 'DOMAIN' "$domain" 'PROXY_PORT_INTERNAL' 'PROXY' +update_object_value 'web' 'DOMAIN' "$domain" '$PROXY_PORT_INTERNAL' "$proxy_port_internal" # Restarting proxy $BIN/v-restart-proxy "$restart" check_result $? "Proxy restart failed" > /dev/null # Logging -$BIN/v-log-action "$user" "Info" "Web" "Proxy template changed (Domain: $domain, Template: $template)." +$BIN/v-log-action "$user" "Info" "Web" "Proxy template changed (Domain: $domain, Template: $template, Port: $proxy_port_internal)." log_event "$OK" "$ARGUMENTS" exit diff --git a/bin/v-list-web-domain b/bin/v-list-web-domain index 55d7a96..1b2f786 100755 --- a/bin/v-list-web-domain +++ b/bin/v-list-web-domain @@ -54,7 +54,8 @@ json_list() { "CUSTOM_DOCROOT": "'$CUSTOM_DOCROOT'", "SUSPENDED": "'$SUSPENDED'", "TIME": "'$TIME'", - "DATE": "'$DATE'" + "DATE": "'$DATE'", + "PROXY_PORT_INTERNAL": "'$PROXY_PORT_INTERNAL'" }' echo '}' } @@ -86,6 +87,7 @@ shell_list() { fi if [ -n "$PROXY_SYSTEM" ]; then echo "PROXY: $PROXY" + echo "PROXY_PORT_INTERNAL: $PROXY_PORT_INTERNAL" echo "PROXY EXT: ${PROXY_EXT//,/ }" fi if [ -n "$STATS" ]; then @@ -109,18 +111,18 @@ plain_list() { echo -ne "$DOMAIN\t$IP\t$IP6\t$DOCROOT\t$U_DISK\t$U_BANDWIDTH\t$TPL\t" echo -ne "$ALIAS\t$STATS\t$STATS_USER\t$SSL\t$SSL_FORCE\t$SSL_HSTS\t$SSL_HOME\t,$LETSENCRYPT" echo -ne "$FTP_USER\t$FTP_PATH\t$AUTH_USER\t$BACKEND\t$PROXY\t" - echo -e "$PROXY_EXT\t$SUSPENDED\t$TIME\t$DATE" + echo -e "$PROXY_EXT\t$SUSPENDED\t$TIME\t$DATE\t$PROXY_PORT_INTERNAL" } # CSV list function csv_list() { echo -n "DOMAIN,IP,IP6,DOCROOT,U_DISK,U_BANDWIDTH,TPL,ALIAS,STATS,STATS_USER,SSL," echo -n "SSL_FORCE,SSL_HSTS,SSL_HOME,LETSENCRYPT,FTP_USER,FTP_PATH,AUTH_USER,BACKEND,PROXY,PROXY_EXT," - echo "SUSPENDED,TIME,DATE" + echo "SUSPENDED,TIME,DATE,PROXY_PORT_INTERNAL" echo -n "$DOMAIN,$IP,$IP6,$DOCROOT,$U_DISK,$U_BANDWIDTH,$TPL,\"$ALIAS\",$STATS" echo -n "\"$STATS_USER\",$SSL,$SSL_FORCE,$SSL_HSTS,$SSL_HOME,$LETSENCRYPT,\"$FTP_USER\",\"$FTP_PATH\"," - echo -n "\"$AUTH_USER\",$BACKEND,$PROXY,\"$PROXY_EXT\",$SUSPENDED,$TIME," - echo "$DATE" + echo -n "\"$AUTH_USER\",$BACKEND,$PROXY,\"$PROXY_EXT\",$SUSPENDED,$TIME,$DATE," + echo "\"$PROXY_PORT_INTERNAL\"" } #----------------------------------------------------------# @@ -145,6 +147,10 @@ else DOCROOT="$HOMEDIR/$user/web/$DOMAIN/public_html/" fi +if [ -z "$PROXY_PORT_INTERNAL" ];then + PROXY_PORT_INTERNAL="0" +fi + # Listing data case $format in json) json_list ;; diff --git a/bin/v-list-web-domains b/bin/v-list-web-domains index 0cb683e..1f49abf 100755 --- a/bin/v-list-web-domains +++ b/bin/v-list-web-domains @@ -55,6 +55,7 @@ json_list() { "BACKEND": "'$BACKEND'", "PROXY": "'$PROXY'", "PROXY_EXT": "'$PROXY_EXT'", + "PROXY_PORT_INTERNAL": "'$PROXY_PORT_INTERNAL'", "SUSPENDED": "'$SUSPENDED'", "TIME": "'$TIME'", "DATE": "'$DATE'" @@ -94,7 +95,7 @@ plain_list() { echo -ne "$DOMAIN\t$IP\t$IP6\t$DOCROOT\t$U_DISK\t$U_BANDWIDTH\t$TPL\t" echo -ne "$ALIAS\t$STATS\t$STATS_USER\t$SSL\t$SSL_HOME\t$LETSENCRYPT\t" echo -ne "$FTP_USER\t$FTP_PATH\t$AUTH_USER\t$BACKEND\t$PROXY\t" - echo -e "$PROXY_EXT\t$SUSPENDED\t$TIME\t$DATE" + echo -e "$PROXY_EXT\t$PROXY_PORT_INTERNAL\t$SUSPENDED\t$TIME\t$DATE" done < <(cat $USER_DATA/web.conf) } @@ -103,7 +104,7 @@ csv_list() { IFS=$'\n' echo -n "DOMAIN,IP,IP6,DOCROOT,U_DISK,U_BANDWIDTH,TPL,ALIAS,STATS,STATS_USER," echo -n "SSL,SSL_HOME,LETSENCRYPT,FTP_USER,FTP_PATH,AUTH_USER,BACKEND,PROXY," - echo "PROXY_EXT,SUSPENDED,TIME,DATE" + echo "PROXY_EXT,PROXY_PORT_INTERNAL,SUSPENDED,TIME,DATE" while read str; do parse_object_kv_list "$str" # Set correct document root path @@ -115,7 +116,7 @@ csv_list() { echo -n "$DOMAIN,$IP,$IP6,$DOCROOT,$U_DISK,$U_BANDWIDTH,$TPL," echo -n "\"$ALIAS\",$STATS,\"$STATS_USER\",$SSL,$SSL_HOME,$LETSENCRYPT," echo -n "\"$FTP_USER\",\"$FTP_PATH\",\"$AUTH_USER\",$BACKEND,$PROXY," - echo "\"$PROXY_EXT\",$SUSPENDED,$TIME,$DATE" + echo "\"$PROXY_EXT\",\"$PROXY_PORT_INTERNAL\",$SUSPENDED,$TIME,$DATE" done < <(cat $USER_DATA/web.conf) } @@ -127,6 +128,10 @@ check_args '1' "$#" 'USER [FORMAT]' is_format_valid 'user' is_object_valid 'user' 'USER' "$user" +if [ -z "$PROXY_PORT_INTERNAL" ];then + PROXY_PORT_INTERNAL="0" +fi + #----------------------------------------------------------# # Action # #----------------------------------------------------------# diff --git a/func/domain.sh b/func/domain.sh index 298e592..a97b509 100644 --- a/func/domain.sh +++ b/func/domain.sh @@ -254,6 +254,20 @@ prepare_web_domain_values() { fi } +convert_proxy_ngix_internal_redirect(){ + proxy_port="$1" + if [[ "$proxy_port" =~ ^[0-9]+$ ]];then + echo "localhost:${proxy_port}" + return 0 + fi + if [[ "$proxy_port" =~ ^/ ]];then + echo "unix:${proxy_port}" + return 0 + fi + echo "localhost:9999" + return 1 +} + # Add web config add_web_config() { # Check if folder already exists @@ -316,6 +330,14 @@ add_web_config() { -e "s|%ssl_ca_str%|$ssl_ca_str|g" \ -e "s|%ssl_ca%|$ssl_ca|g" \ > $conf + + if [ "$2" == "srvproxy.tpl" -o "$2" == "srvproxy.stpl" ];then + proxy_backend_port_internal=$(convert_proxy_ngix_internal_redirect "$3") + cat "$conf" \ + | sed -e "s|%proxy_backend_srv_port%|$proxy_backend_port_internal|g" \ + > $conf.tmp + mv -f ${conf}.tmp $conf + fi process_http2_directive "$conf" diff --git a/install/rpm/templates/web/nginx/srvproxy.stpl b/install/rpm/templates/web/nginx/srvproxy.stpl new file mode 100644 index 0000000..bfcac40 --- /dev/null +++ b/install/rpm/templates/web/nginx/srvproxy.stpl @@ -0,0 +1,60 @@ +#=========================================================================# +# Default Web Domain Template # +# DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS # +# https://hestiacp.com/docs/server-administration/web-templates.html # +#=========================================================================# + +server { + listen %ip%:%proxy_ssl_port% ssl; + server_name %domain_idn% %alias_idn%; + root %sdocroot%; + index index.php index.html index.htm; + access_log /var/log/nginx/domains/%domain%.log combined; + access_log /var/log/nginx/domains/%domain%.bytes bytes; + error_log /var/log/nginx/domains/%domain%.error.log error; + + ssl_certificate %ssl_pem%; + ssl_certificate_key %ssl_key%; + ssl_stapling on; + ssl_stapling_verify on; + + # TLS 1.3 0-RTT anti-replay + if ($anti_replay = 307) { return 307 https://$host$request_uri; } + if ($anti_replay = 425) { return 425; } + + include %home%/%user%/conf/web/%domain%/nginx.hsts.conf*; + + location ~ /\.(?!well-known\/) { + deny all; + return 404; + } + + location / { + client_max_body_size 512M; + + proxy_max_temp_file_size 0; + proxy_read_timeout 120; + proxy_redirect off; + + proxy_set_header Host $http_host; + proxy_set_header Early-Data $rfc_early_data; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Real-IP $remote_addr; + + proxy_pass http://%proxy_backend_srv_port%; + } + + location /error/ { + alias %home%/%user%/web/%domain%/document_errors/; + } + + location /vstats/ { + alias %home%/%user%/web/%domain%/stats/; + include %home%/%user%/web/%domain%/stats/auth.conf*; + } + + proxy_hide_header Upgrade; + + include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*; +} diff --git a/install/rpm/templates/web/nginx/srvproxy.tpl b/install/rpm/templates/web/nginx/srvproxy.tpl new file mode 100644 index 0000000..e13b085 --- /dev/null +++ b/install/rpm/templates/web/nginx/srvproxy.tpl @@ -0,0 +1,48 @@ +#=========================================================================# +# Default Web Domain Template # +# DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS # +# https://hestiacp.com/docs/server-administration/web-templates.html # +#=========================================================================# + +server { + listen %ip%:%proxy_port%; + server_name %domain_idn% %alias_idn%; + root %docroot%; + index index.php index.html index.htm; + access_log /var/log/nginx/domains/%domain%.log combined; + access_log /var/log/nginx/domains/%domain%.bytes bytes; + error_log /var/log/nginx/domains/%domain%.error.log error; + + include %home%/%user%/conf/web/%domain%/nginx.forcessl.conf*; + + location ~ /\.(?!well-known\/) { + deny all; + return 404; + } + + location / { + client_max_body_size 512M; + + proxy_max_temp_file_size 0; + proxy_read_timeout 120; + proxy_redirect off; + + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Real-IP $remote_addr; + + proxy_pass http://%proxy_backend_srv_port%; + } + + location /error/ { + alias %home%/%user%/web/%domain%/document_errors/; + } + + location /vstats/ { + alias %home%/%user%/web/%domain%/stats/; + include %home%/%user%/web/%domain%/stats/auth.conf*; + } + + include %home%/%user%/conf/web/%domain%/nginx.conf_*; +} diff --git a/web/edit/web/index.php b/web/edit/web/index.php index 9aea5af..6253887 100644 --- a/web/edit/web/index.php +++ b/web/edit/web/index.php @@ -83,6 +83,7 @@ if (empty($v_nginx_cache_duration)) { $v_proxy = $data[$v_domain]["PROXY"]; $v_proxy_template = $data[$v_domain]["PROXY"]; $v_proxy_ext = str_replace(",", ", ", $data[$v_domain]["PROXY_EXT"]); +$v_proxy_port = $data[$v_domain]["PROXY_PORT_INTERNAL"]; $v_stats = $data[$v_domain]["STATS"]; $v_stats_user = $data[$v_domain]["STATS_USER"]; $v_stats_password = ""; @@ -422,6 +423,9 @@ if (!empty($_POST["save"])) { if (!empty($_POST["v_proxy_template"])) { $v_proxy_template = $_POST["v_proxy_template"]; } + if (!empty($_POST["v_proxy_port"])) { + $v_proxy_port = $_POST["v_proxy_port"]; + } exec( HESTIA_CMD . "v-change-web-domain-proxy-tpl " . @@ -432,7 +436,9 @@ if (!empty($_POST["save"])) { quoteshellarg($v_proxy_template) . " " . quoteshellarg($ext) . - " 'no'", + " 'no'" . + " " . + quoteshellarg($v_proxy_port), $output, $return_var, ); @@ -459,6 +465,9 @@ if (!empty($_POST["save"])) { $ext = str_replace(" ", ",", $ext); $v_proxy_ext = str_replace(",", ", ", $ext); } + if (!empty($_POST["v_proxy_port"])) { + $v_proxy_port = $_POST["v_proxy_port"]; + } exec( HESTIA_CMD . "v-add-web-domain-proxy " . @@ -469,7 +478,9 @@ if (!empty($_POST["save"])) { quoteshellarg($v_proxy_template) . " " . quoteshellarg($ext) . - " 'no'", + " 'no'" . + " " . + quoteshellarg($v_proxy_port), $output, $return_var, ); diff --git a/web/js/src/editWebListeners.js b/web/js/src/editWebListeners.js index f49622b..4d3cf1f 100644 --- a/web/js/src/editWebListeners.js +++ b/web/js/src/editWebListeners.js @@ -53,6 +53,7 @@ export default function handleEditWebListeners() { // show "Purge Nginx Cache" button if "caching" selected const proxyTemplateSelect = document.querySelector('.js-proxy-template-select'); const clearCacheButton = document.querySelector('.js-clear-cache-button'); + const proxyConnect = document.querySelector('.js-proxy-connect') if (proxyTemplateSelect && clearCacheButton) { proxyTemplateSelect.addEventListener('change', () => { // NOTE: Match "caching" and "caching-*" values @@ -63,4 +64,16 @@ export default function handleEditWebListeners() { } }); } + if (proxyTemplateSelect && proxyConnect) { + proxyTemplateSelect.addEventListener('change', () => { + if (proxyTemplateSelect.value === "srvproxy") { + proxyConnect.style.display = 'block'; + } else { + proxyConnect.style.display = 'none'; + } + }); + } + if (proxyTemplateSelect.value === "srvproxy") { + proxyConnect.style.display = 'block'; + } } diff --git a/web/templates/pages/edit_web.php b/web/templates/pages/edit_web.php index 97e316e..9dcf352 100644 --- a/web/templates/pages/edit_web.php +++ b/web/templates/pages/edit_web.php @@ -347,6 +347,19 @@ ?> +
"> +
+ + +
+