Опубликован: 06.08.2012 | Доступ: свободный | Студентов: 1189 / 25 | Оценка: 5.00 / 5.00 | Длительность: 53:41:00
Лекция 22:

Firewalls, IP aliasing and proxies

< Лекция 21 || Лекция 22: 12345 || Лекция 23 >

IP aliasing

In our reference network on page 294, we assumed that our local network had a valid assigned IP address. Sometimes, this isn't possible. In fact, in the Real World it's pretty well impossible to get a complete class C network for a system with only five systems on it. You have the alternative of getting a subset of a class C network (in this case, eight addresses would do) from your ISP, or using just one address and running software that makes all traffic from the network to the outside world look as if it's coming from that system. The latter approach, called network address translation (NAT) or IP aliasing, can be significantly cheaper: ISPs often charge good money for additional addresses. On the down side, NAT restricts you in some ways. Any connection between a machine on a NAT network and the global Internet must start from the machine on the NAT network, because the translation doesn't exist until the connection is set up. This also means that you can't connect two machines on different NAT networks.

Network address translation involves three machines: one on the global Internet with real Internet addresses, one on a private subnet with unroutable addresses, and one in the middle that performs the translation. In our reference network (see page 294), let's consider connecting andante, the laptop, to the Internet with presto acting as address translator. andante is not part of the local network, so it gets an address in one of the address spaces specified by RFC 1918 ( to, to, or to In this example, it has the address, and we can assume that it got this address from a DHCP server on presto. A connection to a remote web site http://www.FreeBSD.org might look like this:

Accessing the Web via NAT

Рис. 22.1. Accessing the Web via NAT

In this diagram, the IP addresses are above the boxes, the interface names above the connection lines, and the port numbers below the connection lines. The connection must be started by andante, because there is no way to route to it directly from outside the local link. It finds the address of http://www.FreeBSD.org ( and sends it out its default route, in this case the only interface, wi0. presto gets the packet on interface xl0 and routes it out through interface dc0.

So far, that's nothing special—it's what any router does. The difference is that presto changes the source address and port number. On the wireless link, andante's address is, and the port number for this connection is 2731. On the remote link, the IP address becomes, presto's own address, and the port number in this case is 3312. Theoretically, the "changed" port address could be the same as the original, since there is no relationship. The destination IP address and port number can't change, of course, or the packet would never get to its destination.

On return, the reverse happens: http://www.FreeBSD.org replies to presto, which recognizes the port number, converts it to andante's IP address and source port, and sends it to andante on the local network.

IP aliasing software

There are a number of ways to perform IP aliasing with FreeBSD. If you're connecting to the outside world via User PPP (see Chapter 20, page 348), you can use the -alias keyword to tell PPP to alias all packets coming from the network to the address of the tunnel interface. In our reference network, this would be the address

This particular form of IP aliasing has some limitations: it works only for a single User PPP connection to the outside world, and it's global in its functionality. One alternative is the Network Address Translation Daemon, or natd, which uses divert sockets to translate addresses. It works well in conjunction with the firewall software we looked at above.


To set up natd for the example above, perform the following steps:

  • Even if you don't plan to run an IP firewall, build and boot a custom kernel with the following options:
    options IPFIREWALL
    options IPDIVERT

    If you are running a firewall, configure the firewall normally, but be sure to include the IPDIVERT option.

  • Make sure your interfaces are running. For example, if you're running Kernel PPP and you want to specify ppp0 as your interface, start pppd before starting natd.
  • What you do next differs a little depending on whether you are also running a firewall or not. If you're not, you're better off with a separate script, which you might call /etc/rc.nat, with the following content:
    /sbin/ipfw -f flush
    /sbin/ipfw add divert natd all from any to any via dc0
    /sbin/ipfw add pass all from any to any
  • If you want to combine NAT with real firewall rules, you need only the second line of the previous example. Set up the firewall as described above, and put the NAT line at the start of the section of /etc/rc.firewall that you have chosen, so that natd sees all packets before they are dropped by the firewall. After natd translates the IP addresses, the firewall rules are run again on the translated packet, with the exception of the divert rules. The client configuration is the most likely one to suit your needs if you're using NAT. After the example in listing 22-1 on 390, you might add:
    #set these to your network and netmask and ip
    /sbin/ipfw add divert natd all from any to any via dc0
    #Allow any traffic to or from my own net. 
    ${fwcmd} add pass all from ${ip} to ${net}:${mask} 
    ${fwcmd} add pass all from ${net}:${mask} to ${ip}
  • Add the following to /etc/rc.conf:
    gateway_enable="YES"        # Set to YES if this host is a gateway.
    firewall_script="/etc/rc.nat"  # script for NAT only
    firewall_type="client"           # firewall type if running a firewall

    The interface name in the second line, dc0, is the name of the external interface (the one with the real IP addresses).

    If you're using NAT but not a firewall, you don't need to specify a firewall_type, because that relates to /etc/rc.firewall. You do need to specify the name of the script to run, however.

  • Enable your firewall as shown above in the firewall section. If you don't intend to reboot now, just run /etc/rc.firewall (or /etc/rc.natd) by hand from the console, and then start natd:
    sh /etc/rc.nat                                            for NAT only
    firewall_type=client sh /etc/rc.firewall   for NAT and firewall
    natd dc0

    The expression firewall_type=client tells the Bourne shell to set the value of the variable firewall just for this command. If you're using csh or tcsh, use the following sequence:

    (setenv firewall_type=client; sh /etc/rc.firewall)

    Never start this script from an X terminal or across the network. If you do, you can lock yourself out of the session in the middle of the script, causing /etc/rc.firewall to stop at this point, blocking all accesses to the system.

< Лекция 21 || Лекция 22: 12345 || Лекция 23 >