Сертификаты TLS между несколькими облаками со случайными ips - PullRequest
0 голосов
/ 02 апреля 2020

Как начинающий tls, я действительно не уверен, что мне следует делать здесь.

У меня есть клиентское приложение в go, использующее ListenAndServeTLS, которое отправляет запрос серверному приложению в go, что также использует ListenAndServeTLS. Я могу отправить запрос от клиента на сервер и проверить локально сгенерированный сертификат.

Когда я обновляю свой клиент для общения с прокси-агентом (c#), у меня в Azure открывается sslstream к службе ретрансляции azure, которая подключена к моему серверу на моей локальной машине. Я получаю следующую ошибку. Get https://<ip_address>:8080/hello: x509: cannot validate certificate for <ip_address> because it doesn't contain any IP SANs

Я использую IP-адрес Dynami c и не имеет хоста или DNS. Как мне проверить мой сертификат на сервере, если IP-адрес меняется с каждым моим запросом.

// Server Code
func helloHandler(w http.ResponseWriter, r *http.Request) {
    // Write "Hello, world!" to the response body
    io.WriteString(w, "Hello, world!\n")
}

func main() {
    // Create a CA certificate pool and add cert.pem to it
    caCert, err := ioutil.ReadFile("../certs/cert.pem")
    if err != nil {
        log.Fatal(err)
    }
    caCertPool := x509.NewCertPool()
    caCertPool.AppendCertsFromPEM(caCert)
    // Create the TLS Config with the CA pool and enable Client certificate validation
    tlsConfig := &tls.Config{
        ClientCAs:  caCertPool,
        ClientAuth: tls.RequireAndVerifyClientCert,
    }
    tlsConfig.BuildNameToCertificate()

    server := &http.Server{
        Addr:      ":8080",
        TLSConfig: tlsConfig,
    }
    // Set up a /hello resource handler
    http.HandleFunc("/hello", helloHandler)

    // Listen to port 8080 and wait
    log.Fatal(server.ListenAndServeTLS("../certs/cert.pem", "../certs/key.pem"))
}
// Client Code
func main() {
    cert, err := tls.LoadX509KeyPair("../certs/cert.pem", "../certs/key.pem")
    if err != nil {
        log.Fatal(err)
    }

    // Create a CA certificate pool and add cert.pem to it
    caCert, err := ioutil.ReadFile("../certs/cert.pem")
    if err != nil {
        log.Fatal(err)
    }
    caCertPool := x509.NewCertPool()
    caCertPool.AppendCertsFromPEM(caCert)

    client := &http.Client{
        Transport: &http.Transport{
            TLSClientConfig: &tls.Config{
                // InsecureSkipVerify: true,
                RootCAs:      caCertPool,
                Certificates: []tls.Certificate{cert},
            },
        },
    }

    // Request /hello over port 8080 via the GET method
    // r, err := http.Get("http://localhost:8080/hello")
    // Request /hello over HTTPS port 8443 via the GET method
    r, err := client.Get("https://<ip_address>:8080/hello")
    if err != nil {
        log.Fatal(err)
    }

    // Read the response body
    defer r.Body.Close()
    body, err := ioutil.ReadAll(r.Body)
    if err != nil {
        log.Fatal(err)
    }

    // Print the response body to stdout
    fmt.Printf("%s\n", body)
}

1 Ответ

0 голосов
/ 02 апреля 2020

Во-первых, чтобы устранить ошибочное представление: сервер не проверяет сертификаты. Сертификаты являются криптографическим c доказательством идентичности, которое используется клиентами , поэтому они могут быть уверены, что они подключены к серверу, к которому они предназначены. Т.е. они хотят быть уверены, что сетевое соединение не было случайно или злонамеренно направлено на другой сервер. Таким образом, если проверка сертификата не удалась, это почти всегда, потому что клиент не удовлетворен, а не сервер.

Когда вы делаете HTTP-запрос к https://192.0.2.1:8080/hello, клиент по умолчанию ожидает, что он будет представлен сертификатом, включающим 192.0.2.1 в альтернативные имена субъекта (SAN), потому что это будет значение поля Host запроса (и, как сказано выше, клиент хочет убедиться, что он действительно подключился к этому серверу) ).

Если вы заранее не знаете IP-адреса, вы не можете выдать такой сертификат, и единственный вариант - изменить ожидания клиента. Для этого и используется поле ServerName в tls.Config . Просто установите для него общее имя сертификата (которое должно быть доменом).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...