Problems with reverse DNS lookup and SSL


#1

Hi there,

I applied twitter cards meta-tags to my blog and tried to validate a page with the validator.

All I’ve got is an error message that doesn’t really help.

ERROR: Fetching the page failed because other errors.

I managed to configure access for the twitterbot via http and the validator works as expected.

So I tried to figure out what the problem could be.

The IP address of the domain is 95.143.172.241
So lets have a look what the reverse lookup returns for the given IP.

dig -x 95.143.172.241 +short
menkar.uberspace.de.

Yeah. That’s the hostname of the server where I rent a shared space at uberspace.de.
So I guess it fails evaluating the ssl certificate as menkar.uberspace.de does not match.
But maybe I am wrong.

Is there anything I can do to circumvent the Problem?


#2

Yes, that looks like what is going on here - when I use openssl s_client -connect www.calmdevelopment.de:443 -tls1 the certificate returned does indeed belong to menkar.uberspace.de.

I’m not sure what your options are exactly as I don’t know your host, but there are some threads on the forums that refer to possible configuration solutions to allow our crawler to connect (such as this one and this one).


#3

Thank you for the quick response. I wrote a mail to the people from uberspace.


#4

Is it possible that the twitter library the validator uses does not use the TLS SNI extension?

Doing so I receive the expected certificate for the domain.

openssl s_client -connect www.calmdevelopment.de:443 -servername www.calmdevelopment.de


#5

It’s not a Twitter library issue AFAIK, it is a Java + SSL strict checking question. I don’t know what the issue might be there.


#6

The problem is now a bit clearer. menkar.uberspace.de is the server hosting multiple virtual hosts, like mine.
If you try to establish a TLS/SSL connection with one of the virtual domains you need to use the SNI Extension of TLS to send the virtual domains hostname to make the server know which certificate you are interested in.
Otherwise you get the certificate from the server not the virtual domain.

I wrote a little Test to verify my assumptions. It’s is written in Groovy and Spock but should be understandable.

import spock.lang.Specification

import javax.net.ssl.SNIHostName
import javax.net.ssl.SSLParameters
import javax.net.ssl.SSLSocket
import javax.net.ssl.SSLSocketFactory
import java.security.Security

class SSLConnectionTest extends Specification {
    private SSLSocket socket

    def setup() {
        //Disable caching for name lookups
        Security.setProperty("networkaddress.cache.ttl", "0")
    }

    void cleanup() {
        if ( !socket?.isClosed() ){
            //invalidate session. other tests should not reuse previous sessions
            socket.session.invalidate()
            socket.close()
        }
    }

    def "should receive wrong certificate"() {

        given:
        String virtualHost = "www.calmdevelopment.de"
        String serverName = "menkar.uberspace.de"

        Integer port = 443
        InetAddress address = InetAddress.getByName(virtualHost)

        when:
        SSLSocketFactory socketFactory = SSLSocketFactory.getDefault()
        socket = socketFactory.createSocket(address, port)

        then:
        socket.session.isValid()
        socket.session.peerPrincipal.name.contains(serverName)

        socket.session.peerCertificateChain.each {
            println it
        }
    }

    def "should receive the correct certificate using SNI Extension server_name set to virtual host name"() {

        given:
        String virtualHost = "www.calmdevelopment.de"
        String serverName = "menkar.uberspace.de"

        Integer port = 443
        InetAddress address = InetAddress.getByName(virtualHost)

        when:

        SSLSocketFactory socketFactory = SSLSocketFactory.getDefault()

        socket = socketFactory.createSocket(address, port)

        SSLParameters parameters = this.socket.getSSLParameters()
        SNIHostName sniHostName = new SNIHostName(virtualHost)
        parameters.setServerNames( Arrays.asList(sniHostName) )

        socket.setUseClientMode(true)
        this.socket.setSSLParameters( parameters )

        then:
        this.socket.session.isValid()
        this.socket.session.peerPrincipal.name.contains(virtualHost)

        this.socket.session.peerCertificateChain.each {
            println it
        }
    }

}

#7

Using a HttpsURLConnection (Which is in Java since 1.4) works as expected. So I wonder what the problem really is.
It doesn’t seem like a problem on my providers side.

HttpsURLConnection connection = (HttpsURLConnection)"https://www.calmdevelopment.de/blog/2016/08/jbake-continuous-with-gradle.html".toURL().openConnection()

println connection.responseCode
println connection.responseMessage
println connection.cipherSuite
println connection.getServerCertificates()


200
OK
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
[[
[
  Version: V3
  Subject: CN=www.calmdevelopment.de
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  Sun RSA public key, 4096 bits
  modulus: 797527413265463577832935844562482118099150345139076880530768661547256628941458942725259158742436331761882425279277127540093222889898324100444102245591769438478724055016572966279747545423041984878596685685650228114200666325437734964139723672860288535170325929160976878728825810863803472475325203543178020887960857099855606399460141427859674819038259048955326948611776222337399205828427568535211689606403595622560509874774791931651048049279757352559123828531569490596148916688920305732662143142585732520716848370333563229839243837793582049071898186568015184768724678951569881045384974511172615855151367626293737088558379550725595379683907507840724673538518337433149309598593611534383871328558249581460370884051266323443449814330676607414299018572117882820764341046525992437245616270251591658755245373900589418718595339679482867440070552419967154389483972272141674411058260012749393509029965164234112315757498399744729530785151293877410393064249803147663160920734720716320519998873660804188511594081468129511323767302907206277996134534408619532059089206673282894173677553813073613876207302573525467937475502480952226437598004942126806273253000102253054327533479447963714735322102263900618846754875363131622932583606366535356717572390853
  public exponent: 65537
  Validity: [From: Wed Jun 29 09:25:00 CEST 2016,
               To: Tue Sep 27 09:25:00 CEST 2016]
  Issuer: CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
  SerialNumber: [    038dcf29 f695038d d3f32be0 14f65838 6f55]

Certificate Extensions: 8
[1]: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
AuthorityInfoAccess [
  [
   accessMethod: ocsp
   accessLocation: URIName: http://ocsp.int-x3.letsencrypt.org/
, 
   accessMethod: caIssuers
   accessLocation: URIName: http://cert.int-x3.letsencrypt.org/
]
]

#8

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.