如果正常的,80 端口 HTTP 跳转 HTTPS,那么直接在 server listen 80 下写 return 301 https://$host$request_uri; 就行
但是,现在的情况是,80/443 都有服务了,然后在 8443 端口上开了一个需要客户端证书认证的 TLS 双向认证服务,通过 https://example.com:8443 可以成功访问,浏览器会提示选择客户端证书,这都没问题。
但是在首次访问的时候,如果没有显式指定 https 协议,将会自动默认使用 http 协议来访问 8443 端口,导致 nginx 报错:400 Bad Request: The plain HTTP request was sent to HTTPS port。
所以,有没有什么办法可以让 http://example.com:8443 自动跳转到 https://example.com:8443 ?
尝试过这样配置,但不行:
server {
listen 8443 default_server;
return 301 https://$host$request_uri;
}
server {
listen 8443 ssl http2;
server_name xxxxx.com;
ssl_verify_client on;
............
}
1
xiri 2020-03-02 02:08:24 +08:00 via Android 1
我只试过重定向到非 443 的 https 端口,没有实践过 http 和 https 绑定到同一个端口,如果你那个配置没有出现报错的话,把 return 301 那里改成
return 301 https://$host:8443$request_uri; 应该就可以了 |
2
chengxy 2020-03-02 02:16:26 +08:00
default_server 应该是 example.com 吧
|
3
uqf0663 2020-03-02 02:17:57 +08:00
没遇到过这种,但是猜测应该写个 if 判断协议来实现跳转
|
4
zhengjian 2020-03-02 02:44:26 +08:00 via iPhone 1
受一楼启发,以 nginx http https same port 搜索,看到几个解决方式,楼主可以试试
https://www.nginx.com/blog/running-non-ssl-protocols-over-ssl-port-nginx-1-15-2/ https://stackoverflow.com/questions/15429043/how-to-redirect-on-the-same-port-from-http-to-https-with-nginx-reverse-proxy https://stackoverflow.com/questions/40996334/how-to-force-ssl-tls-on-nginx-on-a-single-port |
5
seki 2020-03-02 02:51:16 +08:00 1
看了一下,基本方案是这个端口只配置 https,加一个对 nginx 497 错误的处理来改变协议,写成
error_page 497 https://$host$request_uri; 没实际试过,不知道非标准端口需不需要加上端口号 参考 https://stackoverflow.com/questions/14144514/can-i-redirect-non-ssl-traffic-that-comes-in-on-an-ssl-port-with-nginx |
6
iflyime 2020-03-02 03:04:34 +08:00 via Android
楼上的
error_page 497 https://$host$request_uri; 以前试过好像是可以把非 443 端口的直接跳转到 HTTPS 的。 |
7
iflyime 2020-03-02 03:37:32 +08:00 via Android 1
|
8
mgrddsj 2020-03-02 03:43:55 +08:00
@iflyime #7
正解,我的服务器就是这样配置的。原理是把 The plain HTTP request was sent to HTTPS port 的错误页跳转到加了 https:// 的页面。5 楼的方案漏了端口号,7 楼这个应该完美符合楼主场景。 |
9
zvc888 2020-03-02 11:05:36 +08:00
8443 rewrite 就可以了
|
10
jinliming2 OP |
11
Anonono 274 天前
`error_page 497 301 =307`中的 301 有什么作用吗,不是很理解为什么要在这加 301
|
12
jinliming2 OP @Anonono #11 不太记得当时怎么想的了,貌似是看了那个 stack overflow 的回答就直接复制过来了。。。
看了下那个回答的修改记录,最开始是没有 301 =307 这一段的,测试了下这样默认就是 302 。 然后底下有个人说加上 301 =307 防止请求方法发生改变( 301 和 302 的标准规定请求方法不变,但是部分浏览器实现会在重定向后变成 GET )。 但是实际上测试了下,只写 =307 或者 =308 就行。 前面的 301 只在 upstream 服务返回了 301 状态码的情况下生效,用于改写为 307 (按理应该改写成 308🤔)保留请求方法。 |
13
jinliming2 OP @Anonono #11 #12 我注意到 nginx 文档中有一句 The code 308 was not treated as a redirect until version 1.13.0. 也就是说,308 状态码是 nginx 1.13.0 才支持的,查了下 nginx 的更新记录,1.13.0 是 2017 年 4 月 25 发布的。而那个评论的时间是 2015 年 2 月 4 日。
所以评论者当时的 nginx 版本只支持 307 ( 2012 年 2 月 29 日的 1.1.16 和 2012 年 3 月 5 日的 1.0.13 )。评论者的原话是 That way the request method isn't auto converted to a GET as is default 。所以 301 估计就是那个人自己加的,用于避免请求方法被改成 GET 用的,与原题无关,但推荐一块加上? 现在版本的 nginx 支持 308 了,所以应该用 308 更合适? |
14
kevinwu04266 216 天前
@iflyime 为什么我改到别的非 443 的端口,访问网站需要在网站后面加“:端口号”才能正常进入呢
|
15
kevinwu04266 216 天前
@xiri 为什么我改到别的非 443 的端口,访问网站需要在网站后面加“:端口号”才能正常进入呢
|
16
jinliming2 OP @kevinwu04266 标准 https 端口就是 443 ,http 就是 80 ,你用其他端口就是非标准。
浏览器怎么知道你用的哪个端口,你总不能让浏览器去猜吧?肯定是得要你自己明确指定啊! |