Вопрос или проблема
Я хочу запустить Python 3 http.server на порту 80, не запуская его от имени root и не устанавливая дополнительное программное обеспечение (например, authbind). Я использую Arch Linux. Я предпочел бы сделать это с помощью systemd и настроить автозапуск при загрузке, если это возможно.
Я создал этот простой обертку:
#!/bin/sh
cd /srv/http/mywebsite/
python -m http.server 80
Я могу запустить его с помощью этого юнит-файла:
[Unit]
Description=Python 3 http.server
[Service]
Type=simple
ExecStart=/usr/local/bin/website_start.sh
[Install]
WantedBy=multi-user.target
Это “работает”, но это не безопасно. Если я добавляю пользователя и группу, это не срабатывает с ошибкой “Доступ запрещен” (думаю, что потому, что порт 80 требует привилегий root).
[Unit]
Description=Python 3 http.server
[Service]
Type=simple
ExecStart=/usr/local/bin/website_start.sh
User=http
Group=http
[Install]
WantedBy=multi-user.target
Ошибки:
Jun 23 00:58:57 myvps systemd[43060]: http_python_server.service: Не удалось выполнить команду: Доступ запрещен
Jun 23 00:58:57 myvps systemd[43060]: http_python_server.service: Не удалось на этапе EXEC создать процесс /usr/local/bin/website_start.sh: Доступ запрещен
error: connect_to website port 80: failed.
Вы можете дать процессу вашего сервиса возможность использовать порты <1024, но без других привилегий root:
[Unit]
Description=Python 3 http.server
[Service]
Type=simple
ExecStart=/usr/local/bin/website_start.sh
User=http
Group=http
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
Читайте man 7 capabilities
, если хотите узнать больше.
Команда /sbin/getpcaps
может использоваться для запроса возможностей, доступных для процесса по его PID. Обычно процессы, принадлежащие root, имеют длинный список возможностей, а процессы, не принадлежащие root, вообще не имеют.
sudo apt-get install authbind
sudo touch /etc/authbind/byport/80 <- пустой файл `80`
sudo chown $USER /etc/authbind/byport/80
sudo chmod 755 /etc/authbind/byport/80
authbind --deep python manage.py runserver 0.0.0.0:80
Ответ или решение
Чтобы запустить сервер Python 3 http.server
на порту 80 без прав root, используя систему systemd
для автоматического запуска, можно воспользоваться возможностью управления правами доступа на уровне возможностей (capabilities). Вот подробный план действий, который поможет вам достигнуть этой цели на Arch Linux.
1. Создание скрипта для запуска сервера
Создайте скрипт, который будет запускать ваш сервер. Например, вы можете создать файл /usr/local/bin/website_start.sh
со следующим содержимым:
#!/bin/sh
cd /srv/http/mywebsite/
exec python -m http.server 80
Не забудьте сделать этот файл исполняемым:
sudo chmod +x /usr/local/bin/website_start.sh
2. Создание unit-файла для systemd
Создайте unit-файл для вашего сервиса. Создайте файл /etc/systemd/system/http_python_server.service
и добавьте в него следующий код:
[Unit]
Description=Python 3 http.server
[Service]
Type=simple
ExecStart=/usr/local/bin/website_start.sh
User=http
Group=http
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
3. Настройка пользователя и группы
Убедитесь, что у вас есть пользователь и группа, под которыми будет работать сервер. Вы можете создать их, если они ещё не существуют:
sudo useradd -r -s /usr/sbin/nologin http
4. Выдача возможности CAP_NET_BIND_SERVICE
Данная возможность позволяет процессу, работающему под ненадёжным пользователем (например, http
), прослушивать порты ниже 1024. Мы уже указали это в unit-файле вашего сервиса с помощью строки AmbientCapabilities=CAP_NET_BIND_SERVICE
.
5. Перезагрузка systemd и запуск сервиса
После того как вы создали unit-файл, необходимо перезагрузить конфигурацию systemd и запустить ваш сервис:
sudo systemctl daemon-reload
sudo systemctl start http_python_server
Чтобы убедиться, что сервис запускается автоматом при загрузке системы, выполните:
sudo systemctl enable http_python_server
6. Проверка статуса сервиса
Для проверки статуса сервиса используйте следующую команду:
sudo systemctl status http_python_server
Это поможет вам увидеть, работает ли ваш сервер правильно, и отобразит любые ошибки, если они имеются.
Заключение
Теперь ваш Python 3 http.server
работает на порту 80 без необходимости запускать его от имени пользователя root. Механизм управления возможностями обеспечивает дополнительную безопасность, позволяя ограничить привилегии процесса, избегая использования более высоких прав.
Данный подход позволяет минимизировать риски безопасности, обеспечивая при этом необходимую функциональность для веб-сервера. Если у вас возникли дополнительные вопросы или проблемы, не стесняйтесь их задавать.