一个 LAN 上的两个 Web 服务器,分别运行 apache2 和 nginx,使用一个 WAN IP 地址 - 通过(子)域名连接到正确的服务器

一个 LAN 上的两个 Web 服务器,分别运行 apache2 和 nginx,使用一个 WAN IP 地址 - 通过(子)域名连接到正确的服务器

我有两台物理服务器在同一个 LAN 上运行。两台服务器都运行着 Web 服务器;一台运行 apache2,另一台运行 nginx。它们各自拥有不同的域名,但拥有相同的外部 WAN IP 地址。假设网络布局如下:

                WAN
            10.20.30.40
      |----------|----------|
      |                     |
   Domain 1              Domain 2
exampleABC.com     (sub.)exampleXYZ.com
      |                     |
      |----------|----------|
                 |
            Single LAN
                 |
      |----------|----------|
      |                     |
  IP addr 1             IP addr 2
192.168.0.10           192.168.0.20
      |                     |
      |                     |
  Server 1              Server 2
   apache2                nginx

apache2 服务器属于我,而 nginx 服务器不属于我。这两台服务器都为它们提供的每项服务提供了专用子域名 - 例如,(www.)exampleABC.com 用于主页,cloud.exampleXYZ.com 用于反向代理云服务,media.exampleXYZ.com 用于媒体等。

由于未知的原因,在连接到 WAN IP 地址时,nginx 服务器具有优先级 - 最初,两个域都会指向由 nginx 托管的主网页,但使用以下(当前)nginx 配置,exampleABC.com 将正确指向 apache2 服务器,而 exampleXYZ.com 继续指向 nginx 服务器。

server {
    listen 80;

    # listen on all subdomains
    server_name exampleABC.com *.exampleABC.com;
    
    location / {
        # transparently proxy to other server (port 443)
        proxy_pass http://192.168.0.10:80;

        # set "Host" header passed to other server to client-requested FQDN so other server knows which subdomain is being requested
        proxy_set_header Host $http_host;
    }
}

server {
    listen 443 ssl;

    server_name exampleABC.com *.exampleABC.com;
    
    location / {
        proxy_pass https://192.168.0.10:443;
        proxy_set_header Host $http_host;
    }
}

但是,apache2 服务器托管的子域(docs.exampleABC.com 等)继续连接到 nginx。(nginx 子域工作正常。)

这是我通过 apache2 设置的子域配置之一:

<VirtualHost *:80>
    ServerName ft.exampleABC.com
    Redirect permanent / https://ft.exampleABC.com/
    RewriteEngine on
    RewriteCond %{SERVER_NAME} =ft.exampleABC.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.

        ServerName ft.exampleABC.com
        #ServerAlias *.exampleABC.com

        ServerAdmin webmaster@localhost
        DocumentRoot /mnt/external/webserver/ft

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
        
        <Directory /mnt/external/webserver/ft>
            Options Indexes FollowSymLinks
            AllowOverride None
            Require all granted
        </Directory>

        #   SSL Engine Switch:
        #   Enable/Disable SSL for this virtual host.
        SSLEngine on

        < snipped: lines added by certbot >

    </VirtualHost>
</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

我希望这样操作:当连接到 exampleABC.com、ft.exampleABC.com 等时,客户端能够正确连接到 apache2 服务器。当然,exampleXYZ.com 及其子域仍应连接到 nginx 服务器。

其他信息:

最初,客户端(例如 Web 浏览器)无法验证 exampleABC.com 的 TLS 证书的真实性。(请注意,我在 apache2 下正确设置了 TLS 证书。)通过将我的 apache2 域添加到 nginx 服务器的证书解决了这个问题。不过,我认为这没有必要 - 我的证书(在 apache2 下)应该通过反向代理传递,不是吗?

如果我尝试通过 curl 连接到 apache2 服务器,同时手动指定 Host 标头(通过curl -vL -H "Host: ft.exampleABC.com" https://192.168.0.10),我将被重定向到 nginx 服务器的主网页。我不确定这意味着什么。

编辑:

nginx -T根据 nginx 系统的系统管理员的说法,这是的输出:

- 剪辑 -

此外,nginx 服务器通过以下方式在容器中运行:LinuxServer.io 的“SWAG”

编辑:

LinuxServer.io 的 SWAG 加载了与默认配置不同的 nginx 配置。以下命令获取正确的配置:

docker exec -it swag /usr/sbin/nginx -c /config/nginx/nginx.conf -T

该命令的结果可以在以下位置找到此粘贴. (对于 StackExchange 来说字符太多)

答案1

我是他们服务器所在房屋的房主。我绝不是专家;我只是很好地遵循指南。我有一个 DuckDNS 域名,并为 Plex、Sonarr、SABnzbd 等运行 Docker 容器。我还为我的反向代理运行 SWAG 容器。

Unilock 已引入自己的服务器。它有自己的域名,并使用 apache2 进行所有服务器配置。在加入我的网络之前,该服务器监听与我的相同的所有端口(80、443 等)。

有人告诉我,如果 Unilock 可以在非标准端口上运行他们的服务,我们也许可以更改我的 pfSense 路由器的设置以同时运行两个服务器。我还被告知,我可以将其服务器的域名添加到我的 SWAG 容器的 EXTRA_DOMAINS 变量中。我这样做了,但没有帮助。

我还在 SITE_CONF 默认文件中添加了一个额外的服务器块。额外的块如下所示:

#second server block
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name <his domain name>; #change this to your subdomain
    #include /config/nginx/ssl.conf;
    client_max_body_size 0;
    location / {
    #include /config/nginx/proxy.conf;
    resolver 127.0.0.11 valid=30s;
    #set $upstream_app 192.168.0.10;
    #set $upstream_port 443;
    #set $upstream_proto https;
    #proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    proxy_pass https://192.168.0.10:443; 
    proxy_max_temp_file_size 2048m;
   }

我的主服务器块是默认文件。如果我需要发布整个配置,我会这样做;尽管 unilock 似乎已经在 Pastebin 上这样做了。输入上述内容后,我可以访问 unilock 的主页,但它们的子域仍然重定向到我的默认 nginx 服务器起始页。

答案2

有效的方法是创建一个新文件/config/nginx/proxy-confs/exampleABC.subdomain.conf(相当于/etc/nginx/conf.d/exampleABC.subdomain.confexampleABC.subdomain可以用任何内容替换),其中包含以下内容:

server {
    listen 80;
    listen [::]:80;

    server_name .exampleABC.com;
    
    location / {
        proxy_pass http://192.168.0.10:80;
        proxy_set_header Host $http_host;
    }
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name .exampleABC.com;
    
    location / {
        proxy_pass https://192.168.0.10:443;
        proxy_set_header Host $http_host;
    }
}

我在原始帖子中输入的 nginx 配置应该与此几乎完全相同,因此我怀疑问题在于缺乏listen [::]:<port>;IPv6 兼容性,或者是其他配置文件与我创建的配置文件相冲突。

相关内容