Apache: permintaan tidak aman dikirim ke port aman ... ingin mengarahkan

9

Kata pengantar

Pertama: A hanya Port 80 -> Port 443 Menulis Ulang TIDAK AKAN memperbaikinya. Di hampir setiap pertanyaan sebelumnya, utas email, utas forum, dll., Saya telah menemukan ini adalah jawaban bodoh pertama dan di-beo beberapa kali.

Kedua: Ya, saya tahu Anda tidak dapat melayani lalu lintas HTTP dan HTTPS di port yang sama. Bukan itu.

Skenario:

Apache Server meng-hosting beberapa situs melalui multiplikasi port. Port 80 melayani situs publik. Port 443 menyajikan versi aman situs itu.

Ports 7443, 8443, dan 9443 masing-masing melayani situs SSL-Diamankan terpisah.

Jika pengguna salah ketik URL, atau diberi tautan yang tidak valid, katakan http: //hostname.tld: 7443 , mereka diberi halaman konyol berikut:

Pesan kesalahan Apache Bad Request

Alih-alih server hanya mengarahkan mereka ke https: //hostname.tld: 7443 .

Pertanyaan saya adalah, bagaimana dengan nama butthole Zeus Anda dapat memodifikasi perilaku Apache atau pesan kesalahan ini untuk mengarahkan ulang pengguna secara otomatis?

Apache jelas melayani permintaan non-https (untuk menampilkan pesan kesalahan itu) meskipun itu dikonfigurasi untuk HTTPS. Tampaknya sangat bodoh bagi saya untuk tidak hanya melakukan redirect secara default, tapi saya bisa mengerti mengapa mereka mengikuti perilaku yang mereka lakukan, bahkan jika saya tidak setuju dengan itu. Jadi pertanyaan saya adalah: bisakah Anda mengubahnya? Mereka menangani kesalahan DI MANA SAJA, dan dengan Apache sebagai tumpah ruah konfigurasi itu, masuk akal ada beberapa arahan di suatu tempat untuk menangani perilaku ini, tapi saya belum dapat menemukannya dalam beberapa jam bermain-main sejauh ini.

Memperbarui:

Saya telah mencoba berbagai hal termasuk:

  • menggunakan ErrorDocument 400arahan untuk mendapatkan CGI dan skrip PHP yang baru saja dikirim Status 301dan Locationtajuk. Ini menghasilkan halaman kosong. Menggunakan ErrorDocument 400 https://hostname.tld:7443hanya menghasilkan link yang ditampilkan pada halaman.

  • Menggunakan hampir setiap kombinasi mod_rewriteI atau Google dapat muncul, termasuk pernyataan selimut yang mengarahkan situs sepenuhnya; ini tidak pernah berhasil. Secara harfiah, mereka tidak melakukan apa-apa. Saya menduga bahwa Apache menendang ke kesalahan di atas bahkan sebelum mencoba untuk memproses arahan menulis ulang.

Saya tidak dapat menggunakan pengalihan berbasis port, karena penggunaan port khusus. Saya tidak dapat menggunakan pengalihan berbasis skrip karena mereka tidak pernah dilayani karena ketidakcocokan http / https. Saya hampir bersedia untuk mengubah ini menjadi bug, atau perilaku yang tidak disengaja, tetapi seseorang memiliki pemikiran sebelumnya untuk menempatkan pesan kesalahan yang sangat khusus di sana, mereka tidak repot-repot berpikir bahwa mungkin Anda hanya ingin pergi ke URL yang sudah mereka sediakan ?

pengupas
sumber
Daniel, Itu adalah salah satu dari banyak pertanyaan yang saya temukan dan solusi yang saya coba sebelum memposting pertanyaan ini. Saya pikir masalahnya adalah komponen PHP, tetapi karena pembaruan jawaban @ hrunting bekerja dengan baik untuk saya saat ini, saya tidak akan tenggelam lebih lama daripada yang sudah saya miliki; setidaknya tidak sampai aku harus melakukannya.
peelman
2
memilih untuk video yang tertaut, itu menyampaikan emosi saya dengan sempurna
michele b

Jawaban:

6

Saya pikir ini mungkin bug dalam bagaimana Apache 2.2 dan yang lebih rendah menangani keadaan khusus ini.

Tampaknya pada 400 Bad Requestkesalahan pembacaan SSL , Apache 2.2 tidak mengembalikan kode respons HTTP atau header, hanya badan respons HTTP. Saya menguji dengan telnetting ke port 443 dan mengirim:

GET / HTTP/1.1

Server segera kembali (untuk saya):

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

Perhatikan kurangnya kode respons HTTP atau header HTTP apa pun.

Ketika saya melakukan ini ke server Apache 2.4, saya mendapatkan:

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>

Jika saya mengatur baris ErrorDocument seperti yang Anda lakukan:

ErrorDocument 400 https://server.tld/

Lalu saya mendapatkan HTML untuk redirect 302, tapi sekali lagi, tidak ada header. Tanpa 302 redirect response code dan Location:header, browser tidak akan mengalihkan.

Coba tingkatkan ke Apache 2.4 dan lihat apakah itu berfungsi. Saya telah menguji dan mengonfirmasi dengan setidaknya Apache 2.4.3, tetapi saya belum melalui upaya untuk menemukan secara tepat kapan perilaku ini diperbarui. Saya menduga bahwa dalam sejumlah besar pekerjaan yang mereka lakukan persiapan 2.4, mereka memperbaiki perilaku yang tidak diinginkan sebagai efek samping.

Bug httpd Apache yang relevan:

MEMPERBARUI

Anda dapat memaksa Apache buggy untuk memberi Anda perilaku yang Anda inginkan (pengalihan) dengan meminta skrip mencetak header-nya (yang tidak akan dikirim ke klien), dan kemudian secara manual mencetak lagi header yang Anda inginkan. Berikut skrip Perl dasar yang bekerja di bawah 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

Anda harus menyadari bahwa ada alasan lain yang dapat dihasilkan 400 selain hanya berbicara ke port SSL tanpa SSL. Cara mudah untuk menentukan ini adalah dengan mencari HTTPSvariabel lingkungan. Jika diatur, maka SSL dinegosiasikan dengan benar dan sesuatu yang lain menyebabkan 400 (jangan lakukan trik tajuk ganda jika itu masalahnya). Jika HTTPStidak disetel, kembalikan pengalihan Anda seperti di atas.

hrunting
sumber
1
Suci. Sampah. Jawaban Sempurna. Gracias.
peelman
Anda tahu, ketika saya membaca ini, saya berpikir dalam hati, "Ya ampun, sungguh menyebalkan jika Anda memiliki Apache 2.2 dan Anda menginginkan perilaku pengalihan seperti ini." Saya tidak akan melalui upaya menemukan deb Apache 2.4 yang tepat (atau membuat saya sendiri) untuk sistem Ubuntu saya. Saya yakin Anda bisa meretas solusi dari skrip PHP Anda. Apache jelas hanya membuang output ke klien, jadi jika Anda mengembalikan konten yang diharapkan spesifik, saya yakin Anda bisa mendapatkan perilaku yang Anda cari tanpa memutakhirkan Apache. Coba skrip PHP Anda mencetak "HTTP / 1.1 302 Ditemukan \ r \ nLokasi: server.tld \ r \ n \ r \ n".
hrunting
Masalahnya adalah bahwa tampaknya skrip PHP tidak sedang diproses. Saya harus mencatat bahwa saat ini duduk di Apache 2.2.22 di Ubuntu Server 12.04. Dan ya, itu benar-benar menyebalkan; terutama ketika Anda mencatat bahwa dalam laporan bug itu, mereka tampaknya sepenuhnya menentang bahkan memberikan pilihan untuk secara otomatis melakukan redirect, dan tampaknya tidak ada banyak harapan bahwa 2.2 akan pernah mendapatkan perbaikan.
peelman
1
Dan seperti yang saya katakan di atas, tidak masuk akal bagi saya mengapa Anda mengalami kesulitan untuk menulis pesan kesalahan itu, daripada mengarahkan ulang ke aman (serius, mengapa tidak hanya mengarahkan ulang? Semakin saya memikirkannya, semakin saya memikirkannya, semakin sedikit Saya pikir itu ide yang buruk).
peelman
1
Saya telah memahami seluruh sistem file mencari teks dari pesan berdarah itu untuk melihat apakah saya dapat dari mana mereka lintah, jika saya bisa menyuntikkan <javascripttag dan beruntung dengan pengalihan hacking cara itu, tapi sejauh ini, tidak ada dadu. Tampaknya tidak ada yang bisa ditangani dengan cara yang mengikuti
kemahiran
-1

Anda dapat memperbaikinya dengan mod-rewrite. Tetapkan aturan untuk mencocokkan apa pun. Lihat jawaban ini di Stackoverflow

trent
sumber
Tidak, saya sudah mencobanya, tidak berhasil. Ini seperti itu bahkan tidak sampai ke langkah-langkah ModRewrite karena memukul ketidakcocokan http / https pertama.
peelman
Hrm jadi saya menganggap Anda sudah mulai dari atas file konfigurasi apache Anda dan bekerja keras untuk melihat apa namanya
trent
Saya praktis telah menghafal seluruh sites-availabledirektori. Bahkan jika Anda hanya mengarahkannya ke omong kosong, atau mengarahkannya ke situs yang berbeda, port yang berbeda, dll., Itu terus memuat 400 Permintaan Buruk itu.
peelman