Testing Services with Telnet

Testing SMTP

The first service I’ll discuss is SMTP. It can be extremely useful to test a mail server directly, rather than trying to send mail and decipher errors in bounce messages — particularly when mail seems to be disappearing without any bounce!

SMTP, of course, traditionally runs on port 25. Assuming the target server isn’t running SMTP on a non-standard port, you can connect to a mail server like this:

[code lang=”bash”] telnet mail.myhost.com 25[/code]Assuming the target host is running an SMTP server (Exim, Sendmail, Postfix, etc.), you should get a standard greeting:

[code lang=”bash”]220 localhost ESMTP Postfix (Debian/GNU)[/code]Without getting too far into specifications, the ESMTP (as opposed to SMTP) indicates that the server supports the EHLO verb. At this point, you can use the verb HELO or EHLO to “talk” to the SMTP server. Most servers will support EHLO, which will provide a list of extensions available from that server. Here, I’ll use EHLO request to find out what the server’s capabilities are:

[code lang=”bash”]EHLO doyle.zonker.net[/code]At this point, the server will respond with something similar to this:

[code lang=”bash”]250-localhost
250-SIZE 10240000
250 8BITMIME[/code] If you’re just testing whether the server gives a valid response, you can just type “quit” now to end the session. If you want to move on to sending mail, proceed with the MAIL request:

[code lang=”bash”]MAIL FROM: < user@host.tld > [/code]Assuming you’ve typed everything correctly, you should receive the following:

[code lang=”bash”]250 ok[/code]Now enter the address of where you’d like to send mail, using the RCPT verb. To be compatible with all MTAs addresses should be enclosed in brackets (<>), otherwise some MTAs will reject your message because the address is not compliant with the RFCs. Some Mail Transfer Agents are more forgiving than others, but it’s best to follow the standards as much as possible. Note that strict adherence to the RFCs is a feature, not a bug:

[code lang=”bash”]RCPT TO: < user@otherhost.tld >[/code] Again, the server should provide the 250 ok response if the user actually exists on the server, or a 251 if the server will forward mail sent to that address to another address. If the user does not exist, the server will return an error similar to this:[code lang=”bash”]550 < baduser@host.net >: Recipient address rejected: User unknown in local recipient table[/code]Next, you can tell the server that you’d like to start sending mail now, using the DATA request:

[code lang=”bash”]DATA[/code]After sending DATA, you should receive the following (or something very similar):

[code lang=”bash”]354 End data with < CR >< LF >.< CR >< LF >.[/code] This is the “all clear, start sending mail” signal. Let’s go ahead and put this all together for a coherent session, user input is devoid of number: [code lang=”bash”]telnet mail.abc.com 25
Connected to mail.abc.com
Escape character is ‘^]’.
220 localhost ESMTP Postfix (Debian/GNU)
EHLO workstation.xyz.com
250-SIZE 10240000
MAIL FROM: < user@xyz.com >
250 ok
RCPT TO:< user@abc.com >
250 ok
354 End data with < CR >< LF >.< CR >< LF >
FROM: < user@xyz.com >
Mail test, please ignore.
250 Ok: queued as CAE4C22004C
221 Bye[/code] Note that the body of the message doesn’t mean anything, really. The important part is that you terminate the DATA request with a line containing a single period. If you receive an error at this point, it should get you started in the right direction for troubleshooting the problem. See the SMTP RFC for more on error codes.

Testing POP3

Testing POP3 service is just as easy, if not easier, as testing SMTP. Typically, POP3 should respond on port 110:

[code lang=”bash”]telnet popserver.myhost.com 110[/code]

If all is well, you should receive an +OK response. To test a user’s account, follow these steps:

[code lang=”bash”]telnet popserver.myhost.com 110
user username
pass password
+OK[/code]Now, you’re logged into the POP3 server and you can check messages, delete messages, and so forth. You might want to see, for example, how many messages are in the user’s inbox:

[code lang=”bash”]STAT
+OK 102 377111[/code]This tells us that there are 102 messages in the mailbox, and the size of the mailbox (or “maildrop”, in the parlance of the POP3 RFC) in octets.Next, you might want to use the LIST command to see the individual messages and size. If you’d like to see one of the messages, you can use the RETR command. This gives the full content of the message, just as if you were downloading the mail into a POP3 client. This is a really good way to see what messages might be causing problems for a user’s mail client. Some POP3 servers support the optional TOP command, which allows the client to view a specific number of lines of a message, rather than seeing the entire message. This can be useful if you only wish to view the message headers.

If you do have a malformed message that’s causing problems for a user, use the DELE command to delete the message:

[code lang=”bash”]DELE 1[/code]This would the first message in the maildrop. If you make a mistake and delete the wrong message, no problem. The RSET command will unmark the message for deletion — messages won’t be deleted until the POP3 session is ended with QUIT.

Testing IMAP

It’s also possible to test IMAP using Telnet. IMAP should respond on port 143, by default. IMAP is a wee bit more complex than POP3, but it’s not terribly difficult to log into IMAP to ensure that it’s working. (See the RFC for more advanced commands.)

Again, we’ll telnet to the server on the proper port:

[code lang=”bash”]telnet imap.myserver.com 143[/code] You should see a welcome banner something like this, advertising the server’s capabilities:

[code lang=”bash”]Connected to imap.myserver.com.
Escape character is ‘^]’.
Courier-IMAP ready. Copyright 1998-2003 Double Precision, Inc.
See COPYING for distribution information.[/code] Now, pass the server the user’s credentials:

[code lang=”bash”]

1 username password
[/code] Next, you can select the INBOX folder:

[code lang=”bash”]3 select INBOX[/code] [code lang=”bash”] * FLAGS (Draft Answered Flagged Deleted Seen Recent)
* OK [PERMANENTFLAGS (* Draft Answered Flagged Deleted Seen)] Limited
* OK [UIDVALIDITY 1028405230] Ok
3 OK [READ-WRITE] Ok [/code] And finally, you can logout:

[code lang=”bash”] 4 logout
* BYE Courier-IMAP server shutting down
4 OK LOGOUT completed[/code] If you have an SSL-enabled telnet client, you can also test IMAP over SSL:

[code lang=”bash”]telnet -z ssl imap.myhost.com 993[/code]That works with the telnet-ssl package on Debian; it may differ depending on the client you use.

Testing FTP

Need to test an FTP server? Telnet to port 21 telnet ftp.myhost.com 21 and log in with USER and PASS [code lang=”bash”] USER anonymous
331 Anonymous login ok, send your complete email address as your password.
PASS username@myhost.com
230 Anonymous access granted, restrictions apply.[/code]

If you’re curious about the FTP commands that are available, you should be able to get a list by typing HELP .”

Testing HTTP

Last, but definitely not least, let’s look at HTTP. If you want to access a Web server directly for testing, use telnet www.myhost.com 80, or telnet -z ssl www.myhost.com 443 for SSL.

Here’s a basic session:

[code lang=”bash”] telnet www.google.com 80
Connected to www.google.com.
Escape character is ‘^]’.
HEAD /index.html HTTP/1.1
HOST: www.google.com
CRLF [/code] The “CRLF” is the closing linefeed after the HOST: www.google.com line; it’s not something to be typed. You should see something like this:
[code lang=”bash”] HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html
Set-Cookie: PREF=ID=0306562c8b778225:TM=1114160111:LM=1114160111:
expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com
Server: GWS/2.1
Content-Length: 0
Date: Fri, 22 Apr 2005 08:55:11 GMT
[/code]The standard 404 looks like this:

[code lang=”bash”] HTTP/1.1 404 Not Found
Content-Type: text/html
Server: GWS/2.1
Content-Length: 1250
Date: Fri, 22 Apr 2005 08:56:26 GMT [/code] As you can see, you can glean quite a bit from the headers returned when talking directly to the server. If you want to retrieve the entire page, use “GET” rather than “HEAD”. I typically use HEAD because I don’t need to get the entire page just to examine the errors or headers returned by the server. The status code definitions may prove useful for deciphering some of the more uncommon errors.

Leave a Reply