Что означает ошибка Connection Refused
Ошибка Connection Refused (код ECONNREFUSED) возникает, когда клиент (например, curl, telnet, браузер) пытается установить TCP-соединение с сервером, но сервер активно отклоняет запрос. Это происходит, если на указанном порту нет процесса, который бы слушал входящие подключения, или если фаервол настроен на блокировку. Типичные сообщения:
curl: (7) Failed to connect to example.com port 80: Connection refused
telnet: Unable to connect to remote host: Connection refused
ssh: connect to host 192.168.1.1 port 22: Connection refused
В отличие от Connection timed out, здесь хост доступен, но порт "закрыт" с точки зрения TCP-стека.
Причины возникновения
Ошибка Connection Refused обычно вызвана одной из следующих причин:
- Сервис не запущен — целевая программа (например, веб-сервер, SSH-демон) не работает.
- Сервис слушает на другом порту или интерфейсе — конфигурация сервиса привязана только к
127.0.0.1(localhost), а клиент подключается с внешнего IP. - Фаервол блокирует порт — правила
iptables,nftables,ufwилиfirewalldзапрещают входящие подключения на порт. - Порт уже занят другим процессом — другой сервис использует тот же порт, и новый не может его захватить.
- Ошибки в конфигурационных файлах — неверные параметры в файлах сервиса (например,
nginx.conf,sshd_config). - SELinux или AppArmor ограничивают доступ — политики безопасности запрещают сервису слушать на порту или принимать соединения.
- Сетевые настройки ядра — например,
net.ipv4.ip_forwardотключен при необходимости маршрутизации.
Способы решения
Способ 1: Проверка и запуск сервиса
Начните с проверки, работает ли нужный сервис. Например, для веб-сервера Apache:
systemctl status apache2 # Для Ubuntu/Debian
systemctl status httpd # Для CentOS/RHEL
Если сервис неактивен (inactive), запустите его:
sudo systemctl start apache2
Чтобы сервис запускался автоматически при загрузке:
sudo systemctl enable apache2
⚠️ Важно: Замените
apache2на имя вашего сервиса (например,nginx,sshd,postgresql).
Способ 2: Проверка, на каком порту и интерфейсе слушает сервис
Иногда сервис работает, но слушает только на 127.0.0.1, а не на всех интерфейсах (0.0.0.0). Проверьте с помощью ss:
sudo ss -tuln | grep :<порт>
Например, для порта 80:
sudo ss -tuln | grep :80
Вывод должен содержать LISTEN и адрес. Если указано 127.0.0.1:80 или ::1:80, сервис доступен только локально. Измените конфигурацию сервиса, чтобы он слушал на 0.0.0.0:<порт> или конкретном внешнем IP.
Для Nginx проверьте файл /etc/nginx/sites-enabled/default или /etc/nginx/nginx.conf:
listen 80 default_server;
listen [::]:80 default_server;
# Убедитесь, что нет "listen 127.0.0.1:80"
После изменений перезапустите сервис:
sudo systemctl restart nginx
Способ 3: Настройка фаервола
Фаервол может блокировать входящие подключения. Проверьте статус:
Для ufw (Ubuntu/Debian):
sudo ufw status verbose
Если порт закрыт, разрешите его:
sudo ufw allow <порт>/tcp
Для firewalld (CentOS/RHEL/Fedora):
sudo firewall-cmd --list-all
Добавьте порт:
sudo firewall-cmd --add-port=<порт>/tcp --permanent
sudo firewall-cmd --reload
Для iptables (универсально):
sudo iptables -L -n -v | grep <порт>
Если есть правило DROP, удалите или измените его:
sudo iptables -D INPUT -p tcp --dport <порт> -j DROP
Для сохранения правил после перезагрузки используйте iptables-persistent или nftables.
Способ 4: Проверка занятости порта другим процессом
Если порт уже занят, новый сервис не сможет его использовать, и клиенты получат Connection Refused. Найдите процесс:
sudo lsof -i :<порт>
или
sudo ss -tulpn | grep :<порт>
Пример вывода:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1234 root 6u IPv4 123456 0t0 TCP *:http (LISTEN)
Если процесс не ваш, остановите его или измените порт вашего сервиса.
Способ 5: Проверка SELinux/AppArmor
На дистрибутивах с SELinux (CentOS, RHEL, Fedora) политики могут блокировать доступ. Проверьте логи:
sudo ausearch -m avc -ts recent
Если есть записи, связанные с портом, настройте политику. Для быстрого теста временно отключите SELinux (не для продакшена!):
sudo setenforce 0
Если проблема исчезла, нужно создать правильный модуль SELinux.
Для AppArmor (Ubuntu, Debian) проверьте профили:
sudo aa-status
Если сервис в enforce-режиме, попробуйте перевести в complain-режим для теста:
sudo aa-complain /etc/apparmor.d/usr.sbin.<сервис>
Профилактика
Чтобы избежать ошибки Connection Refused в будущем:
- Регулярно проверяйте статус критичных сервисов с помощью
systemctl is-active <сервис>или мониторинговых систем (Zabbix, Prometheus). - Корректно настраивайте привязку к интерфейсам — используйте
0.0.0.0для публичных сервисов, если не требуется ограничение. - Аудитируйте правила фаервола после изменений сети. Используйте
ufw status numberedилиiptables-saveдля резервных копий. - Ведите журналы конфигураций — фиксируйте изменения в файлах сервисов (например, через Git).
- Тестируйте изменения в изолированной среде перед применением на продакшене.
- Обновляйте системы и пакеты — устаревшие версии могут содержать баги в сетевом стеке.