การเปลี่ยนไซต์ Apache http ให้เป็นไซต์ https ที่ปลอดภัยผ่าน Nginx reverse proxy
ฉันต้องสนับสนุนไซต์ WordPress เก่าที่ทำงานบนเว็บเซิร์ฟเวอร์ Apache เพื่อให้สิ่งต่างๆปลอดภัยยิ่งขึ้นเซิร์ฟเวอร์ Apache นี้อยู่ในคอนเทนเนอร์ Docker และสามารถเข้าถึงได้ทั่วโลกผ่านการกำหนดค่า Nginx reverse proxy ขณะนี้ไซต์นี้ให้บริการผ่าน http และฉันต้องการย้ายไปที่ https
ฉันคิดว่าฉันมีสองทางเลือก:
มีการติดตั้งใบรับรอง SSL สำหรับไซต์ Nginx และทำ
proxy_passกับไซต์ http ธรรมดาบนคอนเทนเนอร์ 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; } }ในสถานการณ์นี้จากมุมมองของเซิร์ฟเวอร์ Apache มันยังคงให้บริการไซต์ผ่าน http
สิ่งนี้ยุ่งยากกว่า: ใบรับรอง SSL ติดตั้งทั้งบนเซิร์ฟเวอร์ Nginx เกตเวย์และไซต์ Apache แบบพร็อกซี จากนั้นจะต้องเปลี่ยน
httpเป็นhttpsในproxy_passค่ากำหนดค่า
ฉันหวังว่าทุกอย่างจะดีกับสถานการณ์ที่ 1 แต่ความจริงที่ว่า Apache รู้สึกว่ากำลังให้บริการสิ่งต่างๆผ่าน http ทำให้เกิดปัญหาบางอย่าง: มีการเปลี่ยนเส้นทาง URL ที่ซ่อนอยู่ซึ่งฉันไม่ต้องการกำหนดค่าใหม่ / แก้ไขข้อบกพร่อง และผู้ที่เปลี่ยนเส้นทาง URL ทำอะไรเช่นนี้ถ้า URL ที่ร้องขอคือhttp://www.example.comมันจะเขียนใหม่ (http สถานะ 301) http://www.example.com/mainเช่น เบราว์เซอร์ได้รับการเปลี่ยนเส้นทางนี้ดังนั้นแม้ว่าคำขอแรกจะอยู่บน https แต่ตอนนี้ URL ที่เปลี่ยนเส้นทางคือ http หนึ่ง นอกจากนี้ไซต์ html ยังมี hrefs แบบเต็มพา ธ ที่ให้บริการไปยังทรัพยากรของตัวเอง (ไฟล์ JavaScript และ CSS) ซึ่งรวมถึงการอ้างอิงโปรโตคอลด้วย ในตอนนี้ยังไม่ชัดเจนว่า hrefs เหล่านั้นใช้โปรโตคอลจากวิธีการสร้างคำขอหรือฮาร์ดโค้ด อย่างไรก็ตามน่าเสียดายที่สิ่งนี้ใช้ไม่ได้หากไม่มีการขุดอย่างจริงจัง
ดังนั้นฉันจึงเหลือตัวเลือกที่ 2 ฉันลองแล้วมันใช้งานได้ฉันสามารถตั้งค่าใบรับรอง SSL เดียวกันทั้งบน Nginx และ Apache ที่มีคอนเทนเนอร์ แต่ฉันต้องการทราบว่านี่เป็นวิธีที่ควรปล่อยให้ทำงานจริงหรือไม่ เนื่องจากแม้ว่าตอนนี้เซิร์ฟเวอร์ Apache จะรู้แล้วว่ามีการแสดงเนื้อหาผ่าน https แต่ตอนนี้มี SSL สองครั้งที่เกิดขึ้นสำหรับทุกคำขอ มันไม่ถูกปาก
คำตอบ
คุณควรจะสามารถบอก Apache ได้ว่าคำขอที่เข้ามานั้นกำลังถูกส่งจากคำขอ HTTPS ด้วยการproxy_set_header X-Forwarded-Proto "https";ประกาศในการตั้งค่าครั้งแรก
คุณสามารถแก้ปัญหาได้ในตัวเลือก # 1 ของคุณ (ซึ่งตามที่คุณกล่าวเป็นแนวทางที่ดีกว่ามาก) โดยตั้งค่า HTTP_X_FORWARDED_PROTO ในการกำหนดค่า nginx ของคุณด้วย
proxy_set_header X-Forwarded-Proto $scheme;
และกำหนดค่า WordPress ให้จดจำได้โดยต่อท้ายบรรทัดนี้กับ wp-config.php
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { $_SERVER['HTTPS'] = 'on';
}
ดูบทความสนับสนุน Wordpressสำหรับรูปแบบต่างๆของโซลูชันนี้
โดยปกติฉันต้องการที่จะทำการยกของหนักทั้งหมดใน reverse proxy และรักษาไซต์แบ็กเอนด์ที่ได้รับการเปิดเผยให้เป็นต้นฉบับมากที่สุด
ปัญหาของคุณดูเหมือนจะเป็นสาระสำคัญที่แบ็กเอนด์ (WordPress) สร้างและใช้ URI (สัมบูรณ์) ที่แตกต่างจากสิ่งที่คุณต้องการให้ผู้เยี่ยมชมใช้
คุณสามารถแก้ไขว่าด้วยการเขียนใหม่ (HTML) เนื้อหาที่ WordPress สร้างใน Nginx กับngx_http_sub_module นอกจากนี้ยังช่วยให้คุณสามารถเขียน URL ที่สมบูรณ์ใหม่ด้วยสิ่งที่คล้ายกับ:
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;
}