Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

I analyzed this issue a bit more.

There are 10 DNS names that I know of for PerlMonks: /^( (www\.|css\.)? perlmonks \. (org|com|net) | )$/x

Except for, all of those resolve to the three IP addresses,, and resolves to only the first of those,

There are two SSL certificates:

  1. one for pair Networks, which matches only * - this one is always served by, no matter which of the aforementioned 10 DNS names is used!
  2. one Let's Encrypt certificate, which matches any of the nine DNS names /^ (www\.|css\.)? perlmonks \. (org|com|net) $/x - this one is served by and

The issue is that any time one of the (org|com|net) addresses resolves to (Round-robin DNS), the user will get a certificate warning.

I checked, and the Apache Wiki says this about Name-Based Virtual Hosts and SSL (emphasis mine):

As a rule, it is impossible to host more than one SSL virtual host on the same IP address and port. This is because Apache needs to know the name of the host in order to choose the correct certificate to setup the encryption layer. But the name of the host being requested is contained only in the HTTP request headers, which are part of the encrypted content. It is therefore not available until after the encryption is already negotiated. This means that the correct certificate cannot be selected, and clients will receive certificate mismatch warnings and be vulnerable to man-in-the-middle attacks.

In reality, Apache will allow you to configure name-based SSL virtual hosts, but it will always use the configuration from the first-listed virtual host (on the selected IP address and port) to setup the encryption layer. In reality, Apache will allow you to configure name-based SSL virtual hosts, but it will always use the configuration from the first-listed virtual host (on the selected IP address and port) to setup the encryption layer. In certain specific circumstances, it is acceptable to use a single SSL configuration for several virtual hosts. In particular, this will work if the SSL certificate applies to all the virtual hosts. ...

As a quick fix, could be taken out of the DNS rotation, as already suggested by others, but this has the disadvantage that one of the servers will get much less of the load. Another possible solution would be to make sure that serves up the Let's Encrypt certificate as well, and then set up a redirect from to (both http and https), since I'm not sure how much that address is used anyway.

In any case, I think this is an important issue!

Update: Corion has since published this code on GitHub, please consider that the most current version:

#!/usr/bin/env perl use warnings; use strict; use Data::Dump; use Net::DNS; use LWP::UserAgent; require LWP::Protocol::https; # make sure this is installed use Class::Method::Modifiers qw/around/; my @ADDRS = qw/ /; my $DNS = { # As of 2018-06-17: "" => ["", "", "66 +.39.54.27"], "" => ["", "", "66 +.39.54.27"], "" => ["", "", "66 +.39.54.27"], "" => ["", "", "66 +.39.54.27"], "" => ["", "", "66 +.39.54.27"], "" => ["", "", "66 +.39.54.27"], "" => [""], "" => ["", "", "66 +.39.54.27"], "" => ["", "", "66 +.39.54.27"], "" => ["", "", "66 +.39.54.27"], }; if (0) { $DNS={}; my $resolver = new Net::DNS::Resolver(recurse => 1, debug => 0); for my $addr (@ADDRS) { # figure out the authoritative server $resolver->nameservers(''); my $packet = $resolver->send($addr, 'SOA'); my @server = map {$_->mname} grep {$_->type eq 'SOA'} $packet->answer; die "@server" unless @server==1; $packet = $resolver->send($server[0], 'A'); my @nameservers = map {$_->address} grep {$_->type eq 'A'} $packet->answer; die "@server" unless @nameservers; # query the authoritative server $resolver->nameservers(@nameservers); $packet = $resolver->send($addr, 'A'); my @ips = sort map {$_->address} grep {$_->type eq 'A'} $packet->answer; printf "%23s %-35s %s\n", $addr, "(\@$server[0]/@nameservers)", join ' ', @ips; $DNS->{$addr} = \@ips; } dd $DNS; } our $force_peeraddr; around 'LWP::Protocol::http::_extra_sock_opts' => sub { my $orig = shift; die unless wantarray; my @rv = $orig->(@_); push @rv, PeerAddr => $force_peeraddr if defined $force_peeraddr; return @rv; }; around 'LWP::Protocol::https::_get_sock_info' => sub { my $orig = shift; my ($self, $res, $sock) = @_; my $cert = $sock->get_peer_certificate; my @san = $cert->peer_certificate('subjectAltNames'); while (@san) { my ($type_id, $value) = splice @san, 0, 2; $res->push_header("Client-SSL-Cert-SubjectAltName" => "$type_id: $value"); } $orig->(@_); }; my %certs; my $ua = LWP::UserAgent->new( ssl_opts => { verify_hostname => 0 } ); for my $addr (sort keys %$DNS) { for my $host (sort @{ $DNS->{$addr} }) { warn "Requesting $addr from $host...\n"; local $force_peeraddr = $host; my $res = $ua->get("https://$addr"); die $res->status_line unless $res->is_success; my @peer = $res->header("client-peer"); die "@peer" unless @peer==1 && $peer[0] eq "$host:443"; my @issuer = $res->header("client-ssl-cert-issuer"); my @subject = $res->header("client-ssl-cert-subject"); my @san = $res->header("client-ssl-cert-subjectaltname"); my $certstr = "Issuer: @issuer\nSubject: @subject\n" ."Subject Alt Names: @san\n"; push @{ $certs{$certstr} }, "$host $addr"; } } for my $cert (sort keys %certs) { print "##### Certificate #####\n", $cert, "### Served by:\n"; printf "%15s %s\n", @$_ for map {[split]} @{ $certs{$cert} }; } __END__ # As of 2018-06-17: ##### Certificate ##### Issuer: /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 Subject: / Subject Alt Names: 2: 2: 2: 2: 2: 2: 2: www 2: 2: ### Served by: ##### Certificate ##### Issuer: /C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=U +SERTrust RSA Organization Validation Secure Server CA Subject: /C=US/postalCode=15203/ST=Pennsylvania/L=Pittsburgh/street=Su +ite 510/street=2403 Sidney Street/O=pair Networks, Inc./OU=Provided b +y pair Networks/OU=PairWildcardSSL $250,000/CN=* Subject Alt Names: 2: * 2: ### Served by:

In reply to Re: "This site is not secure" warning message by haukex
in thread "This site is not secure" warning message by roho

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2022-12-08 19:59 GMT
Find Nodes?
    Voting Booth?

    No recent polls found