Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

X-Forwarded Rule for SMTP

Hello All,

We have an SMTP virtual server on our f5 Big IP VE 13.1.0 platform. It works without any issues. However, we would like to add a feature. Effectively, the auto-SNAT means the server owners lose visibility of the real client source IP addresses. We would like to implement an SMTP equivalent of X-forwarded in the header & was wondering if anybody had experience of creating the necessary iRule for this please?

Thanks & Regards, Graham.

0
Rate this Question
Comments on this Question
Comment made 11-May-2018 by Chase Abbott

Well.... I did do this with a pair of Ironports so to preserve source IP, we used the BIG-IP as the external gateway. The removed the need for SNAT preserving source to destination. Worked great. Separate interfaces did the internal SMTP forwarding to Exchange CAS/Transport servers.

If you cannot do this for architectural reasons then I'll defer to the rest of the community. I haven't configured SMTP with SNAT to date.

0

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

There is an example of the sending client ip to the smtp server: https://devcentral.f5.com/questions/irule-for-smtp-passing-client-ip-addr-to-backend-mail-servers

when CLIENT_ACCEPTED {
    set c-addr [IP::client_addr]
    log local0. "Client addr: $c-addr"
    STREAM::expression {@^EHLO.*\r\n@@ @^HELO.*\r\n@@}
    STREAM::enable
}

when STREAM_MATCHED {
    set mstring [STREAM::match]
    log local0. "STREAM_MATCHED: string: $mstring"
    set replacment [string range $mstring 0 1]
    append replacment "LO $c-addr\r\n"
    log local0. "STREAM_MATCHED: replacement string: $replacement"
    STREAM::replace "$mstring/$replacment"
    event STREAM_MATCHED disable
}

when SERVER_CONNECTED {
    STREAM::disable
}
0
Comments on this Answer
Comment made 4 months ago by Misty Spillers 330

I have seen this rule before and never got it to work. Just tried again. First I get

Oct 26 11:19:21 lb1 err tmm3[12551]: 01220001:3: TCL error: /internal/smtp_x_forward - can't read "c": no such variable while executing "log local0. "Client addr: $c-addr""

I change the 3 spots were "c-addr" exist to "caddr" and this error goes away and the log reports the address.

Then I get this message: Oct 26 11:19:52 lb1 info tmm[12551]: Rule /internal/smtp_x_forward : Client addr: 192.168.61.42%207 Oct 26 11:19:59 lb1 info tmm[12551]: Rule /internal/smtp_x_forward : STREAM_MATCHED: string: HELO gmail.com Oct 26 11:19:59 lb1 err tmm[12551]: 01220001:3: TCL error: /internal/smtp_x_forward - can't read "replacement": no such variable while executing "log local0. "STREAM_MATCHED: replacement

I'm not good enough at this to know why it doesn't see that variable

0
Comment made 4 months ago by Misty Spillers 330

Actually "replacement" is spelled wrong in some areas in the original. That solves that.

Now I think the mail server I'm testing with doesn't like gmail.com switched to an IP address%(route domain) working on that

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Hi, did you ever get this script working? Does the source IP appear in the SMTP-header and can you see it with Wireshark like with an XFF? I just ran a test with the above script and I'm not seeing any changes in the SMTP header...

0
Comments on this Answer
Comment made 1 month ago by Misty Spillers 330

I never got it working. On my system it just hangs smtp. This is the script I ended up with but I don't really have a dev background, Just correct syntax/spelling and adjusted for have route domains on my system

    when CLIENT_ACCEPTED {
    set caddr [getfield [IP::client_addr] % 1]
    log local0. "Client addr: $caddr"
    STREAM::expression {@^EHLO.*\r\n@@ @^HELO.*\r\n@@}
    STREAM::enable
}

when STREAM_MATCHED {
    set mstring [STREAM::match]
    log local0. "STREAM_MATCHED: string: $mstring"
    set replacement [string range $mstring 0 1]
    append replacement "LO $caddr\r\n"
    log local0. "STREAM_MATCHED: replacement string: $replacement"
    STREAM::replace "$mstring $replacement"
    event STREAM_MATCHED disable
}
0
Comment made 1 month ago by timvd 1

I now have used this iRule: https://devcentral.f5.com/questions/raw-tcp-insert And that gives the original IP with the initial command that is being sent. So it now appears in the logs. Just not sure if it will have an impact on mail traffic because it also sends a Bad Sequence of Commands back to the client because the first command will fail as it does not follow the standards. Will have to check this in a more sophisticated environment then the lab I quickly set up. This is the iRule I used: when SERVER_CONNECTED { TCP::respond "[clientside {IP::remote_addr}];" }

and this is the Result in Wireshark: Image Text

and the result in the mailserver: Image Text

0
Comment made 1 month ago by timvd 1

The above did not work when sending actual mails it breaks the flow. I have now used this code: https://devcentral.f5.com/questions/irule-for-smtp-passing-client-ip-addr-to-backend-mail-servers and now everything seems to work fine in my lab setup. Have not been able to test in a bigger environment to see the possible impact.

0