V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
yaott2020
V2EX  ›  Go 编程语言

Golang TLS 问题

  •  
  •   yaott2020 · 2022-02-15 23:52:03 +08:00 · 2187 次点击
    这是一个创建于 1003 天前的主题,其中的信息可能已经有所发展或是发生改变。

    用 Golang 写一个 TLS 隧道,不想验证域名(SNI),双向验证两端证书是否为同个 CA 证书签发,该如何实现。。

    试过 VerifyPeerCertificate 但是在本地网络下可以运行,到了远程就报错,不知为何

    路过大佬求点拨,以下是两端配置,谢谢。。。

    ======== Server ======== tlsConfig := tls.Config{} tlsConfig.InsecureSkipVerify = true tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert tlsConfig.Certificates = []tls.Certificate{func() tls.Certificate { CertKey, err := tls.X509KeyPair(ServerCert, ServerKey) if err != nil { panic(err) } return CertKey }()} tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { Roots := x509.NewCertPool() Roots.AppendCertsFromPEM(CA) cert, _ := x509.ParseCertificate(rawCerts[0]) opts := x509.VerifyOptions{ DNSName: "", Roots: Roots, } _, err := cert.Verify(opts) if err != nil { return err } return nil } ===== Client ===== tlsConfig := tls.Config{} tlsConfig.InsecureSkipVerify = true tlsConfig.Certificates = []tls.Certificate{func() tls.Certificate { CertKey, err := tls.X509KeyPair(ClientCert, ClientKey) if err != nil { panic(err) } return CertKey }()} tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { Roots := x509.NewCertPool() Roots.AppendCertsFromPEM(CA) cert, _ := x509.ParseCertificate(rawCerts[0]) opts := x509.VerifyOptions{ DNSName: "", Roots: Roots, } _, err := cert.Verify(opts) if err != nil { return err } return nil }

    7 条回复    2022-03-01 09:11:42 +08:00
    yaott2020
        1
    yaott2020  
    OP
       2022-02-15 23:56:47 +08:00
    我也不清楚为啥会这样,直接看图吧

    https://imgtu.com/i/HW3T76
    https://imgtu.com/i/HW3HAK
    jinliming2
        2
    jinliming2  
       2022-02-16 09:25:55 +08:00
    没做错误处理、自己处理一下
    server 端:
    cert, err := tls.LoadX509KeyPair(*cert, *key)

    CA := x509.NewCertPool()
    file, err := ioutil.ReadFile(*ca)
    CA.AppendCertsFromPEM(file)

    tlsConfig := tls.Config{
    GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
    return &cert, nil
    },
    ClientAuth: tls.RequireAndVerifyClientCert,
    ClientCAs: CA,
    // ...
    }

    客户端:
    cert, err := tls.LoadX509KeyPair(*cert, *key)

    CA := x509.NewCertPool()
    file, err := ioutil.ReadFile(*ca)
    CA.AppendCertsFromPEM(file)

    tlsConfig := tls.Config{
    Certificates: []tls.Certificate{cert},
    RootCAs: certPool,
    ClientAuth: tls.RequireAndVerifyClientCert,
    ClientCAs: certPool,
    // ...
    }
    yaott2020
        3
    yaott2020  
    OP
       2022-02-16 12:54:42 +08:00
    多谢,已解决
    dzdh
        4
    dzdh  
       2022-02-20 21:30:18 +08:00
    @yaott2020 咋解决滴
    yaott2020
        5
    yaott2020  
    OP
       2022-03-01 09:09:22 +08:00 via Android
    服务器设置:
    ```
    InsecureSkipVerify = false
    Certificates //放服务器证书
    ClientCAs //放 CA 证书
    ClientAuth = tls.RequireAndVerifyClientCert
    ```

    客户端设置:
    ```
    InsecureSkipVerify = false
    Certificates //放客户端证书
    RootCAs //放 CA 证书
    ServerName //设置 SNI ,必须与服务器证书的 servername 一致
    ```
    yaott2020
        6
    yaott2020  
    OP
       2022-03-01 09:10:20 +08:00 via Android
    客户端连接地址可以是域名可以是 ip ,反正会使用 ServerName 验证 SNI
    yaott2020
        7
    yaott2020  
    OP
       2022-03-01 09:11:42 +08:00 via Android
    服务器和客户端证书建议用同一个 CA 证书签发,(其他情况没试过)该配置可以实现双向验证
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1048 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 22:18 · PVG 06:18 · LAX 14:18 · JFK 17:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.