A simple guide to FTP with telnet

Telnet is one of those solid tools that don’t change every day. In fact, telnet predates FTP by 2 years as it was released only 2 months after Neil Amstrong walked on the moon.

To work with FTP from telnet, we will need to open 2 telnet connections across 2 terminals, a first one we will call the control channel where we will send FTP commands and another one we will refer to as the data channel. That’s one of the things CLI tools like ftp or curl abstract away from us but using telnet we are much closer to the protocol itself.

Establish the control channel

Our goal here is to establish the control channel and login as an anonymous user onto a server using telnet. Spun up a terminal and type those commands:

~/$ telnet ftp.vim.org 21
Trying 145.220.21.40...
Connected to ftp.nluug.nl.
Escape character is '^]'.
220-Welcome to the FTP archive of
220-The Netherlands Unix Users Group (NLUUG).
220-
220-This server is located in The Netherlands, Europe.
220-If you are abroad, please find an ftp site near you.
220-Most information on this site is mirrored.
220-
220-Information about your login and any transfers you do are logged.
220-If you don't like this, disconnect now.
220-
220-For statistics, see http://ftp.nluug.nl/.statistics/
220-Problems? Mail ftp-admin @ nluug.nl
220-
220-You may login as "ftp" or "anonymous".
220-
220
USER anonymous
331 Please specify the password.
PASS anonymous
230 Login successful.

Send commands through the control channel

There’s a bunch of FTP commands we can use from the control channel, eg:

HELP
214-The following commands are recognized.
ABOR ACCT ALLO APPE CDUP CWD DELE EPRT EPSV FEAT HELP LIST MDTM MKD
MODE NLST NOOP OPTS PASS PASV PORT PWD QUIT REIN REST RETR RMD RNFR
RNTO SITE SIZE SMNT STAT STOR STOU STRU SYST TYPE USER XCUP XCWD XMKD
XPWD XRMD
214 Help OK.
SYST
215 UNIX Type: L8
RETR welcome.msg
425 Use PORT or PASV first.

The FTP command to list files under a directory are LIST and NLST. If you try to use those right now you will get something like this:

LIST /
425 Use PORT or PASV first.
NLST /
425 Use PORT or PASV first.

Indeed those commands give back answer over a data channel and we don’t have such thing yet.

Establish a data channel

We can establish a data channel from our previously established control channel:

PASV /
227 Entering Passive Mode (145,220,21,40,242,69).

That means we can now establish another telnet session over (145,220,21,40,242,69). This can be interpreted in 2 groups of numbers:

To find the correct telnet command to use to establish a data channel, you can either do the calculation on your own or copy and paste what you’re getting onto this calculator:



Once you got your command, keep your control channel open and spun up another terminal and type the generated command:

~/$ telnet 145.220.21.40 62021/
Trying 145.220.21.40...
Connected to 145.220.21.40.
Escape character is '^]'.

Listing files under a directory

After establishing the data channel, you should be able to execute the following from the control channel:

LIST /

The data channel should then returns something like this:

~ # telnet 145.220.21.40 62021
Trying 145.220.21.40...
Connected to 145.220.21.40.
Escape character is '^]'.
lrwxrwxrwx 1 0 0 1 Nov 13 2012 ftp -> .
lrwxrwxrwx 1 0 0 3 Nov 13 2012 mirror -> pub
drwxr-xr-x 23 0 0 4096 Dec 14 2018 pub
drwxr-sr-x 89 0 450 4096 Jul 29 23:24 site
drwxr-xr-x 9 0 0 4096 Jan 23 2014 vol
Connection closed by foreign host.

As you see, the data channel closed itself after being used. Using FTP you need to recreate the data channel whenever you need to use it by sending PASV to the control channel

Download a file store on the FTP server

In the server we’re working from, we will download the file stored under /pub/README.nluug. To do this, you need first need to change the working directory to “pub” like this:

CWD pub /
250 Directory successfully changed.

To retrieve the file named README.nluug, we first need to open a data channel via PASV as we did before, then type under the control channel:

RETR README.nluug
150 Opening BINARY mode data connection for README.nluug (932 bytes).
226 Transfer complete.

Example of what we observed from the data channel:

~/$ telnet 145.220.21.40 60993
The data channel should fill itself like this:
~/Documents/projects/filestash-website # telnet 145.220.21.40 60993
Trying 145.220.21.40...
Connected to 145.220.21.40.
Escape character is '^]'.
========================================================

This machine is a mirror of many packages on the internet. It is managed
by the NLUUG (http://www.nluug.nl/).

The license terms differ per package. Please see the information within
each package. NLUUG accepts no liability for the download and/or use
of the software contained in this archive.

This server connects to the internet via a sponsored SURFnet link.
It supports IPv4 and IPv6 connections and allows downloads via ftp,
http and rsync.

For questions and/or comments, contact ftp-admin@nluug.nl

-=-=-=-=- NLUUG - Open Systems. Open Standards. -=-=-=-=-

Support the NLUUG, Become a member and get discounts on
conferences and more, see http://www.nluug.nl/

================================================================
Want to know where to find what data? See the file
WhereToFindWhat.txt
================================================================

Connection closed by foreign host.