Обслуживание сайта с помощью Caddy в Ubuntu 18.04

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: , ,

Добавить комментарий