Introduction
FTP (File Transfer Protocol) is a standard network protocol used for transferring files between a client and server on a computer network. Despite being one of the oldest protocols, it remains in use for specific scenarios.
This comprehensive guide covers FTP protocol mechanics, commands, modes, and security considerations.
What is FTP?
FTP uses a client-server architecture with separate control and data connections. It operates in active or passive mode.
Key Features
Two Connections: Control (21) and Data (dynamic).
Authentication: Username/password.
Commands: Standardized FTP commands.
Modes: ASCII and Binary.
FTP Commands
Common Commands
| Command | Description |
|---|---|
| USER | Username |
| PASS | Password |
| LIST | List files |
| RETR | Download file |
| STOR | Upload file |
| DELE | Delete file |
| MKD | Make directory |
| RMD | Remove directory |
| CWD | Change working directory |
| PWD | Print working directory |
| QUIT | Disconnect |
Example Session
220 FTP Server ready
USER anonymous
331 Anonymous login ok, give email as password
PASS [email protected]
230 User logged in
LIST
150 Opening ASCII mode data connection
-rw-r--r-- 1 user group 1024 Jan 01 12:00 file.txt
226 Transfer complete
RETR file.txt
150 Opening BINARY mode data connection
226 Transfer complete
QUIT
221 Goodbye
Transfer Modes
Active Mode
Client Server
| |
|-------- PORT -------------------->| (Client opens random port)
| |
|<------- 200 PORT command ok -----| (Server connects to client)
| |
|-------- RETR file ---------------->| (Data connection)
|<------- [file data] ---------------|
Passive Mode
Client Server
| |
|-------- PASV --------------------->|
| |
|<------- 227 Entering Passive ----| (Server opens random port)
| (220.10.10.10,128,32) |
| |
|-------- [connect to port]-------->| (Client connects)
| |
|-------- RETR file ---------------->| (Data connection)
|<------- [file data] ---------------|
Implementation
Python FTP Client
from ftplib import FTP
def ftp_upload(filename, host, username, password):
with FTP(host) as ftp:
ftp.login(user=username, passwd=password)
# Binary mode for files
ftp.voidcmd('TYPE I')
with open(filename, 'rb') as f:
ftp.storbinary(f'STOR {filename}', f)
print(f'Uploaded {filename}')
def ftp_download(filename, host, username, password):
with FTP(host) as ftp:
ftp.login(user=username, passwd=password)
ftp.voidcmd('TYPE I')
with open(filename, 'wb') as f:
ftp.retrbinary(f'RETR {filename}', f.write)
print(f'Downloaded {filename}')
def ftp_list_files(host, username, password):
with FTP(host) as ftp:
ftp.login(user=username, passwd=password)
files = []
ftp.retrlines('LIST', files.append)
for f in files:
print(f)
FTP Commands
from ftplib import FTP
with FTP('ftp.example.com') as ftp:
ftp.login()
# Change directory
ftp.cwd('/pub')
# Make directory
ftp.mkd('newdir')
# Delete file
ftp.delete('oldfile.txt')
# Rename
ftp.rename('old.txt', 'new.txt')
# Get file size
size = ftp.size('largefile.zip')
print(f'Size: {size} bytes')
FTPS (FTP over TLS)
from ftplib import FTP_TLS
class SecureFTP:
def __init__(self, host, username, password):
self.ftp = FTP_TLS(host)
self.ftp.login(username, password)
self.ftp.prot_p() # Enable data encryption
def upload(self, filename):
with open(filename, 'rb') as f:
self.ftp.storbinary(f'STOR {filename}', f)
def download(self, filename):
with open(filename, 'wb') as f:
self.ftp.retrbinary(f'RETR {filename}', f.write)
SFTP (SSH File Transfer)
import paramiko
class SFTPClient:
def __init__(self, host, port, username, password=None, key_file=None):
transport = paramiko.Transport((host, port))
if key_file:
key = paramiko.RSAKey.from_private_key_file(key_file)
transport.connect(username=username, pkey=key)
else:
transport.connect(username=username, password=password)
self.sftp = paramiko.SFTPClient.from_transport(transport)
def upload(self, local_path, remote_path):
self.sftp.put(local_path, remote_path)
def download(self, remote_path, local_path):
self.sftp.get(remote_path, local_path)
def list_files(self, path):
return self.sftp.listdir(path)
def close(self):
self.sftp.close()
# Usage
client = SFTPClient('server.example.com', 22, 'user', password='secret')
client.upload('/local/file.txt', '/remote/file.txt')
client.close()
Best Practices
- Use SFTP or FTPS instead of plain FTP
- Restrict FTP access with firewall
- Use strong authentication
- Monitor transfer logs
- Consider SCP for simple transfers
Conclusion
While FTP has largely been replaced by SFTP and cloud storage, understanding FTP is valuable for legacy systems and specific use cases.
Comments