telnet 到端口 80 (nginx),并转发到端口 8080 的 apache2,失败,显示“外部主机关闭连接”,并且似乎没有任何解释

telnet 到端口 80 (nginx),并转发到端口 8080 的 apache2,失败,显示“外部主机关闭连接”,并且似乎没有任何解释

我正在运行 Kubuntu 22.04 服务器,并且想要将仅 LAN 流量从端口 80(据我所知由 nginx 提供服务)传输到端口 8080(由 apache2 提供服务,用于 PHP 目的)。

但是我得到了这个“外部主机关闭的连接”(大概是来自 nginx),这证明端口 80 完全停止了。我仍然可以通过在浏览器中直接寻址端口 8080 来访问我需要访问的 PHP 和代码文件树,但我确实想知道是什么原因导致了这种情况。

任何帮助将非常感激。 :)

root@parakeet:/var/log/nginx# netstat -tulpn | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3001930/nginx: mast 
tcp6       0      0 :::80                   :::*                    LISTEN      3001930/nginx: mast 
tcp6       0      0 :::8080                 :::*                    LISTEN      3001981/apache2  

root@parakeet:/var/log/nginx# cat error.log
root@parakeet:/var/log/nginx# ls -al | grep error.log
-rw-r-----  1 www-data adm          0 jul  2 21:09 error.log

root@parakeet:/etc/nginx/sites-enabled# cat 000-localhost.conf 
#
# Note: This file must be loaded before other virtual host config files.
# HTTPS
server {
  listen 80 http2;
  listen [::]:80 http2;

  server_name 192.168.178.29;
  root /var/www/192.168.178.29;
    
  add_header 'Access-Control-Allow-Origin' 'https://fiddle.jshell.net' always;
  add_header 'Access-Control-Allow-Credentials' 'true' always;
  add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
  add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;

  location / {
    proxy_pass https://192.168.178.29:8080/;

    proxy_redirect off;
    proxy_buffering off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    #proxy_set_header X-Forwarded-Ssl on;

    proxy_connect_timeout 159s;
    proxy_send_timeout   60;
    proxy_read_timeout   60;
    send_timeout 60;
    resolver_timeout 60;
  }
}

root@parakeet:/etc/apache2/sites-enabled# cat 000-localhost.conf 
<VirtualHost 192.168.178.29:8080>
        # 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 192.168.178.29

        ServerAdmin [email protected]
        DocumentRoot /var/www/192.168.178.29

        # 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
        #LogLevel info ssl:warn
        LogLevel info ssl:warn

        SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
        LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
        LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" forwarded
        ErrorLog ${APACHE_LOG_DIR}/error.8080.log
        CustomLog ${APACHE_LOG_DIR}/access.8080.log combined env=!forwarded
        CustomLog ${APACHE_LOG_DIR}/access.8080.log forwarded env=forwarded

        # 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".

        <Directory /var/www/192.168.178.29>
                Options -Indexes +FollowSymLinks
                AllowOverride All
                Require all granted
        </Directory>
</VirtualHost>

答案1

网络浏览器通常结合加密来支持 HTTP/2 所以您不会在普通的 HTTP 端口 80 上启用此功能。因此您的 nginx 配置:

server {
   listen 80 http2;

应该省略 http2 指令:

server {
   listen 80;

至于为什么你现在无法远程登录到 80 端口:与普通的 HTTP 1.1 不同,您可以通过使用 telnet 或 HTTPS/1.1 输入 HTTP 命令来轻松模拟,例如,您可以对其进行类似的测试openssl s_client -connect host:443;HTTP/2 更难测试。

HTTP/2 不再是基于文本的协议,而是一种更高效的二进制协议,因此 telnet 无法提供正确的握手来成功建立连接。请参阅:https://blog.cloudflare.com/tools-for-debugging-testing-and-using-http-2/以作为一些可替代的例子。


通常你允许 Apache 监听要么绑定到系统上的所有 IP 地址和接口,Listen 8080要么在您描述的配置中将 Apache httpd 专门绑定到 localhost,因此无法使用 进行远程访问Listen 127.0.0.1:8080。无论哪种方式,而不是: VirtualHost 192.168.178.29:8080您通常会使用<VirtualHost *:8080>

其次,你发布的 apache VirtualHost 定义似乎不支持 HTTPS,我假设当“直接在浏览器中寻址端口 8080”您还使用明文 HTTP URI。

然后尝试在 nginx 反向代理中使用proxy_pass https://192.168.178.29:8080/;; 和 HTTPS 注定会失败。这也应该是纯 HTTP:,proxy_pass http://192.168.178.29:8080/; 当 apache 和 nginx 在同一台服务器上运行时甚至:proxy_pass http://127.0.0.1:8080/;

答案2

我不是这个领域的专家,但我只是假设问题可能在于您需要为 nginx 启用 ssl 指令。

listen 80 ssl http2;

您还需要确保已为 apache 启用了 ssl 模块。

我将通过将 https 替换为 http 并确保它可以通过该协议运行来开始寻找问题。

相关内容