Apache VirtualHost dengan mod-proxy dan SSL

28

Saya mencoba menyiapkan server dengan beberapa aplikasi web yang semuanya akan dilayani melalui apache VirtualHost (apache berjalan di server yang sama). Kendala utama saya adalah bahwa setiap aplikasi web harus menggunakan enkripsi SSL. Setelah googling sebentar dan melihat pertanyaan lain tentang stackoverflow, saya menulis konfigurasi berikut untuk 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>

Meskipun https://host.example.org:8443 dapat diakses, https://host.example.org tidak, yang mengalahkan tujuan konfigurasi virtual host saya. Firefox mengeluh bahwa, meskipun berhasil terhubung ke server, koneksi terputus. Saya juga mendapatkan peringatan berikut di 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 

Pada aplikasi web (server Tomcat) log akses menunjukkan permintaan akses aneh:

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

Berikut ini adalah permintaan akses kembali yang benar yang saya dapatkan ketika saya terhubung langsung ke https://host.example.org:8443 :

"GET / HTTP/1.1" 302

Akhirnya saya juga harus menyebutkan bahwa virtual host berfungsi dengan baik ketika saya tidak menggunakan SSL.

Bagaimana saya bisa membuat ini berfungsi?

JMD
sumber

Jawaban:

34

Akhirnya saya menemukan cara untuk membuatnya bekerja. Pertama saya mencoba saran Dave Cheney, jadi saya menginstal sertifikat lain untuk server apache yang dialihkan ke port Tomcat non SSL (jadi proxynya dialihkan ke http: // localhost: 8080 / ). Sayangnya itu tidak sepenuhnya berfungsi karena di peramban web https diubah menjadi http segera setelah koneksi. Jadi saya kembali menggunakan https: // localhost: 8443 / dan sentuhan terakhir untuk membuatnya berfungsi adalah menambahkan lagi SSLProxyEngine.

Berikut adalah konfigurasi VirtualHost yang dihasilkan:

<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
sumber
1
Menghindarinya ProxyPreserveHost Onhampir selalu salah, tidak berguna dan hampir selalu rusak ProxyPassReverse. Sebagai catatan ProxyRequests offadalah default, sehingga berlebihan.
kubanczyk
Ketika kami menggunakan IP eksternal, localhostitu tidak berfungsi.
Chaminda Bandara
4

Coba konfigurasi ini

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

Jika aplikasi Anda perlu memiliki akses ke informasi SSL dari koneksi yang diproksi, Anda harus mempertimbangkan untuk menggunakan mod_proxy_ajp, dan konektor tomcat ajp1.3.

Dave Cheney
sumber
Saya akan menghasilkan sertifikat dengan mengenkripsi mari di server tempat aplikasi untuk host.domain.org berjalan. Lalu saya harus menggunakan kembali sertifikat yang sama di server proxy?
Giox
2

Tetapi jika tujuan Anda adalah menjalankan beberapa aplikasi web yang diaktifkan ssl di server yang sama. menambahkan apache di depan tidak akan menyeimbangkan mereka menggunakan konfigurasi di atas, Anda masih memerlukan load balancer atau Anda dapat menggunakan modul penyeimbang proxy apache dengan sesuatu seperti berikut:

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
sumber
Saat ini saya tidak benar-benar perlu menggunakan load balancing, tetapi itu bisa sangat membantu di masa depan. Terima kasih atas wawasannya.
JMD
1

Nah, apa yang saya tidak mengerti di sini adalah mengapa Anda perlu memiliki koneksi SSL dari apache Anda ke aplikasi Anda yang tampaknya berada di mesin yang sama ( http: // localhost: 8443 / ).

Saya kira cara yang biasa untuk mengatur hal-hal seperti ini adalah memiliki apache yang menyediakan enkripsi SSL ke sisi "pelanggan", misalnya internet, dan memiliki koneksi yang tidak terenkripsi ke aplikasi. Ini juga memberi Anda lebih banyak kebebasan untuk men-debug respons aplikasi Anda.

Hal lain yang disebutkan Dave Cheney adalah menggunakan konektor tomcat asli agar memiliki load balancing dan fitur lainnya.

zero_r
sumber
Yah saya punya dua alasan untuk memilih pengaturan seperti itu. Yang pertama adalah bahwa server Tomcat sudah berjalan dan berjalan di SSL dan saya pikir itu akan mudah untuk menggunakan apache VirtualHost dengannya. Yang kedua adalah bahwa penyedia aplikasi (JIRA) menyediakan beberapa pedoman untuk integrasi apache ( atlassian.com/software/jira/docs/v3.13/apacheintegration.html ) dan saya mendasarkan konfigurasi saya di atasnya dengan menambahkan dukungan VirtualHost. Tebak itu lebih kompleks daripada yang saya pikirkan, selain membuatnya berfungsi, saya benar-benar ingin memahami apa masalahnya.
JMD
0

Apakah Anda benar-benar perlu proksi ke layanan HTTPS? Anda mungkin ingin proksi ke layanan non-ssl di localhost, mis

ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
kepala kode
sumber
Memang menggunakan SSL adalah wajib bagi saya. Saya juga menguji ke proxy tanpa menggunakan SSL hanya untuk memeriksa dan berfungsi dengan baik. Dukungan SSL adalah masalah sebenarnya.
JMD
0

Pertama saya akan melihat apakah Anda dapat melakukan permintaan dari localhost ke localhost: 8443 dan lihat apakah itu berhasil (IE melakukan GET atau wget http: // localhost: 8443 )

Saya tidak begitu yakin mengapa Anda harus mendengarkan host virtual pada port 443 kemudian memproksi ke host ssl lain

mengapa aplikasi tidak bisa hanya menggunakan 443 secara asli? jika Anda tidak bisa mengubahnya, Anda bisa menggunakan iptables untuk mengarahkan ulang port

Brendan
sumber
Alasannya adalah bahwa saya perlu menginstal lebih banyak aplikasi web pada server yang sama, semuanya menggunakan SSL dan mereka tidak dapat semua mendengarkan pada port 443. Jadi saya menggunakan VirtualHosts berbasis IP untuk membuatnya terlihat seperti setiap aplikasi web di-host di server sendiri. Saya menguji perintah wget berikut dan berfungsi dengan baik: wget localhost: 8443 - tidak ada - sertifikat
JMD
2
Catatan - ini adalah masalah sederhana untuk menambahkan alamat IP tambahan ke server Anda, dan karenanya memiliki beberapa aplikasi mendengarkan pada port 443 - semua pada alamat IP yang terpisah.
Brent
0

Periksa log kesalahan SSL Anda dan pastikan Anda tidak memiliki kesalahan tentang tidak dapat memverifikasi rantai sertifikat CA.

Neobyte
sumber
Jika memang ada kesalahan verifikasi, apa solusinya?
Javier Méndez