Forum Discussion
Josh_Hildebran1
Nimbostratus
Jul 11, 2006SMTP EHLO response
I'd like to make an iRule that looks for a "EHLO " command and simply responds w/ a particular error message.
I've tried to piece together something, but I've come up short, apparently. Can anyone help?
rule FixUP-SMTP {
when CLIENT_ACCEPTED {
TCP::collect
TCP::release
}
when CLIENT_DATA {
set sdata [TCP::payload]
if { $sdata starts_with "EHLO " } {
TCP::respond "500 5.3.3 Unrecognized command\r\n"
reject
} else {
TCP::release
TCP::collect
}
}
}8 Replies
- Josh_Hildebran1
Nimbostratus
Hmm.. Thanks for the pointers. Unfortunately, it's still not doing what I need.
The goal is to hijack the TCP stream between a webserver that is behind the F5 (internal) as it communicates to an SMTP server that is external to the F5's.
The SMTP server is reached through a VIP on the F5:virtual smtptest_from_internal { destination 172.20.140.26:smtp ip protocol tcp pool smtp_testpool rule FixUP-SMTP vlans internal enable }
which uses the rule ofrule FixUP-SMTP { when CLIENT_ACCEPTED { TCP::collect} when CLIENT_DATA { if { [TCP::payload] contains "EHLO " } { TCP::respond "500 5.3.3 Unrecognized command\r\n" reject } TCP::release } }
But when I connect to 172.20.140.26 on port 25, and issue the EHLO command this is what I get:220 ********************************* EHLO EXDEMO 502 Error: command not implemented
Any other ideas? - Colin_Walker_12Historic F5 AccountHave you tried moving the status code outside of the quotes on the TCP::respond line?
I.E.when CLIENT_ACCEPTED { TCP::collect } when CLIENT_DATA { if { [TCP::payload] contains "EHLO " } { TCP::respond 500 "5.3.3 Unrecognized command\r\n" reject } TCP::release }
Colin - rapmaster_c_127Historic F5 AccountTry this:
rule FixUP-SMTP { when SERVER_CONNECTED { peer { TCP::collect } } when CLIENT_DATA { if { [TCP::payload] starts_with "EHLO" } { TCP::respond "500 5.3.3 Unrecognized command\r\n" set len [TCP::payload length] TCP::payload replace 0 $len "" TCP::release } else { TCP::release TCP::collect } } }
You might want to disable the rule after it has fired the first time, or after you see the DATA method in order to prevent parsing payload. Up to you, but you get the general idea. - rapmaster_c_127Historic F5 AccountYou also would get generally better performance (at the cost of missing an EHLO if it's not the 1st command from the client) by doing this:
rule FixUP-SMTP { when SERVER_CONNECTED { peer { TCP::collect 4 } } when CLIENT_DATA { if { [TCP::payload] starts_with "EHLO" } { TCP::respond "500 5.3.3 Unrecognized command\r\n" TCP::payload replace 0 [TCP::payload length] "" } TCP::release } }
This is probably the common case you're trying to resolve.
Comments:
1. We use SERVER_CONNECTED instead of CLIENT_ACCEPTED because SMTP is a banner protocol. Many clients will not send their first HELO/EHLO until they see the banner from the server. So we wait for the server connection prior to starting our client side collection.
2. Since the event is on the server side, we need to collect on the client side. Thus the use of the peer command.
3. We want to make sure we have at least 4 bytes of payload in our collect.
4. starts_with is more efficient than contains.
5. reject/discard/etc result in operations on the connection. You don't want this; you simply want the payload in that particular segment to be ignored. So we replace it with nothing and continue.
Hope this helps. - Josh_Hildebran1
Nimbostratus
rapmaster_c,
That sure looks like it should work, but it isn't doing anything differently for some reason. I'm beginning to wonder if I have something misconfigured now.
I don't suppose you've actually tested that iRule, have you? - rapmaster_c_127Historic F5 AccountYes, I tested it. It's working here.
Here is the virtual server:virtual vmail { destination 172.27.138.7:smtp snat automap ip protocol tcp pool mail rule muppet }
Here is the rule:rule muppet { when SERVER_CONNECTED { peer { TCP::collect 4 } } when CLIENT_DATA { if { [TCP::payload] starts_with "EHLO" } { TCP::respond "500 5.3.3 Unrecognized command\r\n" TCP::payload replace 0 [TCP::payload length] "" } TCP::release } }
And here is the dry run:Connected to acheron.pdsea.f5net.com (172.27.138.7). Escape character is '^]'. 220 mail.internal Microsoft ESMTP MAIL Service, Version: 6.0.3790.1830 ready at Thu, 13 Jul 2006 11:29:26 -0700 EHLO foobar 500 5.3.3 Unrecognized command HELO foobar 250 mail.internal Hello [172.27.138.6] ^]c Connection closed.
Have you associated the rule with the right virtual server? - Josh_Hildebran1
Nimbostratus
OMG! If I would use the VIP's IP to test with, it might help! hah.. It works now.
It does reply w/ the response as soon as I type EHLO, even before I hit space and the hostname and hit enter.. sort of not what I was looking for, but it actually works w/ .Net SmtpMail function properly, so that's really all I care about.
Thanks a bunch! - rapmaster_c_127Historic F5 AccountNot that it matters all that much since it's working for your application, but I think the reason it's responding straight away to your "EHLO" command from telnet is because the Microsoft Windows telnet client doesn't enter linemode by default, violating the following section from RFC854 page 4:
TRANSMISSION OF DATA
Although a TELNET connection through the network is intrinsically
full duplex, the NVT is to be viewed as a half-duplex device
operating in a line-buffered mode. That is, unless and until
RFC 854 May 1983
options are negotiated to the contrary, the following default
conditions pertain to the transmission of data over the TELNET
connection:
1) Insofar as the availability of local buffer space permits,
data should be accumulated in the host where it is generated
until a complete line of data is ready for transmission,
Looking at traces from a Windows telnet client, it's clear that the MS client sends "E", "H", "L", and "O" in their own individual segments despite not having negotiated non-linemode operation, triggering the rule right after the "O" is transmitted.
If you tested from a Unix derivative or a Linux box whose telnet client entered linemode by default unless it was negotiated to the contrary it should work fine.
As I mentioned, this is probably largely academic at this point though.
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
