更新
这个问题的细节越来越长,但我认为它可以缩小到这一点:
出于某种原因,当 Nginx 试图确定是否代理请求时,主机名对 Nginx 很重要。如果将主机名设置为git.example.com
请求似乎不会通过,但如果设置为203.0.113.2
则它会通过。为什么主机名很重要?
在这里提出了 Nginx 的问题 和docker compose
原始问题的开始
当我直接在浏览器栏中输入反向代理的 IP 地址时,它会执行重定向。
当使用通过/etc/hosts
条目解析的 URL 时,203.0.113.2 git.example.com
将显示“欢迎来到 Ngnix 页面”。有任何想法吗?这是配置:
server {
listen 203.0.113.2:80 default_server;
server_name 203.0.113.2 git.example.com;
proxy_set_header X-Real-IP $remote_addr; # pass on real client IP
location / {
proxy_pass http://203.0.113.1:3000;
}
}
这是docker-compose.yml
用于启动整个事情的文件:
version: '3'
services:
gogs-nginx:
build: ./proxy
ports:
- "80:80"
networks:
mk1net:
ipv4_address: 203.0.113.2
gogs:
image: gogs/gogs
ports:
- "3000:3000"
volumes:
- gogs-data:/data
networks:
mk1net:
ipv4_address: 203.0.113.3
volumes:
gogs-data:
external: true
networks:
mk1net:
ipam:
config:
- subnet: 203.0.113.0/24
一件有趣的事情是我可以导航到例如:
http://203.0.113.2/issues
上述 URL 的日志是:
gogs-nginx_1 | 203.0.113.1 - - [07/Oct/2018:11:28:06 +0000] "GET / HTTP/1.1" 200 38825 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, 像 Gecko ) Chrome/69.0.3497.100 Safari/537.36" "-"
如果我然后更改203.0.113.2
为git.example.com
(因此 url 最终成为git.example.com
我得到 Nginxs "404 not found" 页面,并且日志显示:
gogs-nginx_1 | 2018/10/07 11:31:34 [error] 8#8: *10 open() "/usr/share/nginx/html/issues" 失败(2:没有这样的文件或目录),客户端:203.0.113.1 ,服务器:本地主机,请求:“GET /issues HTTP/1.1”,主机:“git.example.com”
如果我只http://git.example.com
用作 URL,我会得到 NGINX 欢迎页面和以下日志:
gogs-nginx_1 | 203.0.113.1 - - [07/Oct/2018:11:34:39 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, 像 Gecko ) Chrome/69.0.3497.100 Safari/537.36" "-"
看起来 Nginx 理解请求是针对代理的,因为它记录了代理的 IP,但它没有重定向到代理并返回 304 ...
使用 Curl 执行请求
将 curl 与以代理为目标的主机名参数一起使用,如下所示:
curl -H 'Host: git.example.com' -si http://203.0.113.2
Nginx 欢迎页面中的结果:
ole@mki:~/Gogs/.gogs/docker$ curl -H 'Host: git.example.com' -si http://203.0.113.2
HTTP/1.1 200 OK
Server: nginx/1.15.1
Date: Sun, 07 Oct 2018 17:09:11 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 03 Jul 2018 13:27:08 GMT
Connection: keep-alive
ETag: "5b3b79ac-264"
Accept-Ranges: bytes
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
但是,如果我将主机名更改为 ip 地址,如下所示:
将 curl 与以代理为目标的主机名参数一起使用,如下所示:
curl -H 'Host: 203.0.113.2' -si http://203.0.113.2
然后代理按其应有的方式工作:
ole@mki:~/Gogs/.gogs/docker$ curl -H 'Host: 203.0.113.2' -si http://203.0.113.2
HTTP/1.1 302 Found
Server: nginx/1.15.1
Date: Sun, 07 Oct 2018 17:14:46 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 34
Connection: keep-alive
Location: /user/login
Set-Cookie: lang=en-US; Path=/; Max-Age=2147483647
Set-Cookie: i_like_gogits=845bb09d69587b81; Path=/; HttpOnly
Set-Cookie: _csrf=neGgBfG4LdOcdrdeA0snHjVGz4s6MTUzODkzMjQ4NjE5MzEzNzI3OQ%3D%3D; Path=/; Expires=Mon, 08 Oct 2018 17:14:46 GMT; HttpOnly
Set-Cookie: redirect_to=%252F; Path=/
<a href="/user/login">Found</a>.