Ähnlich wie bei dieser und dieser Frage möchte ich Benutzer daran hindern, die IP für den Zugriff auf meinen Server zu verwenden.
Für HTTP (Port 80) funktioniert dies einwandfrei, nicht jedoch für HTTPS. Benutzer können also weiterhin https://<myip>
auf den Webserver zugreifen, und nginx gibt das Standardzertifikat zurück. Übrigens verwende ich HTTP2 in meinen "üblichen" Serverblöcken (mit meinen Domainnamen), also verwende ich:
listen 443 ssl http2;
listen [::]:443 ssl http2;
Ich habe versucht, den HTTPS-IP-Zugriff jetzt zu blockieren:
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name _;
return 444;
}
Leider blockiert dies alle HTTPS-Anforderungen, unabhängig davon, ob die Domain verwendet wird oder nicht. Ich weiß, dass es möglicherweise notwendig ist, Nicht-SNI-Clients zu blockieren, da diese natürlich nicht den verwendeten Domänennamen an den Server liefern, also bin ich damit einverstanden. (Ich meine, Kunden, die SNI nicht unterstützen, sind sowieso alt ...)
Ich ziehe es im Allgemeinen vor, dies in Nginx zu blockieren, aber wenn Sie einige Ideen zum Blockieren auf Firewall-Ebene (iptables) haben, würde ich diese auch gerne schätzen. Und wenn Sie argumentieren möchten, warum das Blockieren mit iptables besser ist, können Sie dies auch tun und mich davon überzeugen, auch HTTP-Anfragen (oder alle anderen) an die IP zu blockieren. Im Allgemeinen ist das Trennen der Verbindung in Ordnung (wie es der Nginx-Statuscode 444 tut).
Es gibt jedoch eine Anforderung: Ich möchte die IP-Adresse des Servers in der Konfiguration nicht explizit erwähnen, da es sich um eine dynamische IP handelt und der Server einen dynamischen DNS-Dienst verwendet.
Kurz gesagt, hier ist, was ich erreichen möchte:
- Zugriff über IP blockieren
- Zugriff über Domainnamen zulassen
- Es ist in Ordnung, Nicht-SNI-Clients zu blockieren
- Es ist in Ordnung, hierfür eine Firewall-Blockierung zu verwenden
- Das Trennen der Verbindung ist in Ordnung
- ohne die IP-Adresse des Servers zu erwähnen
- Keine Offenlegung des Domainnamens über HTTPS
Bearbeiten: Ein weiterer fehlgeschlagener Versuch. Ich habe versucht, diesem Vorschlag zu folgen und dieses Konfigurations-Snippet zu verwenden, was logischerweise als eine gute Sache erscheint:
if ($host != "example.com") {
return 444;
}
Grundsätzlich funktioniert es auch, aber wenn ich auf "https: //" zugreife, sehe ich, dass nginx zuerst bereits das HTTPS-Zertifikat (das den Domänennamen enthält) sendet, und erst wenn ich die Verbindungswarnung überspringe, sehe ich, dass es den Zugriff blockiert. Dies ist logisch, da nginx den Host-Header nur lesen kann, wenn die HTTPS-Verbindung besteht. Zu diesem Zeitpunkt sendet nginx jedoch bereits das Serverzertifikat mit dem Domänennamen, sodass ein Benutzer jetzt den Domänennamen hat und die Verbindung über die gesamte IP-Adresse wiederherstellen kann Blockieren nutzlos. Ich bin auch ein bisschen besorgt über den Leistungsaspekt dieser Lösung, da Nginx den Host-Header für jede Anfrage überprüft. Daher suche ich hier immer noch nach einer Lösung.