Apache VirtualHost con mod-proxy e SSL


28

Sto cercando di configurare un server con più applicazioni Web che verranno servite tutte tramite apache VirtualHost (apache in esecuzione sullo stesso server). Il mio principale vincolo è che ogni applicazione web deve usare la crittografia SSL. Dopo aver cercato su Google per un po 'e aver esaminato altre domande su StackOverflow, ho scritto la seguente configurazione per 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>

Anche se https://host.example.org:8443 è accessibile, https://host.example.org non lo è, il che vanifica lo scopo della mia configurazione di host virtuale. Firefox si lamenta che, nonostante sia stato correttamente collegato al server, la connessione è stata interrotta. Ricevo anche il seguente avviso in error.log di 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 

Nell'applicazione Web (un server Tomcat) il registro di accesso mostra una strana richiesta di accesso:

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

Di seguito è la richiesta di accesso corretta che ottengo quando mi collego direttamente a https://host.example.org:8443 :

"GET / HTTP/1.1" 302

Infine, dovrei anche menzionare che l'host virtuale funziona perfettamente quando non uso SSL.

Come posso farlo funzionare?

Risposte:


34

Alla fine ho trovato il modo di farlo funzionare. Per prima cosa ho provato il suggerimento di Dave Cheney, quindi ho installato un altro certificato per il server Apache reindirizzato alla porta Tomcat non SSL (quindi il proxy stava reindirizzando a http: // localhost: 8080 / ). Sfortunatamente non ha funzionato completamente poiché nel browser Web l'https è stato trasformato in http immediatamente dopo la connessione. Quindi sono tornato a utilizzare https: // localhost: 8443 / e il tocco finale per farlo funzionare è stato aggiungere nuovamente SSLProxyEngine.

Ecco la configurazione VirtualHost risultante:

<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>

1
Evitarlo ProxyPreserveHost Onè quasi sempre sbagliato, inutile e quasi sempre si rompe ProxyPassReverse. Come nota a margine ProxyRequests offè l'impostazione predefinita, quindi ridondante.
Kubanczyk,

Quando utilizziamo un IP esterno invece localhostche non funziona.
Chaminda Bandara,

4

Prova questa configurazione

<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 l'applicazione deve avere accesso alle informazioni SSL dalla connessione proxy, è consigliabile utilizzare mod_proxy_ajp e il connettore tomcat ajp1.3.


Genererò il certificato con crittografiamo sul server su cui è in esecuzione l'applicazione per host.domain.org. Quindi devo riutilizzare lo stesso certificato sul server proxy?
Giox,

2

Ma se l'obiettivo è eseguire più applicazioni Web abilitate per SSL sullo stesso server. l'aggiunta di apache nella parte anteriore non equivale a bilanciarli utilizzando la configurazione precedente, avresti comunque bisogno di un bilanciamento del carico o potresti utilizzare il modulo di bilanciamento proxy di Apache con qualcosa di simile al seguente:

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

Attualmente non ho davvero bisogno di usare il bilanciamento del carico, ma potrebbe essere abbondante in futuro. Grazie per la comprensione.
JMD,

1

Bene, quello che non capisco qui è perché devi avere una connessione SSL dal tuo apache alla tua applicazione che sembra essere sulla stessa macchina ( http: // localhost: 8443 / ).

Immagino che il solito modo per configurare cose come questa sia avere apache che fornisca la crittografia SSL al lato "cliente", ad esempio Internet, e che abbia una connessione non crittografata all'applicazione. Questo ti dà anche più libertà di eseguire il debug delle risposte alle tue applicazioni.

L'altra cosa menzionata da Dave Cheney è l'uso del connettore Tomcat nativo per avere il bilanciamento del carico e altre funzionalità.


Bene, ho due motivi per scegliere una simile configurazione. Il primo è che il server Tomcat è già attivo e funzionante in SSL e ho pensato che sarebbe stato semplice usare apache VirtualHost con esso. Il secondo è che il provider dell'applicazione (JIRA) fornisce alcune linee guida per l'integrazione di apache ( atlassian.com/software/jira/docs/v3.13/apacheintegration.html ) e ho basato la mia configurazione su di esso aggiungendo il supporto VirtualHost. Immagino che fosse più complesso di quanto pensassi, oltre a farlo funzionare voglio davvero capire qual è il problema.
JMD,

0

Hai davvero bisogno di fare il proxy per un servizio HTTPS? È possibile che si desideri eseguire il proxy al servizio non SSL in localhost, ad es

ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/

In effetti, l'utilizzo di SSL è obbligatorio per me. Ho anche testato il proxy senza usare SSL solo per verificare e funziona benissimo. Il supporto SSL è il vero problema.
JMD,

0

Per prima cosa vorrei vedere se puoi fare una richiesta da localhost a localhost: 8443 e vedere se ha esito positivo (IE fare un GET o wget http: // localhost: 8443 )

Non sono del tutto sicuro del motivo per cui il tuo host virtuale havin ascolto sulla porta 443 per poi inviarlo a un altro host ssl

perché non è possibile utilizzare l'applicazione 443 in modo nativo? se non puoi cambiarlo, puoi semplicemente usare iptables per reindirizzare la porta


Il motivo è che devo installare più applicazioni Web sullo stesso server, tutte utilizzando SSL e non possono ascoltare tutte sulla porta 443. Quindi sto usando VirtualHosts basati su IP per far sembrare che ogni applicazione Web sia ospitata sul proprio server. Ho testato il seguente comando wget e funziona benissimo: wget localhost: 8443 --no-check-certificate
JMD

2
Nota: è semplice aggiungere ulteriori indirizzi IP al server e quindi avere diverse applicazioni in ascolto sulla porta 443, il tutto su indirizzi IP separati.
Brent,

0

Controlla il registro degli errori SSL e assicurati di non avere errori riguardo l'impossibilità di verificare la catena di certificati CA.


Se ci sono davvero errori di verifica, quale sarebbe la soluzione?
Javier Méndez,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.