Как настроить сервер nginx для приема разных поддоменов и портов?

Как настроить сервер nginx для приема разных поддоменов и портов?

У меня есть сервер, работающий на 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 не должен быть доступен на других доменах, напримерпример.com:8080/app.example.com:8080не должно быть доступно.

решение1

Вы можете использовать default_server.

Nginx объявит этот сервер сервером по умолчанию. После этого Nginx будет использовать сервер по умолчанию для обработки запросов, когда их заголовок HTTP Host остается несоответствующим каким-либо другим блокам сервера.

Что такое default_server в Nginx

Пример:

server {
    listen 8080 default_server;
    
    root /www/default;
        
    location / {
        index index.html;
    }
}


Я использую его для приманивания ботов-сканеров и отправки им эмодзи с какашками, если они ищут phpAdmin или что-то в этом роде :)

решение2

Я не думаю, что ответ @Klamberext действительно отвечает на вопрос. То есть, веб-сервер nginx имеетсервер по умолчаниюконцепция. Официальную страницу документации по теме можно найти здесь:Как nginx обрабатывает запрос. Однако один из серверных блоков, прослушивающих некоторую комбинацию сетевого интерфейса/порта, всегда будет действовать как блок по умолчанию. Если вы явно не укажете этот серверный блок, он будет самым первым серверным блоком в вашей конфигурации. Это означает, что ваш серверный блок со строкой server_name app.example.com www.app.example.com;будет серверным блоком по умолчанию для любого запроса, поступающего на порт TCP 443, обслуживая любой запрос, где Hostзаголовок HTTP не будет соответствовать example.comили (или если заголовка вообще www.example.comне будет ).Host

Как уже сказал @Klamberext, общепринятой практикой является определение блока сервера-заглушки для перехвата всех запросов, где Hostзаголовок HTTP не соответствует ни одному из обслуживаемых вами доменов. Вы можете увидеть пример наэтотОтвет ТАК. Обычно такой блок сервера содержит оператор 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
}

Связанный контент