Skip to content

FTP Connection

FanDjango edited this page Nov 13, 2022 · 50 revisions

API

Connection 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 (21 or 990 depending on FTPS config)

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

  • AutoConnect() - See Automatic Connection.

  • Connect() - Connects to an FTP server using manual settings configured.

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

  • Execute() - Execute a custom or unsupported command.

Read-only properties

  • IsConnected - Checks if the connection to the FTP server is still open.

  • IsAuthenticated - Checks if the connection to the FTP server is still open and we have successfully logged in.

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

  • IsClone - Checks if this control connection is a clone. Default: false.

  • LastReply - Returns the last FtpReply object received from the server.

  • LastReplies - Returns the last 5 FtpReply objects received from the server.

  • InternetProtocol - Returns the current internet protocol (IPV4 or IPV6) used to connect. Returns FtpIpVersion.Unknown before connection.

Settings

Important FTP Server settings

You can automatically detect FTP connection settings that work with your server.

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

    • Auto connects in plaintext 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.
  • Config.SslProtocols - Encryption protocols to use. Default: Varying settings by platform.

  • Config.DataConnectionType - Active or Passive connection. Default: FtpDataConnectionType.AutoPassive (tries EPSV then PASV then gives up)

  • Config.InternetProtocolVersions - Whether to use IPV4 and/or IPV6 when making a connection. All addresses returned during name resolution are tried until a successful connection is made. Default: Any.

  • Encoding - Text encoding (ASCII or UTF8) used when talking with the server. ASCII is default, but upon connection, we switch to UTF8 if supported by the server. Manually setting this value overrides automatic detection. Default: Auto.

FTPS Certificate Validation settings

  • Config.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. Can cause memory leaks. Default: false.

Advanced FTPS settings

  • Config.DataConnectionEncryption - Indicates if data channel transfers should be encrypted. Default: true.

  • Config.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.

  • Config.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.

Shared Hosting settings

  • Config.SendHost - Send the HOST command immediately after the handshake. Useful when you are using shared hosting and you need to inform the FTP server which domain you want to connect to. Default: false.

  • Config.SendHostDomain - Controls which domain is sent with the HOST command. If this is null, then the Host parameter of the FTP client is sent. Default: null.

Active FTP settings

  • Config.ActivePorts - List of ports to try using for Active FTP data connections, or null to automatically select a port. Default: null.

  • AddressResolver - Delegate used for resolving local address, used for active data connections. This can be used in case you're behind a router, but port forwarding is configured to forward the ports from your router to your internal IP. In that case, we need to send the router's IP instead of our internal IP.

Passive FTP settings

  • Config.PassiveBlockedPorts - List of ports blocked for Passive FTP data connections (PASV and EPSV), or null if all ports are allowed. Useful when your FTP server has certain ports that are blocked or used for other purposes. Default: null.

  • Config.PassiveMaxAttempts - Maximum number of passive connections made in order to find a working port for Passive Data Connection (PASV and EPSV). Only used if PassiveBlockedPorts is non-null. Default: 100.

Socket settings

  • Config.SocketLocalIp - The local socket will be bound to the given local IP/interface. This is useful if you have several usable public IP addresses and want to use a particular one to connect to the remote FTP server. Meaning that the FTP server would see you coming from the interface you choose, instead of the interface holding the default route that is selected by the OS. Default: null.

  • Config.SocketKeepAlive - Set SocketOption.KeepAlive on all future stream sockets. Default: false.

  • SocketLocalEndPoint - Read-only. Returns the local client EndPoint used to make the FTP connection. Default: null.

  • SocketRemoteEndPoint - Read-only. Returns the remote server EndPoint used to receive the FTP connection. Default: null.

Advanced settings

  • Config.StaleDataCheck - Check if there is stale (unrequested data) sitting on the socket or not. In some cases the control connection may time out but before the server closes the connection it might send a 4xx response that was unexpected and can cause synchronization errors with transactions. To avoid this problem the Execute() method checks to see if there is any data available on the socket before executing a command. Default: true.

  • Config.DisconnectWithQuit - Send a QUIT FTP command before we disconnect from the server. Default: true.

Connection Timeout settings

Examples

C#

VB.NET

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

First try Auto Connection 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 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;
}

How do I login with an anonymous FTP account? / I'm getting login errors but I can login fine in Firefox/Filezilla

Do NOT set the Credentials property, so we can login anonymously. Or you can manually specify the following:

client.Credentials = new NetworkCredential("anonymous", "anonymous");

How do I change the connection timeout on Windows?

If your client machine is Windows, then you can use ConnectTimeout to set a timeout value that is shorter than the default of your Windows OS.

If you want to use higher values that than, you need to change the operating system settings. The default OS timeout for TCP connections is 21 seconds on Windows.

To increase this timeout you need to run the following PowerShell command in Admin mode:

Set-NetTCPSetting -SettingName InternetCustom -MaxSynRetransmissions 4

The last parameter controls the timeout value:

  • 2 = ~21 seconds
  • 3 = ~40 seconds
  • 4 = ~90 seconds

The maximum value is 8.

Learn more at this page, and look for TcpInitialRTT, TcpMaxConnectRetransmissions and TcpMaxConnectResponseRetransmissions which are relevant to this issue.

Clone this wiki locally