Eu tenho um servidor web com muitos servidores virtuais. Apenas 1 deles é SSL. O problema é que, como não há nenhum bloco de servidor completo que atenda ao SSL, qualquer solicitação https para outros sites é atendida pelo bloco 1 SSL.
Minha configuração, basicamente, fica assim:
# the catch all
server {
listen 80 default;
# I could add this, but since I have no default cert, I cannot enable SSL,
# and this listen ends up doing nothing (apparently).
# listen 443;
server_name _;
# ...
}
# some server
server {
listen 80;
server_name server1.com;
# ...
}
# some other server ...
server {
listen 80;
server_name server2.com;
# ...
}
# ... and it's https equivalent
server {
listen 443;
ssl on;
server_name server2.com;
# ...
}
Agora, como não há um ouvinte padrão para 443, uma solicitação como https://server1.com
será finalizada pelo server2.com
bloco https. Isto segue a lógica para server_name
nos docs.
Se não houver correspondência, um bloco de servidor {...} no arquivo de configuração será usado com base na seguinte ordem:
- o bloco do servidor com uma diretiva de escuta correspondente marcada como [default | default_server]
- o primeiro bloco do servidor com uma diretiva de escuta correspondente (ou escuta implícita 80;)
Qual é a solução preferida para esse problema? Preciso configurar o certificado fictício para meu bloco catch all server apenas para que eu possa ouvir 443 e lidar com solicitações ruins? Existe um parâmetro que eu desconheço que força uma correspondência exata de nome de host server
?
Respostas:
Nem é possível. A conexão de um cliente que acessa https://foo.example.com/ não pode ser aceita por nada além de um certificado SSL com "foo.example.com" como um de seus nomes. Não há oportunidade de redirecionar até que a conexão SSL seja aceita.
Se você configurar cada site para SSL, um usuário que clicar no erro de certificado obterá o site solicitado. Se você configurar um site "pegar tudo" para SSL que forneça apenas uma página de erro e configurar hospedagem virtual baseada em nome para o site que deve oferecer suporte a SSL, poderá servir uma página de erro aos clientes.
A hospedagem virtual SSL e HTTP simplesmente não funciona muito bem.
fonte
A única maneira de fazer é criar um certificado SSL autoassinado e usá-lo para obter controle sobre solicitações https recebidas. Você pode criar seu certificado SSL autoassinado em algumas etapas simples descritas nesta postagem .
Digamos que você crie um certificado autoassinado com um nome de arquivo server.crt. Você acrescentaria o seguinte na sua configuração nginx:
Você ainda receberá a mensagem de aviso SSL do navegador, mas pelo menos terá controle sobre o que acontece a seguir.
fonte
Adicione um bloco de servidor abrangente e retorne o código de status 444. Ele informa ao nginx para fechar a conexão antes de enviar qualquer dado.
fonte
Hoje em dia, você pode usar a extensão TLS Server Name Indication (SNI, RFC 6066). O ouvinte HTTPS poderá reconhecer o nome do domínio antes de fornecer o certificado apropriado.
Isso significa que você precisará ter certificados para TODOS os seus domínios e, quando o SNI for usado para reconhecer um dos outros domínios, você poderá usar o redirecionamento HTTP 301 para a versão não criptografada HTTP, a menos que o nome do servidor corresponda ao único que precisa criptografia.
Mais informações sobre o SNI disponíveis na documentação do nginx http://nginx.org/en/docs/http/configuring_https_servers.html
fonte
Mapeie o nome do host solicitado para nomes de host válidos no
http {}
bloco:E então, no
server {}
bloco, mate as conexões com o nome do host errado:Use vários mapas, conforme necessário, para vários blocos de servidores. A conexão ainda será estabelecida usando um de seus certificados, mas se esse último bloco estiver presente em cada bloco de servidor que serve SSL, você "bloqueará" efetivamente as conexões com nomes de host inválidos. Pode ser necessário apenas no primeiro bloco do servidor, mas adicioná-lo a cada bloco do servidor garantirá que o pedido não seja importante.
A
$ssl_server_name
variável está presente no nginx 1.7 ou superior.fonte
Foi assim que resolvi o problema:
openssl req -nodes -x509 -newkey rsa:4096 -keyout self_key.pem -out self_cert.pem -days 3650
cp self*.pem /etc/nginx/ssl/
O que isso fará: ele fornecerá um aviso (sem solução) em qualquer servidor que não tenha seu próprio certificado, mas o aviso não indicará o nome do certificado errado. Se o usuário clicar em "visitar de qualquer maneira", ele será redirecionado para a versão não SSL do site digitado.
advertência :
se o site habilitado para SLL definir apenas
www.example.com
(e nãoexample.com
), sua rota catch-all acabará servindohttps://example.com
com o certificado autoassinado e o aviso correspondente.fonte
Redirecionar para http:
Retorno 404:
fonte