New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

http请求被转成https请求并报400错误 #854

Closed
goywzl opened this Issue Dec 24, 2016 · 9 comments

Comments

Projects
None yet
5 participants
@goywzl

goywzl commented Dec 24, 2016

问题描述:在配置SSL之后,没有配置SSL的域名使用HTTP访问会走HTTPS请求,并且返回400报错,报错如下

400 Bad Request

The plain HTTP request was sent to HTTPS port. Sorry for the inconvenience.
Please report this message and include the following information to us.
Thank you very much!

环境描述:
我使用的是tengine-2.1.2,主配置文件加上如下参数include /opt/nginx/conf.d/*.conf;
比如域名有:pay-m.goywzl.com与pay.m.goywzl.com和callback.m.zhaopin.com与callback-m.goywzl.com
配置文件为:文件名在前,server_name在括号中
pay-m.conf(pay-m.goywzl.com)
pay.m.conf(pay.m.goywzl.com)
callback.m.conf(callback.m.goywzl.com)
callback-m.conf(callback-m.goywzl.com)
分别在pay-m.conf与callback-m.conf下添加如下配置
listen 443 ssl;
ssl on;
ssl_certificate /data/goywzl-certificate/goywzl.com.crt;
ssl_certificate_key /data/goywzl.com-certificate/goywzl.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers XXXXXXXXXXXXXXXXXXXXXXX
其它的配置与普通配置文件并没有差别,但是在使用http访问pay.m.goywzl.com等本tenginx所在的所有域名的时候,就会出现上面的错误,最后发现一个原因,只要我把配置文件名callback-m.conf随便改成不是callback-m这样的名字,如(callbackm.conf)里面的内容不变,就不会在出现上面的报错,并且从网上查到一些文档,如果我继续使用callback-m.conf这个名字,把配置文件内容"ssl on "这一行注释掉,就也恢复了正常200状态,但是其它的配置文件使用"SSL"配置是完全没问题的,只有这个配置文件名字有问题,实在想不出问题的原因,所以在这里请教各位,希望能知道是为什么会出现这个情况?

@goywzl goywzl changed the title from http to http请求被转成https请求并报400错误 Dec 24, 2016

@chobits

This comment has been minimized.

Show comment
Hide comment
@chobits

chobits Dec 28, 2016

Member

只要我把配置文件名callback-m.conf随便改成不是callback-m这样的名字,如(callbackm.conf)里面的内容不变

这个根据你得描述没有想到很合理的解释

把配置文件内容"ssl on "这一行注释掉,就也恢复了正常200状态,

注意ssl on会将整个virtual server都开启成ssl,比如如下配置,即使listen 80没有配置ssl,80端口也是使用https协议,如果使用http协议访问80端口就会返回报错(400)。
建议开启ssl使用listen指令,配置中ssl on可以去掉。

server {
   listen 80;
   listen 443 ssl;

   ssl on;    # 将整个server{}开启成https协议(包括server{}内的80端口)
   ...
}
Member

chobits commented Dec 28, 2016

只要我把配置文件名callback-m.conf随便改成不是callback-m这样的名字,如(callbackm.conf)里面的内容不变

这个根据你得描述没有想到很合理的解释

把配置文件内容"ssl on "这一行注释掉,就也恢复了正常200状态,

注意ssl on会将整个virtual server都开启成ssl,比如如下配置,即使listen 80没有配置ssl,80端口也是使用https协议,如果使用http协议访问80端口就会返回报错(400)。
建议开启ssl使用listen指令,配置中ssl on可以去掉。

server {
   listen 80;
   listen 443 ssl;

   ssl on;    # 将整个server{}开启成https协议(包括server{}内的80端口)
   ...
}
@goywzl

This comment has been minimized.

Show comment
Hide comment
@goywzl

goywzl Dec 28, 2016

你好,非常感谢你的热心帮助,不过我想描述的问题并不是这样的。
首先你说的那个ssl on,我别的都是这样配置的,并没有问题,可以走http,也可以走https,我就是非常不明白的为什么配置文件名会有这样的影响,下面附上我的配置,我的实际配置都是这样的,别的配置文件只是把server_name callback-m.goywzl.com换成别的域名而以,只要配置文件名包含callback-m这样的名字,我所有的配置文件中不同的域名的请求,都会变成400错误
server {
listen 80;
server_name callback-m.goywzl.com;
listen 443 ssl;
ssl on;
ssl_certificate /data/goywzl-certificate/goywzl.com.crt;
ssl_certificate_key /data/goywzl.com-certificate/goywzl.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers XXXXXXXXXXXXXXXXXXXXXXX
然而,使用这个文件名(callback-m),去掉ssl on 这个参数,就恢复正常,
我这里有两个疑问:
第一,如果如你所说,这个ssl on 并不应该影响其它的配置文件中的server {}内容
第二,我更改了文件名callback-m换成任意名字pre-m之后,我这个ssl on也开启,然而也没有影响到其它的server {}内容

goywzl commented Dec 28, 2016

你好,非常感谢你的热心帮助,不过我想描述的问题并不是这样的。
首先你说的那个ssl on,我别的都是这样配置的,并没有问题,可以走http,也可以走https,我就是非常不明白的为什么配置文件名会有这样的影响,下面附上我的配置,我的实际配置都是这样的,别的配置文件只是把server_name callback-m.goywzl.com换成别的域名而以,只要配置文件名包含callback-m这样的名字,我所有的配置文件中不同的域名的请求,都会变成400错误
server {
listen 80;
server_name callback-m.goywzl.com;
listen 443 ssl;
ssl on;
ssl_certificate /data/goywzl-certificate/goywzl.com.crt;
ssl_certificate_key /data/goywzl.com-certificate/goywzl.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers XXXXXXXXXXXXXXXXXXXXXXX
然而,使用这个文件名(callback-m),去掉ssl on 这个参数,就恢复正常,
我这里有两个疑问:
第一,如果如你所说,这个ssl on 并不应该影响其它的配置文件中的server {}内容
第二,我更改了文件名callback-m换成任意名字pre-m之后,我这个ssl on也开启,然而也没有影响到其它的server {}内容

@chobits

This comment has been minimized.

Show comment
Hide comment
@chobits

chobits Dec 29, 2016

Member

只要我把配置文件名callback-m.conf随便改成不是callback-m这样的名字,如(callbackm.conf)里面的内容不变,就不会在出现上面的报错

这个和文件加载顺序有关(include conf.d/*.conf加载配置文件的顺序会更具文件名不同而改变)。

通过sbin/nginx -d参数导出展开整个的配置。

这个展开的配置中第一个server{}(如果没有配置listen default_server参数,第一个server{}块是默认server) 中 的ssl on注释掉后,其他server{}会自动生效。

我举个例子解释下:

server {
    listen 80;    # << 注意这里listen 80所在的第一个server是其他所有listen 80的server的默认server
                  #    这个server所有listen fd的属性会集成到其他server{}上相同监听<ip>:<port>的fd上
    server_name a.com;
    ssl on;       # << 这个ssl on 会影响listen 80的fd的属性
}

server {
    listen 80;
    server_name b.com;
    ssl on;        # << 这个ssl on 不会影响listen 80的fd的属性
}

Member

chobits commented Dec 29, 2016

只要我把配置文件名callback-m.conf随便改成不是callback-m这样的名字,如(callbackm.conf)里面的内容不变,就不会在出现上面的报错

这个和文件加载顺序有关(include conf.d/*.conf加载配置文件的顺序会更具文件名不同而改变)。

通过sbin/nginx -d参数导出展开整个的配置。

这个展开的配置中第一个server{}(如果没有配置listen default_server参数,第一个server{}块是默认server) 中 的ssl on注释掉后,其他server{}会自动生效。

我举个例子解释下:

server {
    listen 80;    # << 注意这里listen 80所在的第一个server是其他所有listen 80的server的默认server
                  #    这个server所有listen fd的属性会集成到其他server{}上相同监听<ip>:<port>的fd上
    server_name a.com;
    ssl on;       # << 这个ssl on 会影响listen 80的fd的属性
}

server {
    listen 80;
    server_name b.com;
    ssl on;        # << 这个ssl on 不会影响listen 80的fd的属性
}

@chobits

This comment has been minimized.

Show comment
Hide comment
@chobits

chobits Dec 29, 2016

Member

BTW,nginx配置中有listen指令其实是层级是要高于server{} 的。
因为listen的fd的连接的属性其实是要先于7层数据包中的server_name属性(对应http请求中Host字段)。

这会导致 不同server{}中相同listen <ip>:<port>配置的属性只受默认server{}的控制。

默认server{}: 可以用listen的default_server参数控制,如果listen指令没有设置该参数,则含有相同listen <ip>:<port>配置的各个server{}块中第一个server{}块是默认server{}。


listen文档

The default_server parameter, if present, will cause the server to become the default server for the specified address:port pair. If none of the directives have the default_server parameter then the first server with the address:port pair will be the default server for this pair.

Member

chobits commented Dec 29, 2016

BTW,nginx配置中有listen指令其实是层级是要高于server{} 的。
因为listen的fd的连接的属性其实是要先于7层数据包中的server_name属性(对应http请求中Host字段)。

这会导致 不同server{}中相同listen <ip>:<port>配置的属性只受默认server{}的控制。

默认server{}: 可以用listen的default_server参数控制,如果listen指令没有设置该参数,则含有相同listen <ip>:<port>配置的各个server{}块中第一个server{}块是默认server{}。


listen文档

The default_server parameter, if present, will cause the server to become the default server for the specified address:port pair. If none of the directives have the default_server parameter then the first server with the address:port pair will be the default server for this pair.

@InfoHunter

This comment has been minimized.

Show comment
Hide comment
@InfoHunter

InfoHunter Dec 29, 2016

Contributor
Contributor

InfoHunter commented Dec 29, 2016

@chobits

This comment has been minimized.

Show comment
Hide comment
@chobits

chobits Dec 29, 2016

Member

hi @InfoHunter
是的。这块配置语义结构不太好导致内部其他相关连实现也受牵连。

感觉这种层次更好些

listen <ip:port> {
  server {} 
  server {} 
}

凯神多照顾下Tengine:) 好些SSL issue我处理起来特别费劲。

Member

chobits commented Dec 29, 2016

hi @InfoHunter
是的。这块配置语义结构不太好导致内部其他相关连实现也受牵连。

感觉这种层次更好些

listen <ip:port> {
  server {} 
  server {} 
}

凯神多照顾下Tengine:) 好些SSL issue我处理起来特别费劲。

@zbxiao

This comment has been minimized.

Show comment
Hide comment
@zbxiao

zbxiao Sep 26, 2017

insteresting

zbxiao commented Sep 26, 2017

insteresting

@levizhao

This comment has been minimized.

Show comment
Hide comment
@levizhao

levizhao Apr 28, 2018

有些服务器确实是这样,可能是客户端https请求Host头字段加了端口
Host: www.163.com 写成
Host: www.163.com:443
引起服务器报错造成的

levizhao commented Apr 28, 2018

有些服务器确实是这样,可能是客户端https请求Host头字段加了端口
Host: www.163.com 写成
Host: www.163.com:443
引起服务器报错造成的

@chobits

This comment has been minimized.

Show comment
Hide comment
@chobits

chobits May 3, 2018

Member

关闭中,如仍有问题可以重新打开

Member

chobits commented May 3, 2018

关闭中,如仍有问题可以重新打开

@chobits chobits closed this May 3, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment