2017-01-28 4 views
1

Ich schreibe ein Perl-Skript, um einen Server zu testen, bevor DNS vom alten Server (für die Unterstützung von Servermigrationen) geschaltet wird. Ich würde lieber nicht/etc/hosts hacken, um DNS für Testzwecke zu überschreiben, und stattdessen die Script-Munge-Dinge funktionieren lassen.Testen eines SNI https-Dienstes durch IP-Adresse

Es ist einfach genug für nicht-SSL-Verbindungen, aber ich habe Probleme mit SSL - es funktioniert für die meisten Websites, da die meisten immer noch eine Website an eine IP-Adresse binden, aber eine bestimmte Kundenseite ist zu schlau für sein eigenes Gut (Und das ist die Richtung, in die die Dinge sowieso gehen sollten), und ich muss LWP :: UserAgent mitteilen, dass er sich mit einer IP-Adresse verbinden soll, aber einen Servernamen in der Anfrage verwenden (sowohl SSL SNI als auch HTTP Host :).

Ich verwende ssl_opts, um den SNI-Hostnamen zu setzen (und die SSLeay-Ablaufverfolgung zeigt, dass es richtig eingestellt wird), und erzwingt den Host-HTTP-Header auf den Servernamen (der Ausdruck der Anfrage soll richtig eingestellt werden) , aber LWP verwendet die URL, um zu entscheiden, mit welchem ​​Host eine Verbindung hergestellt werden soll, und diese URL wird dort eingefügt, wo sie nicht sein sollte (ich würde erwarten, dass das eigentliche "GET" einfach "GET /" ist), also die Anfrage "as_string" isn ' t ganz genau), zu einem Fehler führt:

#!/usr/bin/perl 

# 
# ht 
# 
# https test 
# see if I can force a Host: header 
# while using an ip address to connect 
# 

use strict; 

use Net::SSLeay; 
use LWP::UserAgent; 
$Net::SSLeay::trace = 2; 

my $ip = '1.2.3.4'; 
my $server_name = 'server.name'; 
my $url = "https://$ip/"; 
#my $url = "https://$server_name/"; 

print "connecting to $ip for $server_name\n"; 

my $h = HTTP::Headers->new; 
$h->header('Host' => $server_name); 

my %options = (
    'ssl_opts' => { SSL_hostname => $server_name } 
); 

my $ua = LWP::UserAgent->new(%options); 
$ua->agent("perl-mpchk/0.1 "); 

# Create a request 
my $req; 
$req = HTTP::Request->new('GET', $url, $h); 
print $req->as_string, "\n"; 

# Send request to the user agent and get a response back 
my $res = $ua->request($req); 
if (!defined($res)) { 
    die "connect to $url failed\n"; 
} 

print $res->status_line, "\n"; 

exit 0; 

mit einem Host-Name:

connecting to 1.2.3.4 for server.name 
GET https://server.name/ 
Host: server.name 

DEBUG: .../IO/Socket/SSL.pm:562: socket not yet connected 
DEBUG: .../IO/Socket/SSL.pm:564: socket connected 
DEBUG: .../IO/Socket/SSL.pm:586: ssl handshake not started 
DEBUG: .../IO/Socket/SSL.pm:619: using SNI with hostname server.name 
DEBUG: .../IO/Socket/SSL.pm:654: request OCSP stapling 
DEBUG: .../IO/Socket/SSL.pm:673: set socket to non-blocking to enforce timeout=180 
DEBUG: .../IO/Socket/SSL.pm:699: ssl handshake in progress 
DEBUG: .../IO/Socket/SSL.pm:709: waiting for fd to become ready: SSL wants a read first 
DEBUG: .../IO/Socket/SSL.pm:729: socket ready, retrying connect 
DEBUG: .../IO/Socket/SSL.pm:744: ssl handshake done 
200 OK 

mit einer IP-Adresse

connecting to 1.2.3.4 for server.name 
GET https://1.2.3.4/ 
Host: server.name 

DEBUG: .../IO/Socket/SSL.pm:562: socket not yet connected 
DEBUG: .../IO/Socket/SSL.pm:564: socket connected 
DEBUG: .../IO/Socket/SSL.pm:586: ssl handshake not started 
DEBUG: .../IO/Socket/SSL.pm:619: using SNI with hostname server.name 
DEBUG: .../IO/Socket/SSL.pm:654: request OCSP stapling 
DEBUG: .../IO/Socket/SSL.pm:673: set socket to non-blocking to enforce timeout=180 
DEBUG: .../IO/Socket/SSL.pm:699: ssl handshake in progress 
DEBUG: .../IO/Socket/SSL.pm:709: waiting for fd to become ready: SSL wants a read first 
DEBUG: .../IO/Socket/SSL.pm:729: socket ready, retrying connect 
DEBUG: .../IO/Socket/SSL.pm:744: ssl handshake done 
500 Unknown Domain 

Antwort

2

Sie LWP überspringen könnte und die Buchse direkt verwenden:

use IO::Socket::SSL; 

my $ip_address = ...; 
my $server_name = ...; 

my $cl = IO::Socket::SSL->new(
    PeerAddr => $ip_address, 
    PeerPort => 443, 
    SSL_hostname => $server_name, 
    SSL_verifycn_name => $server_name, 
    SSL_verifycn_scheme => 'http', 
); 
print $cl "GET/HTTP/1.0\r\nHost: $server_name\r\n\r\n"; 
print scalar(<$cl>); # status line 
+0

Das wird der gleiche Fehler, und tshark zeigt, SNI richtig eingestellt ist, so denke ich, das Problem ist eigentlich ein Server-Interaktionsproblem. Ich verfolge das jetzt mit der Remote-Site ... – abatie

-1

Das Problem ein Proxy in der Mitte zu sein, stellte sich heraus, dass eine IP-Adresse url Form übersetzte . Korrigiert, um den Namen richtig zu verwenden, und es begann zu arbeiten.

+0

Ihre Frage zum Testen einer bestimmten IP-Adresse mit SNI. Ihre Antwort beantwortet die Frage nicht, sondern zeigt stattdessen die Lösung des zugrunde liegenden Problems, d. H. Warum Sie diesen Test überhaupt benötigt haben. Es wäre also ein Anfall für einen Kommentar, aber nicht für eine Antwort. –