Apache VirtualHost avec mod-proxy et SSL

28

J'essaie de mettre en place un serveur avec plusieurs applications Web qui seront toutes servies via apache VirtualHost (apache fonctionnant sur le même serveur). Ma principale contrainte est que chaque application web doit utiliser le cryptage SSL. Après avoir googlé pendant un certain temps et examiné d'autres questions sur stackoverflow, j'ai écrit la configuration suivante pour 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>

Même si https://host.example.org:8443 est accessible, https://host.example.org ne l'est pas, ce qui va à l'encontre de l'objectif de ma configuration d'hôte virtuel. Firefox se plaint que, même s'il s'est correctement connecté au serveur, la connexion a été interrompue. Je reçois également l'avertissement suivant dans le fichier error.log d'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 

Sur l'application Web (un serveur Tomcat), le journal d'accès affiche une étrange demande d'accès:

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

Voici la demande d'accès correcte que j'obtiens lorsque je me connecte directement à https://host.example.org:8443 :

"GET / HTTP/1.1" 302

Enfin, je dois également mentionner que l'hôte virtuel fonctionne parfaitement bien lorsque je n'utilise pas SSL.

Comment puis-je faire fonctionner cela?

JMD
la source

Réponses:

34

Enfin, j'ai trouvé un moyen de le faire fonctionner. J'ai d'abord essayé la suggestion de Dave Cheney, j'ai donc installé un autre certificat pour le serveur apache redirigé vers le port Tomcat non SSL (donc le proxy redirigeait vers http: // localhost: 8080 / ). Malheureusement, cela n'a pas complètement fonctionné car dans le navigateur Web, https a été transformé en http immédiatement après la connexion. J'ai donc recommencé à utiliser https: // localhost: 8443 / et la touche finale pour le faire fonctionner était d'ajouter à nouveau SSLProxyEngine.

Voici la configuration VirtualHost résultante:

<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
la source
1
L'éviter ProxyPreserveHost Onest presque toujours faux, inutile et se casse presque toujours ProxyPassReverse. Comme note latérale ProxyRequests offest la valeur par défaut, donc redondante.
kubanczyk
Lorsque nous utilisons une adresse IP externe au lieu de localhostne pas fonctionner.
Chaminda Bandara
4

Essayez cette config

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

Si votre application doit avoir accès aux informations SSL à partir de la connexion proxy, vous devez envisager d'utiliser mod_proxy_ajp et le connecteur tomcat ajp1.3.

Dave Cheney
la source
Je vais générer le certificat avec Let's Encrypt sur le serveur où s'exécute l'application pour host.domain.org. Ensuite, je dois réutiliser le même certificat sur le serveur proxy?
Giox
2

Mais si votre objectif est d'exécuter plusieurs applications Web activées SSL sur le même serveur. l'ajout d'apache devant ne va pas les équilibrer en utilisant votre configuration ci-dessus, vous auriez toujours besoin d'un équilibreur de charge ou vous pourriez utiliser le module d'équilibrage de proxy d'Apache avec quelque chose comme ceci:

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
la source
Actuellement, je n'ai pas vraiment besoin d'utiliser l'équilibrage de charge, mais cela pourrait être utile à l'avenir. Merci pour la perspicacité.
JMD
1

Eh bien, ce que je ne comprends pas ici, c'est pourquoi vous devez avoir une connexion SSL de votre apache à votre application qui semble être sur la même machine ( http: // localhost: 8443 / ).

Je suppose que la façon habituelle de configurer des choses comme celle-ci est d'avoir apache fournissant le cryptage SSL au côté "client", par exemple Internet, et d'avoir une connexion non cryptée à l'application. Cela vous donne également plus de liberté pour déboguer les réponses de votre application.

Dave Cheney a également mentionné l'utilisation du connecteur natif tomcat afin d'avoir l'équilibrage de charge et d'autres fonctionnalités.

zero_r
la source
Eh bien, j'ai deux raisons de choisir une telle configuration. Le premier est que le serveur Tomcat est déjà opérationnel en SSL et j'ai pensé qu'il serait simple d'utiliser Apache VirtualHost avec. Le deuxième est que le fournisseur de l'application (JIRA) fournit des directives pour l'intégration d'Apache ( atlassian.com/software/jira/docs/v3.13/apacheintegration.html ) et j'ai basé ma configuration dessus en ajoutant le support VirtualHost. Je suppose que c'était plus complexe que je ne le pensais, en plus de le faire fonctionner, je veux vraiment comprendre quel est le problème.
JMD
0

Avez-vous vraiment besoin d'un proxy vers un service HTTPS? Vous souhaiterez peut-être un proxy vers le service non SSL dans localhost, par exemple

ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
codehead
la source
En effet, l'utilisation de SSL est obligatoire pour moi. J'ai également testé le proxy sans utiliser SSL juste pour vérifier et cela fonctionne bien. Le support SSL est le vrai problème.
JMD
0

Je voudrais d'abord voir si vous pouvez faire une demande de localhost à localhost: 8443 et voir si c'est réussi (IE faire un GET ou wget http: // localhost: 8443 )

Je ne sais pas trop pourquoi votre hôte virtuel havin ga écoute sur le port 443 puis le procède à un autre hôte ssl

Pourquoi l'application ne peut-elle pas utiliser 443 en mode natif? si vous ne pouvez pas le changer, vous pouvez simplement utiliser iptables pour rediriger le port

Brendan
la source
La raison en est que j'ai besoin d'installer plus d'applications Web sur le même serveur, toutes utilisant SSL et qu'elles ne peuvent pas toutes écouter sur le port 443. J'utilise donc des hôtes virtuels basés sur IP pour donner l'impression que chaque application Web est hébergée sur son propre serveur. J'ai testé la commande wget suivante et cela fonctionne très bien: wget localhost: 8443 --no-check-certificate
JMD
2
Remarque - il est simple d'ajouter des adresses IP supplémentaires à votre serveur, et donc d'avoir plusieurs applications à l'écoute sur le port 443 - toutes sur des adresses IP distinctes.
Brent
0

Vérifiez votre journal d'erreurs SSL et assurez-vous que vous n'avez aucune erreur concernant l'impossibilité de vérifier la chaîne de certificats CA.

Neobyte
la source
S'il y a effectivement des erreurs de vérification, quelle serait la solution?
Javier Méndez