Мне удалось сделать это на Archlinux, но я думаю, что это будет то же самое на Ubuntu.
Запрос сертификата
Запустите certbot следующим образом:
sudo certbot certonly --manual -d yourhostname.org
Следуй инструкциям. В какой-то момент certbot скажет вам запустить веб-сервер, чтобы подтвердить ваше имя хоста. Он также предоставит пару команд для запуска простого веб-сервера с python. Запустите эти команды от имени пользователя root в новой оболочке на вашем сервере.
Обязательно перенаправьте порт 80
с вашего маршрутизатора на сервер, на котором размещен qbittorrent-nox
и откройте тот же порт на брандмауэре вашего сервера. Если вы используете ufw
, вам нужна эта команда:
sudo ufw allow WWW
WWW
- это простая конфигурация, позволяющая устанавливать соединения через порт 80.
По завершении процедуры проверки вы найдете файлы ключей и сертификатов в /etc/letsencrypt/live/yourhostname.org
. Скопируйте / вставьте privkey.pem
и cert.pem
в ваш веб-интерфейс qbittorrent-nox
и все готово.
PS. В конце этого вы можете убить веб-сервер Python.
PPS. Если вы не используете порт 80
на своем сервере, вы также можете удалить его из правил ufw ALLOW
и из переадресации портов вашего маршрутизатора.
Автоматическое продление сертификата
В основном вам нужно автоматизировать шаги, представленные в предыдущем разделе.
Команда для выполнения такова:
certbot renew
--manual-auth-hook /etc/letsencrypt/scripts/auth-hook.sh \
--manual-cleanup-hook /etc/letsencrypt/scripts/cleanup-hook.sh \
--post-hook /etc/letsencrypt/scripts/post-hook.sh
hooks
в основном сценарии , выполняемые certbot. certbot экспортирует некоторые переменные окружения в сценарии. Пожалуйста, обратитесь к Certbot Docs для более подробной информации.
Скрипты помещаются в /etc/letsencrypt/scripts
. Создайте эту папку и поместите туда свои скрипты или используйте любую другую папку по вашему выбору.
Сценарии объяснения и код:
auth-hook.sh
выполняется перед процедурой проверки. Он устанавливает простой веб-сервер для предоставления CERTBOT_TOKEN.
#!/bin/zsh
ufw allow WWW
mkdir -p /tmp/certbot/public_html/.well-known/acme-challenge
cd /tmp/certbot/public_html
printf "%s" $CERTBOT_VALIDATION > .well-known/acme-challenge/$CERTBOT_TOKEN
$(command -v python2 || command -v python2.7 || command -v python2.6) -c "import BaseHTTPServer, SimpleHTTPServer; s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); s.serve_forever()" &> /dev/null &
cleanup-hook.sh
будет выполнен после процедуры проверки независимо от того, был ли сертификат обновлен или нет. Мы используем его для очистки веб-сервера.
#!/bin/zsh
kill $(ps aux | grep SimpleHTTPServer | awk 'NR==1{print $2}')
rm -rf /tmp/certbot/public_html/.well-known/acme-challenge
ufw delete allow WWW
post-hook.sh
будет выполнен, когда сертификат будет фактически обновлен. Мы используем его для обновления /home/user/.config/qBittorrent/qBittorrent.conf
.
#!/bin/zsh
systemctl stop qbittorrent.service &&
/etc/letsencrypt/scripts/update_config.py \
--hostname $CERTBOT_DOMAIN \
--configfile /home/user/.config/qBittorrent/qBittorrent.conf &&
systemctl start qbittorrent.service &&
Обратите внимание: конфигурация qbittorrent
помещается в домашнюю папку пользователя, который ее запускает; отредактируйте этот скрипт в соответствии с вашей конфигурацией.
update_config.py
обновляет qBittorrent.conf
. Я использовал python, потому что модуль ConfigParser был очень удобен для редактирования INI-файлов (key=value
). Кто-то умнее меня может добиться того же с помощью sed
или awk
.
#!/usr/bin/python3
import argparse
import configparser
Config = configparser.ConfigParser()
Config.optionxform = str
parser = argparse.ArgumentParser(description='Updates qbittorrent config.')
parser.add_argument('--hostname', required=True)
parser.add_argument('--configfile', required=True)
args = parser.parse_args()
with open('/etc/letsencrypt/live/' + args.hostname + '/cert.pem', 'r') as f:
cert = f.read()
with open('/etc/letsencrypt/live/' + args.hostname + '/privkey.pem', 'r') as f:
key = f.read()
cert = cert.replace('\n', '\\n')[:-2]
cert = "\"@ByteArray(" + cert + ")\""
key = key.replace('\n', '\\n')[:-2]
key = "@ByteArray(" + key + ")"
Config.read(args.configfile)
Config["Preferences"]["WebUI\HTTPS\Certificate"] = cert
Config["Preferences"]["WebUI\HTTPS\Key"] = key
with open(args.configfile, 'w') as f:
Config.write(f, space_around_delimiters=False)
Пробный прогон
Отредактируйте эти скрипты в соответствии с вашими потребностями. Теперь попробуйте запустить предыдущую команду с параметром --dry-run
. Это запустит процедуру продления, даже если срок действия сертификата не истек.
certbot renew --manual-auth-hook /etc/letsencrypt/scripts/auth-hook.sh --manual-cleanup-hook /etc/letsencrypt/scripts/cleanup-hook.sh --post-hook /etc/letsencrypt/scripts/post-hook.sh --dry-run
Cron Job
Если все хорошо, вы можете настроить работу cron.
# EDITOR=vim crontab -e
00 04,16 * * * sleep $((RANDOM % 60)); certbot renew --quiet --manual-auth-hook /etc/letsencrypt/scripts/auth-hook.sh --manual-cleanup-hook /etc/letsencrypt/scripts/cleanup-hook.sh --post-hook /etc/letsencrypt/scripts/post-hook.sh
Работа будет выполняться каждый день в 04:00 и 16:00. Случайный сон выберет случайную минуту в течение выбранных часов (в соответствии с рекомендациями certbot docs).
Мы добавляем опцию --quiet
: она лучше для заданий cron.