You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx SSL与Varnish搭配异常,报400错误求助

问题:Nginx+Varnish配置出现400 Bad Request(HTTP请求发送到HTTPS端口)

环境:Ubuntu 20.04.6服务器,带SSL的Nginx,Varnish 6.2.1

报错内容:400 Bad Request The plain HTTP request was sent to HTTPS port nginx/1.18.0 (Ubuntu)


现有配置文件

Nginx站点配置(/etc/nginx/sites-available/file)

server {
    listen 91 ssl http2;
    server_name my_site_name;
    # varnish proxy
    location / {
        proxy_pass http://127.0.0.1:6081;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
   }
   ssl_certificate /etc/letsencrypt/live/my_site_name/fullchain.pem; # managed by Certbot
   ssl_certificate_key /etc/letsencrypt/live/my_site_name/privkey.pem; # managed by Certbot
   include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
   ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

Varnish配置(/etc/varnish/default.vcl)

vcl 4.0;

backend default {
    .host = "my_https_site";
    .port = "85";
}

sub vcl_recv {
    if (client.ip != "127.0.0.1" && req.http.host ~ "my_host.by") {
       set req.http.x-redir = "https://my_https_site" + req.url;
       return(synth(850, ""));
    }
}
sub vcl_deliver {
    if (resp.status == 850) {
       set resp.http.Location = req.http.x-redir;
       set resp.status = 301;
       return (deliver);
    }
}

Varnish启动配置(/etc/default/varnish)

DAEMON_OPTS="-a :6081 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s malloc,256m"

日志信息

Varnish后端日志(varnishlog -b)

*   << BeReq    >> 98394     
-   Begin          bereq 98393 fetch
-   VCL_use        boot
-   Timestamp      Start: 1682520086.557505 0.000000 0.000000
-   BereqMethod    GET
-   BereqURL       /
-   BereqProtocol  HTTP/1.1
-   BereqHeader    Host: my_host
-   BereqHeader    sec-ch-ua: "Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"
-   BereqHeader    sec-ch-ua-mobile: ?0
-   BereqHeader    sec-ch-ua-platform: "Linux"
-   BereqHeader    upgrade-insecure-requests: 1
-   BereqHeader    user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36
-   BereqHeader    accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
-   BereqHeader    sec-fetch-site: none
-   BereqHeader    sec-fetch-mode: navigate
-   BereqHeader    sec-fetch-user: ?1
-   BereqHeader    sec-fetch-dest: document
-   BereqHeader    accept-language: en-US,en;q=0.9,ru;q=0.8
-   BereqHeader    X-Forwarded-For: 127.0.0.1
-   BereqHeader    Accept-Encoding: gzip
-   BereqHeader    X-Varnish: 98394
-   VCL_call       BACKEND_FETCH
-   VCL_return     fetch
-   BackendOpen    26 default 181.122.19.2 85 181.122.19.2 33736
-   BackendStart   181.122.19.2 85
-   Timestamp      Bereq: 1682520086.557843 0.000338 0.000338
-   Timestamp      Beresp: 1682520086.558193 0.000688 0.000350
-   BerespProtocol HTTP/1.1
-   BerespStatus   400
-   BerespReason   Bad Request
-   BerespHeader   Server: nginx/1.18.0 (Ubuntu)
-   BerespHeader   Date: Wed, 26 Apr 2023 14:41:26 GMT
-   BerespHeader   Content-Type: text/html
-   BerespHeader   Content-Length: 666
-   BerespHeader   Connection: close
-   TTL            RFC -1 10 0 1682520087 1682520087 1682520086 0 0 cacheable
-   VCL_call       BACKEND_RESPONSE
-   TTL            VCL 120 10 0 1682520087 cacheable
-   TTL            VCL 120 10 0 1682520087 uncacheable
-   VCL_return     deliver
-   Filters        
-   Storage        malloc Transient
-   Fetch_Body     3 length stream
-   BackendClose   26 default
-   Timestamp      BerespBody: 1682520086.558474 0.000969 0.000281
-   Length         666
-   BereqAcct      657 0 657 161 666 827
-   End            

客户端请求日志

*   << Request  >> 98399     
-   Begin          req 98398 rxreq
-   Timestamp      Start: 1682521060.864589 0.000000 0.000000
-   Timestamp      Req: 1682521060.864589 0.000000 0.000000
-   VCL_use        boot
-   ReqStart       127.0.0.1 35458 a0
-   ReqMethod      GET
-   ReqURL         /favicon.ico
-   ReqProtocol    HTTP/1.1
-   ReqHeader      Connection: upgrade
-   ReqHeader      Host: my_host
-   ReqHeader      sec-ch-ua: "Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"
-   ReqHeader      sec-ch-ua-mobile: ?0
-   ReqHeader      user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36
-   ReqHeader      sec-ch-ua-platform: "Linux"
-   ReqHeader      accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
-   ReqHeader      sec-fetch-site: same-origin
-   ReqHeader      sec-fetch-mode: no-cors
-   ReqHeader      sec-fetch-dest: image
-   ReqHeader      referer: https://alva.by:91/
-   ReqHeader      accept-encoding: gzip, deflate, br
-   ReqHeader      accept-language: en-US,en;q=0.9,ru;q=0.8
-   ReqHeader      X-Forwarded-For: 127.0.0.1
-   VCL_call       RECV
-   VCL_return     hash
-   ReqUnset       accept-encoding: gzip, deflate, br
-   ReqHeader      Accept-Encoding: gzip
-   VCL_call       HASH
-   VCL_return     lookup
-   VCL_call       MISS
-   VCL_return     fetch
-   Link           bereq 98400 fetch
-   Timestamp      Fetch: 1682521060.865292 0.000702 0.000702
-   RespProtocol   HTTP/1.1
-   RespStatus     400
-   RespReason     Bad Request
-   RespHeader     Server: nginx/1.18.0 (Ubuntu)
-   RespHeader     Date: Wed, 26 Apr 2023 14:57:40 GMT
-   RespHeader     Content-Type: text/html
-   RespHeader     Content-Length: 666
-   RespHeader     X-Varnish: 98399
-   RespHeader     Age: 0
-   RespHeader     Via: 1.1 varnish (Varnish/6.2)
-   VCL_call       DELIVER
-   VCL_return     deliver
-   Timestamp      Process: 1682521060.865304 0.000715 0.000012
-   Filters        
-   RespHeader     Connection: keep-alive
-   Timestamp      Resp: 1682521060.865364 0.000775 0.000061
-   ReqAcct        568 0 568 224 666 890
-   End

解决方案

问题根源

从日志可见:Varnish以纯HTTP协议向后端my_https_site:85发送请求,但该端口的Nginx配置为HTTPS服务,因此返回400错误。

方案1:让Varnish用HTTPS请求后端

修改/etc/varnish/default.vcl,为后端启用SSL连接:

vcl 4.0;

backend default {
    .host = "my_https_site";
    .port = "85";
    .ssl = true; # 开启SSL连接
    .ssl_sni = "my_https_site"; # 指定SNI,适配多域名SSL证书
}

# 保留原有重定向逻辑
sub vcl_recv {
    if (client.ip != "127.0.0.1" && req.http.host ~ "my_host.by") {
       set req.http.x-redir = "https://my_https_site" + req.url;
       return(synth(850, ""));
    }
}
sub vcl_deliver {
    if (resp.status == 850) {
       set resp.http.Location = req.http.x-redir;
       set resp.status = 301;
       return (deliver);
    }
}

修改后重启Varnish:

systemctl restart varnish

方案2:调整后端Nginx,让端口85接收HTTP请求

如果后端无需在端口85启用SSL,修改对应Nginx站点配置,将listen 85 ssl http2;改为listen 85;,并移除该server块内的SSL相关配置(证书、ssl_dhparam等),然后重启Nginx:

systemctl restart nginx

额外检查项

  1. 用curl -v http://my_https_site:85测试后端端口,若返回400则说明是HTTPS端口,需用方案1
  2. Varnish 6.0+原生支持HTTPS后端,6.2.1版本无需额外依赖
  3. 若后端是自签名SSL证书,需在Varnish后端配置中添加.ssl_verify_depth和.ssl_ca指定证书路径,Let's Encrypt证书无需额外配置

内容的提问来源于stack exchange,提问作者Sulti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:09:55