Tag Archives: NAT

A curious case for FTP passive mode over NAT on Cisco IOS router

Recently, I came across an interesting feature on Cisco IOS that mysteriously do something similar to an application inspection for FTP protocol and more that that, make modifications into replay messages from FTP server. You know, a router is a Layer 3 device that has no rights to do payload modifications, in some cases at most just several fields in IP header (e.g. TTL, src/dst IP addresses and port numbers in case of NAT). The behavior observed by me looks like oposite: a Cisco IOS router, when configured to do NAT, make specific changes on some FTP control messages. It’s like a router had borrowed something from ASA firewall inspection features.

Let’s do now some testings. For our scenario I built the following simple topology in GNS3.

a curios case for FTP passive mode over NAT on Cisco IOS router - lab topolgy

The three components used are:

  • the FTP client is a Windows 7 VM running in VMware Workstation
  • the FTP Server is a Windows Server 2008R2 VM running in VMware Workstation
  • the R1 is a Cisco IOS 7200 router with Cisco IOS version 12.4(24)T5

Note0: In my testings I used the FileZila 0.9.56 as an FTP server and Total Commander of version 8.51a with his embedded FTP client.

Note1: FTP server run in Passive Mode. My focus was only for FTP passive mode simply because this is the use case I have in my production scenario. I will not talk about FTP active mode.

On Cisco router applied the following simple configuration (interface & static inside NAT conf):

After NAT, the FTP server is seen by the FTP client by IP address.

As you can observe an additional ACL that deny any un-NAT-ed communications is applied inside on FastEthernet0/0 (from FTP client side) – just to be sure that all sessions pass through NAT.

Now, I will start two packet capture sessions in Wireshark for both router’s interfaces and initiate a new FTP passive mode connection to FTP server.

In Passive Mode the client request Passive mode operation by issuing the PASV command over the control connection on TCP port 21. The server suggest a data port and IP address, to which the client must connect. The port number are somewhat encoded in several message fields, see the formula in the illustration below.

a curios case for FTP passive mode over NAT on Cisco IOS router - passive mode ilustration

The following screen show the capture of Passive mode acknowledge message (Passive OK, 227) packet with most important fields highlighted (src/dst ports, pasv response args).

a curios case for FTP passive mode over NAT on Cisco IOS router - packet capture at source_c

Where: 1-passive mode request, 2-passive mode acknowledge, 3-acknowledge message arguments, 4-passive IP address (server IP), 5-passive port (listener for data connection), 6-source port for data connection (ephemeral), 7-control connection server source port, 8-control connection server destination port (a value different from 6).

If we look now at the same packet but this time after it passed the router/NAT we would see, besides the destination IP change in IP header (because of NAT), also the FTP message payload modifications: specifically, in message arguments, values from 192,168,2,20 changed to 192,168,3,20. It is obviously an effect of NAT FTP protocol inspection and corresponding changes in message made by router.

a curios case for FTP passive mode over NAT on Cisco IOS router - packet capture at destination_b

A more in depth information about how this all works you can find here: ciscopress.com – Routing TCP/IP, Volume II (CCIE Professional Development) – Network Address Translation (link here), btw, one the few sources available on the net.

What if the FTP server will be set to function on a non-standard port ?

The answer is that the inspection embedded in NAT would ignore such a server. It simply do just the standard NAT section but not also the payload inspection and modification. Ironically, that was the reason why, initially, I couldn’t understand why this works perfect in lab but not also in production. It appeared to be that the non-standard port applied on prod. FTP server was the culprit.

The next question then arise: What needs to be done for NAT FTP inspection work for non-standard FTP ports ?

More by accident than intentionally I found this cool Cisco article: cisco.com – Using Non-Standard FTP Port Numbers with NAT (link here), that explain what to do – not so much, just two additional configurations. In my case these would be:

First, we create a standard ACL that would include the FTP server’s IP address (before NAT), and second, we would teach the IOS NAT to inspect on non-standard port number (in our case 5555) for that IP. If more than one FTP servers are used then add those to ACL too and if more than one tcp port numbers are used for control connections then specify those one by one separated by comma in second configuration command.

Bellow, you can see the ftp connection logs before (first section) and after (second section) the above configuration wad applied and FTP server configured to work with non-standard port number.

a curios case for FTP passive mode over NAT on Cisco IOS router - ftp client logs

As can be observed, after applying configuration, the FTP server answer message arrive already modified with NATed (global inside) server IP address in payload.

How to deliberately disable NAT inspection?

It can be done only per NAT entry (no global configuration), by specifying no-payload keyword at the end of NAT entry definition command.

Why is so important for IP addr. in pasv answer to be fixed to FTP server’s NATed (global inside) value?

Well, actually the importance depends on how FTP client are configured/build. The truth is that an FTP client can work either in restrictive or in less restrictive mode (can’t remember from where I got the terms, they may be wrong) and depending on that, ignore or not the value provided in pasv answer message. An FTP client configured for restrictive mode will try a data connection only to IP address suggested in pasv answer, if the de connection could not be established the FTP session will fail. At the oposite side, an FTP client in less restrictive mode would simply ignore the IP address suggested in pasv answer and would try instead the IP address used initially for data connection (the IP address that you configure in FTP client. Obviously, the global inside address).

So, if you have an FTP client configured/build for restrictive mode then is important to have NAT inspection doing IP address exchange in pasv answer message. Again, absolutely by accident, I found that older versions of Total Commander use the restrictive mode for their FTP client (7.04a in my particular case). It was an opportunity for a little test with such a client. Bellow, you can see the FTP client connection logs for (a) with NAT inspection and (b) without it and the final FTP session status. 

a curios case for FTP passive mode over NAT on Cisco IOS router - ftp client in restrictive mode

Clearly, for FTP session to succeed, a NAT FTP inspection that will do also translations in pasv answer message payload, needs to be in place.

Configurație destination-based NAT realizată prin route-map-uri

Imaginativă un scenariu prin care o companie se interconectează cu rețeaua unuia din partenerii săi. Pentru siguranță interconectarea se face prin două circuite separate: unul de bază printr-un Layer 2 overlay peste MPLS și altul de backup printr-un circuit virtual peste o rețea Frame-Relay. Rețeaua companiei este ascunsă de parteneri printr-un serviciu NAT prin care pe de-o parte se exclude riscul suprapunerii spațiilor de adrese IP utilizate pe intern și pe de altă parte ține confidențial particularitățile de subnetare a rețelei companiei. In plus, partenerul își poate construi un sistem de protecție (e.g. prin liste de acces) prin care să permită accesul doar pentru adrese IP din spațiul adrese agreat pentru configurația NAT-ului. Configurația NAT-ului trebuie realizată în așa mod încât aceasta să transleze in adrese IP (inside global) din intervale care să depindă de circuitul activ la momentul translării. Fiecare circuit are rezervat câte un interval de adrese IP (pool) destinat translărilor NAT.

Ca să formalizez, in cele ce urmează vom modela o topologie cu următoarele particularități:

  • interconectare între companie și partener prin două circuite: (a) unul de bază prin L2 peste MPLS și (b) altul de rezervă printr-un PVC peste Frame Relay.
  • rețeaua companiei protejată prin NAT, fiecare circuit configurat cu pool de adrese NAT separat: (a) pentru MPLS NAT pe 32 IP-uri din subnet-ul: și (b) pentru Frame Relay NAT 32 de IP-uri din subnet-ul: 172.31.5. 64/27. Funcție de circuitul activ: main sau back-up, NAT-ul va funcționa fie pe primul fie pe al doilea interval de IP-uri.
  • segmentul punct-la-punct MPLS se configurează cu adrese IP din (.1 la companie)
  • segmentul PVC FR se configurează cu adrese IP din (.5 la companie și .6  la partener)
  • circuitul Frame Relay folosește PVC cu: (a) DLCI 423 pe partea companiei și (b) DLCI 324 partener.
  • rețea utilizatori companie: cu stație pentru test (client_companie) pe adresa:
  • rețea servere partener: cu server pentru test (server_partener) pe adresă

Pentru modelare vom folosi GNS3 într-o schemă ca cea de mai jos:


În schemă:

  • MPLS format pe două switch-uri ethernet sintetice (PE1/PE2), incluse in serie pentru a putea întrerupe circuitul fără ca interfețele să treacă in down.
  • Frame Relay pe switch FR sintetic (port 1 – DLCI 423, port 10 – DLCI 324)

În plus, pentru completeness, la configurația de routing și NAT pe deasupra vom configura pe routerul companiei o probă IP SLA pentru tracking-ul circuitului de bază și rută flotantă pentru failover automat pe circuitul de backup.

Configurație router R1 (companie)

Configurație interfețe FastEherenet1/0, Serial0/0, Serial0/0.423:

Configurație serviciu NAT pe două pool-uri de adrese IP

În care linkfr și linkmpls sunt pool-urile de adree IP destinate NAT-ului pentru circuitele MPLS și respectiv Frame Relay. Ceea ce face ca NAT-ul să depinde de destinație este utilizarea in comenzile ip nat inside a route-map-rilor rmfr si rmmpls care la rândul lor sunt asociate fiecare cu altă interfață, partea cu match in secvența de mai jos:

Pentru route tracking vom folosi o proba SLA bazată pe ICMP echo-request/replay la IP-ul interfeței de partea partenerului pentru circuitul MPLS:

Note: secvența de mai sus pentru IP SLA valabilă pentru versiunea de IOS folosită de mine în GNS3, alte versiuni au altă sintaxă.

În final configurăm rutele statice către rețeaua de servere parteneri. Vom folosi două rute: una dependentă de track-ul la proba IP SLA și alta ca back-up inclusă cu o metrică mai proastă (100):

track 10 face referință la proba ip-sla 10

Configurație router R2 (partener)

Pe partea partenerului minim de configurație. Interfețe:

și două rute statice câte una pentru fiecare interval (subnet) de IP-uri NAT:

Acum că avem configurate toate componentele topologiei, putem să incercăm câteva teste.

Testing and Troubleshooting

Vom verifica două scenarii, unul pentru regimul normal cu trafic peste circuitul de bază și altul pentru cazul când circuitul de bază se intrerupe și traficul se redirecționează automat pe circuitul de rezervă. In avele cazuri se va verifica tabelul translărolor NAT și câte un capturi de wireshark pe fiecare circuit.

Așadar, după ce ne convingem că ping-ul are loc cu succes de la client la server verificam tabelul translarilor NAT pe router-ul R1:


se observă o translare NAT cu un IP (inside global) din intervalul rezervat circuitului de bază, fapt confirmat și prin captura Wireshark (pe interfața R1-F1/0)


in captură, IP-ul sursa la pachetul cu ICMP request pleacă NAT-uit cu Ce este interant captura include și pachetele periodice de ICMP pentru proba IP SLA (R1 – la R2 – Funcționarea track-ului pe proba IP-SLA o confirmăm cu următoarele comenzi:


din output interesant de urmărit Number fo Failures care e zero pentru moment, statutul track-ului care e Reachability is Up și ruta către servere prin circuitul de bază (R1-F1/0).

Acum să incercăm să simulăm intreruperea circutului de bază și să observăm efectul. Vom intrerupe link-ul intre switch-urile PE1 si PE2. Verificăm statutul IP SLA:


din care imediat observăm efectul: (a) Number of failures in proba IP SLA diferit de zero (b) track 10 cu statut Reachability is down și (c) rută peste segmentul de bază in down. Ruta către rețeaua de servere parteneri trece deacum prin circuitul de back-up:


executăm un ping de la client la server, după care verificam tabelul translărilor NAT:


deja se observa o translare cu un IP ( din intervalul rezervat circuitului de rezerva Fapt confirmat și prin captura Wireshar pe interfața Serial0/0:


se observă respectivul IP-ul sursă pentru pachetele ICMP echo request (și encapsularea FR).

Cam asta pe azi. Dacă vă doriți să reproduceți scenariul puteți descărca fișierele de configurație pentru R1 și R2 de aici (link).