Передайте тунель CONNECT SMTP-клієнту Go
Використовуйте smtp.NewClient із уже встановленим тунелем і тримайте ім'я хоста SMTP та рукостискання STARTTLS окремо від налаштування проксі.
smtp.Dial відкриває нове з'єднання за своєю адресою. Отримавши з'єднання через проксі HTTP CONNECT, передайте цей наявний потік у smtp.NewClient замість цього.
Для SMTP-сервера, який вимагає STARTTLS на порту надсилання, передавання може виглядати так:
func smtpOverTunnel(conn net.Conn, mailHost string) (*smtp.Client, error) {
client, err := smtp.NewClient(conn, mailHost)
if err != nil {
conn.Close()
return nil, err
}
err = client.StartTLS(&tls.Config{
ServerName: mailHost,
MinVersion: tls.VersionTLS12,
})
if err != nil {
client.Close()
return nil, err
}
return client, nil
}Пакети — net, net/smtp і crypto/tls. Викликач надає тунель, уже з'єднаний із потрібним хостом і портом SMTP, із завершеним обміном CONNECT проксі. Просто відкрити TCP до проксі недостатньо: відповідь HTTP не є привітанням SMTP.
mailHost — це ім'я хоста SMTP-сервера без порту. Зберігайте цю ідентичність для автентифікації SMTP і перевірки сертифіката. TLS-з'єднання з проксі HTTPS захищає іншу ділянку маршруту.
Повернутий клієнт готовий до наявної автентифікації SMTP і поштової транзакції застосунку. Закрийте його після завершення. Обмежте набір, CONNECT і подальші протокольні операції політикою термінів застосунку.
Проксі має дозволяти CONNECT до вибраного поштового порту. Деякі обмежують його HTTPS-призначеннями на порту 443. Для SMTP з неявним TLS установіть TLS-сеанс призначення перед викликом NewClient, а не видавайте STARTTLS.