У меня есть приложение на Go, в котором в одном из потоков работает простой HTTP сервер. К этому серверу обращаются по HTTPS. Запрос приходит на Pound — HTTP/HTTPS reverse-proxy and load-balancer и перенаправляется в приложение. TLS сертификат изготавливается и обновляется с помощью Let’s Encrypt.
Простая и привычная схема. Правда, чаще в этой схеме бывает Nginx, но в этой статье мы не будем рассуждать, почему Pound, а не Nginx. Все очень хорошо, но меня последнее время начинает раздражать, когда к простому и понятному коду на Go нужно прикрутить небольшого динозаврика с пять-шестью скриптами на Ansible, закатать все это в деплой и радоваться тому, как это все славно улеглось в небольшой виртуалке.

Я где-то там, в своем начале длительное время писал на Assembler-е. Размер откомпилированной программы больше одного Кб считался огромным. Видимо с тех пор во мне застряло желание экономить ресурсы компьютера, несмотря на то, что разработчики железа предоставляют их все больше и больше. Так же я ни как не могу привыкнуть к этим жутким папкам под названием ‘node_modules’ и всегда хочу стереть их содержимое.
И я задумался…
Задумался над тем, как можно сократить количество участников в задаче «HTTP-сервер с сертификатом Let’s Encrypt на Go». Год думал. Шучу. Мое приложение с динозавриками замечательно проработало год, и настало время сделать обновления.
И решение нашлось. Оказывается, все, что нужно для облегчения этой задачи, есть в библиотеке Go. Итак, вот что нужно написать в программе на Go для того, что бы работал HTTPS сервер и автоматически создавался и обновлялся TLS сертификат по технологии Let’s Encrypt:
mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, TLS user! Your config: %+v", r.TLS) }) log.Fatal(http.Serve(autocert.NewListener(domain), mux))
И все! Да, и все — те же самые стандартные три строчки, которые присутствуют во всех примерах создания HTTP-сервера. Ищем отличия, а я посмотрю на секундомер…
Ну конечно! — ‘autocert.NewListener(domain)’ в ‘http.Serve’.
Приложение, использующее этот код, должно быть запущено с правами администратора, и на хосте должен быть белый IP адрес. Без него Let’s Encrypt не сможет создать сертификат.
Для того что бы работала привычная нам переадресация с HTTP на HTTPS, добавим еще пару строк кода перед предыдущим кодом:
go func() { if err := http.ListenAndServe(":80", http.HandlerFunc(redirectTLS)); err != nil { log.Fatalf("ListenAndServe error: %v", err) } }()
Здесь мы создали еще один HTTP сервер, работающий на 80-м порту и пересылающий все на наш основной сервер с помощью функции ‘redirectTLS’:
func redirectTLS(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "https://"+domain+":443"+r.RequestURI, http.StatusMovedPermanently) }
Приложение имеет параметр ‘–domain’ и строка запуска выглядит так:
sudo go run . -domain=example.com
Конечно. Для запуска этого приложения у вас должен быть зарегистрированный домен и белый IP адрес.
Программа размещена на Github:
https://github.com/kirill-scherba/https-example
Вот ещё один адрес на Gitflic, пока он запасной:
https://gitflic.ru/project/kirill-scherba/https-example
ссылка на оригинал статьи https://habr.com/ru/post/662940/
Добавить комментарий