Вопрос или проблема
У меня есть сервер, работающий на Ubuntu/Nginx. У меня есть поддомены, работающие с разных внутренних портов. Я хочу открыть одно приложение для доступа из интернета, но не связывать его с каким-либо именем домена/сервера.
Ниже приведен мой конфигурационный файл:
server {
server_name app.example.com www.app.example.com;
access_log /home/hub-app/logs/app.example.com.access.log;
location / {
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8082;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
server_name example.com www.example.com;
access_log /home/hub-public/logs/example.com.access.log;
location / {
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8081;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
Это работает хорошо и указывает на указанные домены, т.е. example.com и app.example.com. Теперь я хочу добавить еще один виртуальный сервер, который будет работать на MY_PUBLIC_IP:8080. Порт 8080 не должен быть доступен на других доменах, т.е. example.com:8080/app.example.com:8080 не должны быть доступны.
Вы можете использовать default_server
.
Nginx будет объявлять этот сервер как сервер по умолчанию. После этого Nginx будет использовать сервер по умолчанию для обработки запросов, когда их HTTP Host заголовок не соответствует ни одному из других блоков сервера.
Что такое default_server в Nginx
Пример:
server {
listen 8080 default_server;
root /www/default;
location / {
index index.html;
}
}
Я использую это, чтобы honeypot сканеры-боты и стримлю им эмодзи фекалий, если они ищут phpAdmin или что-то подобное 🙂
Я не думаю, что ответ от @Klamberext действительно отвечает на вопрос. То есть, веб-сервер nginx имеет концепцию сервер по умолчанию. Официальная страница документации по этому теме находится здесь: Как nginx обрабатывает запрос. Однако один из блоков серверов, слушающих на какой-либо комбинации сетевого интерфейса/порта, всегда будет действовать как сервер по умолчанию. Если вы не укажете этот блок сервера явно, это будет самый первый блок сервера в вашей конфигурации. Это означает, что ваш блок сервера с строкой server_name app.example.com www.app.example.com;
будет сервером по умолчанию для любых запросов, приходящих на 443 TCP-порт, обслуживающих любой запрос, где заголовок HTTP Host
не совпадает с example.com
или www.example.com
(или если заголовка Host
вовсе нет).
Как уже было сказано @Klamberext, общая практика состоит в том, чтобы определить пустой блок сервера для перехвата всех запросов, где заголовок HTTP Host
не совпадает ни с одним из доменов, которые вы обслуживаете. Вы можете увидеть пример в этот ответ SO. Обычно такой блок сервера содержит оператор return 444;
, который является специальным кодом возврата nginx для немедленного закрытия соединения. Однако, похоже, вам нужно что-то противоположное, и вам понадобятся два блока сервера для достижения этого, так как, как уже было сказано, один блок сервера, слушающий на TCP-порту 8080, будет действовать как сервер по умолчанию, независимо от того, какой заголовок Host
установлен:
server {
listen 8080;
server_name example.com www.example.com app.example.com www.app.example.com;
return 444;
}
server {
listen 8080 default_server;
... your config here
}
В качестве альтернативы вы можете проверить значение заголовка Host
внутри вашего блока сервера, например, чтобы заблокировать домен example.com
и любые его поддомены:
server {
listen 8080;
if ($http_host ~ \.?example\.com$) { return 444; }
... your config here
}
Ответ или решение
Для настройки вашего Nginx-сервера для работы с различными поддоменами и портами, особенно если у вас есть уникальные требования для отдельных приложений и доменов, следуйте нижеприведенным рекомендациям. Изучив вашу конфигурацию и требования, мы можем предложить следующую структурированную и продуманную конфигурацию:
Общий обзор задачи
Ваш сервер работает на Ubuntu с использованием Nginx и имеет несколько приложений, работающих на разных внутренних портах. Вы хотите сделать одно приложение доступным для общественности, но не связывать его с каким-либо доменом или именем сервера, и также использовать порт 8080 таким образом, чтобы он не был доступен через текущие домены.
Решение
-
Настройка существующих серверных блоков:
Продолжайте использование ваших текущих конфигураций для доменовexample.com
иapp.example.com
, так как они корректные. -
Добавление нового серверного блока для порта 8080:
Чтобы использовать порт 8080 для нового приложения без связывания с определенными доменами, добавьте новый серверный блок. Вам потребуется указать, что этот серверный блок будет использоваться по умолчанию (default_server), чтобы обрабатывать все запросы к этому порту, которые не соответствуют указанным HTTP заголовкамHost
.
# Блок для обработки несанкционированного доступа через известные домены на порту 8080
server {
listen 8080;
server_name example.com www.example.com app.example.com www.app.example.com;
return 444; # Закрыть соединение для несанкционированных запросов
}
# Основной блок обработки запросов на порту 8080
server {
listen 8080 default_server;
# Ваши дополнительные конфигурации здесь
root /your/application/root;
location / {
# Конфигурации для обработки запросов к этому приложению
index index.html;
}
}
Проверка заголовков Host
Если внутри вашего серверного блока на 8080 вы хотите дополнительно проверять значение заголовка Host
, добавьте условие для блокировки нежелательных доменов:
server {
listen 8080;
if ($http_host ~ \.?example\.com$) { return 444; }
# Здесь вмешаете основную логику вашего приложения
}
Заключение
Используя вышеописанную архитектуру, вы сможете управлять доступом к вашему приложению на порту 8080, предотвращая доступ через нежелательные домены, сохраняя при этом вашу основную безопасность и конфиденциальность. Поддерживайте вашу конфигурацию в актуальном состоянии и регулярно проверяйте обновления безопасности для ваших сертификатов и других инструментов, используемых в конфигурации.
Эта информация будет полезна как новичкам, так и продвинутым специалистам в области администрирования Nginx серверов.