Apache: คำขอที่ไม่ปลอดภัยส่งไปยังพอร์ตที่ปลอดภัย…ต้องการเปลี่ยนเส้นทาง


9

คำนำ

ประการแรก: เพียงแค่พอร์ต 80 -> พอร์ต 443 Rewrite จะไม่แก้ไขปัญหานี้ ในเกือบทุกคำถามก่อนหน้านี้เมลเธรดฟอรัมและอื่น ๆ ฉันพบว่านี่เป็นการตอบสนองครั้งแรกที่ไม่รู้และถูก parroted หลายครั้ง

ประการที่สอง: ใช่ฉันรู้ว่าคุณไม่สามารถให้บริการการรับส่งข้อมูล HTTP และ HTTPS บนพอร์ตเดียวกัน นี่ไม่ใช่อย่างนั้น

สถานการณ์:

เซิร์ฟเวอร์ Apache โฮสต์หลายไซต์ผ่านการคูณพอร์ต พอร์ต 80 ให้บริการเว็บไซต์สาธารณะ พอร์ต 443 ให้บริการเวอร์ชันที่ปลอดภัยของไซต์นั้น

พอร์ต 7443, 8443 และ 9443 แต่ละแห่งให้บริการไซต์ SSL ที่แยกต่างหาก

หากผู้ใช้พิมพ์ URL ผิดหรือได้รับลิงก์ที่ไม่ถูกต้องให้พูดhttp: //hostname.tld: 7443พวกเขาจะได้รับหน้าไร้สาระดังต่อไปนี้:

ข้อความแสดงข้อผิดพลาด Apache Bad Request

แทนของเซิร์ฟเวอร์เพียงการเปลี่ยนเส้นทางพวกเขาไปยังhttps: //hostname.tld: 7443

คำถามของฉันคือในชื่อbutthole ของ Zeusคุณสามารถปรับเปลี่ยนพฤติกรรมของ Apache หรือข้อความแสดงข้อผิดพลาดนี้เพื่อเปลี่ยนเส้นทางผู้ใช้โดยอัตโนมัติได้อย่างไร?

เห็นได้ชัดว่า Apache ให้บริการคำขอที่ไม่ใช่ https (เพื่อแสดงข้อความแสดงข้อผิดพลาดนั้น) แม้ว่าจะได้รับการกำหนดค่าสำหรับ HTTPS ดูเหมือนว่าฉันจะไม่เพียงแค่เปลี่ยนเส้นทางไปตามค่าเริ่มต้น แต่ฉันสามารถเข้าใจได้ว่าทำไมพวกเขาถึงมีพฤติกรรมที่พวกเขาทำแม้ว่าฉันจะไม่เห็นด้วยก็ตาม ดังนั้นคำถามของฉันคือคุณเปลี่ยนได้ไหม พวกเขาจัดการกับข้อผิดพลาดได้ไม่นานและด้วย Apache เป็นความอุดมสมบูรณ์ของการกำหนดค่าว่ามันเป็นเหตุผลที่มีคำสั่งบางอย่างที่จะจัดการกับพฤติกรรมนี้ แต่ฉันไม่สามารถหามันได้ในเวลาไม่กี่ชั่วโมง

ปรับปรุง:

ฉันได้ลองทำสิ่งต่าง ๆ รวมถึง:

  • ใช้ErrorDocument 400คำสั่งเพื่อรับ CGI และสคริปต์ PHP ที่เพิ่งส่งStatus 301และLocationส่วนหัว ผลลัพธ์นี้ในหน้าว่าง การใช้ErrorDocument 400 https://hostname.tld:7443ผลลัพธ์เพียงอย่างเดียวในลิงค์นั้นจะปรากฏบนหน้าเว็บ

  • การใช้การรวมกันของmod_rewriteI หรือ Google เกือบทุกครั้งสามารถเกิดขึ้นได้ สิ่งเหล่านี้ไม่ทำงาน แท้จริงพวกเขาไม่ทำอะไรเลย ฉันคาดการณ์ว่า Apache กำลังเตะไปยังข้อผิดพลาดด้านบนก่อนที่จะพยายามประมวลคำสั่งที่เขียนใหม่

ฉันไม่สามารถใช้การเปลี่ยนเส้นทางแบบพอร์ตได้เนื่องจากการใช้พอร์ตแบบกำหนดเอง ฉันไม่สามารถใช้การเปลี่ยนเส้นทางแบบอิงสคริปต์ได้เนื่องจากไม่ได้รับการแสดงผลเนื่องจาก http / https ไม่ตรงกัน ฉันเกือบจะยินดีที่จะชอล์กนี้ถึงข้อผิดพลาดหรือพฤติกรรมที่ไม่ตั้งใจ แต่ใครบางคนมีความคาดหวังที่จะใส่ข้อความข้อผิดพลาดที่กำหนดเองมากในนั้นพวกเขาไม่ได้คิดว่าบางทีคุณอาจต้องการที่จะซื้อ URL ที่พวกเขาให้บริการอยู่แล้ว ?



Daniel นั่นเป็นหนึ่งในคำถามมากมายที่ฉันค้นพบและวิธีแก้ไขที่ฉันได้ลองก่อนโพสต์คำถามนี้ ฉันคิดว่าปัญหาคือองค์ประกอบของ PHP แต่เนื่องจากการอัปเดตคำตอบของ @ hrunting ทำงานได้อย่างสวยงามสำหรับฉันในขณะนี้ฉันจะไม่จมลงไปในเวลามากกว่าที่ฉันมีอยู่แล้ว อย่างน้อยก็จนกว่าฉันจะต้อง
peelman

2
โหวตขึ้นสำหรับวิดีโอที่เชื่อมโยงมันสื่อถึงอารมณ์ของฉันอย่างสมบูรณ์แบบ
michele b

คำตอบ:


6

ฉันคิดว่านี่อาจเป็นข้อผิดพลาดในวิธีที่ Apache 2.2 และต่ำกว่าจัดการกับสถานการณ์เฉพาะนี้

ดูเหมือนว่าใน400 Bad Requestข้อผิดพลาดในการอ่าน SSL Apache 2.2 จะไม่ส่งคืนรหัสตอบกลับ HTTP หรือส่วนหัวเฉพาะเนื้อหาของการตอบกลับ HTTP ฉันทดสอบโดยเทลเน็ตติ้งไปที่พอร์ต 443 และส่ง:

GET / HTTP/1.1

เซิร์ฟเวอร์ส่งคืนทันที (สำหรับฉัน):

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />
Instead use the HTTPS scheme to access this URL, please.<br />
<blockquote>Hint: <a href="https://server.tld/"><b>https://server.tld/</b></a></blockquote></p>
</body></html>

สังเกตการขาดรหัสตอบกลับ HTTP หรือส่วนหัว HTTP ใด ๆ

เมื่อฉันทำสิ่งนี้กับเซิร์ฟเวอร์ Apache 2.4 ฉันจะได้รับ:

HTTP/1.1 400 Bad Request
Date: Sun, 10 Feb 2013 00:47:23 GMT
Server: Apache/2.4.3 (Unix) OpenSSL/1.0.0g
Content-Length: 462
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />
Instead use the HTTPS scheme to access this URL, please.<br />
</p>
<hr>
<address>Apache/2.4.3 (Unix) OpenSSL/1.0.0g Server at server.tld Port 443</address>
</body></html>

หากฉันตั้งค่าบรรทัด ErrorDocument เหมือนที่คุณทำ:

ErrorDocument 400 https://server.tld/

จากนั้นฉันจะได้รับ HTML สำหรับการเปลี่ยนเส้นทาง 302 แต่อีกครั้งไม่มีส่วนหัว หากไม่มีรหัสตอบกลับการเปลี่ยนเส้นทาง 302 และLocation:ส่วนหัวเบราว์เซอร์จะไม่เปลี่ยนเส้นทาง

ลองอัปเกรดเป็น Apache 2.4 และดูว่าใช้งานได้หรือไม่ ฉันได้ทดสอบและยืนยันด้วยอย่างน้อย Apache 2.4.3 แต่ฉันยังไม่ได้ผ่านความพยายามในการค้นหาว่าสิ่งนี้เป็นพฤติกรรมที่ได้รับการปรับปรุง ฉันสงสัยว่าในการทำงานจำนวนมากที่พวกเขาได้เตรียม 2.4 พวกเขาแก้ไขพฤติกรรมที่ไม่พึงประสงค์เป็นผลข้างเคียง

Apache httpd bugs ที่เกี่ยวข้อง:

UPDATE

คุณสามารถบังคับให้อาปาเช่บั๊กกี้ให้พฤติกรรมที่คุณต้องการ (การเปลี่ยนเส้นทาง) โดยให้สคริปต์พิมพ์ส่วนหัว (ซึ่งจะไม่ถูกส่งไปยังไคลเอนต์) จากนั้นพิมพ์ส่วนหัวที่คุณต้องการอีกครั้งด้วยตนเอง นี่คือสคริปต์ Perl พื้นฐานที่ทำงานภายใต้ Apache 2.2.22:

#!/usr/bin/perl

use strict;
use CGI;

my $q = CGI->new();

# this will cause Apache to handle the response properly, but is meaningless otherwise
print $q->redirect("https://localhost/");

# this actually performs the redirect
print "HTTP/1.1 302 Found\r\n";
print "Location: https://localhost/\r\n";
print "\r\n";

# you can do whatever you want here; this will be the HTML body

คุณควรทราบว่ามีสาเหตุอื่น ๆ 400 อาจถูกสร้างขึ้นนอกเหนือจากการพูดคุยกับพอร์ต SSL โดยไม่ใช้ SSL วิธีง่ายๆในการพิจารณาสิ่งนี้คือการมองหาHTTPSตัวแปรสภาพแวดล้อม หากมีการตั้งค่าแสดงว่า SSL ได้รับการเจรจาอย่างถูกต้องและมีสิ่งอื่นที่ทำให้เกิด 400 (ไม่ใช้เคล็ดลับส่วนหัวคู่หากเป็นกรณีนี้) หากHTTPSไม่ได้ตั้งค่าให้ส่งคืนการเปลี่ยนเส้นทางของคุณตามด้านบน


1
ศักดิ์สิทธิ์ อึ. คำตอบที่สมบูรณ์แบบ กราเซีย
ปอกเปลือก

คุณรู้ไหมว่าเมื่อฉันอ่านสิ่งนี้ฉันคิดกับตัวเองว่า "ผู้ชายมันแย่จริงๆถ้าคุณมี Apache 2.2 และคุณต้องการพฤติกรรมการเปลี่ยนเส้นทางแบบนี้" ฉันจะไม่พยายามค้นหา Apache 2.4 deb ที่เหมาะสม (หรือสร้างด้วยตัวเอง) สำหรับระบบ Ubuntu ของฉัน ฉันคิดว่าคุณสามารถแฮ็คโซลูชันจากสคริปต์ PHP ของคุณได้ อาปาเช่เห็นได้ชัดว่าเพียงแค่ทิ้งเอาต์พุตไปยังไคลเอนต์ดังนั้นหากคุณส่งคืนเนื้อหาที่คาดหวังไว้ฉันเดิมพันว่าคุณสามารถรับพฤติกรรมที่คุณต้องการโดยไม่ต้องอัพเกรด Apache ลองพิมพ์สคริปต์ PHP ของคุณออกมา "HTTP / 1.1 302 Found \ r \ n สถานที่: server.tld \ r \ n \ r \ n"
วิ่ง

ปัญหาที่เกิดขึ้นคือมันไม่ปรากฏว่าสคริปต์ PHP กำลังได้รับการประมวลผล ฉันควรทราบว่านี่คือการนั่งบน Apache 2.2.22 บน Ubuntu Server 12.04 และใช่มันดูดจริงๆ โดยเฉพาะอย่างยิ่งเมื่อคุณทราบว่าในรายงานข้อผิดพลาดเหล่านั้นดูเหมือนว่าพวกเขาจะถูกตั้งค่าอย่างสมบูรณ์แม้จะมีตัวเลือกในการเปลี่ยนเส้นทางโดยอัตโนมัติและดูเหมือนจะไม่หวังว่า 2.2 จะได้รับการแก้ไข
ปอกเปลือก

1
และอย่างที่ฉันพูดไว้ข้างต้นมันไม่สมเหตุสมผลกับฉันว่าทำไมคุณถึงมีปัญหาในการเขียนข้อความแสดงข้อผิดพลาดแทนที่จะเปลี่ยนเส้นทางเพื่อความปลอดภัย (จริงจังทำไมไม่เปลี่ยนเส้นทางไปเลย) ยิ่งฉันคิดถึงมันมากเท่าไหร่ ฉันคิดว่านั่นเป็นความคิดที่ไม่ดี)
ปอกเปลือก

1
ฉันได้ greiled ระบบไฟล์ทั้งหมดมองหาข้อความของข้อความเลือดนั้นเพื่อดูว่าฉันสามารถที่พวกเขากำลัง leeching จากที่โอกาสฉันสามารถฉีด<javascriptแท็กและได้รับโชคดีกับการเปลี่ยนเส้นทางแฮ็ค แต่ตอนนี้ยังไม่มี ลูกเต๋า. ไม่มีอะไรเกี่ยวกับเรื่องนี้ดูเหมือนว่าจะได้รับการจัดการในทางที่เป็นไปตาม Apache awesomeness มิฉะนั้นแข็งสวย ...
peelman

-1

คุณสามารถแก้ไขได้ด้วย mod-rewrite กำหนดกฎเพื่อให้ตรงกับสิ่งใด ดูคำตอบนี้ในStackoverflow


ไม่ฉันลองไปแล้วมันใช้งานไม่ได้ มันเหมือนไม่ได้ไปที่ขั้นตอน ModRewrite เพราะมันกดปุ่ม http / https ไม่ตรงกันก่อน
ปอกเปลือก

Hrm ดังนั้นฉันคิดว่าคุณได้เริ่มต้นจากด้านบนของไฟล์ apache config ของคุณและทำงานของคุณลงเพื่อดูสิ่งที่มันกำลังโทร
เทรนต์

ฉันจำsites-availableไดเรกทอรีทั้งหมดได้แล้ว แม้ว่าคุณเพียงแค่เปลี่ยนเส้นทางไปที่ไร้สาระหรือเปลี่ยนเส้นทางไปยังไซต์อื่นพอร์ตอื่น ฯลฯ ก็จะโหลด 400 คำขอที่ไม่ดี
peelman
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.