Tutorial

Хостинг веб-сайта с Caddy в Ubuntu 18.04

GoLet's EncryptUbuntu 18.04

Автор выбрал фонд Free and Open Source Fund для получения пожертвования в рамках программы Write for DOnations.

Введение

Caddy — это простой и безопасный веб-сервер, имеющий ряд функций, которые могут быть полезны для хостинга веб-сайтов. Например, он может автоматически получать и управлять сертификатами TLS из Let’s Encrypt для использования HTTPS и включает поддержку HTTP/2. HTTPS — это система защиты трафика, которым пользователи обмениваются с сервером.Она очень быстро становится стандартом для любого запущенного в производственную среду веб-сайта. Без HTTPS браузеры Chrome и Firefox будут предупреждать, что ваш веб-сайт является «небезопасным» при отправке пользователями учетных данных.

Ранее для установки Caddy рекомендовалось загружать предварительно подготовленные бинарные файлы с сайта проекта Caddy. Однако изменения в лицензировании Caddy означает, что вы больше не можете использовать эти предварительно подготовленные бинарные файлы в коммерческих целях, если не оплатите лицензионный сбор, даже если вы используете Caddy для внутренних нужд вашего бизнеса. К счастью, исходный код Caddy остается полностью открытым, и вы можете создать сборку Caddy самостоятельно, чтобы избежать проблем с лицензированием.

В этом обучающем руководстве вы выполните сборку Caddy из исходного кода и используете его для хостинга веб-сайта, защищенного с помощью HTTPS. Эти задачи подразумевают компиляцию, настройку с помощью Caddyfile и установку плагинов. В конце вы узнаете, как обновить вашу установку при появлении новой версии.

Предварительные требования

  • Сервер Ubuntu 18.04 с привилегиями root и дополнительная учетная запись без прав root. Вы можете выполнить настройку, следуя указаниям документа Начальная настройка сервера для Ubuntu 18.04. В этом руководстве нашим пользователем без прав root будет sammy.
  • Зарегистрированное полное доменное имя. В этом обучающем руководстве мы будем использовать your_domain. Вы можете купить доменное имя на Namecheap, получить его бесплатно на Freenom или воспользоваться услугами любого предпочитаемого регистратора доменных имен.
  • Запись DNS A с your_domain​​​, указывающая на публичный IP-адрес вашего сервера. В руководстве Введение в DigitalOcean DNS содержится подробная информация по их добавлению.
  • Набор инструментов для языка Go, установленный на вашем сервере. Воспользуйтесь нашим руководством Установка Go и настройка локальной среды программирования в Ubuntu 18.04 для настройки Go. Создавать примеры проектов не нужно.
  • Персональный токен доступа (ключ API) с правами на чтение и запись для вашей учетной записи DigitalOcean. Его создание описано в материале Создание персонального токена доступа.

Шаг 1 — Сборка Caddy

В этом шаге вы выполните сборку Caddy из исходного кода с возможностью последующего добавления плагинов без внесения изменений в исходный код Caddy.

Для целей настоящего обучающего руководства вы будете хранить исходный код в директории ~/caddy. Создайте директорию, запустив следующую команду:

  • mkdir ~/caddy

Перейдите в директорию:

  • cd ~/caddy

Вы сохраните исходный код для запуска и настройки Caddy в файле с именем caddy.go. Создайте файл с помощью следующей команды:

  • nano caddy.go

Добавьте следующие строки:

~/caddy/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
Output
go: creating new go.mod: module caddy

В настоящий момент вы можете выполнить сборку стоковой версии Caddy из исходного кода, запустив следующую команду:

  • go install

Вы получите большое количество данных в выводе с информацией о том, какие библиотеки Go, загруженные в качестве зависимостей, необходимы для компиляции. Полученный в результате исполняемый файл хранится в файле $GOPATH/bin, как описано в предварительных требованиях.

После завершения попробуйте запустить Caddy:

  • caddy

Результат будет выглядеть примерно так:

Output
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

Теперь, когда вы убедились в возможности выполнения сборки и запуска Caddy, пришло время настроить службу systemd, чтобы Caddy можно было запускать автоматически при загрузке системы. Дополнительную информацию о systemd можно найти в руководстве по основам Systemd.

Для начала переместите бинарный файл Caddy в /usr/local/bin, стандартное местоположение для бинарных файлов, которые не управляются диспетчером пакетов Ubuntu и не используются для работы системы:

  • sudo mv $GOPATH/bin/caddy /usr/local/bin/

Далее измените принадлежность бинарного файла Caddy на пользователя root:

  • sudo chown root:root /usr/local/bin/caddy

Это предотвратит внесение изменений в исполняемый файл с помощью других учетных записей. Однако даже при использовании пользователя root для определения принадлежности Caddy рекомендуется запускать Caddy с помощью других учетных записей, не имеющих прав 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 определяет права для файлов. В этой команде она предоставляет право CAP_NET_BIND_SERVICE​​​ для бинарного файла Caddy, что позволяет исполняемому файлу выполнять привязку с номером ниже 1024. В этой команде она указывает возможности CAPNETBIND_SERVICE для бинарного файла Caddy, который позволяет привязку исполняющего файла к порту ниже 1024.

Теперь вы завершили настройку бинарного файла Caddy и можете приступать к созданию конфигурации Caddy. Создайте директорию, где вы будете хранить файлы конфигурации Caddy, запустив следующую команду:

  • sudo mkdir /etc/caddy

Затем установите правильные разрешения для пользователя и группы:

  • sudo chown -R root:www-data /etc/caddy

Установка пользователя в качестве root, а группы как www-data гарантирует, что у Caddy будет доступ к папке с правами на чтение и запись (через группу www-data) и что только учетная запись суперпользователя будет иметь аналогичные права на чтение и изменение. www-data — это используемые в Ubuntu по умолчанию пользователь и группа при работе с веб-сервером.

В следующем шаге вы должны будете активировать автоматическое предоставление сертификата 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 загрузите юнит-файл 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, запустив systemctl status:

  • sudo systemctl status caddy

Результат будет выглядеть примерно так:

Output
● 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

Результат будет выглядеть следующим образом:

Output
Rule added Rule added (v6)

Используйте ufw status, чтобы проверить, вступили ли в силу ваши изменения:

  • sudo ufw status

Вывод должен выглядеть так:

Output
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)

Установка Caddy завершена, но вам необходимо настроить его для обслуживания любого контента. В следующем шаге вы должны будете настроить Caddy для обслуживания файлов из директории /var/www.

Шаг 3 — Настройка Caddy

В этом разделе вы создадите базовую конфигурацию Caddy для обслуживания статичных файлов с вашего сервера.

Начнем с создания базового файла HTML в /var/www с названием index.html​​​:

  • sudo nano /var/www/index.html

Добавьте следующие строки:

/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

Добавьте следующие строки:

/etc/caddy/Caddyfile
:80 {
  root /var/www
  gzip
}

Это базовая конфигурация Caddy, которая объявляет, что порт 80 вашего сервера должен обслуживать файлы из директории /var/www, а для сокращения времени загрузки страниц со стороны клиента будет использоваться сжатие с помощью gzip.

В большинстве случаев Caddy позволяет выполнять дальнейшую настройку директив конфигурации. Например, вы можете ограничить сжатие gzip только для файлов HTML и PHP и установить уровень сжатия 6 (1 — самый низкий, а 9 — самый высокий), добавив к директиве фигурные скобки и перечислив судбирективы ниже:

/etc/caddy/Caddyfile
:80 {
  root /var/www
  gzip {
      ext .html .htm .php
      level 6
  }
}

После внесения изменений сохраните и закройте файл.

У Caddy есть огромное количество различных директив для самых разных случаев использования. Например, директива fastcgi может быть полезной для обеспечения возможностей PHP. Директива markdown может быть использована для автоматической конвертации файлов разметки в HTML, прежде чем обслуживать их, что может быть полезно для создания простого блога.

Чтобы проверить, что все работает корректно, запустите службу Caddy:

  • sudo systemctl start caddy

Затем запустите systemctl status, чтобы найти информацию о статусе службы Caddy:

  • sudo systemctl status caddy

Вы увидите следующее:

Output
● 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-адрес вашего сервера в браузере. Вы увидите следующий пример веб-страницы:

Сообщение от Caddy

Теперь вы настроили Caddy для обслуживания статичных файлов с вашего сервера. В следующем шаге вы должны будете расширить функционал Caddy с помощью плагинов.

Шаг 4 — Использование плагинов

Плагины предоставляют возможность изменения и расширения поведения Caddy. Обычно они предлагают дополнительные директивы конфигурации в соответствии с вашим вариантом использования. В этом разделе вы должны будете добавить и использовать плагины, установив плагин minify, который удаляет лишние пробелы и вычищает код, отправляемый клиенту, дополнительно снижая размер и время загрузки.

Репозиторий плагина minify на GitHub — hacdias/caddy-minify.

Перейдите в директорию с исходным кодом, который вы создали в шаге 1:

  • cd ~/caddy

Для добавления плагина в Caddy вам потребуется импортировать его в файл caddy.go​​​, который вы использовали при сборке Caddy. Откройте файл caddy.go для редактирования:

  • nano caddy.go

Импортируйте плагин minify, добавив выделенную строку:

~/caddy/caddy.go
package main

import (
    "github.com/caddyserver/caddy/caddy/caddymain"

    _ "github.com/hacdias/caddy-minify"
)

func main() {
    // caddymain.EnableTelemetry = false
    caddymain.Run()
}

Сохраните и закройте файл.

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

Каждый раз при добавлении нового плагина необходимо выполнять повторную сборку 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

Активируйте плагин, добавив следующую строку в блок конфигурации:

/etc/caddy/Caddyfile
:80 {
  root /var/www
  gzip
  minify
}

Перезапустите ваш сервер с помощью systemctl:

  • sudo systemctl restart caddy

Теперь Caddy запущен и будет сжимать любые файлы, которые он обслуживает, включая файл index.html, созданный вами ранее. Вы можете наблюдать за «минимизацией» в работе, запросив содержимое вашего домена с помощью curl:

  • curl http://your_domain

Вы должны увидеть следующий вывод: Обратите внимание, что все ненужные пробелы были удалены, что подтверждает, что плагин minify работает.

Output
<!doctype html><title>Hello from Caddy!</title><h1 style=font-family:sans-serif>This page is being served via Caddy</h1>

На этом шаге вы узнали, как расширить функционал Caddy с помощью плагинов. Далее вы должны будете активировать HTTPS, установив плагин tls.dns.digitalocean.

Шаг 5 — Активация автоматического предоставления TLS с помощью Let’s Encrypt

В этом разделе вы должны будете активировать автоматическое предоставление и обновление сертификата Let’s Encrypt, используя записи TXT DNS для верификации.

Для верификации с помощью записей TXT DNS вы должны будете устанавливать плагин для взаимодействия с API DigitalOcean, который называется tls.dns.digitalocean. Процедура установки практически полностью повторяет процедуру установки плагина minify на предыдущем шаге. Для начала откройте caddy.go​​​:

  • nano caddy.go

Добавьте репозиторий плагина в раздел с импортами:

~/caddy/caddy.go
package main

import (
    "github.com/caddyserver/caddy/caddy/caddymain"

    _ "github.com/hacdias/caddy-minify"

    _ "github.com/caddyserver/dnsproviders/digitalocean"
)

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 DigitalOcean, чтобы настроить записи DNS. Caddy должен получить доступ к этому токену, используемому в качестве пременной среды, для настройки DNS DigitalOcean, поэтому вы должны будете изменить юнит-файл systemd:

  • sudo nano /etc/systemd/system/caddy.service

Найдите строку, начинающуюся с Environment= в разделе [Service]. Эта строка определяет переменные среды, которые должны быть переданы в процесс Caddy. Добавьте пробел в конце этой строки, затем добавьте переменную DO_AUTH_TOKEN, за которой должен следовать токен, который вы только что создали:

/etc/systemd/system/caddy.service
[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 DO_AUTH_TOKEN=your_token_here

Сохраните и закройте этот файл, затем перезагрузите демон systemd, как вы делали ранее, чтобы убедиться, что конфигурация обновлена:

  • sudo systemctl daemon-reload

Запустите systemctl status, чтобы проверить, что изменения конфигурации выполнены корректно:

  • sudo systemctl status caddy

Вывод должен выглядеть следующим образом:

Output
● 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

Добавьте выделенные строки в Caddyfile, убедившись, что вы заменили your_domain на ваш собственный домен (вместо простого указания порта :80), и закомментируйте gzip:

/etc/caddy/Caddyfile
your_domain {
  root /var/www
  #gzip
  minify
  tls {
      dns digitalocean
  }
}

Использование домена, а не только порта для имени хоста, заставит Caddy обслуживать запросы через HTTPS. Директива tls определяет поведение Caddy при использовании TLS, а субдиректива dns указывает, что Caddy должен использовать систему DNS-01, а не HTTP-01.

Теперь ваш веб-сайт готов к развертыванию. Запустите Caddy с помощью systemctl, а затем активируйте его, чтобы задать запуск при загрузке:

  • sudo systemctl start caddy
  • sudo systemctl enable caddy

При открытии вашего домена в браузере вы будете автоматически перенаправлены на HTTPS, после чего будет отображаться то же самое сообщение.

Ваша установка Caddy завершена и защищена, и вы можете продолжить настройку в соответствии с вашим вариантом использования.

Если вы захотите обновить Caddy при выходе новой версии, вам потребуется обновить файл go.mod (он хранится в той же директории), который выглядит следующим образом:

~/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. Например, вы можете использовать фид Atom для релизов Caddy или специальную службу, например dependencies.io.

Дополнительную информацию о настройке Caddy см. в документации Caddy.

0 Comments

Creative Commons License