Создать HTTPS тестовый сервер для любого клиента - PullRequest
0 голосов
/ 27 февраля 2019

Сервер, созданный NewTLSServer , может проверять вызовы для клиента, явно созданного из него:

ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Hello, client")
}))
defer ts.Close()

client := ts.Client()
res, err := client.Get(ts.URL)

в строке client := ts.Client().

ОднакоУ меня есть производственная программа, которую я хочу установить для использования ts.URL в качестве хоста.Я получаю

x509: certificate signed by unknown authority

ошибки при его вызове.

Как настроить ts для аутентификации на клиенте, как на обычном HTTPS-сервере?

1 Ответ

0 голосов
/ 02 марта 2019

Начиная с Go 1.11, это просто невозможно полностью выполнить в программе _test.go, из-за механики HTTPS.

Однако вы можете выполнить подпись одного сертификата и генерацию server.crt и server.key файлов, а затем ссылаться на них в ваших _test.go программах из локального каталога на неопределенный срок.

Единовременное .crt и .key поколение

Это сокращенное, слегка упрощенная версия шагов, указанных в статье Дакша Шаха «Средний», Как заставить HTTPS работать в локальной среде разработки за 5 минут , которая будет работать на Mac.

В каталогегде вам нужны ваши файлы server.crt и server.key, создайте два файла конфигурации

server.csr.cnf

[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[dn]
C=US
ST=RandomState
L=RandomCity
O=RandomOrganization
OU=RandomOrganizationUnit
emailAddress=hello@example.com
CN = localhost

и

v3.ext

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1

Затем введите в этот каталог следующие команды

openssl genrsa -des3 -out rootCA.key 2048 
# create a passphrase
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem -config server.csr.cnf
# enter passphrase
openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout server.key -config server.csr.cnf
openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 500 -sha256 -extfile v3.ext
# enter passphrase

Наконец, сделайте так, чтобы ваша система доверяла сертификату, который вы использовали для подписи файлов, запустив

open rootCA.pem

Это должно открыть CСертификат в приложении Keychain Acces, где он будет найден в разделе Сертификаты и назван localhost.Затем Always Trust it

  • Нажмите enter, чтобы открыть его окно
  • Нажмите пробел, чтобы повернуть вниз Trust
  • Измените «При использовании этого сертификата:» на Всегда доверять
  • Закройте окно и подтвердите свое решение

Примечание: Я пыталсямногие перестановки security add-trusted-cert из командной строки и, несмотря на то, что он добавляет сертификат в цепочку для ключей и помечает его как «Всегда доверять», мои программы на Go просто не будут ему доверять.Только метод GUI переводит систему в состояние, в котором мои Go-программы будут доверять сертификату.

Любые Go-программы, которые вы запускаете локально с использованием HTTPS, теперь будут доверять серверам, на которых вы используете server.crt и server.key.

Запуск сервера

Вы можете создать *httptest.Server экземпляров, которые используют эти учетные данные с

func NewLocalHTTPSTestServer(handler http.Handler) (*httptest.Server, error) {
    ts := httptest.NewUnstartedServer(handler)
    cert, err := tls.LoadX509KeyPair("server.crt", "server.key")
    if err != nil {
        return nil, err
    }
    ts.TLS = &tls.Config{Certificates: []tls.Certificate{cert}}
    ts.StartTLS()
    return ts, nil
}

Вот пример использования:

func TestLocalHTTPSserver(t *testing.T) {
    ts, err := NewLocalHTTPSTestServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprint(w, "Hello, client")
    }))
    assert.Nil(t, err)
    defer ts.Close()

    res, err := http.Get(ts.URL)
    assert.Nil(t, err)

    greeting, err := ioutil.ReadAll(res.Body)
    res.Body.Close()
    assert.Nil(t, err)

    assert.Equal(t, "Hello, client", string(greeting))
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...