簡體   English   中英

在Go中升級到TLS的連接

[英]Upgrade a connection to TLS in Go

我有一個開放的TCP連接,並使用for循環讀取它

for {
  // tx.Text is of type textproto.Conn
  // the underlying connection is stored in tx.Conn
  l, err := tx.Text.Reader.ReadLine()

  // do stuff with the text line ...
}

現在我想像這樣升級到TLS的連接( TlsConf包含一個用tls.LoadX509KeyPair加載的證書)

tx.Conn = tls.Server(tx.Conn, tx.Server.Conf.TlsConf)
tx.Text = textproto.NewConn(tx.Conn)

當我這樣做時,我在服務器嘗試握手時在客戶端上出現分段錯誤。 我正在實現一個SMTP服務器,並使用-tls標志進行swaks測試。 swaks的終端輸出如下

-> STARTTLS
<-  220 Start TLS
Segmentation fault: 11

由於swaks是一個經過測試的工具,並且使用過我之前使用的nodeJS SMTP實現,我不懷疑錯誤是在客戶端。

我做錯了什么或缺少什么?

PS:當從現有的不安全連接啟動TLS連接時,究竟會發生什么? 客戶端是否在其他端口上建立新連接或重用連接?

以下是將net.conn升級到tls.con的方法:

1)在代碼中的某處,您定義了這些變量

var TLSconfig *tls.Config
...
// conn is a normal connection of type net.Conn
conn, err := listener.Accept()
...

2)在上面的某處初始化TLSConfig,做這樣的事情

cert, err := tls.LoadX509KeyPair("/path/to/cert", "/path/to/key")
if err != nil {
    // ...
}
TLSconfig = &tls.Config{
Certificates: []tls.Certificate{cert}, 
ClientAuth: tls.VerifyClientCertIfGiven, 
ServerName: "example.com"}

3)此時您正在讀/寫標准連接。

當客戶端發出STARTTLS命令時,請在您的服務器中執行以下操作:

// Init a new TLS connection. I need a *tls.Conn type 
// so that I can do the Handshake()
var tlsConn *tls.Conn
tlsConn = tls.Server(client.socket, TLSconfig)
// run a handshake
tlsConn.Handshake()
// Here is the trick. Since I do not need to access 
// any of the TLS functions anymore,
// I can convert tlsConn back in to a net.Conn type
conn = net.Conn(tlsConn)

接下來,您可能會使用新連接等更新緩沖區。

像這樣測試你的服務器:

openssl s_client -starttls smtp -crlf -connect  example.com:25

這允許您通過tls連接與服務器交互,您可以發出一些命令等。

有關Go中轉換的更多信息

我想轉換是Go變得如此強大的另一個原因!

http://golang.org/ref/spec#Conversions

http://golang.org/doc/effective_go.html#conversions

拋棄了swaks,構建了一個小工具來使用Go自己的smtp.SendMail來測試TLS:

package main

import (
  "fmt"
  "net/smtp"
)

func main() {
  err := smtp.SendMail(
    "127.0.0.1:2525",
    nil,
    "src@test.local",
    []string{"dst@test.local"},
    []byte("Hello! Just testing."),
  )
  if err != nil {
    panic(err)
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM