Apache: richiesta non sicura inviata alla porta sicura ... desidera reindirizzare


9

Prefazione

Innanzitutto: una semplice Porta 80 -> Porta 443 Riscrivi NON risolverà questo problema. In quasi ogni domanda precedente, thread di posta, thread del forum, ecc., Ho scoperto che questa è stata la prima risposta ignorante ed è stata ripetutamente pappagallo.

In secondo luogo: Sì, so che non è possibile servire il traffico HTTP e HTTPS sulla stessa porta. Questo non è quello.

Scenario:

Server Apache che ospita più siti tramite moltiplicazione delle porte. Port 80 serve un sito pubblico. La porta 443 serve la versione sicura di quel sito.

Le porte 7443, 8443 e 9443 servono ciascuna siti separati protetti da SSL.

Se un utente digita in modo errato l'URL o riceve un link non valido, ad esempio http: //hostname.tld: 7443 , viene visualizzata la seguente pagina ridicola:

Messaggio di errore Richiesta non valida Apache

Invece del server semplicemente reindirizzandoli su https: //hostname.tld: 7443 .

La mia domanda è: come in nome del butthole di Zeus puoi modificare il comportamento di Apache o questo messaggio di errore per reindirizzare l'utente automagicamente?

Apache ovviamente serve una richiesta non https (per visualizzare quel messaggio di errore) anche se è configurato per HTTPS. Mi sembra straordinariamente stupido non solo fare il reindirizzamento di default, ma posso capire perché sono andati con il comportamento che hanno fatto, anche se non sono d'accordo. Quindi la mia domanda è: puoi cambiarlo? Stanno gestendo l'errore QUALCUNO, e con Apache che è la configurazione cornucopia che è, è logico che ci sia qualche direttiva da qualche parte per gestire questo comportamento, ma finora non sono riuscito a trovarlo in diverse ore di armeggiamento.

Aggiornare:

Ho tentato una varietà di cose tra cui:

  • usando le ErrorDocument 400direttive per arrivare a un CGI e uno script PHP che inviano Status 301e Locationintestazioni. Ciò si traduce in una pagina vuota. L'uso di ErrorDocument 400 https://hostname.tld:7443semplicemente comporta la visualizzazione di quel link sulla pagina.

  • Usando quasi tutte le combinazioni di mod_rewriteI o Google può venire in mente, comprese dichiarazioni generali che dirigono interamente il sito; questi non funzionano mai . Letteralmente, non fanno nulla. Sto supponendo che Apache stia dando dei calci all'errore precedente prima ancora di tentare di elaborare le direttive di riscrittura.

Non riesco a utilizzare i reindirizzamenti basati sulle porte, a causa dell'utilizzo personalizzato delle porte. Non riesco a utilizzare i reindirizzamenti basati su script perché non vengono mai offerti a causa della mancata corrispondenza di http / https. Sono quasi disposto a scrivere questo su un bug o un comportamento non intenzionale, ma qualcuno ha avuto la premura di mettere un messaggio di errore molto personalizzato lì dentro, non si sono preoccupati di pensare che forse avresti voluto solo passare al URL che stanno già fornendo ?



Daniel, questa era una delle tante domande che avevo trovato e delle soluzioni che avevo tentato prima di pubblicare questa domanda. Penso che il problema fosse il componente PHP, ma dal momento che l'aggiornamento della risposta di @ hrunting sta funzionando magnificamente per me al momento, non ci sprofonderò più tempo di quello che ho già; almeno non fino a quando devo.
Peelman,

2
votato per il video collegato, trasmette perfettamente le mie emozioni
michele b

Risposte:


6

Penso che questo sia probabilmente un bug nel modo in cui Apache 2.2 e versioni inferiori gestiscono questa particolare circostanza.

Sembra che su un 400 Bad Requesterrore di lettura SSL , Apache 2.2 non restituisca il codice di risposta HTTP o le intestazioni, ma solo il corpo della risposta HTTP. Provo telefonando alla porta 443 e inviando:

GET / HTTP/1.1

Il server restituisce immediatamente (per me):

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

Nota la mancanza di un codice di risposta HTTP o di eventuali intestazioni HTTP.

Quando lo faccio su un server Apache 2.4, ottengo:

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>

Se imposto una riga ErrorDocument come hai fatto tu:

ErrorDocument 400 https://server.tld/

Quindi ottengo l'HTML per un reindirizzamento 302, ma ancora nessuna delle intestazioni. Senza il codice di risposta di reindirizzamento 302 e l' Location:intestazione, il browser non reindirizzerà.

Prova ad aggiornare ad Apache 2.4 e vedi se funziona. Ho testato e confermato almeno con Apache 2.4.3, ma non ho fatto lo sforzo di trovare esattamente quando questo comportamento è stato aggiornato. Ho il sospetto che nella grande quantità di lavoro svolto preparando 2.4, abbiano corretto il comportamento indesiderato come effetto collaterale.

Rilevanti bug di Apache httpd:

AGGIORNARE

Puoi forzare un buggy Apache a darti il ​​comportamento che desideri (il reindirizzamento) facendo stampare dallo script le sue intestazioni (che non verranno inviate al client) e quindi stampare di nuovo manualmente le intestazioni che desideri. Ecco uno script Perl di base che funziona con 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

Dovresti essere consapevole che ci sono altri motivi per cui un 400 può essere generato oltre a parlare con una porta SSL senza SSL. Il modo più semplice per determinare ciò è cercare la HTTPSvariabile d'ambiente. Se è impostato, SSL è stato negoziato correttamente e qualcos'altro sta causando il 400 (non fare il doppio trucco dell'intestazione se è il caso). Se HTTPSnon impostato, restituisci il reindirizzamento come sopra.


1
Santo. Una schifezza. Risposta perfetta. Gracias.
peelman,

Sai, mentre leggo questo, penso tra me e me: "Amico, fa davvero schifo se hai Apache 2.2 e vuoi questo tipo di comportamento di reindirizzamento." Non ho intenzione di trovare un deb (Apache 2.4) appropriato per Apache 2.4 per il mio sistema Ubuntu. Scommetto che puoi hackerare una soluzione dal tuo script PHP. Apache sta chiaramente scaricando l'output sul client, quindi se restituisci il contenuto previsto specifico, scommetto che puoi ottenere il comportamento che stai cercando senza aggiornare Apache. Prova a stampare lo script PHP "HTTP / 1.1 302 Found \ r \ nLocation : server.tld \ r \ n \ r \ n".
caccia il

Il problema è che non sembra che lo script PHP venga elaborato. Dovrei notare che questo è attualmente seduto su Apache 2.2.22 su Ubuntu Server 12.04. E sì, davvero, fa davvero schifo; specialmente quando noti che in quelle segnalazioni di bug, sembrano essere completamente contro persino fornendo un'opzione per fare automaticamente il reindirizzamento, e non sembra esserci molta speranza che 2.2 possa mai ottenere la correzione.
peelman,

1
E come ho detto sopra, non ha senso per me perché attraversi il problema a scrivere quel messaggio di errore, piuttosto che reindirizzare per proteggere (sul serio, perché non semplicemente reindirizzare? Più ci penso, meno Penso che sia una cattiva idea).
peelman,

1
Ho greppato l'intero file system alla ricerca del testo di quel messaggio sanguinante per vedere se posso da dove lo stanno facendo sanguinare, per caso potrei iniettare un <javascripttag e essere fortunato con l'hacking del reindirizzamento in quel modo, ma finora, no dado. Niente di tutto ciò sembra essere gestito in un modo che segue la
bellezza

-1

Puoi risolvere questo problema con mod-rewrite. Imposta una regola per abbinare qualsiasi cosa. Vedi questa risposta su StackOverflow


No, l'ho già provato, non funziona. È come se non arrivasse nemmeno ai passaggi di ModRewrite perché ha colpito prima la mancata corrispondenza http / https.
peelman,

Hrm, quindi presumo che tu abbia iniziato dalla cima del tuo file di configurazione di Apache e sia sceso giù per vedere come si chiama
Trento,

Ho praticamente memorizzato l'intera sites-availabledirectory. Anche se lo reindirizzi semplicemente a una sciocchezza o lo reindirizzi a un sito diverso, a una porta diversa, ecc., Continua a caricare quella 400 richiesta errata.
peelman,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.