我正在使用 SSH 端口转发 - 效果非常好此处有图解和详细说明- 访问我的服务器。
我花了比我想承认的更多的时间来排除访问我的 Python Web 服务器 404 错误的原因。完整的问题请在此处完成。
我的问题是,如果我使用端口转发将我的请求直接转发到运行 Python 服务器的端口(例如 8282),所有请求都会变成 404。
为了简单起见,Python 服务器(提供包含字符串的 index.html hello
):
python -m http.server 8282
我想要获取访问权限的主机的 SSH 端口转发:
ssh -L 8181:<farawayhost-ip>:8282 <sshuser>@<remotehost-ip>
对于主机上的后续请求curl
,我定义了环境变量http_proxy
:
export http_proxy=127.0.0.1:8181
显然这些请求不正确,因为它们前面添加了 IP 地址。为了进行比较,下面是 Python http.server 日志,首先从服务器本地访问它,然后从外部主机访问它,使用 SSH 端口转发。
Serving HTTP on 0.0.0.0 port 8282 ...
<server-public-ip> - - [<timestamp>] "GET /index.html HTTP/1.1" 200 -
<proxy-ip> - - [<timestamp>] code 404, message File not found
<proxy-ip> - - [<timestamp>] "GET http://<server-public-ip>:8282/index.html HTTP/1.1" 404 -
通过在 Python Web 服务器和外部主机之间放置 Nginx 代理,我能够从外部主机访问 Python Web 服务。
Nginx 与 Python web 服务安装在同一台服务器上,只是监听端口 80 并代理localhost:8282
。
Nginx 配置:
server {
listen 80 default_server;
location / {
proxy_pass http://127.0.0.1:8282;
}
在外部主机上,SSH 端口转发配置为端口 80,而不是 8282。
ssh -L 8181:<farawayhost-ip>:80 <sshuser>@<remotehost-ip>
export http_proxy=127.0.0.1:8181 # proxy for curl
现在可以成功访问 Web 服务。
Nginx 日志:
<remotehost-ip> - - [<timestamp>] "GET http://<server-ip>/ HTTP/1.1" 200 6 "-" "<user-agent>"
Python http.server 日志:
127.0.0.1 - - [<timestamp>] "GET / HTTP/1.0" 200 -
我的问题:
我最初的问题已经解决,但我想了解原因。
这些请求有何不同,为什么通过 SSH 端口转发直接访问 Python 服务器会失败,而通过 Nginx 代理访问却可以成功?
答案1
您的问题是 SSH 隧道不是 HTTP 代理(虽然nginx
是),因此设置http_proxy
为指向 SSH 隧道端点会导致curl
以适合 HTTP 代理的格式发送 HTTP 请求,而 SSH 隧道会将这些请求直接发送到您的 python 应用程序,而无需像 HTTP 代理那样进行任何特殊处理。使用 SSH 隧道,您需要删除http_proxy
变量并直接使用 访问您的应用程序curl http://localhost:8181/
。