Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

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":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

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

    How do I use this? | Other CB clients
    Other Users?
    Others pondering the Monastery: (3)
    As of 2020-10-29 23:14 GMT
    Find Nodes?
      Voting Booth?
      My favourite web site is:

      Results (274 votes). Check out past polls.