Go сервер Https

Пытаюсь запустить приложение, написанное на Go, с использованием самоподписанного SSL сертификата. Пример:

func main() {
    mux := http.NewServeMux()

    mux.Handle("/", httpHandlerFunc(func(w http.ResponseWriter, r *http.Request) {

        if r.URL.Path != "/" {
            http.Error(w, "404", http.StatusNotFound)
            return
        }

        w.WriteHeader(http.StatusOK)
        w.Write([]byte("Hello Https"))
    }))

    http.Handle("/assets/", http.FileServer(http.Dir(".")))
    log.Fatal(http.ListenAndServeTLS(":443", "cert.pem", "cert.key", mux))
}

Какие действия предпринимались:

  1. Создание сертификата через гошный generate_cert.go, но получаю ошибку: TLS handhsake EOF
  2. Пробовал с помощью встроенного в Linux openssl создать сертификат, результат тот же

Как генерирую сертификат: go run generate_cert.go --host="127.0.0.1" (в случае со встроенной утилитой) openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 (в случае со встроенным в linux openssl)

UPD: Браузер считает сертификат (Acme Co) не подлинным / ненадёжным


Ответы (2 шт):

Автор решения: Kirill Veresnikov

Самоподписанные сертификаты в доверенные нужно добавить с помощью ca-certificates Тут вроде норм инструкция https://unix.stackexchange.com/questions/90450/adding-a-self-signed-certificate-to-the-trusted-list

→ Ссылка
Автор решения: Thony

Поскольку ответа я так и не получил и изначально сформулировал вопрос не совсем корректно, а задачу уже решил самостоятельно, отвечу для тех, кому это в дальнейшем может пригодится.

Есть два пути решения:

  1. Проксирование через Nginx
  2. Использование пакета autocert (https://pkg.go.dev/golang.org/x/crypto/acme/autocert)

Примечание:

Что в первом, что во-втором случае, вам необходимо обзавестись доменом (поскольку для IP адреса выпустить SSL сертификат не получится).

Первый вариант (с Nginx) универсальный (по этой и другим причинам я на нём и остановился), но, лучше всего подходит в том случае, когда ваш проект использует несколько сервисов (допустим, основной сайт у вас работает на Go, на 80 и 443 порту, а сервис оплаты на Java у вас работает на 8000 порту).

Второй вариант (autocert) будет оптимальным, если ваше приложение (веб-сервис) написан на Go и проксировать какие-то определенные маршруты на другое приложение, запущенное на другом порту, не нужно.

В первом варианте вам необходимо установить nginx, затем открыть 80 и 443 порты (напр. через ufw, если у вас ubuntu), после чего запустить вашу программу на Go на каком-нибудь условном 9000 порту, открыть sudo nano /etc/nginx/sites-available/default и сделать proxy_pass на ваше Go приложение с указанием порта (в нашем случае 9000). Перезапустить nginx с помощью systemctl restart nginx. Всё.

В первом случае (с Nginx), вам необходимо сделать следующее:

  1. Установить nginx
  2. Открыть порты (80 и 443). Для Ubuntu это делается через ufw
  3. Проверить, что ufw (как и nginx) включен и работает
  4. Установить certbot-nginx
  5. Привязать ваш домен к IP адресу вашего сервера (обычно у хостера в настройках просто меняете DNS записи и всё готово)
  6. Выпустить сертификат для домена с помощью команды: sudo certbot --nginx -d mysite.ru -d www.mysite.ru (если пишет ошибку, подождите пока обновятся данные DNS). Если прошло больше суток, а сертификат не выпускается, проверьте, что домен привязан к IP. См. пункт 5.
  7. Прописать proxy_pass на порт вашего приложения на Go с помощью: sudo nano /etc/nginx/sites-available/default
  8. Перезапустить Nginx с помощью: sudo systemctl restart nginx
  9. В методе ListenAndServerTLS указать путь к файлу key и cert (они обычно лежат по пути: /etc/letsencrypt). См. терминал.
  10. Запустить приложение на Go и протестировать

Во-втором случае (с autocert), если кто-нибудь пробовал, дополните. Но общий принцип: https://gist.github.com/alexedwards/fd7e2725962be79a00818488ea1bcd00

Надеюсь, это было полезно.

→ Ссылка