Understanding Network Address Translation, NAT
Network Address Translation (NAT) is one of the basic functions of a circuit level gateway. The simple purpose of NAT is to hide the IP addresses of a private network from the outside world.
Normally, when a router forwards a packet from one segment to another, the packet is unchanged. With NAT, as a packet crosses from a trusted segment of a circuit level gateway to an untrusted segment, the packet is rewritten so that the packet’s source address as it appears on the private segment is replaced by a translated source address. The translated source address is what the outside world sees. Thus, the private address remains hidden from the outside world.

When a host on a public network transmits a packet to a host on the private network, the source host addresses the packet to the private host’s publicly translated address. The sender on the public side does not know the destination host’s true address. As the packet crosses the circuit level gateway, the gateway rewrites the packet so that the destination address is translated to the destination host’s private address.

This image illustrates the changes in source and destination addresses as packets cross a circuit level gateway performing network address translation
One to One Translation
One form of NAT establishes a one to one translation between an equal number of private and public host addresses. For example, each host address on a Class C network on the private side of a circuit level gateway is uniquely mapped to a corresponding host address on a Class C network on the public side of the gateway. If 10.1.1.0/24 is the private network address and 172.19.19.0/24 is the public network address, then outbound packets with a source address of 10.1.1.5 can always be rewritten with a translated source address of 172.19.19.5, and inbound packets with a destination address of 172.19.19.5 can be rewritten with a translated destination address of 10.1.1.5. The mapping is persistent and bi-directional. Therefore, connections may be initiated from either side of the circuit level gateway unless a default deny policy is applied.
Pool of Translated Addresses
One form of NAT maps a large block of addresses from the private network to a small pool of addresses on the public segment. Multiple Class A addresses may be mapped to part of a Class C network block. If 10.0.0.0/4 is the private segment’s network address and 172.19.19.0/28 is the public pool of addresses, then an outbound packet with a source address of 10.1.1.5 may be rewritten to have a translated source address of any host address in the pool of 172.19.19.0/28. The NAT gateway will then create a temporary entry in its internal translation table to track the mapping. An inbound packet’s destination address cannot be translated unless a corresponding entry exists in the NAT table. If a current translation exists in the NAT table, the inbound packet’s destination address will be rewritten in accordance with the NAT table entry. The mapping is not persistent and is only temporarily bi-directional. An inbound connection may be accepted only until the NAT table entry expires.
Single Translated Addresses
The form of NAT commonly (but not exclusively) used in commercial circuit level gateways maps any number of addresses from the private network to a single address on the public segment. Given a private segment with the network address 10.0.0.0/8 and a NAT policy that sets 172.19.19.130 as the public address, all outbound packets from the private network will be rewritten to have a translated source address of 172.19.19.130. To correctly map replies to the private host that initiated the connection, the source port number of the outbound packet must also be translated. The NAT gateway will then create a temporary entry in its internal translation table to track the translated source address and port number. An inbound packet’s destination address and port number cannot be translated unless a corresponding entry exists in the NAT table. If a current translation exists in the NAT table, the inbound packet’s destination address and port number will be rewritten in accordance with the NAT table entry. The mapping is not persistent and is only temporarily bi-directional. An inbound connection may be accepted only until the NAT table entry expires.
This image illustrates the changes in IP addresses and port numbers as packets cross a circuit level gateway performing network address and port translation.
nat Chains
netfilter implements network address translation in the nat table. This pre-defined table consists of three built-in chains, the PREROUTING, OUTPUT and POSTROUTING chains. Rules in the PREROUTING chain apply to inbound packets (packets arriving at the gateway from any direction). Rules in the OUTPUT chain apply to locally generated packets (packets that are generated on the gateway itself). Rules in the POSTROUTING chain apply to outbound packets (packets leaving the gateway in any direction).
nat Targets
The nat table includes the built-in targets MASQUERADE, SNAT, DNAT, NETMAP and REDIRECT.
The MASQUERADE target is available in the POSTROUTING chain. MASQUERADE is intended to be used where a firewall’s public side IP address is dynamically assigned, such as where an ISP assigns IP addresses by DHCP. MASQUERADE translates all private network addresses to the single address of the external interface as illustrated, performing port translation as needed and rewriting the destination address and port of replies as needed. When the firewall’s external IP address is released or changed, all translations are dropped.
The SNAT target is available in the POSTROUTING chain. SNAT may be used on a firewall with statically assigned IP addresses. SNAT provides outbound (more trusted to less trusted) network address translation to a pool of public side addresses such that the source address of each outbound packet is translated to an address from the pool, with port translation being performed as needed and the destination address and port of replies being rewritten as needed.
SNAT can use a single public side address as an alternative to a pool of addresses, making SNAT comparable to MASQUERADE. However, SNAT should not be used with dynamically assigned public addresses.
Conversely to SNAT, the DNAT target is available in the PREROUTING and OUTPUT chains and provides inbound (less trusted to more trusted) network address translation. When a connection is initiated from a less trusted network, the destination address is the address of the firewall interface that faces the originating network. DNAT translates the destination address to the address of a host on a more trusted segment. Optionally, the destination port may also be translated. The source address and port of replies from the more trusted segment will be rewritten as needed.
DNAT can use a pool of destination addresses and ports, providing a simple circuit level method of performing load balancing across a number of hosts such as a farm of web servers.
The NETMAP target provides static one to one translation between two network blocks of equal size.
The REDIRECT target is available in the PREROUTING and OUTPUT chains. REDIRECT translates the destination IP address of each packet arriving on any interface to the IP address of the interface on which the packet arrived. For example, REDIRECT will translate the destination address of any packet arriving at eth2. Optionally, the destination port may also be translated. Among other uses, REDIRECT facilitates use of transparent proxies whereby client software such as web browsers may be automatically redirected through the firewall to a proxy server without reconfiguration on the client side.
Traffic classification using BGP (a quagga+realms approach)
Realms patch - Quagga 0.98.6
Stable: quagga-0.98.6-realms.diff
Development: quagga-0.99.5-realms.diff
Updated versions (>0.99.5) - http://linux.mantech.ro/quagga+realm_en.html
This patch enables Linux route realms support in quagga 0.98.6
By Arcady Stepanov’s patch for zebra 0.93b http://win.mol.ru/penguin/zebra-hacks/, adapted it to quagga 0.98.4 interface and added some useful features.
The following commands are supported:
* Route-map
o
bgpd(config-route-map)# set realm
<1-255> Realm id for Linux FIB routes
WORD Realm name for Linux FIB routes
origin-as Use route origin AS as realm id
peer-as Use route peer AS as realm id
o
bgpd(config-route-map)# no set realm
<0-255> Realm value
WORD Realm name
origin-as Origin AS - realm
peer-as Peer AS - realm
<cr>
* Neighbor
o
bgpd(config-router)# neighbor x.x.x.x realm
<0-255> default realm id
WORD default realm name
origin-as Set default realm to received route origin AS
peer-as Set default realm to peer AS
o
bgpd(config-router)# no neighbor x.x.x.x realm
<0-255> default realm id
WORD default realm name
origin-as Set default realm to received route origin AS
peer-as Set default realm to peer AS
<cr>
Note:
’set realm origin-as’ was added with inter-AS traffic accounting in mind. For now, this is possible only with the iptables realm match which can match on the full 16bit realm value. The current realm accounting code in the kernel (rtacct - /proc/net/rt_acct) supports only 256 values for realms, and displays incorrect statistics.
Bugs/suggestions should go to: vcalinusATgemenii.ro
Brief usage guide…
0. kernel support (if you want to classify traffic into htb classes using tc)
CONFIG_NET_CLS_ROUTE=y
1. /eetc/iproute2/rt_realms
Assign meaningful names to realm numbers...
user@router:/# cat /eetc/iproute2/rt_realms
10 localnet
20 metro-isp
22 metro-other
30 international
2. compile/install quagga
Stable Quagga 0.98.6
quagga 0.98.6 - official release
+
quagga 0.98.6 realms patch
Big thanks to Alin Nastac for updating the patch to 0.98.6!
Patch for development Quagga 0.99.5
quagga-0.99.5-realms.diff
Older patches
quagga-0.98.5-realms.diff
quagga-0.98.4-realms.diff
quagga-0.98.3-realms.diff
Remember to use ./configure --enable-realms
3. BGP CONFIGURATION
a possible bgp setup:
(if you hold the full routing table - replace defgw with a match on the desired community)
AS-regexp match is also possible
neighbor xxx.xxx.xxx.xxx remote-as XXXXX
neighbor xxx.xxx.xxx.xxx soft-reconfiguration inbound
neighbor xxx.xxx.xxx.xxx route-map isp_in in
ip prefix-list defgw seq 5 permit 0.0.0.0/0
ip community-list standard metro-isp permit XXXXX:comm1
ip community-list standard metro-other permit XXXXX:comm2
route-map isp_in permit 10
match ip address prefix-list defgw
set realm 30
!
route-map isp_in permit 20
match community metro-isp
set realm 20
!
route-map isp_in permit 30
match community metro-other
set realm 22
!
route-map isp_in permit 40
3.1 'ip route sh' will show kernel routes - they should have the realms specified in the route-map
something like....
62.217.192.0/18 via 193.19.192.65 dev eth1 proto zebra equalize realm 20
82.137.0.0/18 via 172.16.100.1 dev eth2 proto zebra equalize realm 22
84.243.64.0/18 via 172.16.100.1 dev eth2 proto zebra equalize realm 20
82.208.128.0/18 via 193.19.192.65 dev eth1 proto zebra equalize realm 22
4. iptables
Can be used in FORWARD or POSTROUTING (remember that realms are valid only after the forwarding decision)
Download: match default route, community 1, and community 2 sets
-A FORWARD -i eth3 -m realm --realm 0x1e0000/0xffff0000 -j sometarget...
-A FORWARD -i eth3 -m realm --realm 0x140000/0xffff0000 -j sometarget...
-A FORWARD -i eth3 -m realm --realm 0x160000/0xffff0000 -j sometarget...
Upload: match default route, community 1, and community 2 sets
-A FORWARD -o eth3 -m realm --realm 0x1e/0xffff -j sometarget...
-A FORWARD -o eth3 -m realm --realm 0x14/0xffff -j sometarget...
-A FORWARD -o eth3 -m realm --realm 0x16/0xffff -j sometarget...
(realms 30,20 and 22 are specified in hexadecimal)
5. tc
Excerpt from LARTC
# ip route add 192.168.2.0/24 dev eth2 realm 2
# tc filter add dev eth1 parent 1:0 protocol ip prio 100
route from 2 classid 1:2
Here the filter specifies that packets from the subnetwork 192.168.2.0 (realm 2) will match class id 1:2.
You can also find useful QoS stuff at: http://kernel.umbrella.ro/net/
6. what are realms after all?
Realms are 16bit integer values used to group routes into sets, according to
some defined policy. Each route in the set will have the same realm.
Each packet routed will have a 32bit integer value specifying a source and a destination realm. (they may be 0 - or unknown)
On the leftmost 16bits you will find the source realm, on the rightmost 16bits the destination realm.
More info: http://www.policyrouting.org/iproute2.doc.html#ss9.9
Quagga realms Tutorial
Quagga is an open source routing software based on the Zebra router, for which development was stopped in 2003. It supports the main standardised routing protocols such as RIP, OSPF or BGP and can be installed on any Linux system with a 2.4 or higher kernel.
Quagga is composed of several daemons, one per routing protocol and another one called Zebra acting as the kernel routing manager. Each daemon has its own configuration file and terminal interface which can be accessed by telnet.
The vtysh tool is provided to configure the Quagga router from the localhost, in a unique interface.
See the Quagga tutorial for instructions on configuring the router.
Quagga works independently from the operational system (OS) over which it is installed. This is not the case for the open source Vyatta router or the commercial routers where the OS and the routing engine are built together.
With Vyatta routers, you can access the operational system (a modified version of the Debian Linux distribution) but even this is not necessary to configure the router.
With commercial routers like Cisco or Nortel, you can access only the router interface.
It must be emphasised that Quagga owns only routing capabililies and functionalities associated with it, such as access lists or route maps. It does not provide "non-routing" functionalities such as DHCP server, NTP server/client or ssh access but it is often possible to enable them on the operating system supporting your Quagga router.
See the Routers' comparison to get an overview about the functionalities available with Cisco, Vyatty or Quagga routers.
The Quagga Command line Interface is very similar to the Cisco IOS software allows it to be configured very easily for those who are familiar with Cisco.
And finally, little story: the word 'quagga' comes from an extinct animal which was a subspecies of the plains zebra.
1. QUAGGA DAEMONS:
You have to activate the Quagga daemons matching the routing protocols you want to set on your router.
zebra:
bgpd:
ospfd:
ospf6d:
ripd:
ripngd: Interface declaration and static routing
BGP routing protocol
OSPF routing protocol
OSPF IPv6 routing protocol
RIP v2 routing protocol
RIP Ipv6 routing protocol
In the example below, the zebra and IPv4 OSPF daemon have been activated.
#vim /etc/quagga/daemons
zebra=yes
bgpd=no
ospfd=yes
ospf6d=no
ripd=no
ripngd=no
Restart the Quagga service:
#/etc/init.d/quagga restart
Stopping Quagga daemons (prio:0): ospfd zebra (bgpd) (ripd) (ripngd) (ospf6d) (isisd).
Removing all routes made by zebra.
Nothing to flush.
Loading capability module if not yet done.
Starting Quagga daemons (prio:10): zebra ospfd.
You can check the Quagga daemons status:
#ps -ef | grep quagga
UID PID PPID C STIME TTY TIME CMD
quagga 4632 1 0 22:25 ? 00:00:00 /usr/lib/quagga/ospfd --daemon
quagga 4636 1 0 22:25 ? 00:00:00 /usr/lib/quagga/zebra --daemon
If a Quagga daemon doesn't stop properly, you can kill it manually and start the quagga service:
#kill -9 "UID number"
#/etc/init.d/quagga start
2. CONFIGURATION FILES: (/etc/quagga/*.conf files)
You must create a configuration file (even if it is empty) each time you activate a Quagga daemon.
Each daemon is associated with a specific file name:
zebra:
bgpd:
ospfd:
ospf6d:
ripd:
ripngd: zebra.conf
bgpd.conf
ospfd.conf
ospf6d.conf
ripd.conf
ripngd.conf
To create the config files, copy the sample config files as follows:
In our example, as we activated the zebra and ospfd daemons; we need to create the zebra.conf and ospfd.conf files.
#cp /usr/share/doc/quagga/examples/zebra.conf.sample /etc/quagga/zebra.conf
#cp /usr/share/doc/quagga/examples/ospfd.conf.sample /etc/quagga/ospfd.conf
Another way to do it is to create two empty files called /etc/quagga/ospfd.conf and /etc/quagga/zebra.conf. But in this case you cannot telnet a daemon, you need to configure the telnet permissions with vtsh (see below).
Finally, give user and group ownership to respectively quagga and quaggavty to the files inside the /etc/quagga directory:
#chown quagga.quaggavty /etc/quagga/*.conf
#chmod 640 /etc/quagga/*.conf
Restart the Quagga service:
#/etc/init.d/quagga restart
Top of the page
3. DEBIAN.CONF FILE
By default, the Quagga daemons are listening only to the loopback interface 127.0.0.1. It means that you can telnet a daemon only on its loopback address 127.0.0.1 and thus cannot access it remotely.
If you want to telnet a Quagga daemon remotely you can, in the /etc/quagga/debian.conf file. Either indicate one or several IP addresses or remove the -A option meaning that you can telnet a daemon on any of its IP addresses.
Here are two examples:
The ospfd daemon is listening to the 127.0.0.1 and 192.168.1.104 IP addresses.
ospfd_options=" --daemon -A 127.0.0.1 192.168.1.104"
The zebra daemon is listening to all the Linux interfaces IP addresses. We recommend using this setting. If you want to filter who can access to your router, configure access lists on the router software.
zebra_options=" --daemon "
Here is the recommended debian.conf file:
#vim /etc/quagga/debian.conf
# If this option is set the /etc/init.d/quagga script automatically loads
# the config via "vtysh -b" when the servers are started.
# Check /etc/pam.d/quagga if you intend to use "vtysh"!
#
vtysh_enable=yes
zebra_options=" --daemon -A "
bgpd_options=" --daemon -A "
ospfd_options=" --daemon -A "
ospf6d_options="--daemon -A "
ripd_options=" --daemon -A "
ripngd_options="--daemon -A "
isisd_options=" --daemon -A "
The "vtysh_enable=yes" setting is required to access the Quaggga router via vtysh. (see vtysh section).
Restart the Quagga service
#/etc/init.d/quagga restart
Top of the page
4. VTYSH
As indicated in the Quagga introduction, you can access the daemons by telnetting their port number because each daemon has its own configuration file and terminal interface.
zebra:
ripd:
ripng:
ospfd:
bgpd:
ospf6d: 2601
2602
2603
2604
2605
2606
By instance, to access the ospfd daemon:
#telnet localhost 2604
As it's not very practical to configure your router by telnetting its daemons separately, vtysh has been created to configure everything in one single interface.
To use vtysh, you must first create its configuration file as follows:
#cp /usr/share/doc/quagga/examples/vtysh.conf.sample /etc/quagga/vtysh.conf
/etc/quagga/vtysh.conf
!
! Sample
!
! service integrated-vtysh-config
hostname quagga-router
username root nopassword
!
Apply correct permissions and restart Quagga:
#chown quagga.quaggavty /etc/quagga/*.conf
#chmod 640 /etc/quagga/*.conf
#/etc/init.d/quagga restart
In the example above the "service integrated-vtysh-config" setting has been disabled (recommended). In this case, when you save the config under vtysh, it will be stored in separate files depending on the protocols you activated.
Below, an example where the Quagga configuration is saved under vtysh. (The zebra and ospfd daemons have been enabled.)
#vtysh
quagga-router#write
Configuration saved to /etc/quagga/zebra.conf
Configuration saved to /etc/quagga/ospfd.conf
If you activate "service integrated-vtysh-config", the configuration under vtysh will be saved in one file called Quagga.conf in the /etc/quagga/ directory.
With this setting, when you access a daemon via telnet, the daemon will look first to the Quagga.conf file before looking for its own file. This means that, when you telnet a device, there can be a difference between what you see after the "show run" command and the content of the associated file, for example zebra.conf.
#vtysh
quagga-router#write
Configuration saved to /etc/quagga/Quagga.conf
It is recommended to disable "service integrated-vtysh-config" because if this setting is enabled and in case of a syntax error in the Quagga.conf file, this can lead to all your daemons being unable to start up. This will not be case when "service integrated-vtysh-config" is disabled because the configurations are stored in separate files.
Check that the default "vtysh_enable=yes" setting are configured in your /etc/quagga/debian.conf file. You can read the previous paragraph about the debian.conf file to get more information.
Then it's useful to add the "VTYSH_PAGER=more" setting in your /etc/environment file, otherwise you will see an unfriendly "(END)" blinking in the left-down corner of the screen each time your enter a command and will need to press the "q" key to continue.
#echo VTYSH_PAGER=more > /etc/environnement
Log off and log on to enable the environment setting. You can now access the Quagga router with the vtysh command:
#vtysh
Hello, this is Quagga (version 0.99.6).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
quagga-router#
If you want to run a Quagga command from the Linux shell:
#vtysh -c "command"
For instance, vtysh -c "show ip route" will display the Quagga routing table.
You can use ping and traceroute to perform connectivity checks from the vtysh prompt. Of course, these two programs need to be installed on the Linux machine. Ping is generally installed by default but traceroute often not.
To install traceroute:
#apt-get install traceroute
Top of the page
5. IP FORWARDING:
IP forwarding is required to transfer packets between the network interfaces of a Linux system.
See a picture of the Linux kernel routing.
#echo "1" > /proc/sys/net/ipv4/ip_forward
The command above will add the "1" value inside the /proc/sys/net/ipv4/ip_forward file and thus activate the IP forwarding.
If you want to keep the IP forwarding after a Linux reboot:
#echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
It is possible to check the ip_forwarding status under the Quagga router:
#show ip forwarding
IP forwarding is on
In this case the IP forwarding is activated.
Top of the page.
6. SPEED/DUPLEX:
It is not possible to set the duplex and speed settings on the Quagga plateform. You have to configure them at the Linux level.
Use the interface configuration tutorial for assistance.
Here is a comparison of some characteristics you can find on four routers: the first two are the best open source routers available, Quagga and Vyatta and the remaining two are commercial devices and best-sellers from Cisco: a standard router from the 26xx family and a Layer Three Switch 3750.
| RFC | QUAGGA 0.99.6 |
VYATTA VC 3.0 |
CISCO 2651 |
CISCO 3750 L3 |
|
| Software type | IOS-Like | JunOS-Like | Cisco IOS | Cisco IOS | |
| Opensource | YES | YES | NO | NO | |
| Installation | YES | YES | NO | NO | |
| Static Routing | - | YES | YES | YES | YES |
| RIPv2 | 2453 | YES | YES | YES | YES |
| OSPFv2 | 2328 | YES | YES | YES | YES |
| BGPv4 | 1771/4271 | YES | YES | YES | YES |
| NAT | 2766 | NO/Linux | YES | YES | NO |
| VRRP | 3768 | NO/Linux | YES | YES | NO |
| Access lists | YES | YES | YES | YES | |
| Route maps | YES | YES | YES | YES | |
| VPN IPSec | 4301 | NO/Linux (1) | YES | YES | YES |
| VPN SSL | NO/Linux (2) | NO/Linux (2) | NO | NO | |
| FTP client | 959 | NO/Linux | YES | YES | YES |
| TFTP client | 1350 | NO | YES | YES | YES |
| Telnet server | 854 | YES (3) | YES | YES | YES |
| ssh server | 4251 | NO/Linux | YES | YES/NO | YES/NO |
| HTTP server | NO | YES | YES | YES | |
| DHCP server | 2131 | NO/Linux | YES | YES | YES |
| DHCP relay | NO/Linux | YES | YES | YES | |
| NTP server | 1305 | NO/Linux | NO | YES/NO | NO |
| NTP client | 1305 | NO/Linux | YES | YES | YES |
| SNMP | 3412/1157 | YES (4) | YES | YES | YES |
| Ping | YES (5) | YES | YES | YES | |
| traceroute | YES (5) | YES | YES | YES |
Legend:
| YES: YES/NO: BUGGED: NO/Linux: (1) (2) (3) (4) |
The protocol is supported. Available on specific Cisco IOSs only. There is a major bug on the protocol. Not supported on the Quagga router but can be enabled at the Linux level. Openswan can be used as an implementation of IPsec for Linux. OpenVPN can be used to build SSL VPNs on Linux. Each routing protocol daemon and the zebra kernel routing manager have to be telnetted separately. Quagga must be compiled with the SNMP functionality. Ping or traceroute must be installed at the Linux level to be used under Quagga. |
