pavement

Daemons, testing via Telnet

From FreeBSDwiki
Revision as of 15:39, 27 December 2008 by Jimbo (Talk | contribs)
Jump to: navigation, search

The telnet client can be used to interact directly with service daemons which use human-readable communications protocols - such as IMAP, SMTP, POP3, or HTTP - and make sure they're doing what they are supposed to do. This is an extremely valuable troubleshooting tool, as the experienced admin can see the exact communication from the server rather than rely on "friendly" but often inaccurate error messages given by client utilities intended for end users.

Contents

Testing an SMTP service via telnet

ph34r# telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
220  ESMTP
HELO justtesting
250
MAIL FROM: me@telnettingin.com
250 ok
RCPT TO: postmaster@mail.getsdeliveredhere.net
250 ok
DATA
354 go ahead
To: postmaster@mail.getsdeliveredhere.net
From: telnetclient@mail.getsdeliveredhere.net
Subject: this is a test message
Date: Thu, 21 Jun 2007 11:11:40 -0400
Just testing SMTP functionality by telnetting in to port 25.  I'll end this message now
by entering in a line with nothing but a period in it and hitting return.
.
250 ok 1103093638 qp 87827
QUIT
221
Connection closed by foreign host.

Okay - our SMTP server just accepted a telnet connection, responded like a mailserver, and accepted a nice little test email for delivery. (Any response other than a 250 ok would represent an error of one sort or another.)

Testing SMTP AUTH via telnet

First, we need to generate base64-encoded strings to use with the PLAIN and LOGIN methods. IMPORTANT NOTE: you must be sure to escape any special characters (such as the '@' in an email address!) with backslashes when using Perl for base64 encoding!

First, we'll generate the string for the PLAIN method, in the form of [null]username[null]password:

# perl -MMIME::Base64 -e 'print encode_base64("\0user\@domain.com\0password");' 
AHVzZXJAZG9tYWluLmNvbQBwYXNzd29yZA==

OK, let's telnet in:

ph34r# telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.privatedns.com.
Escape character is '^]'.
220 mail.server.local ESMTP

Great, we got a banner. OK, now let's tell it we want to use extended SMTP with the "ehlo" command:

ehlo test
250-mail.server.local
250-AUTH LOGIN PLAIN
250-AUTH LOGIN PLAIN
250-STARTTLS
250-PIPELINING
250 8BITMIME

Alright. Good. Notice that we support two AUTH methods: LOGIN, and PLAIN. Let's try PLAIN first, using the string we generated for it above:

AUTH PLAIN AHVzZXJAZG9tYWluLmNvbQBwYXNzd29yZA==
235 ok, go ahead (#2.0.0)
quit
221 mail.server.local
Connection closed by foreign host.

Excellent! If we want to try the LOGIN method, we'll need to generate separate base64-encoded strings for the username and the password:

ph34r# perl -MMIME::Base64 -e 'print encode_base64("user\@domain.com");' 
dXNlckBkb21haW4uY29t
ph34r# perl -MMIME::Base64 -e 'print encode_base64("password");' 
cGFzc3dvcmQ=

Now we telnet back in, ehlo as before, and this time authenticate using the LOGIN method:

AUTH LOGIN
334 VXNlcm5hbWU6
dXNlckBkb21haW4uY29t
334 UGFzc3dvcmQ6
cGFzc3dvcmQ=
235 2.0.0 Authentication successful
quit
221 2.0.0 Bye

Again, excellent. (If you were curious, the 334 and 235 SMTP messages are also Base64 encoded, and decode to "Username:" and "Password:".)


Testing an IMAP service via telnet

ph34r# telnet localhost 143
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
* OK dovecot ready.
A LOGIN postmaster@mail.getsdeliveredhere.net thisismypassword
A OK logged in.
A LIST "" "*"
* LIST (\HasNoChildren) "." "INBOX"
* LIST (\HasChildren) "." "Sent"
* LIST (\HasNoChildren) "." "Sent.2006"
* LIST (\HasNoChildren) "." "Sent.2007"
a OK List completed.
A SELECT inbox
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 1 EXISTS
* 1 RECENT
* OK [UIDVALIDITY 1103088195] UIDs valid
* OK [UIDNEXT 1] Predicted next UID
A OK [READ-WRITE] Select completed.
A LOGOUT
* BYE Logging out
A OK Logout completed.
Connection closed by foreign host.

Okay - we've just verified on a very direct level that the IMAP server we connected to answers incoming connections, successfully authenticates users, and successfully opens their inboxes - see the * 1 EXISTS and * 1 RECENT lines? That tells us that there is a single email in the inbox folder, and it hasn't been read yet. (We got "inbox" from the results of our LIST "" "*" command, which asked for a complete list of folders on this account.)


Testing a POP3 service via telnet

ph34r# telnet localhost 110
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
+OK dovecot ready.
USER postmaster@mail.getsdeliveredhere.net
+OK
PASS thisismypassword
+OK Logged in.
LIST
+OK 1 messages:
1 354
.
QUIT
+OK Logging out.
Connection closed by foreign host.

Confirmed - the POP3 server answers connections, authenticates users, and can access its mail store - in this case, we can see that there is a message queued up and waiting for delivery. (Note that frequently you may NOT see any messages in the queue on a POP3 server, as most organizations using POP3 expect users to download their mail and delete it as soon as they have.)


Testing an HTTP service via telnet

ph34r# telnet testdomain.tld 80
Trying 192.168.0.252...
Connected to testdomain.tld.
Escape character is '^]'.
GET http://www.testdomain.tld/
<html><body><h1>It works!</h1></body></html>
Connection closed by foreign host.

In this case, we connected to a fictious webserver and asked it to serve us its home page. Note the response - that's a recent Apache "congratulations" page, meaning that the server hasn't really been configured properly (yet). (Usually, you'll get a MUCH longer response - typical HTML pages these days run 150K+ in size in code alone!)

Note that the GET command is in all caps - Apache is very particular about capitalization, and will not understand HTTP commands which are not in all caps!

What happens if we ask for a page that doesn't exist?

ph34r# telnet testdomain.tld 80
Trying 192.168.0.250...
Connected to testdomain.tld.
Escape character is '^]'.
GET http://testdomain.tld/doesntexist.html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /doesntexist.html was not found on this server.</p>
<hr>
<address>Apache/2.0.52 (FreeBSD) PHP/5.2.1 with Suhosin-Patch Server at testdomain.tld Port 80</address>
</body></html>
Connection closed by foreign host.
Personal tools