Доступ к Nginx только по доменному имени

Просмотры: 24
Категория: Администрирование
Создано: 19 февраля 2025
Тэги: Linux Nginx

Часто бывает необходимо ограничить доступ к HTTP-серверу Nginx по IP-адресу. Например, из соображений безопасности или приватности. Нужно сделать так, чтобы при обращении к веб-серверу по IP-адресу выдавалась ошибка и сервер сразу же бы закрывал соединение. В этой заметке я расскажу, как это сделать.

Веб-сервер Nginx слушает интерфейсы и порты, указанные в директиве listen. Например, вот такая запись в конфигурационном файле

    listen 80;

указывает на то, что сервер прослушивает 80-й порт на всех сетевых интерфейсах. Для соединений по протоколу HTTPS чаще всего используется 443-й порт, а соответствующие директивы имеет вид

    listen 443 ssl;
    http2 on;

Согласно документации Nginx для директивы listen можно указать параметр default_server. Сервер, для которого такой параметр указан, будет являться сервером по умолчанию и на него будут отправляться те запросы, которые не нашли свой сервер (а имя сервера, как мы знаем, задаётся в server_name), или запрос пришёл не по доменному имени, а сразу на IP-адрес. Если же параметр default_server не указан ни для одного сервера, который обслуживает Ngnix, то сервером по умолчанию будет первым, для которого указан порт или адрес и порт. Чаще всего настройки виртуальных серверов выносят в отдельные файлы и подключают директивой include, так что сервером по умолчанию в этом случае станет первый в алфавитном порядке сервер.

Разобравшись с теорией, можно приступить к практике. Я предполагаю, что файлы настройки Nginx лежат в директории /etc/nginx. Файлы кофнигурации, чаще всего, размещают тогда в директории /etc/nginx/sites-available, а для их подключения используются символические ссылки, которые делаются в директории /etc/nginx/sites-enabled приблизительно следующим образом

sudo ln -s ../sites-available/example.com example.com

Чтобы всё работало должным образом, нужно в главном конфигурационном файле nginx.conf дописать строки

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

Первая строка, как правило, уже присутствует здесь, а вторую иногда нужно дописать. Теперь в директории sites-available создаем файл default

nano sites-available/default

Для того, чтобы нельзя было подключиться к серверу по IP-адресу по протоколу HTTP добавляем следующие строки

server {
  listen 80 default_server;
  deny all;
  return 444;
}

Обратите внимание на параметр default_server в директиве listen. Он указывает, что данные настройки применяются к серверу по умолчанию. Второй строкой deny all мы запрещаем доступ к этому серверу. А третьей директивой return 444 возвращаем ответ 444, т.е. закрыть соединение без объяснения каких либо причин.

Для SSL-соединений нужны другие директивы. Сразу хочу отметить, что указанный ниже пример будет работать только для Nginx версии не ниже 1.19.4. Итак, дописываем следующие строки

server {
  listen 443 ssl default_server;
  http2 on;
  ssl_reject_handshake on;

  ssl_protocols TLSv1.3;
}

Опять же первая директива listen 443 ssl default_server говорит от том, что мы конфигурируем дефолтный сервер на 443-м порту, который слушает его для SSL соединений. Вторая строка http2 on стандартная для новых версий Nginx. Самая главная строка здесь — третья: ssl_reject_handshake on. Она прерывает SSL рукопожатие. А без него браузер не сможет законнектится к серверу через SSL. Наконец, директива ssl_protocols TLSv1.3 говорит о том, что будет использоваться TLS только версии 1.3. Без этой строки можно будет подключиться к Nginx по другому (более старому) протоколу.

Далее поступаем стандартным образом. Во-первых создаем символическую ссылку в sites-enabled:

cd /etc/nginx/sites-enabled
ln -s ../sites-available/default default

Проверяем, что нет ошибок в конфигурационных файлах Nginx-а.

nginx -t

Если вышли ошибки или предупреждения, исправляем. Когда все нас устраивает, просим Nginx перечитать конфигурационные файлы:

systemctl reload nginx

Вместо reload можно перезапустить Nginx командой restart. Но тут надо быть осторожным. Если в конфигаг есть всё-таки ошибки, то при reload Nginx просто проигнорирует новые конфигурационные файла. А при restart он не запустится. Однако, ошибки обязательно нужно исправить. Иначе при перезагрузке системы или при некоторых обновлениях, когда должен будет произойти рестарт веб-сервера, он не запустится.

Вот и всё. Пробуем зайти через браузер или curl зайти на сервер по IP-адресу и убеждаемся, что нас туда не пускают. Также проверяем, что доступ по доменным адресам остался. Для справки, команда для проверки соединения через curl может выглядеть так

curl -vI http://111.222.33.4
curl -vI https://111.222.33.4