zoukankan      html  css  js  c++  java
  • nginx的access日志打印十六进制x16x03x01x02x00x01

    背景

    心血来潮想给自己的小网站加上https协议,照着网上一顿操作,结果浏览器提示“ERR_SSL_PROTOCOL_ERROR”无法打开。查看nginx的error日志没有报错,查看access日志如下,其中$request字段打印的全是十六进制(以x16x03x01x02x00x01开头)。

    先说解决办法-启用SSL支持

    不同版本(nginx -v查看)的Nginx启用ssl的配置不一样!!

    #版本1.15.0及以下
    listen 443;
    ssl on;
    
    #版本1.15.0以上
    listen 443 ssl;
    

    --------- 分割线 ---------

    再看看这一串十六进制怎么回事

    有几个疑问需要解决一下:

    1.为什么浏览器中访问一次,access日志会有四条记录?

    本机fiddler抓包发现,浏览器中访问一次,chrome向服务器发出了四次https连接请求。

    2.十六进制是乱码吗?

    .尝试解码“x16x03...”这一段,失败不行!其实熟悉ASCII码就知道这串是转换不成字符串的,可见字符是从32(空格)开始的

    .怀疑是中文,照着网上的方法将nginx的logformat增加一个escape属性“log_format main escape=json”,结果打印的十六进制部分变成了“u0016u0003u0001u0002”,失败!

    所以这些十六进制并不是乱码!怎么肥事?

     

    首先查看nginx的logformat可以知道显示成十六进制的这部分是$request,$request由三个部分组成:http请求方法 http的url http的版本,如“GET / HTTP/1.1.0”。HTTP报文中请求方法与URL直接用空格(x20)分隔,协议版本和其他内容用换行(x0A)分隔。

    其次对比一下http、https访问连接服务器过程:

    http:  TCP三次握手——发送请求数据——后台处理——返回结果

    https: TCP三次握手——客户端发起https认证请求(第一步由client发送hello报文并带上相关信息)...

    Nginx没有正确开启支持SSL的情况下,access日志会出现$request字段是十六进制字符串,会不会是Nginx把https认证过程中的第一个hello报文当作http报文进行解析了?

    抓包验证截图如下,其中报文的原始数据中(最后一个红框)显示的十六进制与access日志中打印的十六进制几乎完全一样!有兴趣的同学可以自行对比验证一下!

    结论

    在Nginx没有开启SSL支持的情况下,Nginx将https连接建立过程中的客户端hello报文当作http报文处理,暴力的截取了报文中指定位置的十六进制字符串当作了$request的http请求方法、URL和版本号,所以access日志中会出现十六进制字符串。

    那为什么access日志中4个请求的$request开头部分是一致的,后面部分又不一致了呢?分析hello报文格式就知道了!

  • 相关阅读:
    hdu--4336--概率dp
    hdu--3905--dp
    codeforces--279--
    hdu--5023--线段树
    正则表达式
    vim编辑器使用
    圆头像控件,自动监听点击跳转到Activity
    ImageView切换两种状态下的模式
    string字符串截取
    Class对象获取方法
  • 原文地址:https://www.cnblogs.com/wurijie/p/13222397.html
Copyright © 2011-2022 走看看