While FTP has been around since the early days of the internet, its lack of encryption makes it unsuitable for modern file transfer needs. The protocol sends credentials and data in plain text, exposing sensitive information to potential interception. As developers, we need better solutions that maintain ease of use while providing proper security.
Here are the most robust alternatives that meet developer requirements:
- SFTP (SSH File Transfer Protocol)
- FTPS (FTP Secure)
- WebDAV over HTTPS
- rsync over SSH
- Secure file sharing platforms
SFTP runs over SSH, providing strong encryption and easy integration with existing SSH infrastructure. Unlike regular FTP:
# Connect to SFTP server
sftp user@example.com
# Secure file upload
put local_file.txt /remote/directory/
# Secure file download
get /remote/file.txt ~/local_directory/
To provide secure file sharing without full shell access, configure a chrooted SFTP environment:
# /etc/ssh/sshd_config
Match Group sftpusers
ChrootDirectory /var/sftp/%u
ForceCommand internal-sftp
X11Forwarding no
AllowTcpForwarding no
FTPS adds TLS/SSL encryption to standard FTP. For vsftpd configuration:
# /etc/vsftpd.conf
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
For web-friendly file sharing with fine-grained permissions:
# Apache configuration for WebDAV
Alias /webdav /path/to/shared/folder
<Location /webdav>
DAV On
AuthType Basic
AuthName "WebDAV"
AuthUserFile /etc/apache2/webdav.password
Require valid-user
</Location>
For temporary sharing with non-technical users, consider:
- Sharefile (enterprise-grade)
- Nextcloud (self-hosted)
- Magic Wormhole (CLI-based)
When choosing a solution, consider:
- Client compatibility requirements
- Authentication methods (SSH keys vs passwords)
- Audit logging needs
- Transfer speed requirements
While FTP has been around since the 1970s, its security vulnerabilities make it unsuitable for modern file transfers. The protocol sends credentials and data in plaintext, making it susceptible to man-in-the-middle attacks. As developers, we need better alternatives that provide:
- Encrypted connections
- Directory restriction capabilities
- No full server access requirement
- Simple user management
SFTP (SSH File Transfer Protocol)
Built on SSH, SFTP provides strong encryption and works on port 22 by default. To set up restricted access:
# Create SFTP-only group
sudo groupadd sftpusers
# Create user with restricted access
sudo useradd -g sftpusers -d /upload -s /bin/false sftpuser
sudo passwd sftpuser
# Configure sshd_config
Match Group sftpusers
ChrootDirectory /upload
ForceCommand internal-sftp
X11Forwarding no
AllowTcpForwarding no
FTPS (FTP Secure)
FTPS adds TLS/SSL encryption to traditional FTP. For vsftpd configuration:
# Enable SSL
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
# Restrict to specific directory
chroot_local_user=YES
user_sub_token=$USER
local_root=/var/ftp/$USER
WebDAV over HTTPS
For Apache HTTP Server:
<Directory "/var/webdav">
DAV On
SSLRequireSSL
AuthType Basic
AuthName "WebDAV Restricted"
AuthUserFile /etc/apache2/webdav.password
Require valid-user
</Directory>
When choosing between these options, consider:
Protocol | Port | Encryption | Client Support |
---|---|---|---|
SFTP | 22 | SSH | Excellent |
FTPS | 990/21 | TLS/SSL | Good |
WebDAV | 443 | HTTPS | Moderate |
For custom implementations:
package main
import (
"github.com/pkg/sftp"
"golang.org/x/crypto/ssh"
"net"
)
func main() {
config := &ssh.ServerConfig{
PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
if c.User() == "sftpuser" && string(pass) == "password" {
return nil, nil
}
return nil, fmt.Errorf("denied")
},
}
privateBytes, _ := ioutil.ReadFile("id_rsa")
private, _ := ssh.ParsePrivateKey(privateBytes)
config.AddHostKey(private)
listener, _ := net.Listen("tcp", "0.0.0.0:2022")
for {
nConn, _ := listener.Accept()
_, chans, reqs, _ := ssh.NewServerConn(nConn, config)
go ssh.DiscardRequests(reqs)
go handleChannels(chans)
}
}