bind: Permission denied при привязке к порту
Отказ в доступе именно при привязке к адресу почти всегда означает попытку занять порт ниже 1024 без нужных прав. Порты 1–1023 считаются привилегированными: обычному пользователю они недоступны, и служба с User= получает отказ.
Что это значит
Есть три рабочих решения, и они не равнозначны. Оставить службе возможность CAP_NET_BIND_SERVICE — точечно и безопасно. Использовать сокет-активацию — systemd откроет порт от root и передаст готовый дескриптор. Снизить порог net.ipv4.ip_unprivileged_port_start — меняет правила для всей машины, поэтому применять стоит осознанно.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Служба от непривилегированного пользователя занимает порт ниже 1024
Ядро разрешает такие порты только процессам с CAP_NET_BIND_SERVICE. При
User=appэтой возможности нет. -
Возможность указана в постоянных, но исключена из ограничивающего набора
Ограничивающий набор — это потолок. Возможность, которой в нём нет, не появится у процесса, и привязка всё равно не пройдёт.
-
Мешают параметры изоляции сети
При
PrivateNetwork=yesу службы только петлевой интерфейс, аRestrictAddressFamilies=без нужного семейства не даст открыть сокет вовсе.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Пользователь и возможности — всё, что нужно для этого разбора.
systemctl show myapp.service -p User -p AmbientCapabilities -p CapabilityBoundingSetПоказывает границу привилегированных портов на этой машине: она могла быть изменена.
sysctl net.ipv4.ip_unprivileged_port_startТочная формулировка: она отличает отказ при привязке от отказа при доступе к файлу.
journalctl -u myapp.service -n 30 --no-pager | grep -i -E "bind|denied"Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Ядро разрешает такие порты только процессам с CAP_NET_BIND_SERVICE. При
User=appэтой возможности нет.
- Как проверить
-
Посмотрите пользователя и порт.
systemctl show myapp.service -p User -p AmbientCapabilities systemctl cat myapp.service | grep -iE "port|listen"
- Как исправить
-
Дайте службе только нужную возможность, не возвращая её к root.
[Service] AmbientCapabilities=CAP_NET_BIND_SERVICE CapabilityBoundingSet=CAP_NET_BIND_SERVICE
- Почему происходит
- Ограничивающий набор — это потолок. Возможность, которой в нём нет, не появится у процесса, и привязка всё равно не пройдёт.
- Как проверить
-
Сравните оба набора.
systemctl show myapp.service -p CapabilityBoundingSet -p AmbientCapabilities
- Как исправить
- Добавьте возможность в оба параметра или уберите ограничивающий набор, если он задавался без разбора.
- Почему происходит
- При
PrivateNetwork=yesу службы только петлевой интерфейс, аRestrictAddressFamilies=без нужного семейства не даст открыть сокет вовсе.
- Как проверить
-
Посмотрите параметры сети.
systemctl show myapp.service -p PrivateNetwork -p RestrictAddressFamilies -p IPAddressDeny
- Как исправить
- Уберите изоляцию сети для службы, которая должна слушать порт наружу, либо добавьте нужные семейства адресов.
Пример вывода
Служба от пользователя app пытается занять порт 443. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
× web.service - Web server
Active: failed (Result: exit-code) since Mon 2026-09-15 17:04:51 MSK; 1s ago
Process: 8100 ExecStart=/usr/local/bin/web --listen 0.0.0.0:443 (code=exited, status=1/FAILURE)
web[8100]: fatal: listen tcp 0.0.0.0:443: bind: permission denied
systemd[1]: web.service: Main process exited, code=exited, status=1/FAILURE
Связанные ошибки
- Address already in use при запуске службы Порт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Permission denied в журнале службы Отказ в доступе у службы systemd: права на файл, каталоги по пути, пользователь службы, параметры изоляции, SELinux и AppArmor.
- status=218/CAPABILITIES в systemd Код 218/CAPABILITIES: не удалось применить набор возможностей процесса из CapabilityBoundingSet= или AmbientCapabilities=.
- status=4/NOPERMISSION в systemd Код 4/NOPERMISSION: программа сообщила о недостатке прав. По соглашению LSB это «у пользователя недостаточно привилегий».
- Caddy не занимает порты 80 и 443 без прав Служба падает при открытии слушателя: нет возможности занимать привилегированные порты.
- Node-служба не может занять порт 80 Приложение на Node падает при привязке к привилегированному порту: как дать возможность вместо запуска от root.
- PostgreSQL: could not bind IPv4 address Кластер PostgreSQL не занимает порт: адрес занят другим экземпляром или остался файл сокета. Разбор.
- dnsmasq: failed to create listening socket for port 53 Порт 53 занят встроенной службой разрешения имён. Как развести dnsmasq и systemd-resolved.
Где встречается чаще всего
Источники
-
systemd.exec(5)
AmbientCapabilities=, CapabilityBoundingSet= и возможность CAP_NET_BIND_SERVICE. -
systemd.socket(5)
Сокет-активация как способ отдать службе готовый привилегированный порт. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено на службе с User=app и портом 443; решение с AmbientCapabilities проверено.