Apache VirtualHost mit Mod-Proxy und SSL

28

Ich versuche, einen Server mit mehreren Webanwendungen einzurichten, die alle über Apache VirtualHost (Apache wird auf demselben Server ausgeführt) bereitgestellt werden. Meine Hauptbeschränkung ist, dass jede Webanwendung SSL-Verschlüsselung verwenden muss. Nachdem ich eine Weile gegoogelt und andere Fragen zum Stackoverflow untersucht hatte, schrieb ich die folgende Konfiguration für den 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>

Auf https://host.example.org:8443 kann zwar zugegriffen werden, nicht jedoch auf https://host.example.org , was den Zweck meiner virtuellen Hostkonfiguration beeinträchtigt. Firefox beschwert sich, dass die Verbindung unterbrochen wurde, obwohl die Verbindung zum Server erfolgreich hergestellt wurde. Ich erhalte auch die folgende Warnung in Apaches error.log:

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 

In der Webanwendung (einem Tomcat-Server) zeigt das Zugriffsprotokoll eine ungewöhnliche Zugriffsanforderung an:

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

Das Folgende ist die korrekte Zugriffsanfrage, die ich erhalte, wenn ich mich direkt mit https://host.example.org:8443 verbinde :

"GET / HTTP/1.1" 302

Abschließend sollte ich noch erwähnen, dass der virtuelle Host einwandfrei funktioniert, wenn ich kein SSL verwende.

Wie kann ich das schaffen?

JMD
quelle

Antworten:

34

Endlich habe ich einen Weg gefunden, es zum Laufen zu bringen. Zuerst habe ich den Vorschlag von Dave Cheney ausprobiert, also habe ich ein anderes Zertifikat für den Apache-Server installiert, der auf den Tomcat-Nicht-SSL-Port umgeleitet wurde (der Proxy hat also auf http: // localhost: 8080 / umgeleitet ). Leider funktionierte es nicht vollständig, da im Webbrowser das https sofort nach dem Herstellen der Verbindung in http umgewandelt wurde. Also habe ich wieder https: // localhost: 8443 / verwendet und als letzten Schliff habe ich SSLProxyEngine hinzugefügt.

Hier ist die resultierende VirtualHost-Konfiguration:

<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
quelle
1
Vermeiden ProxyPreserveHost OnSie, dass es fast immer falsch, nutzlos und fast immer kaputt ist ProxyPassReverse. Als Randnotiz ProxyRequests offist die Voreinstellung somit überflüssig.
Kubanczyk
Wenn wir externe IP verwenden, localhostfunktioniert dies nicht.
Chaminda Bandara
4

Probieren Sie diese Konfiguration

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

Wenn Ihre Anwendung über die Proxy-Verbindung auf die SSL-Informationen zugreifen muss, sollten Sie die Verwendung von mod_proxy_ajp und des Tomcat-Connectors ajp1.3 in Betracht ziehen.

Dave Cheney
quelle
Ich werde das Zertifikat generieren, indem wir es auf dem Server verschlüsseln, auf dem die Anwendung für host.domain.org ausgeführt wird. Muss ich dann dasselbe Zertifikat auf dem Proxy-Server wiederverwenden?
Giox
2

Wenn Sie jedoch mehrere SSL-fähige Webanwendungen auf demselben Server ausführen möchten. Wenn Sie Apache in Front hinzufügen, werden sie mit der obigen Konfiguration nicht ausgeglichen. Sie benötigen weiterhin einen Load Balancer.

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
quelle
Momentan brauche ich keinen Lastausgleich, aber das könnte in Zukunft hilfreich sein. Danke für den Einblick.
JMD
1

Was ich hier nicht verstehe, ist, warum Sie eine SSL-Verbindung von Ihrem Apache zu Ihrer Anwendung benötigen, die sich anscheinend auf demselben Computer befindet ( http: // localhost: 8443 / ).

Ich vermute, die übliche Art, solche Dinge einzurichten, besteht darin, dass Apache dem "Kunden" eine SSL-Verschlüsselung zur Verfügung stellt, z. B. das Internet, und eine unverschlüsselte Verbindung zur Anwendung hat. Dies gibt Ihnen auch mehr Freiheit beim Debuggen Ihrer Anwendungsantworten.

Die andere Sache, die Dave Cheney erwähnte, ist die Verwendung des nativen Tomcat-Connectors, um einen Lastenausgleich und andere Funktionen zu erhalten.

zero_r
quelle
Nun, ich habe zwei Gründe, ein solches Setup zu wählen. Das erste ist, dass der Tomcat-Server bereits in SSL läuft und ich dachte, es wäre einfach, Apache VirtualHost damit zu verwenden. Die zweite ist, dass der Anbieter der Anwendung (JIRA) einige Richtlinien für die Apache-Integration bereitstellt ( atlassian.com/software/jira/docs/v3.13/apacheintegration.html ) und ich meine Konfiguration darauf basierend durch Hinzufügen von VirtualHost-Unterstützung erstellt habe. Ich schätze, das war komplexer als ich dachte, aber ich möchte nicht nur wirklich verstehen, was das Problem ist.
JMD
0

Müssen Sie wirklich einen Proxy für einen HTTPS-Dienst einrichten? Möglicherweise möchten Sie dem Nicht-SSL-Dienst in localhost einen Proxy zuweisen, z

ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
Codehead
quelle
In der Tat ist die Verwendung von SSL für mich obligatorisch. Ich habe auch getestet, um Proxy ohne SSL nur zu überprüfen, und es funktioniert gut. SSL-Unterstützung ist das eigentliche Problem.
JMD
0

Zuerst würde ich schauen, ob Sie eine Anfrage von localhost an localhost machen können: 8443 und sehen, ob das erfolgreich ist (IE tun ein GET oder wget http: // localhost: 8443 )

Ich bin mir nicht ganz sicher, warum Ihr virtueller Host Port 443 abhört und ihn dann an einen anderen SSL-Host weiterleitet

warum kann man die anwendung nicht einfach 443 nativ nutzen? Wenn Sie es nicht ändern können, können Sie einfach iptables verwenden, um den Port umzuleiten

Brendan
quelle
Der Grund dafür ist, dass ich mehr Webanwendungen auf demselben Server installieren muss, die alle SSL verwenden und nicht alle Port 443 überwachen können. Daher verwende ich IP-basierte VirtualHosts, damit es so aussieht, als ob jede Webanwendung auf einem eigenen Server gehostet wird. Ich habe den folgenden wget-Befehl getestet und er funktioniert einwandfrei: wget localhost: 8443 --no-check-certificate
JMD
2
Hinweis: Es ist ganz einfach, Ihrem Server zusätzliche IP-Adressen hinzuzufügen, sodass mehrere Anwendungen den Port 443 abhören - und das alles auf separaten IP-Adressen.
Brent
0

Überprüfen Sie Ihr SSL-Fehlerprotokoll und stellen Sie sicher, dass Sie keine Fehler haben, weil Sie die CA-Zertifikatkette nicht überprüfen können.

Neobyte
quelle
Wenn es tatsächlich Überprüfungsfehler gibt, welche Lösung wäre das?
Javier Méndez