Skip to content

FTPS Connection

TheFlash edited this page Aug 22, 2020 · 24 revisions

API

  • new FtpClient() - Creates and returns a new FTP client instance.

  • Host - The FTP server IP or hostname. Required.

  • Port - The FTP port to connect to. Default: Auto (990)

  • Credentials - The FTP username & password to use. Must be a valid user account registered with the server. Default: anonymous/anonymous

  • Connect() - Connects to an FTP server (uses TLS/SSL if configured).

  • Disconnect() - Closes the connection to the server immediately.

  • IsConnected - Checks if the connection is still alive.

  • IsEncrypted - Checks if FTPS/SSL encryption is currently active. Useful to see if your server supports FTPS, when using FtpEncryptionMode.Auto.

FTPS Settings

Set these before you call Connect(). You can automatically detect FTPS connection settings that work with your server.

  • EncryptionMode - Type of Encryption to use. Default: FtpEncryptionMode.Auto.

    • Auto connects in FTP and then attempts to upgrade to FTPS (TLS) if supported by the server.
    • Explicit (TLS) connects in FTP and upgrades to FTPS, throws an exception if encryption is not supported
    • Implicit (SSL) directly connects in FTPS assuming the control connection is encrypted
    • None uses plaintext FTP.
  • DataConnectionEncryption - Indicates if data channel transfers should be encrypted. Default: true.

  • SslProtocols - Encryption protocols to use. Default: SslProtocols.Default.

  • SslBuffering - Whether to use SSL Buffering to speed up data transfer during FTP operations. Turn this off if you are having random issues with FTPS/SSL file transfer. Default: FtpsBuffering.Auto.

  • ClientCertificates - X509 client certificates to be used in SSL authentication process. Learn more.

  • ValidateCertificate - Event is fired to validate SSL certificates. If this event is not handled and there are errors validating the certificate the connection will be aborted.

  • ValidateAnyCertificate - Accept any SSL certificate received from the server and skip performing the validation using the ValidateCertificate callback. Useful for Powershell users. Default: false.

  • ValidateCertificateRevocation - Indicates if the certificate revocation list is checked during authentication. Useful when you need to maintain the certificate chain validation, but skip the certificate revocation check. Default: true.

  • PlainTextEncryption - Disable encryption immediately after connecting with FTPS, using the CCC command. This is useful when you have a FTP firewall that requires plaintext FTP, but your server mandates FTPS connections. Default: false.

Examples

C#

VB.NET

How do I connect with SSL/TLS? / How do I use FTPS?

First try Auto Detection to calculate the most secure and compatible FTP connection settings that works with your FTP server.

If you want to simply connect using FTP/FTPS and accept any server certificate:

FtpClient client = new FtpClient(hostname, username, password); // or set Host & Credentials
client.EncryptionMode = FtpEncryptionMode.Auto;
client.ValidateAnyCertificate = true;
client.Connect();

If you want to manually specific FTPS settings and manually validate the server certificate:

FtpClient client = new FtpClient(hostname, username, password); // or set Host & Credentials
client.EncryptionMode = FtpEncryptionMode.Explicit;
client.SslProtocols = SslProtocols.Tls12;
client.ValidateCertificate += new FtpSslValidation(OnValidateCertificate);
client.Connect();

void OnValidateCertificate(FtpClient control, FtpSslValidationEventArgs e) {
    // add logic to test if certificate is valid here
    e.Accept = true;
}

If you have issues connecting to the server, try using either of these:

Let the OS pick the highest and most relevant TLS protocol.

client.SslProtocols = Security.Authentication.SslProtocols.None;

Prevent the OS from using TLS 1.0 which has issues in .NET Framework.

client.SslProtocols = SslProtocols.Default | SslProtocols.Tls11 | SslProtocols.Tls12;

If you are on Linux and failing to connect via SSL/TLS, you may be having this issue.

How do I validate the server's certificate when using FTPS?

Method 1: Connect if the SSL certificate has no errors.

client.ValidateCertificate += new FtpSslValidation(delegate (FtpClient c, FtpSslValidationEventArgs e) {
	if (e.PolicyErrors != System.Net.Security.SslPolicyErrors.None){
		e.Accept = false;
	}else{
		e.Accept = true;
	}
});

Method 2: Connect if the certificate matches a whitelisted certificate.

First you must discover the string of the valid certificate. Use this code to save the valid certificate string to a file:

client.ValidateCertificate += new FtpSslValidation(delegate (FtpClient c, FtpSslValidationEventArgs e) {
    File.WriteAllText(@"C:\cert.txt", e.Certificate.GetRawCertDataString());
});

Then finally use this code to check if the received certificate matches the one you trust:

string ValidCert = "<insert contents of cert.txt>";
client.ValidateCertificate += new FtpSslValidation(delegate (FtpClient c, FtpSslValidationEventArgs e) {
    if (e.PolicyErrors == SslPolicyErrors.None || e.Certificate.GetRawCertDataString() == ValidCert) {
        e.Accept = true;
    }else{
        throw new Exception("Invalid certificate : " + e.PolicyErrors);
    }
});

How do I connect to Azure using SSL/TLS?

Assuming you are using FTP publishing service on an Azure App Service instance.

If you have issues connecting to Azure, ensure you are not using "FTPS Only". As per the Azure documentation, "FTPS Only" does not support TLS 1.0 and 1.1 and this might break connectivity when trying to use FluentFTP with older versions of Windows. So when you try to connect to an Azure FTP instance that is blocking TLS 1.1 the connection silently fails because it only accepts TLS 1.2.

After changing the settings to allow insecure FTP, you can connect with FTPS using both Explicit and Implicit SSL modes.

How do I connect with FTPS and then switch back down to plaintext FTP?

This is useful when you have a FTP firewall that requires plaintext FTP, but your server mandates FTPS connections. We use the CCC command to instruct the server to revert back to FTP.

Set this option before calling Connect() or any other method on the FtpClient class.

client.PlainTextEncryption = true;

How do I connect with SFTP?

SFTP is not supported as it is FTP over SSH, a completely different protocol. Use SSH.NET for that.

How do I use client certificates to login with FTPS?

Add your certificate into ClientCertificates and then Connect().

client.EncryptionMode = FtpEncryptionMode.Explicit;
client.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12;
client.SocketKeepAlive = false;
client.ClientCertificates.Add(new X509Certificate2("C:\mycert.cer"));
client.ValidateCertificate += (control, e) => {
	e.Accept = e.PolicyErrors == SslPolicyErrors.None;
};
client.Connect();

And ensure that:

  1. You use X509Certificate2 objects, not the incomplete X509Certificate implementation.

  2. You do not use pem certificates, use p12 instead. See this Stack Overflow thread for more information. If you get SPPI exceptions with an inner exception about an unexpected or badly formatted message, you are probably using the wrong type of certificate.

How do I bundle an X509 certificate from a file?

You need the certificate added into your local store, and then do something like this:

FluentFTP.FtpClient client = new FluentFTP.FtpClient("WWW.MYSITE.COM", "USER","PASS");

// Select certificate and add to client
X509Store store = new X509Store("MY", StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
X509Certificate2Collection scollection = X509Certificate2UI.SelectFromCollection(fcollection, "Select a certificate", "Select a certificate", X509SelectionFlag.MultiSelection); 

if (scollection.Count != 1)
{
    throw new Exception("Error: You have not chosen exactly one certificate");
 }
foreach (X509Certificate2 x509 in scollection)
{
    client.ClientCertificates.Add(x509);
}
store.Close();

//client.ReadTimeout = 10000;
client.Connect();

This is another way. And use X509Certificate2. I've been unable to get X509Certificate to work and from my reading it's because it's an incomplete implementation.

public void InitSFTP(){

    FluentFTP.FtpClient client = new FluentFTP.FtpClient("WWW.MYSITE.COM", "USER", "PASS");
    X509Certificate2 cert_grt = new X509Certificate2("C:\mycert.xyz"); 
    client.EncryptionMode = FtpEncryptionMode.Explicit; 
    client.DataConnectionType = FtpDataConnectionType.PASV; 
    client.DataConnectionEncryption = true; 
    client.ClientCertificates.Add(cert_grt); 
    client.ValidateCertificate += new FtpSslValidation(OnValidateCertificate); 
    client.Connect();
}       

private void OnValidateCertificate(FtpClient control, FtpSslValidationEventArgs e)
{
    e.Accept = true;
}
Clone this wiki locally