Подробный гайд по ошибке Connection refused
Ошибка «Connection refused» (в переводе с английского — «в соединении отказано») возникает, когда клиент пытается установить сетевое соединение с сервером, но сервер активно отвергает эту попытку. Это одна из самых распространённых сетевых ошибок, с которой сталкиваются разработчики, системные администраторы и пользователи при работе с сетевыми сервисами: веб-серверами, базами данных, SSH, почтовыми серверами и т.д.
В отличие от ошибки «Connection timed out» (таймаут соединения), которая обычно указывает на недоступность хоста или блокировку трафика без отправки ответа, «Connection refused» означает, что пакет дошёл до целевой машины, но на запрашиваемом порту нет процесса, готового принять соединение, или система отклонила запрос по другим причинам (например, правила брандмауэра с явным отказом).
В этом гайде мы подробно разберём:
- как работает установка TCP-соединения;
- что именно означает отказ;
- основные причины возникновения ошибки;
- методы диагностики;
- способы устранения для разных сценариев.
2. Основы: как устанавливается TCP-соединение
Для понимания ошибки полезно вспомнить механизм установки соединения по протоколу TCP (основной транспортный протокол для большинства сервисов).
Процесс называется трёхсторонним рукопожатием (three-way handshake):
- SYN — клиент отправляет серверу пакет с флагом SYN, указывая порт, к которому хочет подключиться.
- SYN-ACK — если на этом порту слушает какое-то приложение (сокет в состоянии LISTEN), сервер отвечает пакетом с флагами SYN и ACK, подтверждая готовность установить соединение.
- ACK — клиент отправляет финальное подтверждение, и соединение считается установленным.
Если на целевом порту нет слушающего процесса, операционная система сервера отвечает не SYN-ACK, а пакетом с флагом RST (reset), который говорит клиенту: «порт закрыт, я отказываюсь». Клиентская программа интерпретирует это как «Connection refused».
Важно:
Отказ приходит именно от хоста, которому был адресован запрос, поэтому ошибка обычно означает, что сеть до сервера работает, но сервис на нужном порту недоступен.
3. Что означает «Connection refused»?
Конкретные ситуации, при которых клиент может получить эту ошибку:
- Порт не прослушивается — ни один процесс не открыл сокет на указанном порту и IP-адресе.
- Процесс слушает, но на другом интерфейсе — например, сервис привязан только к
127.0.0.1(localhost), а вы пытаетесь подключиться по внешнему IP. - Очередь ожидания (backlog) переполнена — ядро может отбрасывать новые SYN-запросы, если очередь уже полна (обычно при высокой нагрузке). В этом случае клиент может получить отказ или таймаут.
- Брандмауэр с политикой REJECT — некоторые межсетевые экраны могут отправлять RST-пакеты вместо простого отбрасывания (DROP), что также приводит к «Connection refused».
- Ошибка в адресе/порте — клиент подключается не к тому IP или порту (например, опечатка).
- Проблемы с DNS — имя хоста разрешилось в неправильный IP-адрес, и на этом адресе нет нужного сервиса.
Отличие от «Connection timed out»:
- Refused = сервер ответил отказом (RST), соединение не установлено мгновенно.
- Timed out = сервер не ответил вообще (пакеты могли быть отброшены, хост недоступен, фильтр DROP), клиент ждал и не дождался ответа.
4. Типичные причины возникновения
4.1. Сервис не запущен или упал
Самая частая причина — программа, которая должна слушать порт, не работает.
Например:
- веб-сервер nginx/apache остановлен;
- база данных MySQL/PostgreSQL не запущена;
- SSH-демон отключён;
- приложение в Docker-контейнере упало.
4.2. Сервис слушает на другом порту или IP
Иногда сервис запущен, но сконфигурирован на другой порт (например, 8080 вместо 80) или привязан только к локальному интерфейсу (127.0.0.1), а не к 0.0.0.0 (все интерфейсы). Подключение извне в таком случае вызовет отказ.
4.3. Брандмауэр или пакетный фильтр
- Локальный firewall (iptables, nftables, ufw, firewalld) может блокировать входящие соединения на порт, отправляя RST.
- Облачные группы безопасности (AWS Security Groups, Azure NSG, GCP Firewall) могут быть настроены на отбрасывание пакетов, но иногда облачный провайдер может отправлять отказ (зависит от реализации).
- Аппаратные межсетевые экраны.
4.4. Неправильные параметры подключения
Ошибки в адресе сервера, порта, протоколе (например, попытка подключиться по HTTPS к порту HTTP и наоборот).
4.5. Проблемы с DNS
Имя хоста резолвится в неправильный IP (устаревшая запись, ошибка в /etc/hosts, проблемы с DNS-сервером). Клиент пытается подключиться к хосту, где сервис не запущен.
4.6. Переполнение очереди listen backlog
При большом количестве одновременных подключений ядро может отклонять новые SYN, если очередь заполнена. Это проявляется как случайные «Connection refused» под нагрузкой.
4.7. Ограничения SELinux/AppArmor
В системах с мандатным контролем доступа (SELinux в RHEL/CentOS, AppArmor в Ubuntu) политика может запрещать сервису привязываться к определённому порту или принимать входящие соединения, что приводит к отказам.
4.8. Несоответствие IPv4/IPv6
Сервис слушает только IPv6 (например, ::1), а клиент пытается подключиться по IPv4, или наоборот. Либо DNS возвращает адрес одного семейства, а сервис слушает на другом.
5. Диагностика ошибки
Для успешного устранения необходимо определить, на каком этапе возникает проблема. Последовательно проверьте следующие аспекты.
5.1. Проверка сетевой доступности хоста
Убедитесь, что целевой хост вообще доступен по сети.
ping <IP-адрес или домен>
Если ping не проходит (и ICMP не заблокирован), проблема может быть на уровне сети, маршрутизации или хост выключен. Однако помните, что многие серверы блокируют ICMP, поэтому отсутствие ответа на ping не всегда означает недоступность.
5.2. Проверка, слушает ли порт на удалённом хосте
Используйте инструменты, которые пытаются установить TCP-соединение:
- telnet:
telnet <host> <port>
При успехе вы увидите сообщение о подключении, при отказе — «Connection refused».
- nc (netcat):
nc -zv <host> <port>
-z — сканирование без отправки данных, -v — подробный вывод.
- nmap:
nmap -p <port> <host>
Покажет состояние порта: open, closed, filtered. «Closed» обычно означает, что хост доступен и ответил RST (то есть refused), «filtered» — пакеты отбрасываются (timeout).
5.3. Локальная проверка на сервере (если есть доступ)
Если у вас есть SSH-доступ к серверу, проверьте, какой процесс слушает нужный порт:
sudo netstat -tulpn | grep <port>
# или
sudo ss -tulpn | grep <port>
# или
sudo lsof -i :<port>
Вывод покажет:
- адрес, на котором слушает процесс (например,
0.0.0.0:80или127.0.0.1:80); - PID и имя процесса;
- состояние (LISTEN).
Если порт не отображается, значит, процесс не запущен или слушает на другом порту.
5.4. Проверка брандмауэра на сервере
Просмотрите правила локального firewall:
- iptables:
sudo iptables -L -n -v
Обратите внимание на цепочку INPUT, особенно правила с REJECT.
- ufw (Ubuntu):
sudo ufw status verbose
- firewalld (CentOS/RHEL):
sudo firewall-cmd --list-all
Если используется облачная платформа, проверьте группы безопасности в консоли: разрешён ли входящий трафик на нужный порт с вашего IP.
5.5. Проверка логов сервиса
Логи приложения могут указать на ошибки запуска, проблемы с привязкой к порту (address already in use), отказы из-за SELinux и т.д.
sudo journalctl -u <service-name> -n 100 --no-pager
# или
sudo tail -f /var/log/<приложение>/error.log
5.6. Проверка SELinux/AppArmor
Если SELinux включен, проверьте его статус:
getenforce
Если Enforcing, временно переключите в Permissive для проверки (не забудьте вернуть обратно):
sudo setenforce 0
Попробуйте подключиться снова. Если помогло, нужно настроить политику SELinux, а не отключать его.
Смотрите аудит-лог:
sudo ausearch -m avc -ts recent
Аналогично для AppArmor:
sudo aa-status
5.7. Проверка конфигурации сервиса
Убедитесь, что в конфигурации сервиса указан правильный порт и адрес прослушивания:
- nginx/apache: директивы
listen,server_name. - SSH:
/etc/ssh/sshd_config, параметрPort,ListenAddress. - Базы данных:
my.cnf(MySQL),postgresql.conf(PostgreSQL), параметрыbind-address,port.
5.8. Тест с другого клиента
Попробуйте подключиться с другой машины или с самого сервера к самому себе (localhost). Если с локальной машины подключение проходит, а с удалённой нет — проблема в сетевой доступности или брандмауэре. Если и локально отказывает — сервис не слушает.
6. Устранение ошибки по причинам
6.1. Сервис не запущен
Запустите сервис и включите его автозапуск:
sudo systemctl start <service>
sudo systemctl enable <service>
Если сервис падает при старте, изучите логи.
6.2. Сервис слушает не на том адресе/порту
Измените конфигурацию, чтобы сервис слушал на нужном интерфейсе (обычно 0.0.0.0 для всех IPv4 или :: для всех IPv6) и правильном порту, затем перезапустите сервис.
Пример для nginx:
listen 80 default_server;
listen [::]:80 default_server;
Для MySQL в /etc/mysql/mysql.conf.d/mysqld.cnf:
bind-address = 0.0.0.0
6.3. Брандмауэр блокирует порт
Добавьте разрешающее правило:
- ufw:
sudo ufw allow <port>/tcp
- firewalld:
sudo firewall-cmd --permanent --add-port=<port>/tcp
sudo firewall-cmd --reload
- iptables (временно):
sudo iptables -A INPUT -p tcp --dport <port> -j ACCEPT
- Для облачных платформ добавьте правило в группу безопасности.
6.4. Неправильные параметры подключения
Проверьте адрес, порт, протокол. Убедитесь, что используете правильный IP или доменное имя, и порт соответствует сервису.
6.5. Проблемы с DNS
Проверьте резолвинг:
nslookup <domain>
dig <domain>
Сравните с ожидаемым IP. При необходимости исправьте записи DNS или временно используйте IP-адрес для теста.
6.6. Переполнение backlog
Это сложнее исправить, обычно требуется оптимизация сервиса или увеличение параметра net.core.somaxconn:
sudo sysctl -w net.core.somaxconn=4096
И в настройках приложения увеличьте размер backlog (например, в nginx backlog=4096 в директиве listen).
6.7. SELinux/AppArmor
Настройте политику.
Например, для SELinux разрешите сервису использовать порт:
sudo semanage port -a -t http_port_t -p tcp 8080
Или для AppArmor добавьте профиль. Не рекомендуется полностью отключать системы безопасности.
6.8. Несоответствие IPv4/IPv6
Убедитесь, что клиент и сервер используют одно семейство адресов. Можно настроить сервис на прослушивание обоих протоколов или использовать правильный адрес.
7. Распространённые сценарии и их решения
7.1. Веб-сервер (nginx/apache) не отвечает
- Симптом: при заходе на сайт браузер показывает «ERR_CONNECTION_REFUSED».
- Диагностика:
sudo ss -tulpn | grep ':80\|:443'. Если пусто — сервер не запущен. - Решение: запустите
sudo systemctl start nginx(или apache2). Проверьте конфигурацию на ошибки:sudo nginx -t.
7.2. База данных MySQL/PostgreSQL доступна только локально
- Симптом: приложение на другом сервере не может подключиться к БД, ошибка connection refused.
- Причина: в конфигурации
bind-address = 127.0.0.1. - Решение: изменить на
0.0.0.0или конкретный IP, перезапустить сервис, не забыть настроить права пользователя (GRANT ...@'%') и firewall.
7.3. SSH-подключение отклонено
- Симптом:
ssh user@host→ «Connection refused». - Причины: sshd не запущен, слушает на другом порту, firewall блокирует.
- Решение:
- Проверьте статус:
sudo systemctl status sshd. - Убедитесь, что порт 22 открыт.
- Проверьте
sshd_config(порт,ListenAddress). - Если изменён порт, подключайтесь с флагом
-p.
- Проверьте статус:
7.4. Docker-контейнер: проброс портов
- Симптом: хост не может подключиться к сервису в контейнере.
- Причины: контейнер не опубликовал порт (
-p), приложение внутри слушает наlocalhostвместо0.0.0.0, сетевые настройки Docker. - Решение:
- Запускайте контейнер с
-p <host_port>:<container_port>. - Внутри контейнера приложение должно слушать
0.0.0.0. - Проверьте
docker psдля списка проброшенных портов.
- Запускайте контейнер с
7.5. Kubernetes: Service/Ingress
- Симптом: под в кластере не может достучаться до сервиса или ingress отдаёт 502/503/connection refused.
- Причины: неправильные селекторы, порты, Service type, readiness probes.
- Решение: проверьте
kubectl describe svc,kubectl get endpoints, логи подов, конфигурацию ingress.
8. Инструменты для диагностики — сводка
| Инструмент | Назначение | Пример |
|---|---|---|
ping |
Проверка доступности хоста | ping 8.8.8.8 |
telnet |
Ручная проверка TCP-порта | telnet example.com 80 |
nc (netcat) |
Проверка портов, сканирование | nc -zv host 22 |
nmap |
Сканирование портов | nmap -p 80,443 host |
ss |
Просмотр слушающих сокетов | ss -tulpn |
netstat |
Аналогично ss | netstat -tulpn |
lsof |
Какой процесс использует порт | lsof -i :3306 |
curl |
Тест HTTP/HTTPS | curl -v http://host:port |
journalctl |
Логи системных сервисов | journalctl -u nginx |
tcpdump |
Перехват трафика | tcpdump -i eth0 port 80 |
9. Чек-лист
- Проверьте, запущен ли сервис:
systemctl status <service>. - Проверьте, слушает ли порт:
ss -tulpn | grep <port>. - Если порт не слушается, запустите сервис или исправьте конфигурацию (порт, адрес).
- Если слушается, но только на localhost, измените bind на
0.0.0.0. - Проверьте локальный firewall:
iptables -L,ufw status,firewall-cmd --list-all. - Проверьте облачные группы безопасности.
- Проверьте SELinux/AppArmor статусы.
- Попробуйте подключиться с самого сервера (
localhost) и с другого хоста. - Проверьте логи приложения на ошибки.
- Убедитесь, что клиент использует правильный IP/порт и DNS резолвится корректно.
Важно
Ошибка «Connection refused» — это чёткий сигнал о том, что на целевом хосте нет активного слушателя на запрашиваемом порту или доступ к нему активно отклоняется. Систематическая диагностика по шагам, описанным выше, позволит быстро локализовать и устранить проблему. В большинстве случаев достаточно запустить нужный сервис или открыть порт в брандмауэре.
Помните:
Всегда проверяйте самые простые вещи в первую очередь — запущен ли процесс, на том ли порту он слушает и доступен ли порт извне.
Мы делимся этой технической информацией, чтобы помочь вам в решении задач — используйте её с пониманием. Статья носит рекомендательный характер, поэтому, пожалуйста, применяйте описанные методы осмотрительно.