Nginx que serve conteúdo do "host virtual" errado enquanto acessa com https

7

Eu tenho um servidor rodando Nginx e Apache em uma configuração de proxy, o Nginx serve o conteúdo estático e o Apache o conteúdo dinâmico que funciona muito bem.

Esta configuração está hospedando atualmente duas versões do mesmo site, vamos chamá-las de production.com e staging.com.

Acabei de concluir a configuração do site production.com usando o SSL, que também funciona muito bem, mas descobri que, se eu navegasse até o staging.com usando o SSL também, eu receberia o conteúdo da produção. com a raiz da web, que obviamente está errada.

Foi-me dito para usar um manipulador padrão para SSL e não-SSL, o que eliminaria esse comportamento, mas é aí que estou tendo problemas.

Agora eu tenho essa configuração incluída no nginx.conf

default_80.conf
server {
    listen 80;
    server_name "";
    return 444;
}
default_443.conf
server {
    listen 443 default_server ssl;
    server_name "";
    return 444;
}
staging.com.conf
server {

    listen 80;
    server_name staging.com;
    access_log /var/log/nginx/staging.com.log;

    # static content folders
    location ^~ /(images|css|js) {
            root /var/www/staging.com/current;
            access_log /var/log/nginx/staging.com.static.log;
    }

    # static content files
    location ~* \.(js|css|rdf|xml|ico|txt|jpg|gif|png|jpeg)$ {
            root /var/www/staging.com/current;
            access_log /var/log/nginx/staging.com.static.log;
    }

    # proxy the rest to apache
    location / {

        proxy_pass         http://127.0.0.1:8080/;
        proxy_redirect     off;

        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

        client_max_body_size       10m;
        client_body_buffer_size    128k;

        proxy_connect_timeout      90;
        proxy_send_timeout         90;
        proxy_read_timeout         90;

        proxy_buffer_size          4k;
        proxy_buffers              4 32k;
        proxy_busy_buffers_size    64k;
        proxy_temp_file_write_size 64k;
    }
}
production.com.conf
server {

    listen 80;
    server_name production.com;
    rewrite ^       https://$server_name$request_uri? permanent;
}

server {

    listen 443 ssl;
    server_name production.com;
    access_log /var/log/nginx/production.com.log;

    ssl_certificate /etc/httpd/conf.d/SSL/ev.crt;
    ssl_certificate_key /etc/httpd/conf.d/SSL/server.key;
    keepalive_timeout 60;

    # static content folders
    location ^~ /(images|css|js) {
            root /var/www/production.com/current;
            access_log /var/log/nginx/production.com.static.log;
    }

    # static content files
    location ~* \.(js|css|rdf|xml|ico|txt|jpg|gif|png|jpeg)$ {
            root /var/www/production.com/current;
            access_log /var/log/nginx/production.com.static.log;
    }

    # proxy the rest to apache
    location / {

        # proxy settings
        proxy_pass         http://127.0.0.1:8080/;
        proxy_redirect     off;

        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

        client_max_body_size       10m;
        client_body_buffer_size    128k;

        proxy_connect_timeout      90;
        proxy_send_timeout         90;
        proxy_read_timeout         90;

        proxy_buffer_size          4k;
        proxy_buffers              4 32k;
        proxy_busy_buffers_size    64k;
        proxy_temp_file_write_size 64k;
    }

}

Essa configuração elimina todo o tipo de acesso SSL a qualquer um dos dois sites, e se eu remover a diretiva "default_server" do default_443.conf, ela funcionará para ambos os sites.

Então, a questão é como desativar o acesso SSL ( link retorna 444) para staging.com e habilitá-lo no production.com?

Atenciosamente Lars

    
por Lars 24.04.2012 / 16:30

3 respostas

6

Primeiro, confirme se a sua versão do Nginx suporta o SNI caso você esteja usando uma dessas distros estranhas (você deve ver o suporte a TLS SNI ativado no topo):

nginx -V

Eu postei a configuração abaixo, aqui estão os resultados na minha caixa (/var/www/production/index.html contém PRODUCTION e /var/www/staging/index.html, STAGING)

link redefinir conexão (444)
link reset (444)
link GRAVE link redirecionamento para o redirecionamento link do http para https
link PRODUÇÃO

Para referência, eu usei a versão estável do nginx dos repositórios do Debian (0.7.67), mas eu tenho uma configuração muito semelhante em 1.0. algo que funciona quase exatamente da mesma forma. Se você não conseguir trabalhar, informe-nos sua versão exata.

No seu caso, você provavelmente desejará alterar os dois padrões para default_server. Você também pode querer tornar a reescrita permanente, e talvez alterá-la para um retorno 301 se sua versão nginx permitir.

/ etc / nginx / sites-enabled / default

server {
    listen 80 default;
    return 444;
}

server {
    listen 443 default;
    ssl on;
    ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
    return 444;
}

/ etc / nginx / sites-enabled / production

server {
    listen   80; ## listen for ipv4
    server_name production.example.com;
    rewrite ^ https://production.example.com$request_uri?;
}

server {
    listen  443;
    server_name production.example.com;
    ssl on;
    ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
    keepalive_timeout 60;

    location / {
            proxy_pass      http://127.0.0.1:81;
            proxy_set_header        Host    $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

/ etc / nginx / sites-enabled / staging

server {
    listen  80;
    server_name staging.example.com;
    keepalive_timeout 60;

    location / {
            proxy_pass      http://127.0.0.1:81;
            proxy_set_header        Host    $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

server {
    listen   443; ## listen for ipv4
    server_name staging.example.com;
    ssl on;
    ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
    ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
    keepalive_timeout 60;

    rewrite ^(.*) http://staging.example.com$1;
}

/ etc / apache2 / sites habilitados / produção

<VirtualHost *:81>
    ServerAdmin webmaster@localhost
    ServerAlias production.example.com

    DocumentRoot /var/www/production
    <Directory />
            Options FollowSymLinks
            AllowOverride None
    </Directory>
    <Directory /var/www/production>
            Options Indexes FollowSymLinks MultiViews
            AllowOverride None
            Order allow,deny
            allow from all
    </Directory>

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
            AllowOverride None
            Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
            Order allow,deny
            Allow from all
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

/ etc / apache2 / sites-enabled / staging

<VirtualHost *:81>
    ServerAdmin webmaster@localhost
    ServerAlias staging.example.com

    DocumentRoot /var/www/staging
    <Directory />
            Options FollowSymLinks
            AllowOverride None
    </Directory>
    <Directory /var/www/staging>
            Options Indexes FollowSymLinks MultiViews
            AllowOverride None
            Order allow,deny
            allow from all
    </Directory>

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
            AllowOverride None
            Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
            Order allow,deny
            Allow from all
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

/etc/apache2/ports.conf

NameVirtualHost *:81
Listen 81
    
por 25.04.2012 / 03:45
0

Eu (com ajuda do 3molo on IRC) resolvi isso adicionando um bloco de servidor usando ssl para staging.com com uma reescrita para HTTP, que é uma solução alternativa aprovada em minha mente.

server {
    listen 443 ssl;
    server_name staging.com;

    ssl_certificate /etc/httpd/conf.d/SSL/ev.crt;
    ssl_certificate_key /etc/httpd/conf.d/SSL/server.key;
    keepalive_timeout 60;

    rewrite ^       http://$server_name$request_uri? permanent;
}

Mas o problema ainda permanece, por que o Nginx está servindo conteúdo quando $ http_host e server_name não combinam? Se houver alguém que tenha a resposta para essa pergunta, eu ficaria feliz em ouvir isso.

    
por 25.04.2012 / 00:32
-1

Se staging.com e production.com apontarem para os mesmos endereços IP, isso estará além do seu controle, pois o SSL é negociado antes do cabeçalho do Host ser enviado pelo cliente.

Se possível, use um IP por site e, caso contrário, você poderá "se $ host = staging.com .." no contexto do servidor para o production.com.

    
por 24.04.2012 / 16:38