【问题标题】:Nginx 2 different domains on one serverNginx 一台服务器上有 2 个不同的域
【发布时间】:2021-11-17 22:07:36
【问题描述】:

我想知道如何配置 nginx 以使 2 个域在一台服务器上工作(1 个 IP 地址)。 我想在 bookstack 实例旁边设置一个 Keycloak SSO。

我的问题是,当我想访问 bookstack.domain.com 时,它会重定向到 keycloak.domain.com。

这是我的 /etc/nginx/conf.d/keycloak.conf :

upstream keycloak {
# Use IP Hash for session persistence
ip_hash;

# List of Keycloak servers
server 127.0.0.1:8080;
}


server {
listen 80;
server_name keycloak.domain.com;

# Redirect all HTTP to HTTPS
location / { 
return 301 https://\$server_name\$request_uri;
}
}

server {
listen 443 ssl http2;
server_name keycloak.domain.com;

ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/certificate_key.key;
ssl_session_cache shared:SSL:1m;
ssl_prefer_server_ciphers on;

location / {
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_pass http://keycloak;
}
}

这是我的 /etc/nginx/conf.d/bookstack.conf :

server {
    listen 3480;

    access_log  /var/log/nginx/bookstack_access.log;
    error_log   /var/log/nginx/bookstack_error.log;
    server_name bookstack.domain.com;
    root        /var/www/bookstack/public;
    #
    # redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
    #
    return 301 https://$host$request_uri;
}


server {
  listen 5443 ssl http2;

  ssl_certificate /path/to/certificate.crt;
  ssl_certificate_key /path/to/certificate_key.key;
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AE;
  ssl_prefer_server_ciphers on;

  ssl_dhparam /etc/nginx/dhparam.pem;

  server_name bookstack.domain.com;

  #HSTS
  add_header Strict-Transport-Security "max-age=63072000" always;

  root /var/www/bookstack/public;

  access_log  /var/log/nginx/bookstack_access.log;
  error_log  /var/log/nginx/bookstack_error.log;

  client_max_body_size 1G;
  fastcgi_buffers 64 4K;

  index  index.php;

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ~ ^/(?:\.htaccess|data|config|db_structure\.xml|README) {
    deny all;
  }

  location ~ \.php(?:$|/) {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_pass unix:/var/run/php-fpm.sock;
  }

  location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ {
    expires 30d;
    access_log off;
  }
}

请告诉我:)

【问题讨论】:

  • 这个工作https://bookstack.domain.com:5443 吗?

标签: web-services nginx ssl single-sign-on keycloak


【解决方案1】:

对于给定的配置,这正是预期的 nginx 行为。对于到达某个 IP/端口组合的任何请求,server 块之一始终充当 默认服务器,无论 Host HTTP 标头值是什么。这是有关此主题的官方documentation。您可以为 listen 指令使用 default_server 参数来明确指定应充当默认服务器的 server 块,否则它将是第一个侦听这些 IP/端口的 server 块。正如here 所讨论的,在多宿主服务器上,事情可能会更加复杂。

现在回到问题。您的配置中有四个服务器块:第一个侦听 TCP 端口 80(http:// 方案的默认端口),第二个侦听 TCP 端口 443(https:// 方案的默认端口),一个侦听端口 3480 和最后一个侦听端口 5443。由于每个端口只有一个 server 块侦听,因此每个 server 块将充当到达该端口的任何请求的默认服务器。因此,如果您在浏览器地址栏中键入http://bookstack.domain.com,将使用http:// 方案的默认端口80,您的请求将被重定向到https://keycloak.domain.com。你正在使用

return 301 https://\$server_name\$request_uri;

对于重定向,对于该服务器块,$server_name 变量将始终为keycloak.domain.com(阅读this 答案以了解$host$http_host$server_name 变量之间的区别)。如果您明确指定端口并键入http://bookstack.domain.com:3480,您的请求将由第三个server 块提供服务,从而被重定向到https://bookstack.domain.com(这里您使用的是$host 变量,这是正确的)。默认的 TCP 端口 https:// 方案是 443。但是在该端口上侦听的唯一 server 块是 keycloak.domain.com!哎呀。访问bookstack.domain.com 的唯一方法是在浏览器中输入https://bookstack.domain.com:5443。如果您正确理解以上所有信息,您也可以输入https://keycloak.domain.com:5443,不会有任何区别。

好吧,我试着解释一下你的 nginx 配置发生了什么。正如@Evil_skunk 在他的answer 中推荐的那样,摆脱非标准端口。在尝试新配置之前不要忘记清除浏览器缓存 - 永久 HTTP 301 重定向通常由浏览器缓存,这与临时 HTTP 302 重定向不同。

【讨论】:

  • 感谢您非常明确的回答。正如你所说,我确实尝试指定端口,它适用于 bookstack,但不适用于 keycloak。正如您和@Evil_skunk 所说,我摆脱了非标准端口,现在一切正常!我的问题是我认为我不能在相同的端口上监听 2 个不同的服务器。
  • 应该处理请求的服务器块由 nginx 根据Host HTTP header 值选择。如果它与server_name 指令指定的任何服务器名称都不匹配(或者如果根本没有Host 标头),则请求将由默认服务器块处理。您可以拥有任意数量的服务器块,但它们的服务器名称不应相互匹配。
【解决方案2】:

您的 keycloak 配置似乎没问题

它侦听端口80 (http) 和端口443 (https),所有对80 (http) 的请求都被重定向到443 (https)

您的 bookstack 配置对我来说看起来不对 它不监听端口80443(而是监听54433480)。如果您没有某种特殊的端口转发,那么我认为对bookstack.domain.com 的请求永远不会到达bookstack.conf 中定义的nginx-server,因此唯一匹配的服务器将为请求提供服务=> keycloak

你应该改变bookstack.conf的监听端口:

server {
   listen 80;
   #... redirect to https
}

server {
   listen 443 ssl;
   #ssl config, webroot, ...
}

【讨论】:

  • 感谢您的回答,正如您所说,我摆脱了非标准端口,现在我的 bookstack 工作得很好!我认为我不能监听 2 个不同服务器的相同端口。
猜你喜欢
  • 2018-09-06
  • 2014-01-02
  • 2016-01-02
  • 1970-01-01
  • 2015-03-08
  • 1970-01-01
  • 2019-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多