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.

Схожі статті