mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
feature: new global setting options to enable SNI-forward to external domains to cover cases where YunoHost is hosted behind a VPN or to host several servers behind the same IP
This commit is contained in:
parent
465f6da5cd
commit
4fd41688c0
7 changed files with 109 additions and 0 deletions
|
@ -39,8 +39,12 @@ server {
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
|
{% if sni_forward_enabled != "True" %}
|
||||||
listen 443 ssl http2;
|
listen 443 ssl http2;
|
||||||
listen [::]:443 ssl http2;
|
listen [::]:443 ssl http2;
|
||||||
|
{% else %}
|
||||||
|
listen 127.0.0.1:443 ssl http2;
|
||||||
|
{% endif %}
|
||||||
server_name {{ domain }};
|
server_name {{ domain }};
|
||||||
|
|
||||||
include /etc/nginx/conf.d/security.conf.inc;
|
include /etc/nginx/conf.d/security.conf.inc;
|
||||||
|
|
27
conf/nginx/sni_forward.conf
Normal file
27
conf/nginx/sni_forward.conf
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{% set domain_ip_map = sni_forward_list.split(',') %}
|
||||||
|
stream {
|
||||||
|
|
||||||
|
map $ssl_preread_server_name $name {
|
||||||
|
{% for domain_ip in domain_ip_map %}
|
||||||
|
{{ domain_ip.split(":")[0] }} {{ domain_ip.split(":")[0].replace('.', '') }};
|
||||||
|
{% endfor %}
|
||||||
|
default https_default_backend;
|
||||||
|
}
|
||||||
|
|
||||||
|
{% for domain_ip in domain_ip_map %}
|
||||||
|
upstream {{ domain_ip.split(":")[0].replace('.', '') }} {
|
||||||
|
server {{ domain_ip.split(":")[1] }}:443;
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
upstream https_default_backend {
|
||||||
|
server 127.0.0.1:443;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443;
|
||||||
|
listen [::]:443;
|
||||||
|
proxy_pass $name;
|
||||||
|
ssl_preread on;
|
||||||
|
}
|
||||||
|
}
|
38
conf/nginx/sni_forward_server.conf
Normal file
38
conf/nginx/sni_forward_server.conf
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# This snippet is only here to redirect traffic to another domain on port 80,
|
||||||
|
# which is also forwarded for port 443 based on the SNI (which is handled
|
||||||
|
# differently because of the whole SNI story)
|
||||||
|
|
||||||
|
# We don't explicitly redirect to HTTPS by default and let the forwarded server
|
||||||
|
# handle the redirection (or not depending on what's configured on the other
|
||||||
|
# server)
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name {{ sni_forward_domain }};
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://{{ sni_forward_ip }};
|
||||||
|
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Forwarded-Host $http_host;
|
||||||
|
proxy_set_header X-Forwarded-Uri $request_uri;
|
||||||
|
proxy_set_header X-Forwarded-Ssl on;
|
||||||
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header Connection "";
|
||||||
|
|
||||||
|
real_ip_header X-Forwarded-For;
|
||||||
|
real_ip_recursive on;
|
||||||
|
|
||||||
|
send_timeout 5m;
|
||||||
|
proxy_read_timeout 360;
|
||||||
|
proxy_send_timeout 360;
|
||||||
|
proxy_connect_timeout 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
access_log /var/log/nginx/{{ sni_forward_domain }}-access.log;
|
||||||
|
error_log /var/log/nginx/{{ sni_forward_domain }}-error.log;
|
||||||
|
}
|
|
@ -68,6 +68,23 @@ do_pre_regen() {
|
||||||
export redirect_to_https="$(yunohost settings get 'security.nginx.nginx_redirect_to_https' | int_to_bool)"
|
export redirect_to_https="$(yunohost settings get 'security.nginx.nginx_redirect_to_https' | int_to_bool)"
|
||||||
export compatibility="$(yunohost settings get 'security.nginx.nginx_compatibility')"
|
export compatibility="$(yunohost settings get 'security.nginx.nginx_compatibility')"
|
||||||
export experimental="$(yunohost settings get 'security.experimental.security_experimental_enabled' | int_to_bool)"
|
export experimental="$(yunohost settings get 'security.experimental.security_experimental_enabled' | int_to_bool)"
|
||||||
|
export sni_forward_enabled="$(yunohost settings get 'misc.sni_forward.sni_forward_enabled' | int_to_bool)"
|
||||||
|
export sni_forward_list="$(yunohost settings get 'misc.sni_forward.sni_forward_list')"
|
||||||
|
|
||||||
|
local sni_module="${pending_dir}/etc/nginx/modules-enabled/sni_forward.conf"
|
||||||
|
if [[ "$sni_forward_enabled" == "True" ]]
|
||||||
|
then
|
||||||
|
ynh_render_template "sni_forward.conf" "${sni_module}"
|
||||||
|
for sni_forward_domain_and_ip in $(echo "$sni_forward_list" | sed 's/,/\n/g')
|
||||||
|
do
|
||||||
|
export sni_forward_domain=$(echo $sni_forward_domain_and_ip | awk -F: '{print $1}')
|
||||||
|
export sni_forward_ip=$(echo $sni_forward_domain_and_ip | awk -F: '{print $2}')
|
||||||
|
ynh_render_template "sni_forward_server.conf" "${nginx_conf_dir}/${sni_forward_domain}.forward80.conf"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
touch "${sni_module}"
|
||||||
|
fi
|
||||||
|
|
||||||
ynh_render_template "security.conf.inc" "${nginx_conf_dir}/security.conf.inc"
|
ynh_render_template "security.conf.inc" "${nginx_conf_dir}/security.conf.inc"
|
||||||
|
|
||||||
cert_status=$(yunohost domain cert status --json)
|
cert_status=$(yunohost domain cert status --json)
|
||||||
|
@ -128,6 +145,8 @@ do_pre_regen() {
|
||||||
|| touch "${nginx_conf_dir}/${file}"
|
|| touch "${nginx_conf_dir}/${file}"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# FIXME : also add the .forward80 files
|
||||||
|
|
||||||
# remove old mail-autoconfig files
|
# remove old mail-autoconfig files
|
||||||
autoconfig_files=$(ls -1 /var/www/.well-known/*/autoconfig/mail/config-v1.1.xml 2>/dev/null || true)
|
autoconfig_files=$(ls -1 /var/www/.well-known/*/autoconfig/mail/config-v1.1.xml 2>/dev/null || true)
|
||||||
for file in $autoconfig_files; do
|
for file in $autoconfig_files; do
|
||||||
|
|
|
@ -424,6 +424,10 @@
|
||||||
"firewall_rules_cmd_failed": "Some firewall rule commands have failed. More info in log.",
|
"firewall_rules_cmd_failed": "Some firewall rule commands have failed. More info in log.",
|
||||||
"global_settings_reset_success": "Reset global settings",
|
"global_settings_reset_success": "Reset global settings",
|
||||||
"global_settings_setting_admin_strength": "Admin password strength requirements",
|
"global_settings_setting_admin_strength": "Admin password strength requirements",
|
||||||
|
"global_settings_setting_sni_forward_enabled": "Enable SNI-based forwarding",
|
||||||
|
"global_settings_setting_sni_forward_enabled_help": "This is an advanced feature to reverse-proxy an entire domain to another machine *without* decrypting the traffic. Useful when you want to expose several machines behind the same IP but still allow each machine to handle the SSL termination.",
|
||||||
|
"global_settings_setting_sni_forward_list": "List of forwarding",
|
||||||
|
"global_settings_setting_sni_forward_list_help": "Should be a list of DOMAIN:IPv4, such as domain.tld:1.2.3.4",
|
||||||
"global_settings_setting_admin_strength_help": "These requirements are only enforced when initializing or changing the password",
|
"global_settings_setting_admin_strength_help": "These requirements are only enforced when initializing or changing the password",
|
||||||
"global_settings_setting_backup_compress_tar_archives": "Compress backups",
|
"global_settings_setting_backup_compress_tar_archives": "Compress backups",
|
||||||
"global_settings_setting_backup_compress_tar_archives_help": "When creating new backups, compress the archives (.tar.gz) instead of uncompressed archives (.tar). N.B. : enabling this option means create lighter backup archives, but the initial backup procedure will be significantly longer and heavy on CPU.",
|
"global_settings_setting_backup_compress_tar_archives_help": "When creating new backups, compress the archives (.tar.gz) instead of uncompressed archives (.tar). N.B. : enabling this option means create lighter backup archives, but the initial backup procedure will be significantly longer and heavy on CPU.",
|
||||||
|
|
|
@ -169,3 +169,18 @@ name = "Other"
|
||||||
choices.ipv4 = "IPv4 Only"
|
choices.ipv4 = "IPv4 Only"
|
||||||
choices.ipv6 = "IPv6 Only"
|
choices.ipv6 = "IPv6 Only"
|
||||||
default = "both"
|
default = "both"
|
||||||
|
|
||||||
|
[misc.sni_forward]
|
||||||
|
name = "SNI-based forwarding"
|
||||||
|
|
||||||
|
[misc.sni_forward.sni_forward_enabled]
|
||||||
|
type = "boolean"
|
||||||
|
default = false
|
||||||
|
|
||||||
|
[misc.sni_forward.sni_forward_list]
|
||||||
|
type = "tags"
|
||||||
|
# Regex is just <domain regex>:<ip regex>
|
||||||
|
pattern.regexp = '^([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,}):((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$'
|
||||||
|
pattern.error = "You should specify a list of items formatted as DOMAIN:IPv4, such as yolo.test:12.34.56.78"
|
||||||
|
default = ""
|
||||||
|
visible = "sni_forward_enabled"
|
||||||
|
|
|
@ -300,6 +300,8 @@ def regen_ssowatconf(setting_name, old_value, new_value):
|
||||||
app_ssowatconf()
|
app_ssowatconf()
|
||||||
|
|
||||||
|
|
||||||
|
@post_change_hook("sni_forward_enabled")
|
||||||
|
@post_change_hook("sni_forward_list")
|
||||||
@post_change_hook("ssowat_panel_overlay_enabled")
|
@post_change_hook("ssowat_panel_overlay_enabled")
|
||||||
@post_change_hook("nginx_redirect_to_https")
|
@post_change_hook("nginx_redirect_to_https")
|
||||||
@post_change_hook("nginx_compatibility")
|
@post_change_hook("nginx_compatibility")
|
||||||
|
|
Loading…
Add table
Reference in a new issue