CoreOS / rkt / systemd - как получить доступ к портам с низким номером?
[первоначально спросили в Stack Overflow, но отложили там с предложением, которое я спрашиваю здесь.]
У меня есть веб-приложение, написанное на go, которое принимает трафик через порты 80 и 443. Это нормально работает, если я:
- скопируйте исполняемый двоичный файл на сервер, на котором работает CoreOS
sudo setcap 'cap_net_bind_service=+eip' executable-name
- вызвать программу вручную, как непривилегированный пользователь
Я сейчас пытаюсь запустить его под rkt, в контейнере, построенном с acbuild:
acbuild begin
acbuild set-name myapp
acbuild copy myapp /app/myapp
acbuild set-exec -- /app/myapp
acbuild set-working-directory /app
acbuild mount add etcssl /etc/ssl
acbuild mount add cacert /usr/share/ca-certificates
acbuild set-user 500
acbuild set-group 500
acbuild write --overwrite myapp.aci
acbuild end
...
sudo rkt run ... --net=host
Это прекрасно работает, если приложение прослушивает порты с высоким номером, но я не смог заставить его работать, прослушивая порты 80 и 443.
Я пытался:
echo '{ "set": ["CAP_NET_BIND_SERVICE"] }' | acbuild isolator add "os/linux/capabilities-retain-set" -
sudo rkt run ... --net=host
Похоже, это не имеет никакого эффекта, поскольку ListenAndServeTLS возвращает:
listen tcp :443: bind: permission denied
Измените приложение для прослушивания на 8480 и 8443.
acbuild port add http tcp 8480
acbuild port add https tcp 8443
sudo rkt run ... --port=http:80 --port=https:443
Приложение работает и не сообщает об ошибках, но никогда не видит никаких входящих запросов.
Измените приложение для прослушивания на 8480 и 8443.
sudo iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 8480
sudo iptables -A PREROUTING -t nat -p tcp --dport 443 -j REDIRECT --to-port 8443
sudo rkt run ... --net=host
Приложение работает и не сообщает об ошибках, но никогда не видит никаких входящих запросов.
Примечание: у меня нет опыта
iptables
и я вполне могу делать что-то неправильно.iptables -nvL
выдает одинаковые выходные данные до и после того, как я выполню две вышеуказанные команды, поэтому я не уверен, что они на самом деле что-то делаютЯ пробовал бегать
rkt
подsystemd
сAmbientCapabilities=CAP_NET_BIND_SERVICE
, но это также не удается сbind: permission denied
Я также попытался добавить
--caps-retain=CAP_NET_BIND_SERVICE
кrkt run
командная строка, но это не помогло.Если я удалю
set-user
а такжеset-group
Если приложение работает, оно работает, но оно запускается с правами root, что сводит на нет одну из основных целей работы в контейнере - снижение привилегий в целях безопасности.
Буду признателен за любую информацию, которую может предложить каждый. Благодарю.
РЕДАКТИРОВАТЬ: Там было краткое обсуждение этого в группе rkt-dev, и есть github проблема отслеживания этого. Для моих текущих целей я обнаружил, что один только systemd, без rkt или любого другого времени выполнения контейнера, обеспечивает достаточную защиту, и я переключился на него, поэтому я больше не буду следить за этой проблемой.