Mengubah situs http Apache menjadi situs https yang aman melalui proxy balik Nginx
Saya harus mendukung situs WordPress lama yang berjalan di server web Apache. Untuk membuat segalanya lebih aman, server Apache ini berada dalam wadah Docker, dan dapat diakses oleh dunia melalui konfigurasi proxy balik Nginx. Situs ini sekarang disajikan melalui http, dan saya ingin memindahkannya ke https.
Saya rasa saya punya dua pilihan:
Sertifikat SSL diinstal untuk situs Nginx, dan itu berlaku
proxy_passuntuk situs http biasa di penampung Apache:server { listen 443 ssl; server_name www.example.com; ssl_certificate /etc/nginx/ssl/letsencrypt/live/www.example.com/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/letsencrypt/live/www.example.com/privkey.pem; access_log /var/log/nginx/example.com.access.log; location / { proxy_pass http://Apache2-PHP5.6:80; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }Dalam skenario ini dari sudut pandang server Apache, itu masih melayani situs melalui http
Ini lebih merepotkan: sertifikat SSL diinstal di server gateway Nginx, dan situs Apache yang di-proxy. Maka perlu diubah
httpkehttpsdalam nilaiproxy_passconfig.
Saya berharap semuanya baik-baik saja dengan skenario pertama. Tetapi fakta bahwa Apache merasa itu menyajikan barang melalui http menimbulkan beberapa masalah: ada beberapa pengalihan URL tersembunyi yang saya benar-benar ingin tidak mengkonfigurasi ulang / debug. Dan pengalihan URL tersebut melakukan sesuatu seperti ini: jika URL yang diminta adalah http://www.example.com, itu ditulis ulang (http status 301) sebagai http://www.example.com/main. Pengalihan ini diterima oleh browser, jadi, meskipun permintaan pertama lebih dari https, sekarang URL yang dialihkan adalah http satu. Juga html situs berisi href jalur lengkap serveral ke sumber dayanya sendiri (JavaScript dan file CSS) yang juga menyertakan referensi protokol. Tidak jelas pada saat ini apakah href tersebut mengadopsi protokol dari cara permintaan dibuat, atau di-hardcode. Bagaimanapun, sayangnya ini tidak berfungsi tanpa penggalian yang serius.
Jadi, saya dibiarkan dengan opsi 2. Saya mencoba, berhasil, saya dapat mengatur sertifikat SSL yang sama pada Nginx dan Apache dalam container. Tapi saya ingin tahu apakah ini benar-benar bagaimana seharusnya dibiarkan berjalan. Karena meskipun server Apache sekarang mengetahui bahwa konten disajikan melalui https, sekarang ada SSL ganda yang terjadi untuk setiap permintaan. Rasanya tidak benar.
Jawaban
Anda harus dapat memberi tahu Apache bahwa permintaan masuk sedang diproksikan dari permintaan HTTPS dengan proxy_set_header X-Forwarded-Proto "https";deklarasi di penyiapan pertama
Anda dapat menyelesaikan masalah dalam opsi # 1 (yang, seperti yang Anda katakan, merupakan pendekatan yang jauh lebih baik) dengan menyetel HTTP_X_FORWARDED_PROTO di konfigurasi nginx Anda dengan
proxy_set_header X-Forwarded-Proto $scheme;
dan mengkonfigurasi WordPress untuk mengenalinya dengan menambahkan baris ini ke wp-config.php
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { $_SERVER['HTTPS'] = 'on';
}
Lihat juga artikel dukungan Wordpress untuk variasi dari solusi ini.
Biasanya saya lebih suka melakukan semua pekerjaan berat pada proxy terbalik dan menjaga situs backend yang terekspos seasl mungkin.
Masalah Anda tampaknya pada dasarnya bahwa backend (WordPress) menghasilkan dan menggunakan URI (mutlak) yang berbeda dari apa yang Anda ingin pengunjung gunakan.
Anda dapat memperbaikinya dengan menulis ulang konten (HTML) yang dihasilkan WordPress di nginx dengan ngx_http_sub_module . Itu juga akan memungkinkan Anda untuk menulis ulang URL absolut dengan sesuatu yang mirip dengan:
location / {
sub_filter 'http://example.com/' 'https://www.example.com/' ;
sub_filter 'http://www.example.com/' 'https://www.example.com/' ;
sub_filter_once off;
proxy_pass http://Apache2-PHP5.6:80;
proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}