如何将现有的 nginx 配置更改为多台具有工作加密证书的本地计算机的反向代理
How to alter existing nginx config into a reverse proxy for multiple local machines with working lets-encrypt certificate
首先让我说一下,我的大部分“经验”来自于盲目地从各种博客和网站复制粘贴配置行,并希望一切顺利。
目前我有这样的设置:
动态 ddns 主机名指向我的 public IP 将传入流量从端口 80 和 443 重定向到具有 nextcloud 的 LXC 容器 + 来自 letsencrypt 的相同 ddns 主机名的证书。到目前为止一切顺利。
这是相关的 nginx 配置:
server {
server_name stats;
listen 9753 default_server;
listen [::]:9753 default_server;
location /nginx-status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow ::1;
deny all;
}
location ^~ /.well-known/acme-challenge {
proxy_pass http://127.0.0.1:81;
proxy_set_header Host $host;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
server_name nextcloud;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
client_max_body_size 10240M;
root /var/www/nextcloud/;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
location / {
rewrite ^ /index.php;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ^~ /apps/rainloop/app/data {
deny all;
}
location ~ \.(?:flv|mp4|mov|m4a)$ {
mp4;
mp4_buffer_size 100M;
mp4_max_buffer_size 1024M;
fastcgi_split_path_info ^(.+?.php)(\/.*|)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
include php_optimization.conf;
}
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+).php(?:$|\/) {
fastcgi_split_path_info ^(.+?.php)(\/.*|)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
include php_optimization.conf;
}
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
location ~ .(?:css|js|woff2?|svg|gif|map|png|html|ttf|ico|jpg|jpeg)$ {
try_files $uri /index.php$request_uri;
access_log off;
expires 30d;
}
}
我改变这个的最初设想是像以前一样使用 nextcloud.ddns.net 访问我的 nextcloud,但也能够通过 nextcloud.ddns.net/whatever 反向代理到不同的本地机器, nextcloud.ddns.net/something 等等 为什么?因为我完全不理解底层技术,所以我设想这将继续使用 nextcloud.ddns.net 已经有效的 ssl 证书,而我不必为每个目的地获取新证书。它是这样工作的吗?我仍然不知道,但这并没有阻止我尝试。我尝试在不同的地方包含一个新的 location /whatever 指令,但我所取得的只是 a) 它根本不起作用,b) 将我重定向到原始的 nextcloud,c) 仅在连接到本地 lan 时工作。
看到我没有到达任何地方,我走了另一条路并注册了另一个 ddns 主机名,指向相同的 public IP 并将此块包含在 nginx.conf 的顶部:
server {
listen 443 ssl;
server_name other_hostname.ddns.net;
location / {
proxy_pass http://different_local_machine.lan/;
}
}
这有效,但显然抱怨证书颁发给 nextcloud.ddns.net 而不是 other_hostname.ddns.net
然后回答我的问题:
是否完全可以像我最初想的那样使用 1 个具有不同 / 后缀的 ddns 主机名进行设置,或者这根本不是它的工作方式?
在具有多个 ddns 主机名的工作场景中,我将如何获取多个 lets-encrypt 证书?我担心如果我按照与获得 nextcloud 证书时相同的说明进行操作,我最终会搞砸它,因为它仍然是唯一面向互联网的 nginx。
如果忽略警告,我有多“安全”?我的意思是我知道该证书适用于不同的主机名,但我实际上知道它仍然是一个有效的证书。
再次为我的技术缺陷道歉,我花了几天时间才发现我想要实现的是反向代理,并没有从那里改进太多,但我认为我想要实现的应该在互联网陌生人的帮助下成为可能,而无需完成一个学期的计算机科学
感谢您的帮助!
这是一个可用于处理此问题的示例...您可能需要根据自己的需要调整设置...
我在与两个容器联网的 nginx docker 中使用它
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
在/etc/nginx/conf.d/ 目录中驻留了每个容器的配置文件..
--在site1.conf--
upstream production{
server container_name1:80;
}
server {
server_name site1.com;
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Access-Control-Allow-Origin *;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://production/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/site1.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/site1.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = site1.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name site1.com;
listen 80;
return 404; # managed by Certbot
}
--在site2.conf--
upstream production_admin{
server container_name2:80;
}
server {
server_name admin.site1.com;
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Access-Control-Allow-Origin *;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://production_admin/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/site1.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/site1.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = admin.site1.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name admin.site1.com;
listen 80;
return 404; # managed by Certbot
}
Upstream 将设置在 proxypass 中使用的名称,并仅在服务器的端口 80 之外提供服务。这应该可以帮助您入门
如果有人像我一样绝望并且遇到完全相同的问题,我设法在另一个论坛上找到了解决方案。 1 条该死的线,仅此而已。 proxy_set_header Referer $http_referer;
它有什么作用?我怎么知道?它让我的东西按我想要的方式工作,这就是我所关心的。
因此完整的工作位置块如下所示:
location ~ /something {
proxy_pass http://somehost.lan:someport;
proxy_set_header Referer $http_referer;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
导致我“发现”的讨论:https://unix.stackexchange.com/questions/290141/nginx-reverse-proxy-redirection底部post,第一条评论。
首先让我说一下,我的大部分“经验”来自于盲目地从各种博客和网站复制粘贴配置行,并希望一切顺利。
目前我有这样的设置:
动态 ddns 主机名指向我的 public IP 将传入流量从端口 80 和 443 重定向到具有 nextcloud 的 LXC 容器 + 来自 letsencrypt 的相同 ddns 主机名的证书。到目前为止一切顺利。
这是相关的 nginx 配置:
server {
server_name stats;
listen 9753 default_server;
listen [::]:9753 default_server;
location /nginx-status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow ::1;
deny all;
}
location ^~ /.well-known/acme-challenge {
proxy_pass http://127.0.0.1:81;
proxy_set_header Host $host;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
server_name nextcloud;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
client_max_body_size 10240M;
root /var/www/nextcloud/;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
location / {
rewrite ^ /index.php;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ^~ /apps/rainloop/app/data {
deny all;
}
location ~ \.(?:flv|mp4|mov|m4a)$ {
mp4;
mp4_buffer_size 100M;
mp4_max_buffer_size 1024M;
fastcgi_split_path_info ^(.+?.php)(\/.*|)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
include php_optimization.conf;
}
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+).php(?:$|\/) {
fastcgi_split_path_info ^(.+?.php)(\/.*|)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
include php_optimization.conf;
}
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
location ~ .(?:css|js|woff2?|svg|gif|map|png|html|ttf|ico|jpg|jpeg)$ {
try_files $uri /index.php$request_uri;
access_log off;
expires 30d;
}
}
我改变这个的最初设想是像以前一样使用 nextcloud.ddns.net 访问我的 nextcloud,但也能够通过 nextcloud.ddns.net/whatever 反向代理到不同的本地机器, nextcloud.ddns.net/something 等等 为什么?因为我完全不理解底层技术,所以我设想这将继续使用 nextcloud.ddns.net 已经有效的 ssl 证书,而我不必为每个目的地获取新证书。它是这样工作的吗?我仍然不知道,但这并没有阻止我尝试。我尝试在不同的地方包含一个新的 location /whatever 指令,但我所取得的只是 a) 它根本不起作用,b) 将我重定向到原始的 nextcloud,c) 仅在连接到本地 lan 时工作。
看到我没有到达任何地方,我走了另一条路并注册了另一个 ddns 主机名,指向相同的 public IP 并将此块包含在 nginx.conf 的顶部:
server {
listen 443 ssl;
server_name other_hostname.ddns.net;
location / {
proxy_pass http://different_local_machine.lan/;
}
}
这有效,但显然抱怨证书颁发给 nextcloud.ddns.net 而不是 other_hostname.ddns.net
然后回答我的问题:
是否完全可以像我最初想的那样使用 1 个具有不同 / 后缀的 ddns 主机名进行设置,或者这根本不是它的工作方式?
在具有多个 ddns 主机名的工作场景中,我将如何获取多个 lets-encrypt 证书?我担心如果我按照与获得 nextcloud 证书时相同的说明进行操作,我最终会搞砸它,因为它仍然是唯一面向互联网的 nginx。
如果忽略警告,我有多“安全”?我的意思是我知道该证书适用于不同的主机名,但我实际上知道它仍然是一个有效的证书。
再次为我的技术缺陷道歉,我花了几天时间才发现我想要实现的是反向代理,并没有从那里改进太多,但我认为我想要实现的应该在互联网陌生人的帮助下成为可能,而无需完成一个学期的计算机科学
感谢您的帮助!
这是一个可用于处理此问题的示例...您可能需要根据自己的需要调整设置...
我在与两个容器联网的 nginx docker 中使用它
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
在/etc/nginx/conf.d/ 目录中驻留了每个容器的配置文件..
--在site1.conf--
upstream production{
server container_name1:80;
}
server {
server_name site1.com;
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Access-Control-Allow-Origin *;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://production/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/site1.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/site1.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = site1.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name site1.com;
listen 80;
return 404; # managed by Certbot
}
--在site2.conf--
upstream production_admin{
server container_name2:80;
}
server {
server_name admin.site1.com;
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Access-Control-Allow-Origin *;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://production_admin/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/site1.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/site1.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = admin.site1.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name admin.site1.com;
listen 80;
return 404; # managed by Certbot
}
Upstream 将设置在 proxypass 中使用的名称,并仅在服务器的端口 80 之外提供服务。这应该可以帮助您入门
如果有人像我一样绝望并且遇到完全相同的问题,我设法在另一个论坛上找到了解决方案。 1 条该死的线,仅此而已。 proxy_set_header Referer $http_referer;
它有什么作用?我怎么知道?它让我的东西按我想要的方式工作,这就是我所关心的。
因此完整的工作位置块如下所示:
location ~ /something { proxy_pass http://somehost.lan:someport; proxy_set_header Referer $http_referer; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; }
导致我“发现”的讨论:https://unix.stackexchange.com/questions/290141/nginx-reverse-proxy-redirection底部post,第一条评论。