Apache VirtualHost com proxy mod e SSL

28

Estou tentando configurar um servidor com vários aplicativos da web que serão servidos por meio do apache VirtualHost (apache em execução no mesmo servidor). Minha principal restrição é que cada aplicativo Web deve usar criptografia SSL. Depois de pesquisar um pouco e examinar outras questões sobre o stackoverflow, escrevi a seguinte configuração para o VirtualHost:

<VirtualHost 1.2.3.4:443>
    ServerName host.example.org

    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    SSLProxyEngine On
    ProxyRequests Off
    ProxyPreserveHost On
    ProxyPass / https://localhost:8443/
    ProxyPassReverse / https://localhost:8443/
</VirtualHost>

Embora https://host.example.org:8443 esteja acessível, https://host.example.org não é, o que anula o objetivo da minha configuração de host virtual. O Firefox reclama que, apesar de ter se conectado com sucesso ao servidor, a conexão foi interrompida. Também recebo o seguinte aviso no error.log do apache:

proxy: no HTTP 0.9 request (with no host line) on incoming request and preserve host set forcing hostname to be host.example.org for uri 

No aplicativo Web (um servidor Tomcat), o log de acesso mostra uma solicitação de acesso estranha:

"?O^A^C / HTTP/1.1" 302

A seguir, é apresentado o pedido de acesso correto que recebo quando me conecto diretamente a https://host.example.org:8443 :

"GET / HTTP/1.1" 302

Por fim, devo mencionar também que o host virtual funciona perfeitamente quando não uso SSL.

Como posso fazer isso funcionar?

JMD
fonte

Respostas:

34

Por fim, encontrei uma maneira de fazê-lo funcionar. Primeiro, tentei a sugestão de Dave Cheney e instalei outro certificado para o servidor apache redirecionado para a porta não SSL do Tomcat (para que o proxy estivesse redirecionando para http: // localhost: 8080 / ). Infelizmente, não funcionou completamente, pois no navegador da Web o https foi transformado em http imediatamente após a conexão. Então, voltei a usar https: // localhost: 8443 / e o toque final para fazê-lo funcionar foi adicionar novamente SSLProxyEngine.

Aqui está a configuração VirtualHost resultante:

<VirtualHost 1.2.3.4:443>
    ServerName host.domain.org

    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    SSLEngine on
    SSLProxyEngine On
    SSLCertificateFile /etc/apache2/ssl/certificate.crt
    SSLCertificateKeyFile /etc/apache2/ssl/certificate.key

    ProxyRequests Off
    ProxyPreserveHost On
    ProxyPass / https://localhost:8443/
    ProxyPassReverse / https://localhost:8443/
</VirtualHost>
JMD
fonte
11
Evite ProxyPreserveHost Onque quase sempre esteja errado, inútil e quase sempre quebre ProxyPassReverse. Como nota lateral ProxyRequests offé o padrão, portanto redundante.
Kbanczyk 06/12/19
Quando usamos IP externo em vez de localhostnão estar funcionando.
Chaminda Bandara 23/01
4

Experimente esta configuração

<VirtualHost 1.2.3.4:443>
    ServerName host.domain.org

    SSLEngine On
    # include other ssl options, like cert and key here

    ProxyRequests Off
    ProxyPreserveHost On

    <Location />
        ProxyPass http://localhost:8443/
    </Location>
</VirtualHost>

Se seu aplicativo precisar ter acesso às informações SSL da conexão em proxy, considere usar mod_proxy_ajp e o conector tomcat ajp1.3.

Dave Cheney
fonte
Gerarei o certificado com vamos criptografar no servidor em que o aplicativo host.domain.org está em execução. Então eu tenho que reutilizar o mesmo certificado no servidor proxy?
Giox
2

Mas se seu objetivo é executar vários aplicativos Web habilitados para SSL no mesmo servidor. adicionar o apache na frente não os equilibrará usando a configuração acima, você ainda precisará de um balanceador de carga ou poderá usar o módulo do balanceador de proxy do apache com algo como o seguinte:

ProxyRequests Off

<Proxy balancer://someapplication>
    BalancerMember http://127.0.0.1:18443 keepalive=on max=2 retry=30
    BalancerMember http://127.0.0.1:18444 keepalive=on max=2 retry=30
    BalancerMember http://127.0.0.1:18445 keepalive=on max=2 retry=30
</Proxy>


<VirtualHost 1.2.3.4:443>
    SSLEngine on
    SSLCipherSuite SSLv2:-LOW:-EXPORT:RC4+RSA
    SSLCertificateFile /path/to/cert.pem
    SSLCertificateKeyFile //path/to/key.pem
    SSLVerifyClient optional

    RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
    RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e

<Location />
    SetHandler balancer-manager
    Order allow,deny
    Allow from all
</Location>

ProxyPass / balancer://someapplication:443/
ProxyPassReverse / balancer://someapplication:443/
ProxyPreserveHost on
Brendan
fonte
Atualmente, eu realmente não preciso usar o balanceamento de carga, mas isso pode ser difícil no futuro. Obrigado pela compreensão.
JMD
1

Bem, o que eu não entendo aqui é por que você precisa ter uma conexão SSL do seu apache para o seu aplicativo que parece estar na mesma máquina ( http: // localhost: 8443 / ).

Eu acho que a maneira usual de configurar coisas assim é ter o apache fornecendo criptografia SSL para o lado do "cliente", por exemplo, internet, e ter uma conexão não criptografada com o aplicativo. Isso também oferece mais liberdade para depurar as respostas do aplicativo.

A outra coisa que Dave Cheney mencionou é usar o conector tomcat nativo para ter balanceamento de carga e outros recursos.

zero_r
fonte
Bem, eu tenho duas razões para escolher essa configuração. A primeira é que o servidor Tomcat já está instalado e funcionando em SSL e pensei que seria simples usar o apache VirtualHost com ele. O segundo é que o provedor do aplicativo (JIRA) fornece algumas diretrizes para a integração do apache ( atlassian.com/software/jira/docs/v3.13/apacheintegration.html ) e eu baseei minha configuração adicionando suporte ao VirtualHost. Acho que era mais complexo do que eu pensava, além de fazê-lo funcionar, eu realmente quero entender o que é o problema.
JMD
0

Você realmente precisa fazer proxy para um serviço HTTPS? Você pode querer fazer proxy para o serviço não-ssl no localhost, por exemplo

ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
codehead
fonte
De fato, o uso de SSL é obrigatório para mim. Eu também testei para proxy sem usar SSL apenas para verificar e funciona bem. O suporte a SSL é o verdadeiro problema.
JMD
0

Primeiro, verificaria se você pode fazer uma solicitação de localhost para localhost: 8443 e ver se isso foi bem-sucedido (o IE faz um GET ou wget http: // localhost: 8443 )

Não sei ao certo por que o seu host virtual havin ga escuta na porta 443 e em seguida o proxy para outro host ssl

por que o aplicativo não pode usar apenas 443 nativamente? se você não pode alterá-lo, você pode simplesmente usar o iptables para redirecionar a porta

Brendan
fonte
O motivo é que preciso instalar mais aplicativos da Web no mesmo servidor, todos usando SSL e nem todos podem escutar na porta 443. Portanto, estou usando VirtualHosts baseados em IP para fazer com que pareça que cada aplicativo da Web está hospedado em seu próprio servidor. Eu testei o seguinte comando wget e ele funciona muito bem: wget localhost: 8443 --no-check-certificado
JMD
2
Nota - é simples adicionar endereços IP adicionais ao seu servidor e, portanto, ter vários aplicativos escutando na porta 443 - todos em endereços IP separados.
Brent
0

Verifique seu log de erros SSL e verifique se não há erros para não poder verificar a cadeia de certificados da CA.

Neobyte
fonte
Se realmente houver erros de verificação, qual seria a solução?
Javier Méndez