Summary for lazy readers
Let's consider this scenario:
- We are using FTPs (FTP over SSL) to connect to a FTP site hosted on a Windows Server 2008 or later
- We have multiple FTP sites using SSL and we are using the virtual hostname feature
- FTP clients suddenly report connection error: "431 Failed to setup secure session"
- The FTP site certificate has been renewed or it is still valid
Let's also add a few conditions more:
- We have another FTP site using a wildcard FTPs binding (no virtual hostname used)
- The certificate used by the wildcard FTP site is expired or invalid
As you may have guessed already, the key is to make sure a valid certificate is used by the FTP site using the wildcard binding.
When I faced this issue myself, my very first question was:
What's the link between the two FTP sites? Aren't they supposed to be completely unrelated?
The quick answer is: yes and no 🙂
From a resource isolation perspective, they are completely unrelated. Each site has its own directories, ACLs, authentication enforcement and so on.
However, the link between the two does exist when it comes to the binding definition.
To go through the detailed answer, we first need to understand how virtual hostnames work.
Virtual hostnames do not exist in the FTP protocol. Although RFC 7151 defines the HOST command, which extends the FTP commands subset, not all clients and servers implement it. As far as Windows Server and FTP 7 or later are concerned, the virtual hostname feature entirely relies on the proprietary implementation defined in the article referenced earlier:
the virtual host name is used as part of the user name during the login process
Virtual hostnames are a clever way to cope with the two contrasting goals:
- Have multiple FTP sites
- Have all the sites bound to the same IP & Port
Quite as much as HTTP SNI does, virtual hostnames allow clients to inform the server about the specific site they are intending to reach. This allows the server to disambiguate among multiple sites listening on the same port.
While SNI is an extension over the TLS handshake protocol, meaning the server can be informed about the client will to reach a specific hostname before the HTTP request is actually processed, in FTPs (being it implicit or explicit) there is no way to use such feature. Using virtual hostnames is a good workaround, but it causes the client "intentions" to be unveiled to the server only during the FTP handshake, which means once the TLS channel has been already brought up and the incoming request mapped to the destination site.
Did you guess what's the caveat here? 🙂
Let me show you with a practical example.
- My FTP server be1i.albigi.lab has two sites: FTPA and FTPB
- Both are using a FTPs implicit, with binding on IP 172.23.8.163 and port 990
- FTPA is not using virtual hostnames and the SSL certificate bound to it is self-signed and has localhost as subject name (invalid according to the client)
- FTPB is using virtual hostname ftpb.albigi.lab and its certificate is a valid one issued by the domain authority with be1i.albigi.lab as subject name
Here's how they look like in IIS Manager:
And here's the netstat -ano output after both sites are up and running:
Notice there is one only binding on port 990 (actually two, if we consider the IPv6 binding) and the process listening on it is the FTP Service:
Below are the client connection settings:
Here's where the magic happens: the connections are exactly identical but the FTPB one uses a username prefix (yes, for anonymous users too!)
Now, here's what happens from a client perspective:
This is totally what we would expect, right?
Depending on the client used and its configuration, receiving an invalid certificate can either show a security prompt (like the one in the screenshot) or simply do not trust the server and close the connection. This is when the error 431 Failed to setup secure session gets logged.
Believe it or not (I don't like to believe, so I would encourage you to test this out for yourself) we get the same prompt!
For both sites, discarding the warning and telling the client to ignore the certificate validation issues results into a successful connection.
What's going on?
The FTP client logs show this:
And the client logs:
A part from the FTP USER command, there are no differences at all!
By now, I believe you should have guessed what's actually happening. But we are curious and we like to play geeky games, right?
Let's change the FTPB site SSL settings so that it is not bound to any certificate:
Logically speaking, a FTP site with such settings should never work.
From our client, let's connect to the FTPB site…wait, what? It's still complaining about the certificate but it's working!
Surprised, are you? I don't believe so! 🙂
Ok, enough playing!
Let's wrap it up!
- There is one and only one actual SSL binding up!
- The SSL certificate set in the most general binding is used.
- A site not using virtual hostnames is considered to have a more general binding, thus FTPA configuration is honored.
Do I have to setup a FTPB site then?
- Of course! FTPB configuration comes into play only when the FTP client has shared his will to connect to FTPB by sending the virtual hostname in the USER prefix. Once the FTP handshake is complete, the life cycle of the communication is completely separated between the two sites.
Do I need to bind the SSL Certificate to all of the FTP sites?
- Ah! Good question! No, you do not. The SSL channel is always established between the client and the FTP site with the most general matching binding configuration.
If you have many FTPs sites with different virtual hostname bindings, a good strategy is to have a "general" site (wildcard binding) used for central administration of the SSL certificate. The site can be as simple as possible and don't authorize any user (it doesn't really matter as during the FTP logon the proper site based on the virtual hostname is selected). All the other actual sites do not need any specific SSL configuration.
So, if we want to solve the error "431 Failed to setup secure session", let's first make sure the site handling the FTPs connection in the first place uses a valid certificate!
Catch you guys on the flip side!
albigi / Alessandro