Обслуживание сайта с помощью Caddy в Ubuntu 18.04
Ubuntu | Комментировать запись
Caddy – это простой и надежный веб-сервер, который поставляется с большим количеством полезных функций для обслуживания сайтов. Caddy может автоматически получать TLS-сертификаты Let’s Encrypt и управлять ими. Также он включает поддержку HTTP/2. HTTPS – это система для защиты трафика между пользователями и вашим сервером. Она давно стала основным требованием для работы любого веб-сайта в среде производства – если сайт не поддерживает HTTPS, браузеры Chrome и Firefox будут выдавать предупреждение «Not Secure».
Ранее для установки Caddy рекомендовалось загрузить предварительно собранные двоичные файлы с веб-сайта проекта. Однако изменения в лицензировании Caddy больше не разрешают использовать эти готовые двоичные файлы в коммерческих целях, если вы не платите лицензионный сбор (даже если вы используете Caddy только внутри компании). К счастью, исходный код Caddy по-прежнему открыт, и вы можете собрать Caddy самостоятельно и так избежать проблем с лицензированием.
В этом мануале мы соберем Caddy из исходного кода и покажем, как использовать его для обслуживания сайта с поддержкой HTTPS. Вы узнаете, как скомпилировать Caddy, настроить его с помощью Caddyfile и установить плагины, а затем обновить свою установку при выходе новой версии.
Требования
- Сервер Ubuntu 18.04 с привилегиями root и пользователем с доступом к sudo (здесь мы условно назовем его 8host). Читайте мануал по начальной настройке.
- Зарегистрированное доменное имя, указывающее на сервер (чтобы веб-сервер Caddy смог получить SSL-сертификат для сайта). В мануале мы будем использовать условный домен your_domain.
- DNS-запись А для your_domain, указывающая на внешний IP-адрес сервера.
- Цепочка инструментов Golang. Установить ее поможет этот мануал.
- Токен API.
1: Сборка Caddy
Давайте скомпилируем Caddy из исходного кода с возможностью позже добавлять плагины. При этом нам не нужно менять код Caddy.
В данном мануале мы будем хранить код в каталоге ~/caddy. Создайте этот каталог и перейдите в него:
mkdir ~/caddy
cd ~/caddy
Код для запуска и пользовательской настройки Caddy будет храниться в файле caddy.go. Создайте этот файл.
nano caddy.go
Вставьте в файл эти строки:
package main
import (
"github.com/caddyserver/caddy/caddy/caddymain"
)
func main() {
// caddymain.EnableTelemetry = false
caddymain.Run()
}
Этот код импортирует Caddy с Github с помощью Git и запускает его через функцию main. Если вы хотите включить телеметрию, раскомментируйте строку caddymain.EnableTelemetry и присвойте ей значение true. Сохраните и закройте файл.
Чтобы caddy.go мог использовать импортированные зависимости, его нужно инициализировать как модуль:
go mod init caddy
go: creating new go.mod: module caddy
Теперь у вас все готово к сборке Caddy из исходного кода. Запустите эту команду:
go install
Команда вернет очень большой вывод, в котором вы найдете подробный список библиотек Go, загруженных в качестве зевисимостей компиляции. Получившийся исполняемый файл хранится в $GOPATH/bin.
Читайте также: Всё, что нужно знать о GOPATH
Когда команда завершит работу, попробуйте запустить Caddy:
caddy
На экране вы увидите:
Activating privacy features... done.
Serving HTTP on port 2015
http://:2015
WARNING: File descriptor limit 1024 is too low for production servers. At least 8192 is recommended. Fix with `ulimit -n 8192`.
Это означает, что сервер Caddy успешно запущен и доступен по порту 2015. Предупреждение в выводе можно игнорировать, поскольку этот лимит будет скорректирован позже без вашего вмешательства. Для выхода нажмите CTRL+C.
Вы собрали и запустили Caddy. Теперь нужно установить Caddy как сервис, чтобы он автоматически запускался при загрузке сервера. Затем мы изменим права собственности и доступа, чтобы обеспечить безопасность сервера.
2: Установка Caddy
Давайте настроим сервис systemd для Caddy, чтобы Caddy мог автоматически запускаться при запуске системы.
Читайте также: Основы Systemd: управление сервисами и журналирование
Для начала переместите бинарный файл Caddy в /usr/local/bin, стандартное расположение для файлов, которые не управляются менеджером пакетов Ubuntu и не являются ключевыми для работы системы:
sudo mv $GOPATH/bin/caddy /usr/local/bin/
Затем передайте права на файл Caddy пользователю root:
sudo chown root:root /usr/local/bin/caddy
Это не позволит другим учетным записям редактировать этот исполняемый файл. Однако несмотря на то, что права на Caddy принадлежат пользователю root, запускать его рекомендуется только с помощью других пользователей без привилегий root. Тогда в случае взлома Caddy (или другой программы) злоумышленник не сможет изменить двоичный файл или выполнить команды от имени пользователя root.
Затем установите 755 как права доступа к двоичному файлу – это даст пользователю root полные права на чтение, запись и выполнение файла, а другие пользователи смогут только читать и выполнять его:
sudo chmod 755 /usr/local/bin/caddy
Поскольку процесс Caddy не будет работать от имени пользователя root, Linux не позволит ему связываться с портами 80 и 443 (стандартные порты HTTP и HTTPS соответственно), поскольку для этих операций нужны высокие привилегии. Чтобы Caddy был доступен по вашему домену, его нужно привязать к одному из этих портов, в зависимости от протокола. В противном случае вам нужно будет добавить номер порта к URL-адресу домена в браузере, чтобы просмотреть контент.
Чтобы разрешить Caddy связываться с такими портами, не работая при этом через пользователя root, выполните следующую команду:
sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy
Утилита setcap определяет опции файлов. Здесь она присваивает двоичному файлу Caddy опцию CAP_NET_BIND_SERVICE, что позволяет исполняемому файлу связываться с портом ниже 1024.
Вы завершили установку двоичного файла Caddy и теперь готовы приступать к написанию конфигурации Caddy. Создайте каталог, в котором вы будете хранить конфигурационные файлы Caddy, выполнив следующую команду:
sudo mkdir /etc/caddy
Затем передайте права необходимому пользователю и группе:
sudo chown -R root:www-data /etc/caddy
Передав права пользователю root и группе www-data, вы можете быть уверены, что Caddy будет иметь возможность читать и изменять каталог (через группу www-data). Аналогичные права будет иметь только учетная запись суперпользователя. В Ubuntu www-data – это пользователь и группа по умолчанию для веб-серверов.
Немного позже мы включим автоматическую инициализацию сертификатов TLS из Let’s Encrypt. Чтобы подготовиться к этому, создайте каталог для хранения всех сертификатов TLS, которые получит Caddy, и задайте для него те же права собственности, что и для каталога /etc/caddy:
sudo mkdir /etc/ssl/caddy
sudo chown -R root:www-data /etc/ssl/caddy
Caddy должен иметь возможность записывать сертификаты в этот каталог и читать файлы, чтобы шифровать запросы. По этой причине нужно изменить привилегии для каталога /etc/ssl/caddy, чтобы он был доступен только для root и www-data:
sudo chmod 0770 /etc/ssl/caddy
Затем создайте каталог для хранения файлов, которые будет обслуживать Caddy:
sudo mkdir /var/www
После этого передайте права собственности на каталог пользователю и группе www-data:
sudo chown www-data:www-data /var/www
Caddy считывает свою конфигурацию из файла Caddyfile, который хранится в /etc/caddy. Создайте этот файл:
sudo touch /etc/caddy/Caddyfile
Чтобы установить сервис Caddy, загрузите unit-файл systemd из репозитория Caddy Github в /etc/systemd/system:
sudo sh -c 'curl https://raw.githubusercontent.com/caddyserver/caddy/master/dist/init/linux-systemd/caddy.service > /etc/systemd/system/caddy.service'
Измените права доступа к файлу, чтобы его мог изменять только его владелец, root:
sudo chmod 644 /etc/systemd/system/caddy.service
Затем перезагрузите systemd, чтобы система обнаружила сервис Caddy:
sudo systemctl daemon-reload
Проверьте, нашла ли systemd сервис Caddy, запросив статус:
sudo systemctl status caddy
caddy.service - Caddy HTTP/2 web server
Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: e
Active: inactive (dead)
Docs: https://caddyserver.com/docs
Если вы видите такой же вывод, то новый сервис правильно обнаружен системой systemd.
Во время начальной установки сервера вы включили брандмауэр UFW и разрешили в нем соединения SSH. Чтобы Caddy мог обслуживать трафик HTTP и HTTPS с вашего сервера, вам нужно разблокировать их в ufw, выполнив следующую команду:
sudo ufw allow proto tcp from any to any port 80,443
Вы увидите такой результат:
Rule added
Rule added (v6)
Запросите состояние брандмауэра, чтобы убедиться, что его правила изменились:
sudo ufw status
Вы должны увидеть такой результат:
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
80,443/tcp ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
80,443/tcp (v6) ALLOW Anywhere (v6)
3: Настройка Caddy
В этом разделе мы создадим простую конфигурацию Caddy для обслуживания статичных файлов.
Создайте простую страницу HTML.
sudo nano /var/www/index.html
Поместите в файл такие строки:
<!DOCTYPE html>
<html>
<head>
<title>Hello from Caddy!</title>
</head>
<body>
<h1 style="font-family: sans-serif">This page is being served via Caddy</h1>
</body>
</html>
В браузере этот файл будет отображать фразу «This page is being served via Caddy». Сохраните и закройте файл.
Теперь откройте Caddyfile.
sudo nano /etc/caddy/Caddyfile
Вставьте следующие строки:
:80 {
root /var/www
gzip
}
Это базовая конфигурация Caddy, которая объявляет, что порт 80 вашего сервера должен обслуживать файлы из /var/www со сжатием gzip (это сократит время загрузки страницы на клиентской стороне).
В большинстве случаев Caddy позволяет дополнительно настраивать директивы. Например, вы можете ограничить сжатие gzip только файлами HTML и PHP и установить уровень сжатия 6 (1 – самый низкий, а 9 – самый высокий), расширив директиву фигурными скобками и перечислив поддирективы ниже:
:80 {
root /var/www
gzip {
ext .html .htm .php
level 6
}
}
Сохраните и закройте файл.
Caddy предлагает огромное количество различных директив для разных вариантов использования. Например, директива fastcgi поможет включить PHP. Директива markdown может автоматически преобразовывать файлы Markdown в HTML перед их обслуживанием, что позволяет вам создать простой блог.
Чтобы убедиться, что все работает правильно, запустите сервис Caddy:
sudo systemctl start caddy
Затем запустите команду systemctl status, чтобы получить информацию о состоянии сервиса Caddy:
sudo systemctl status caddy
Вы увидите следующее:
caddy.service - Caddy HTTP/2 web server
Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: enabled)
Active: active (running) since Thu 2020-03-12 11:17:49 UTC; 11s ago
Docs: https://caddyserver.com/docs
Main PID: 3893 (caddy)
Tasks: 7 (limit: 1152)
CGroup: /system.slice/caddy.service
└─3893 /usr/local/bin/caddy -log stdout -log-timestamps=false -agree=true -conf=/etc/caddy/Caddyfile -root=/var/tmp
Mar 12 11:17:49 caddy-article-update systemd[1]: Started Caddy HTTP/2 web server.
Mar 12 11:17:49 caddy-article-update caddy[3893]: [INFO] Caddy version: v1.0.5
Mar 12 11:17:49 caddy-article-update caddy[3893]: Activating privacy features... done.
Mar 12 11:17:49 caddy-article-update caddy[3893]: Serving HTTP on port 80
Mar 12 11:17:49 caddy-article-update caddy[3893]: http://
Mar 12 11:17:49 caddy-article-update caddy[3893]: [INFO] Serving http://
Mar 12 11:17:49 caddy-article-update caddy[3893]: [INFO][cache:0xc00007a7d0] Started certificate maintenance routine
Mar 12 11:17:49 caddy-article-update caddy[3893]: [WARNING] Sending telemetry (attempt 1): Post "https://telemetry.caddyserver.com/v1/update/6a8159c4-3427-42
Mar 12 11:17:57 caddy-article-update caddy[3893]: [WARNING] Sending telemetry (attempt 2): Post "https://telemetry.caddyserver.com/v1/update/6a8159c4-3427-42
...
Теперь откройте IP-адрес сервера в браузере. на странице появится фраза:
This page is being served via Caddy
4: Плагины Caddy
Плагины позволяют изменить и расширить поведение Caddy. Как правило, они предлагают больше директив для конфигурации (в зависимости от того, как вы используете Caddy). В этом разделе вы научитесь добавлять и использовать плагины на примере плагина minify, который удаляет лишние пробелы и приводит в порядок отправляемый клиенту код, сокращая занимаемую площадь и время загрузки.
GitHub-репозиторий плагина minify называется hacdias/caddy-minify.
Перейдите в каталог с исходным кодом, который вы создали в первом разделе:
cd ~/caddy
Чтобы добавить плагин в Caddy, вам нужно импортировать его в файл caddy.go, который вы использовали для сборки Caddy. Откройте caddy.go для редактирования:
nano caddy.go
Импортируйте плагин minify, добавив выделенную красным строку:
package main
import (
"github.com/caddyserver/caddy/caddy/caddymain"
_ "github.com/hacdias/caddy-minify"
)
func main() {
// caddymain.EnableTelemetry = false
caddymain.Run()
}
Сохраните и закройте файл.
Для импорта некоторых плагинов могут потребоваться небольшие изменения в конфигурации, поэтому обязательно прочитайте документацию плагина, который вы устанавливаете. Вы можете найти список популярных плагинов в левой панели документации Caddy, в разделе Plugins.
Добавив в файл сборки новый плагин, вы должны пересобрать Caddy. Это нужно потому, что Go – это компилируемый язык программирования, то есть перед выполнением исходный код преобразуется в машинный. Строка с объявлением импорта изменила только исходный код, она не повлияет на двоичный файл до его повторной компиляции.
Используйте команду go install для компиляции Caddy:
go install
Затем переместите сгенерированный двоичный файл в /usr/local/bin и настройте права доступа к нему, как вы делали ранее. Эти действия следует повторять каждый раз, когда вы повторно компилируете Caddy, чтобы обеспечить его функциональность и безопасность:
sudo mv $GOPATH/bin/caddy /usr/local/bin/
sudo chown root:root /usr/local/bin/caddy
sudo chmod 755 /usr/local/bin/caddy
sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy
Чтобы начать использовать плагин minify, вам нужно добавить директиву minify в Caddyfile. Откройте его в редакторе:
sudo nano /etc/caddy/Caddyfile
Включите плагин, добавив следующую строку в блок конфигурации:
:80 {
root /var/www
gzip
minify
}
Теперь перезагрузите сервер с помощью systemctl:
sudo systemctl restart caddy
Теперь Caddy будет уменьшать все файлы, которые он обслуживает, включая файл index.html, который вы создали ранее. Чтобы увидеть минификацию на практике, извлеките контент вашего домена с помощью curl:
curl http://your_domain
Вы увидите следующий вывод. Обратите внимание, все ненужные пробелы были удалены, а это значит, что плагин minify работает.
<!doctype html><title>Hello from Caddy!</title><h1 style=font-family:sans-serif>This page is being served via Caddy</h1>
Теперь вы знаете, как расширить функционал Caddy с помощью плагинов.
5: Включение автоматической поддержки TLS с помощью Let’s Encrypt
В этом разделе мы включим автоматическое получение и продление сертификатов Let’s Encrypt. Чтобы сервис мог убедиться, что у вас права на домен, вам понадобятся DNS-записи TXT.
Эти записи вы можете создать самостоятельно или получить с помощью плагина вашего DNS-провайдера. Список плагинов вы найдете здесь. Чтобы установить необходимый плагин, повторите процедуру, описанную в предыдущем разделе. Откройте файл caddy.go:
nano caddy.go
Добавьте репозиторий необходимого плагина в импорт:
package main
import (
"github.com/caddyserver/caddy/caddy/caddymain"
_ "github.com/hacdias/caddy-minify"
_ "github.com/caddyserver/dnsproviders/<provider>"
)
func main() {
// caddymain.EnableTelemetry = false
caddymain.Run()
}
Скомпилируйте его:
go install
Остановите Caddy с помощью systemctl, а затем завершите установку плагина, для этого скопируйте недавно созданный двоичный файл Caddy и настройте права собственности и доступ:
sudo systemctl stop caddy
sudo mv $GOPATH/bin/caddy /usr/local/bin/
sudo chown root:root /usr/local/bin/caddy
sudo chmod 755 /usr/local/bin/caddy
sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy
Затем вам нужно настроить Caddy для работы с API вашего провайдера, чтобы он мог настроить необходимые записи. Этот токен должен быть доступен Caddy в качестве переменной среды. Откройте unit-файл systemd.
sudo nano /etc/systemd/system/caddy.service
В разделе [Service] найдите строку Environment=. Она определяет переменные среды, которые передаются процессу Caddy. Поставьте пробел, добавьте переменную AUTH_TOKEN и присвойте ей свой токен.
[Service]
Restart=on-abnormal
; User and group the process will run as.
User=www-data
Group=www-data
; Letsencrypt-issued certificates will be written to this directory.
Environment=CADDYPATH=/etc/ssl/caddy AUTH_TOKEN=your_token_here
Сохраните и закройте файл. Затем перезапустите демон systemd:
sudo systemctl daemon-reload
Запустите следующую команду, чтобы убедиться, что изменения вступили в силу.
sudo systemctl status caddy
Вы получите такой вывод:
caddy.service - Caddy HTTP/2 web server
Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: https://caddyserver.com/docs
...
Затем нужно внести пару изменений в Caddyfile:
sudo nano /etc/caddy/Caddyfile
В раздел your_domain (в своем файле укажите ваш домен) вставьте следующие выделенные строки и закомментируйте gzip:
your_domain {
root /var/www
#gzip
minify
tls {
dns <provider>
}
}
Получив в качестве имени хоста домен, а не просто порт, Caddy будет обслуживать запросы по HTTPS. Директива tls настраивает поведение Caddy при использовании протокола TLS, а поддиректива dns настраивает Caddy на использование системы DNS-01, а не HTTP-01.
Итак, ваш сайт готов к развертыванию. Запустите Caddy с помощью systemctl, а затем включите его, чтобы добавить в автозагрузку:
sudo systemctl start caddy
sudo systemctl enable caddy
Если вы откроете свой домен в браузере, вы будете автоматически перенаправлены на HTTPS-страницу с тем же сообщением:
This page is being served via Caddy
Установка Caddy завершена, сайт защищен. Теперь вы можете дополнительно настроить Caddy в соответствии с вашими требованиями.
Если вы хотите обновить Caddy при выходе новой версии, вам нужно обновить файл go.mod (хранящийся в том же каталоге), который выглядит следующим образом:
module caddy
go 1.14
require (
github.com/caddyserver/caddy v1.0.5
github.com/caddyserver/dnsproviders v0.4.0
github.com/hacdias/caddy-minify v1.0.2
)
Выделенная красным часть – это версия Caddy, которую вы используете. Когда на Github выходит новая версия (что можно узнать здесь), вы можете заменить ей существующую версию в файле go.mod и скомпилировать Caddy в соответствии с первыми двумя разделами мануала. То же самое можно сделать и для всех импортируемых плагинов.
Заключение
Теперь сайт обслуживается веб-сервером Caddy по защищенным соединениям TLS. Веб-сервер будет автоматически обновлять сертификаты Let’s Encrypt.
Больше информации о Caddy можно получить в официальной документации.
Чтобы не пропустить выход новых версий Caddy, вы можете использовать Atom feed или специальные сервисы типа dependencies.io.
Tags: Caddy, Ubuntu, Ubuntu 18.04