我一直试图使用nginx作为我的外部REST GET API之一的反向代理,以调试延迟问题b/w我的Golang服务和外部服务.

我可以通过Golang的net/http库很容易地调用公共URL并获得成功的响应,但当我使用nginx作为反向代理时,nginx给出了502 Bad Gateway.在nginx-error.log文件中,我收到了如下所示关于SSL的错误,但我想知道如何在通过Golang Net/http客户端调用API时没有收到错误.

附注:我创建了一个简单的/ping-nginx API,它只返回200 statusCode和pong-nginx作为响应,从而交叉判断了nginx是否正在运行.

Ping.go

package main

import (
    "fmt"
    "log"
    "net/http"
    "strconv"
)

func main() {
    http.HandleFunc("/ping-via-go-client", func(w http.ResponseWriter, r *http.Request) {
        url := "https://flights-explorer.makemytrip.com/ping"
        resp, err := http.Get(url)
        var statusCode string
        if err == nil {
            statusCode = strconv.Itoa(resp.StatusCode)
        }
        fmt.Fprintf(w, "pong-via-go-client with statusCode:"+statusCode)
    })

    http.HandleFunc("/ping-via-nginx", func(w http.ResponseWriter, r *http.Request) {
        url := "http://localhost/ping"
        resp, err := http.Get(url)
        var statusCode string
        if err == nil {
            statusCode = strconv.Itoa(resp.StatusCode)
        }
        fmt.Fprintf(w, "pong-via-nginx with statusCode:"+statusCode)
    })

    log.Fatal(http.ListenAndServe(":3003", nil))
}

卷发的react :

➜  ~ curl http://localhost:3003/ping-via-go-client
pong-via-go-client with statusCode:200%
➜  ~ curl http://localhost:3003/ping-via-nginx
pong-via-nginx with statusCode:502%

Nginx.conf

#user  nginx;
daemon off;

worker_processes  auto;

error_log  /opt/logs/nginx-error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  250;
}
http {
log_format upstream_time '$time_local $status $remote_addr to:- $upstream_addr $request '
    'uct:$upstream_connect_time uht:$upstream_header_time urt:$upstream_response_time '
    'request_time:$request_time tid_header:$http_tid status:$upstream_cache_status '
    'slot:$http_slot slot_time:$http_slotstarttime ttl_req:$http_ttl ttl_resp:$upstream_http_x_accel_expires '
    'job_flag:$http_jobflag cookies:"$http_cookie" bytes_sent:$bytes_sent gzip_ratio:$gzip_ratio '
    '"$http_referer" "$http_user_agent" $http_x_forwarded_for cur_time:$msec';
        keepalive_timeout 85;
        upstream flights-explorer.makemytrip.com {
              server flights-explorer.makemytrip.com:443;
              keepalive 30;
        }
    server {
        listen 80;
        access_log /opt/logs/nginx-access.log upstream_time;
                  location = /basic_status {
                            stub_status;
                  }

        location /ping-nginx {
            return 200 'pong-nginx\n';
            add_header Content-Type text/plain;
        }

        location /ping {
               # proxy_buffering off;
             proxy_pass https://flights-explorer.makemytrip.com$request_uri;
             proxy_http_version 1.1;
             proxy_set_header Connection "";
             proxy_ssl_verify off;  # Disable SSL certificate verification
             proxy_ssl_verify_depth 0;
             #proxy_ssl_session_reuse on;
             #proxy_socket_keepalive on;
             proxy_connect_timeout 10s;
             proxy_read_timeout 10s;
        }

    }
}

Nginx-error.log中的错误

2024/03/03 11:07:55 [error] 20078#0: *6 SSL_do_handshake() failed (SSL: error:0A000438:SSL routines::tlsv1 alert internal error:SSL alert number 80) while SSL handshaking to upstream, client: 127.0.0.1, server: , request: "GET /ping HTTP/1.1", upstream: "https://23.63.110.25:443/ping", host: "localhost"
2024/03/03 11:07:55 [warn] 20078#0: *6 upstream server temporarily disabled while SSL handshaking to upstream, client: 127.0.0.1, server: , request: "GET /ping HTTP/1.1", upstream: "https://23.63.110.25:443/ping", host: "localhost"
2024/03/03 11:07:55 [error] 20078#0: *6 SSL_do_handshake() failed (SSL: error:0A000438:SSL routines::tlsv1 alert internal error:SSL alert number 80) while SSL handshaking to upstream, client: 127.0.0.1, server: , request: "GET /ping HTTP/1.1", upstream: "https://23.63.110.67:443/ping", host: "localhost"
2024/03/03 11:07:55 [warn] 20078#0: *6 upstream server temporarily disabled while SSL handshaking to upstream, client: 127.0.0.1, server: , request: "GET /ping HTTP/1.1", upstream: "https://23.63.110.67:443/ping", host: "localhost"
2024/03/03 11:07:56 [error] 20078#0: *6 SSL_do_handshake() failed (SSL: error:0A000438:SSL routines::tlsv1 alert internal error:SSL alert number 80) while SSL handshaking to upstream, client: 127.0.0.1, server: , request: "GET /ping HTTP/1.1", upstream: "https://23.63.110.74:443/ping", host: "localhost"
2024/03/03 11:07:56 [warn] 20078#0: *6 upstream server temporarily disabled while SSL handshaking to upstream, client: 127.0.0.1, server: , request: "GET /ping HTTP/1.1", upstream: "https://23.63.110.74:443/ping", host: "localhost"

Nginx-acces.log上的日志(log)

03/Mar/2024:11:07:56 +0530 502 127.0.0.1 to:- 23.63.110.25:443, 23.63.110.67:443, 23.63.110.74:443 GET /ping HTTP/1.1 uct:-, -, - uht:-, -, - urt:0.131, 0.116, 0.107 request_time:0.354 tid_header:- status:- slot:- slot_time:- ttl_req:- ttl_resp:- job_flag:- cookies:"-" bytes_sent:314 gzip_ratio:- "-" "Go-http-client/1.1" - cur_time:1709444276.083

推荐答案

终于找到了解决办法.

这篇博客清楚地解释了upstream 对ServerName(SNI)的需求(可以使用openssl命令进行验证),在进行了它建议的更改后,它对我来说没有任何问题.

https://www.infiniroot.com/blog/1120/nginx-reverse-proxy-ssl-alert-number-40-while-ssl-handshaking-upstream

附言:我直接贴了链接,而不是解释BCZ,作者已经详细解释了一切,值得一读.

@Steffen Ullrich早些时候就曾建议过这一点,但对于另外两名Conf,他们没有让这一建议奏效.

Go相关问答推荐

CGO Linux到Windows交叉编译中的未知类型名称

如何描述OpenAPI规范中围棋的数据类型.JSON?

GO错误:Tim.Time未实现driver.Valuer(缺少方法值)

如何将GoFr筛选器用于查询参数?

在GO中创建[]字符串类型的变量

理解Golang中的IOTA和常量

Go 是否提供了标准或事实上的方法来处理单个语句中的错误(即内联错误处理)?

转到 bufio.Writer、gzip.Writer 并上传到内存中的 AWS S3

从 ApiGateway 中的 lambda Go 返回 Json

如何将验证器标记添加到嵌套字段

在 Cloud Run 中找不到默认凭据

数据流中的无根单元错误,从 Golang 中的 PubSub 到 Bigquery

Golang Getrlimit 返回与 ulimit 不同的值

如何在Go中替换符号并使下一个字母大写

Golang Echo Labstack 如何在模板视图中调用函数/方法

递归数据 struct 解组在 Go Lang Protobuf 中给出错误无法解析无效的线格式数据

如何在 docker 文件中安装 golang 包?

在 Go 中,为什么 exec.Command() 失败但 os.StartProcess() 成功启动winget.exe?

如何在 Gorm 中获得特定日期的最大值?

如何断言类型是指向golang中接口的指针