We had a customer question the other day about configuring FTP Client Certificate Authentication in FTP 7.0 and in FTP 7.5. It had been a while since the last time that I had configured those settings on an FTP server, so I thought that it would be great to re-familiarize myself with that feature. To my initial dismay, it was a little more difficult than I had remembered, because there are a lot of parts to be configured.
That being said, there are a few primary activities that you need to know about and configure correctly:
I will explain each of those in this blog, although I will defer some of the details for Active Directory mapping to an excellent blog series that I discovered by Vivek Kumbhar.
There are several settings that you need to configure for the FTP server; unfortunately there is no user interface for those settings, so you might want to familiarize yourself with the following settings:
At first I had made a batch file that was configuring these settings by using AppCmd, but I eventually abandoned that script and wrote the following VBScript code to configure all of the settings at one time - the only parts that you need to change is your site name and the hash value your SSL certificate, which are highlighted in yellow:
Set adminManager = CreateObject("Microsoft.ApplicationHost.WritableAdminManager")
adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST"
Set sitesSection = adminManager.GetAdminSection("system.applicationHost/sites", "MACHINE/WEBROOT/APPHOST")
Set sitesCollection = sitesSection.Collection
siteElementPos = FindElement(sitesCollection, "site", Array("name", "ftp.contoso.com"))
If (addElementPos = -1) Then
WScript.Echo "Element not found!"
Set siteElement = sitesCollection.Item(siteElementPos)
Set ftpServerElement = siteElement.ChildElements.Item("ftpServer")
Set securityElement = ftpServerElement.ChildElements.Item("security")
Set sslClientCertificatesElement = securityElement.ChildElements.Item("sslClientCertificates")
sslClientCertificatesElement.Properties.Item("clientCertificatePolicy").Value = "CertRequire"
sslClientCertificatesElement.Properties.Item("useActiveDirectoryMapping").Value = True
Set authenticationElement = securityElement.ChildElements.Item("authentication")
Set clientCertAuthenticationElement = authenticationElement.ChildElements.Item("clientCertAuthentication")
clientCertAuthenticationElement.Properties.Item("enabled").Value = True
Set sslElement = securityElement.ChildElements.Item("ssl")
sslElement.Properties.Item("serverCertHash").Value = "57686f6120447564652c2049495320526f636b73"
sslElement.Properties.Item("controlChannelPolicy").Value = "SslRequire"
sslElement.Properties.Item("dataChannelPolicy").Value = "SslRequire"
Function FindElement(collection, elementTagName, valuesToMatch)
For i = 0 To CInt(collection.Count) - 1
Set element = collection.Item(i)
If element.Name = elementTagName Then
matches = True
For iVal = 0 To UBound(valuesToMatch) Step 2
Set property = element.GetPropertyByName(valuesToMatch(iVal))
value = property.Value
If Not IsNull(value) Then
value = CStr(value)
If Not value = CStr(valuesToMatch(iVal + 1)) Then
matches = False
If matches Then
If matches Then
FindElement = i
FindElement = -1
Once you have configured your FTP settings, you should have an FTP site that resembles the following in your ApplicationHost.config file:
<site name="ftp.contoso.com" id="2">
<virtualDirectory path="/" physicalPath="c:\inetpub\ftproot" />
<binding protocol="ftp" bindingInformation="*:21:" />
<ssl serverCertHash="57686f6120447564652c2049495320526f636b73" ssl128="false" controlChannelPolicy="SslRequire" dataChannelPolicy="SslRequire" />
<basicAuthentication enabled="false" />
<anonymousAuthentication enabled="false" />
<clientCertAuthentication enabled="true" />
<sslClientCertificates clientCertificatePolicy="CertRequire" useActiveDirectoryMapping="true" />
More details about these settings can be found in the configuration reference articles that I mentioned in the beginning of this blog post, and additional information about configuring FTP over SSL can be found in the following walkthrough:
The next part of this process is kind of tricky; you need to accomplish all of the following:
That makes it all sound so easy, but it can be very tricky. That being said, as I mentioned earlier, as I was putting together my notes to write this blog, I stumbled across a great blog series by Vivek Kumbhar, where he goes into great detail when describing all of the steps to set up the Active Directory mapping. With that in mind, instead of trying to rewrite what Vivek has already documented, I will include links to his blog series:
I have to give Vivek full credit where it's due - he wrote a truly great blog series, and he included a lot more detail in his blog series than I had originally planned to include in this blog. (In my humble opinion, Vivek's blog series is the best documentation that I have seen for this feature.)
To test out client certificates, I used both the SmartFTP GUI-based FTP client and the MOVEit-Freely command-line FTP client; both of which I discussed in my FTP Clients blog series some time ago.
To configure the SmartFTP client, I just needed to enable and specify the correct client certificate in the properties for my connection:
For the MOVEit-Freely FTP client, I just needed to specify the correct parameters on the command line:
ftps.exe -z -e:on -pfxfile:administrator.pfx -pfxpw:"P@ssw0rd" -user:anonymous -password:"firstname.lastname@example.org"
The important settings are the pfxfile and pfxpw values, where pfxfile is the name of the PFX file that holds your client certificate, and pfxpw is the password for the PFX file. (The username and password values will be ignored for the most part, because you will actually be logged in through your client certificate, so you can leave those as anonymous.)
For more information about these two FTP clients, see the following blog posts:
FTP client certificates are definitely a bit of a challenge to configure correctly, but it's not an impossible task to get this feature working.