- Mar 15, 2002
You will need to address a fair number of issues when designing your network topology. If you do not plan, you will have a good deal of trouble getting things working correctly. A solid network topology map, complete with all the machines, business functions by IP address, routes, other network settings, and the driving business need are critical to establishing a successful VPN setup.
Dedicated vs. Dynamic IP Addresses
Because you are connecting machines across the Internet, the IP addresses of these machines are dictated largely by your Internet service provider. Your ISP will allocate to you one or more IP addresses that you will have available for Internet access.
If you have a dedicated connection such as a T1 or greater, you will likely be given an IP subnet by default. On the other hand, if you have DSL or a dial-up modem, most ISPs prefer to dole out IP addresses with the Dynamic Host Configuration Protocol (DHCP). This means your machine might have a different IP address each time you connect to the Internet.
It is not too much trouble for roaming clients to be given nonstatic IP addresses. When they dial up from their hotel, for example, they will simply point to the VPN serversay, bears.example.comand establish a connection. Unfortunately, supporting roaming users with nonstatic IP addresses means your VPN server cannot restrict the IP of the connecting machine.
Your VPN server, however, must certainly have a dedicated IP address; otherwise, your remote networks and users will never be able to find it. In our example, bears.example.com must resolve to the IP address on which your VPN server is listening. Although you could survive by changing your DNS entries each time your VPN server gets a new IP address, this is largely a hack. It also introduces an unnecessary level of complexity, and is time consuming.
Unless you want to spend a lot of time maintaining your DNS records, we highly suggest that you get a dedicated IP address from your ISP for all of your VPN servers.
If you are creating a host-network or network-network VPN, you will need to have different network IP ranges for each network you want to connect. In our sample network described at the beginning of this chapter, we have two interconnected networks. Chicago is 192.168.1.0/24 and Atlanta is 192.168.2.0/24.
We did not pick these networks entirely at random. These are a set of networks reserved for private internal use, specified in RFC 1918. By using only these networks, you are guaranteed not to have a conflict with a network that exists on the Internet. The "private" networks are as follows:
Number of Networks
Hosts Per Network
|172.16.0.0/16 through 172.31.0.0/16||16||65534|
192.168.0.0/24 through 192.168.255.0/24
We chose the 192.168.x.y networks for Chicago and Atlanta because they are small and only need to support about 20 hosts each, easily fitting within the 254 maximum allowed. We could have used subnets of the 10 or 172 networks instead, but we are lazy and would rather use networks that do not require custom subnetting.
Unless you have large blocks of IP addresses allocated to youwhich is very rare these daysyou should consider using RFC 1918 networks that are dedicated for internal use while using network address translation (NAT) on your gateway to the Internet. It is customary to use similar network numbers for all your internal networks, as we have in our sample network. You might even want to use conventions for your networksfor example, using 10.x.y.z for standard internal networks, 192.168.x.y for VPN links and dedicated lines, and so on.
The important thing is to make sure you pick networks that do not conflict with each other and to use the smallest subnetworks possible such that you do not run out of IP ranges.
If you are new to networking, you are probably wondering what all these /24 and /8 things are. These are called Classless Interdomain Routing (CIDR) blocks, and the network 192.168.1.0/24 is written in CIDR notation.
To understand this, let's start with a history lesson. In the beginning (we love saying that), the IP space was broken into the following blocks:
|16777214 hosts per network|
|65534 hosts per network|
|254 hosts per network|
|Available for multicast network protocols only|
Reserved for future use
There were 128 Class A blocks, each capable of supporting 16777214 hosts. There's no way a single network with 16777214 hosts could have any hope of good performance. Thus, networks were broken up into subnets. Hosts were put onto different subnets based on function or location, and routers connected the various subnets.
Let's say we take the Class A network 10.x.y.z and break it up into 256 Class B networks of the form 10.[0-255].y.z. Each network now has 65534 possible hosts (still a relatively unreasonable number from a management perspective).
By default, a host that saw that its IP address was 10.1.1.1 assumed it was on a full Class A and assumed that if it wanted to communicate with 10.2.2.2, they were on the same physical wire. To be able to correctly understand that 10.2.2.2 was on a different network, the concept of subnet masks was formed.
A subnet mask is simply a dotted quad (like an IP address) that signifies how much of an IP address is the network portion and how much is the host portion. The Class A networks have a default subnet mask of 255.0.0.0, the Class B networks have a default subnet mask of 255.255.0.0, and the Class C networks have a default subnet mask of 255.255.255.0.
To determine the network portion of an IP address, you can perform a bitwise (or Boolean) AND of the IP and netmask. To break our huge Class A network into 256 smaller networks, the administrators use a netmask of 255.255.0.0 instead of the default. Thus, the host 10.2.2.2 is on the 10.2.x.y network, and the host 10.1.1.1 is on the 10.1.x.y network.
A different way of viewing the subnet mask is to represent it in binary form. The common netmasks would be represented as follows:
The CIDR notation at the end is simply a shortcut you can use to specify an IP address and its netmask in one quick form.
Thus, our machine 10.1.1.1 with a netmask 255.255.0.0 could be written as 10.1.1.1/16. The number after the slash is simply the number of 1s in the binary form of the subnet mask.
You can pick any subnet that is more restrictive than the default (that is, you could not pick a subnet of 255.0.0.0 for 172.x.y.z) when designing your networks. Most people find it easiest to use one of the standard subnets /8, /16, or /24.
This makes recognizing the network portion easier because the network portion always falls at a byte boundary.
For example, 192.168.5.0/24 is clearly on a different network than 192.168.10.0/24 simply by reading the first three numbers.
Addresses and Subnets That Are Unavailable
Under ordinary circumstances, the first and last IP addresses of any subnet are not available for use by an actual host. The first is reserved to identify the network itself, and the last is used for the broadcast address of the subnet. Thus, on the 172.20.5.0/24 network, you can neither use 172.20.5.0 (this network) nor 172.20.5.255 (all hosts on this network).
Additionally, some network equipment might not let you use the first subnet at all, because it could cause confusion associated with having network and subnet addresses that are indistinguishable. If your hardware does not support using the first subnet, the entire 172.20.0.0/24 network is also off limits.
The most notable instances of this router behavior are older versions of Cisco's IOS. Unless you configured your router with the ip subnet-zero option, the first subnet was off limits. Cisco IOS >= 12.0 includes ip subnet-zero by default. If you are using IOS prior to 8.3, the configuration option is named service subnet-zero.
In general, you should pick the smallest subnet possible that enables you to host your current and expected hosts. Usually, this means using a /24 subnet.
There are two special cases in which you might use subnets that are even more restrictive. If you are creating a network with only two hosts, such as a dedicated line between two hosts, you might want to use a /30:
Here we have a network with only two hosts and no IPs left unused. Don't forget that the first and last are reserved for network and broadcast.
The other special case is a point-to-point link. In this case, you do not create a specific network at all; instead, you use a /32 (host) subnet. Take the following ifconfig output, for example:
$ ifconfig ppp0 ppp0 Link encap:Point-to-Point Protocol inet addr:192.168.254.254 P-t-P:192.168.254.253 Mask:255.255.255.255
Here we have a local address 192.168.254.254/32 that is connected via a point-to-point link to 192.168.254.253/32. This is commonly used for dial-up connections, but some of our VPNs will use this style of networking as well.
Sometimes you will find yourself in a position in which you have networks to connect that overlap. If this is because you planned poorly, you are now feeling the pain.
More commonly, this is caused by two companies merging. They both might have correctly picked networks from those available per RFC 1918, but they happened to pick the same ones. Ugh.
What do you do in this situation? Well, it's a nasty one. Changing all the IP addresses on one of the offending networks is certainly the cleanest option, though it might be time consuming. If you already allocate IP addresses with DHCP, you will be patting yourself on the back. You can simply change the DHCP server to use the new network and have machines reboot; they'll automatically be reconfigured. You must then only visit hard-coded machines and change them manually.
If changing IP addresses automatically is not an option, you can try to use network address translation (NAT) or port address translation (PAT) on your VPN servers to rewrite the outbound address. Let's say Atlanta and Chicago both use the same network addresses, 192.168.2.0/24.
If you configure Bears to rewrite all the Chicago addresses as if it came from itself, using a nonconflicting address (say, 192.168.3.1), Chicago machines will be able to access Atlanta machines even though they actually have the same network IP address conflicts. You'll need to perform some DNS trickery to supply Chicago hosts with fictitious IP addresses for the Atlanta hosts.
In short, it is possible, but you're going to need a network guru, some heavy planning, and many aspirin. In the end, you might just decide it's better to renumber one of the networks and save yourself the maintenance headaches of this horrible hack.
DNS for VPN
One often-overlooked requirement of a functioning VPN is DNS. For any host-network or network-network VPN, you will be enabling access to machines that are not available on the Internet at large. Unless you want to access machines only by their IP address, you want to have DNS work cleanly.
The easiest way to accomplish this is to create a new domain name for your internal networks. Let's say our company owns example.com, which we use for our external systems. We could create chicago.example.com and atlanta.example.com as internal domain names. We then would run a DNS server internally to support those domains.
Let's assume we install a DNS server on the internal machines Cubs and Braves. We can make Cubs authoritative for the chicago.example.com domain and Braves authoritative for the atlanta.example.com domain. We set up each machine to be secondary for the internal domains it does not serve, which will enable them to send updates cleanly between them.
You then configure Cubs and Braves to relay all other queries to an external DNS server (say, one at your ISP), making sure you have recursive queries allowed from internal addresses. You configure all your internal machines to use Cubs and Braves as their DNS servers, preferring whichever is on the local network to avoid sending DNS traffic across the VPN.
Let's say a user on Bulls wants the IP address for thrashers.atlanta.example.com. Cubs already knows the answer because it is a secondary DNS server for the domain. Should Bulls request the IP for http://www.buildinglinuxvpns.net, Cubs will forward the query to an external DNS server and return the answer to Bulls when it is received.
This situation works seamlessly for all hosts on networks that are connected via dedicated VPNs. The only tricky situation is supporting roaming users. Because those VPNs are created only periodically and the users might want to be connected to the Internet without using the VPN, you cannot hard-code their DNS setting to use the internal DNS servers.
If possible, configure their machines to use the internal DNS servers only when the VPN is active. This can be done by munging the ip-up script when using a PPP-related VPN, for example, or by any other method you desire to rewrite /etc/resolv.conf when the VPN is established.
The worst-case scenario (next to remembering IP addresses, that is) is to simply point first to an internal DNS server and then to an external server, as seen here:
$ cat /etc/resolv.conf search chicago.example.com example.com nameserver 192.168.1.10 # cubs nameserver 3126.96.36.199 # My ISP
The internal DNS server Cubs (192.168.1.10) is first in the list. If the VPN is available, Cubs will handle your DNS requests for both internal and external domains. If the VPN is not up, the DNS request to Cubs will fail, and your machine will then query 3188.8.131.52. This machine will be able to respond for all Internet addresses but not the internal chicago.example.com addresses. This is not a problem, however, because the internal addresses aren't available except when the VPN is running anyway.
You will experience some name-resolution lag when using such a setup when the VPN is not established. DNS queries contact hosts in the order specified in /etc/resolv.conf, only moving onto the next in the list after determining that the first server isn't responding. Some resolver libraries try to consider this and will stop asking a nonresponding server for a while.
As has been alluded to in the previous sections, we must make sure our hosts send their traffic to the correct hosts.
In the case in which you have a simple network connected to the Internet, from the viewpoint of one of the machines on the network, you usually have only two classes of hosts that are accessible.
The first class comprises those on the internal network, which can be contacted directly. The second class comprises all other hosts on the Internet, which you contact via your Internet firewall or gateway/router.
To set up routing for the hosts on our Chicago network, you need to do two things. First, you must assign IP addresses to their network interfaces. Second, you must add a default route to the gateway/router using the following command:
cubs# route add default gw 192.168.1.1
The preceding command shows how you can manually add routes. How you permanently set up a default route depends on your Linux distribution.
For example, Red Hat machines use the file /etc/sysconf/network, Debian uses /etc/network/interfaces, and so on. You can view your routing table with the netstat command. For example, the routing table on Cubs might look like the following:
cubs# netstat rn Destination Gateway Genmask Flags MSS Window irtt Iface default 192.168.1.1 255.255.255.0 UG 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
Based on this routing table, all traffic originating from Cubs destined for 192.168.1.0/24 (the internal network) is sent directly to the eth0 interface. All other traffic originating from Cubs is sent using the default route to the gateway, 192.168.1.1. The gateway then performs NAT, if necessary, and forwards the traffic to its destination on the Internet.
Explicit VPN Routing Configuration
We've discussed three potential VPN and firewall topologies. In the case in which your VPN and firewall are the same machine, it should be obvious that your default route should point to the firewall, which is also conveniently the VPN server. This machine should be smart enough to know where packets should go, and thus the client should need no configuration changes.
So, what do you need to do when the firewall/gateway and VPN server are separate machines? You could configure the client machines to explicitly route VPN packets to the VPN server. If our remote VPN network were 192.168.2.0/24 and our VPN server were 192.168.1.13, we would run the following:
cubs# route add -net 192.168.2.0/24 192.168.1.13 cubs# netstat rn Destination Gateway Genmask Flags MSS Window irtt Iface default 192.168.1.1 255.255.255.0 UG 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.2.0 192.168.1.13 255.255.255.0 UG 0 0 0 eth0 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
Creating these VPN-related routes explicitly means you can clearly see exactly where your packets should go. It is a burden to set these up on each client, however.
The plain fact is that if you set up your firewall/gateway correctly, you have absolutely no need to explicitly define VPN-related routes on your client. We will see how this works in the next section.
Although explicitly defined VPN-related routes are not needed when you have a functioning VPN, they can be very helpful when setting up your VPN for the first time or when you need to debug problems.
If you are setting up a new VPN to connect to a remote network that is already available by other means (an existing VPN, a leased line, and so on), the only way to test the new VPN is by configuring static routes on one or more machines to test.
In the general case, however, you should avoid these static routes because they can only cause you headaches later should you change your network topology and find yourself fixing the routes on each and every client.
Centralized VPN Routing Configuration
If you prefer to configure your clients with a default route only rather than explicitly hard-coding each and every VPN-related route, we have good news for you: It's a cinch. Leave your client with the default gateway route and teach your default gateway the actual routes that should be used.
Let's say our firewall, 192.168.1.1, has the following routing table:
firewall# netstat rn Destination Gateway Genmask Flags MSS Window irtt Iface default 2184.108.40.206 255.255.255.0 UG 0 0 0 eth0 2220.127.116.11 0.0.0.0 255.255.255.248 U 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo 192.168.2.0 192.168.1.13 255.255.255.255 UG 0 0 0 eth1
Our firewall machine has local interfaces eth0 (the Internet segment) and eth1 (the internal segment). It has a default route to the Internet via 218.104.22.168 (the router to the ISP) and a route for our Atlanta network, 192.168.2.0/24, through 192.168.1.13, our internal VPN server.
The clients all point to our firewall as the default gateway, so when Cubs wants to establish a TCP connection to braves.atlanta.example.com (192.168.2.15) through the VPN, the following packets will be sent:
Packet # source dest tcpdump info 1 cubs firewall 04:43:55.731166 < cubs.1600 > braves.www: S 669411963:669411963(0) win 32120 <mss 1460,sackOK,timestamp 79542679 0,nop,wscale 0> (DF) 2 firewall cubs 04:43:55.912572 > firewall> cubs: icmp: redirect
braves to host bears [tos 0xc0] 3 cubs bears 04:43:55.931166 < cubs.1600 > braves.www: S 669411963:669411963(0) win 32120 <mss 1460,sackOK,timestamp 79542679 0,nop,wscale 0> (DF) 4 bears cubs 04:43:56.104105 > braves.www >cubs.1600: S
1678687708:1678687708(0) ack 669411964 win 1460 <mss 1460> (DF) 5 cubs bears 04:43:56.106602 < cubs.1600 > braves.www: . 1:1(0) ack 1 win 32120 (DF) 6 cubs bears 04:43:56.120659 < cubs.1600 > braves.www: P 1:8(7) ack 1 win 32120 (DF) 7 bears cubs 04:43:57.373603 > braves.www > cubs.1600: P 1:200(199) ack 8 win 2920 (DF)
The preceding list is the output of tcpdump (a packet sniffer) watching the packets. Here's an explanation of each packet:
Packet 1: Cubs sends a TCP packet to the firewall (its default gateway) with the final destination of Braves (192.168.2.15).
Packet 2: The firewall, which knows that the 192.168.2.0/24 network is served by a different machine (Bears) tells Cubs "Hey, send data destined for braves to the machine bears instead." This is called an ICMP REDIRECT.
Packet 3: Cubs resends the TCP packet to Bears with the final destination Braves (192.168.2.15).
Subsequent packets: Cubs will talk to Bears directly for all communication to Braves. Bears handles sending this through the VPN.
For your Linux VPN hosts to support ICMP REDIRECT messages arriving from a firewall, use the following:
root@fox # echo "1" > /proc/sys/net/ipv4/conf/all/accept_redirects
You can enable ICMP Redirects on the firewall as follows:
root@fox # echo "1" > /proc/sys/net/ipv4/conf/all/send_redirects
The ICMP REDIRECT is only needed for the first packet you want to send to a machine over the VPN. For the life of that connection, the client will automatically send the packets through the VPN server. There is no performance overhead to this configuration, save the one single ICMP REDIRECT at the beginning of each connection. As you can see from the timestamps in the tcpdump output earlier, this lag is hardly even worth mentioning.
We suggest that you configure all hosts to have a single default gateway and teach that gateway the VPN-related routes. This makes client configuration much easier because they need only the default route set up. It also means you have only one place you need to set up this route. If your firewall or gateway can exchange routing information with other routing hardware (via protocols such as RIP, OSPF, and so on), this makes the single point of configuration even more appealing.
VPN Server Behind a Firewall and NAT Traversal
If you use a routable IP address for the external interface (the one that is not on 192.168.1.0/24) of the Chicago VPN server, you can use the explicit or centralized routing configurations described earlier.
If you can't use a routable IP for the Chicago VPN server outside interface, you'll most likely need to get your VPN server to work over a NAT. Getting VPN solutions to work over NAT can be tricky.
For instance, for an IPSec-based solution, the easiest way is to have it work in tunnel mode. This is because one-to-one NAT mapping can be established (that is, the private IP address of the VPN server will be mapped to the routable IP address of the firewall). In transport mode, one-to-one mapping is a problem because packets can be coming from different IP addresses. Although a number of techniques have been proposed to deal with the problem, as of now, IPSec still does not have an official standard defining IPSec interoperation with NAT. (Check http://www.ietf.org/html.charters/ipsec-charter.html for more up-to-date information.)
Overall, NAT traversal is very implementation dependent and can be affected by a number of factors such as the transport protocols your VPN solution uses and so on. Your best bet is probably to consult the documentation and mailing lists for your particular VPN solution.
Trust is important in an environment in which security is a concern. (In a paranoid world, this would mean every environment.) Which systems you trust should be considered carefully, and even if you do trust a system, be sure to trust it as minimally as possible.
The principle of least privilege should be used on any system that is providing a service out to the Internet. This means don't give people outside of your network access to servers or services they do not need. In regard to VPNs, this means don't run any services that aren't absolutely necessary. Ideally, your machine that provided VPN access should be running only the VPN-related services, thus limiting the services that attackers could try to exploit.
Realistically, you will probably have to be running a service or two for management access to the box. To maintain security, these services should be of the encrypted variety: SSH instead of Telnet, SCP instead of FTP, and so on.
Further, access to these services should be limited to a small range of IPs, at least limited only to your local LAN. This could be done through TCP wrappers or your firewall but preferably should be done on both. A little bit of redundancy can buy you some additional time for damage control if someone manages to break in.
This section so far has discussed trust as it applies to outsiders trying to get in. We will next discuss trust as it applies to site-to-site and end-user VPN connections. You need to apply the principle of least privilege to these connections as well. The intent is not to mistrust the users on your VPN (although you might) but to minimize the possible business impact should one of the users' machines be compromised.
Limiting access to users can be done with the firewall of your choice on the VPN machine. There are two basic ways to limit access: by IP or by the inbound interface on the VPN server. The latter solution is a little more basic and does not provide as much control over the traffic. Most VPNs provide a local interface that is a logical entryway to the VPN. A firewall rule can be placed on this interface, limiting destination traffic. If you choose to limit by IP, you can restrict entire networks. This is useful if you have provisioned a certain range of IPs for a specific group of users.
For example, if you have given your sales team the IP network of 192.168.6.0/24 and it needs access to only one server, 192.168.1.100, you could use ipchains/iptables on your VPN server or firewall to restrict the sales network to access only that server. If you are concerned about security, you could further limit the access by application type. If in this example the sales team only uses that server for POP and SMTP connections, you could limit the access to port 110 and port 25.
Again, you will need to decide how much trust you will need for both your users and your Internet-facing servers. Hopefully, this section has imparted to the reader the importance of limiting trust as much as possible.