Apache VirtualHost z mod-proxy i SSL

28

Próbuję skonfigurować serwer z wieloma aplikacjami internetowymi, które będą obsługiwane przez apache VirtualHost (apache działający na tym samym serwerze). Moim głównym ograniczeniem jest to, że każda aplikacja internetowa musi korzystać z szyfrowania SSL. Po dłuższym przeglądaniu i przejrzeniu innych pytań dotyczących przepływu stosów napisałem następującą konfigurację dla 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>

Mimo że https://host.example.org:8443 jest dostępny, https://host.example.org nie jest dostępny, co przeczy celowi mojej konfiguracji wirtualnego hosta. Firefox skarży się, że mimo pomyślnego połączenia z serwerem połączenie zostało przerwane. Otrzymuję również następujące ostrzeżenie w pliku error.log 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 

W aplikacji internetowej (serwer Tomcat) dziennik dostępu pokazuje dziwne żądanie dostępu:

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

Poniżej przedstawiono poprawne żądanie dostępu, które otrzymuję, gdy łączę się bezpośrednio z https://host.example.org:8443 :

"GET / HTTP/1.1" 302

Na koniec powinienem również wspomnieć, że wirtualny host działa doskonale, gdy nie używam protokołu SSL.

Jak mogę to zrobić?

JMD
źródło

Odpowiedzi:

34

W końcu znalazłem sposób, aby to zadziałało. Najpierw wypróbowałem sugestię Dave'a Cheneya, więc zainstalowałem inny certyfikat dla serwera Apache przekierowanego na port Tomcat inny niż SSL (więc proxy przekierowywało na http: // localhost: 8080 / ). Niestety nie działało to w pełni, ponieważ w przeglądarce internetowej https został przekształcony w http natychmiast po połączeniu. Więc wróciłem do używania https: // localhost: 8443 /, a ostatnim dotknięciem, aby działało, było ponowne dodanie SSLProxyEngine.

Oto wynikowa konfiguracja VirtualHost:

<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
źródło
1
Unikanie ProxyPreserveHost Ontego jest prawie zawsze złe, bezużyteczne i prawie zawsze pęka ProxyPassReverse. Uwaga dodatkowa ProxyRequests offjest domyślna, dlatego jest redundantna.
kubańczyk
Gdy korzystamy z zewnętrznego adresu IP, localhostto nie działa.
Chaminda Bandara
4

Wypróbuj tę konfigurację

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

Jeśli twoja aplikacja musi mieć dostęp do informacji SSL z połączenia proxy, powinieneś rozważyć użycie mod_proxy_ajp i łącznika tomcat ajp1.3.

Dave Cheney
źródło
Wygeneruję certyfikat zaszyfrujmy na serwerze, na którym działa aplikacja host.domain.org. Więc muszę ponownie użyć tego samego certyfikatu na serwerze proxy?
Giox
2

Ale jeśli Twoim celem jest uruchomienie wielu aplikacji internetowych z obsługą SSL na tym samym serwerze. dodanie apache z przodu nie zrównoważy ich przy użyciu powyższej konfiguracji, nadal potrzebujesz modułu równoważenia obciążenia lub możesz użyć modułu równoważenia proxy apache z czymś takim:

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
źródło
Obecnie tak naprawdę nie muszę używać równoważenia obciążenia, ale może to być przydatne w przyszłości. Dzięki za wgląd.
JMD
1

Cóż, nie rozumiem tutaj, dlaczego musisz mieć połączenie SSL z apache do aplikacji, która wydaje się znajdować na tym samym komputerze ( http: // localhost: 8443 / ).

Sądzę, że zwykłym sposobem na skonfigurowanie takich rzeczy jest apache zapewniający szyfrowanie SSL po stronie klienta, np. Internet, i nieszyfrowane połączenie z aplikacją. Daje to również większą swobodę debugowania odpowiedzi aplikacji.

Inną rzeczą, o której wspomniał Dave Cheney, jest użycie natywnego złącza tomcat w celu uzyskania równoważenia obciążenia i innych funkcji.

zero_r
źródło
Cóż, mam dwa powody, by wybrać taką konfigurację. Po pierwsze, serwer Tomcat jest już uruchomiony i działa w protokole SSL i pomyślałem, że można z nim łatwo korzystać z wirtualnego hosta Apache VirtualHost. Drugim jest to, że dostawca aplikacji (JIRA) zapewnia pewne wytyczne dotyczące integracji apache ( atlassian.com/software/jira/docs/v3.13/apacheintegration.html ) i oparłem na nim moją konfigurację dodając obsługę VirtualHost. Myślę, że to było bardziej skomplikowane, niż myślałem, poza tym, że to działa, naprawdę chcę zrozumieć, na czym polega problem.
JMD
0

Czy naprawdę potrzebujesz proxy do usługi HTTPS? Możesz chcieć proxy do usługi innej niż ssl w localhost, np

ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
kodhead
źródło
Rzeczywiście, używanie SSL jest dla mnie obowiązkowe. Przetestowałem również proxy, nie używając SSL tylko do sprawdzenia i działa dobrze. Obsługa protokołu SSL to prawdziwy problem.
JMD
0

Najpierw sprawdzę, czy możesz wykonać żądanie z localhost do localhost: 8443 i zobacz, czy to się powiedzie (IE zrobi GET lub wget http: // localhost: 8443 )

Nie jestem do końca pewien, dlaczego Twój wirtualny host havin ga nasłuchuje na porcie 443, a następnie przekazuje go do innego hosta ssl

dlaczego nie mogę po prostu użyć natywnie 443? jeśli nie możesz tego zmienić, możesz po prostu użyć iptables do przekierowania portu

Brendan
źródło
Powodem jest to, że muszę zainstalować więcej aplikacji internetowych na tym samym serwerze, wszystkie korzystające z SSL i nie wszystkie one mogą nasłuchiwać na porcie 443. Korzystam z VirtualHosts opartych na IP, aby wyglądało, jakby każda aplikacja internetowa była hostowana na własnym serwerze. Przetestowałem następującą komendę wget i działa ona poprawnie: wget localhost: 8443 - no -check-certificate
JMD
2
Uwaga - dodawanie dodatkowych adresów IP do serwera jest proste, dlatego kilka aplikacji nasłuchuje na porcie 443 - wszystkie na osobnych adresach IP.
Brent
0

Sprawdź dziennik błędów SSL i upewnij się, że nie ma błędów związanych z niemożnością zweryfikowania łańcucha certyfikatów urzędu certyfikacji.

Neobajt
źródło
Jeśli rzeczywiście wystąpiły błędy weryfikacji, jakie byłoby rozwiązanie?
Javier Méndez