Chapter 12. Connecting to the Network

My tunnel is now up.
I can do IPv6.
Me and three others.

All that theory of IPv4 and IPv6 is fine. Now let’s do something with it, and actually connect to a network. While dial-up connections work with OpenBSD, they’re not used much these days, so we’ll focus on Ethernet connections. Ethernet is the most common network type today, and the most common network interface on OpenBSD systems.

Most people have IPv4 connectivity, but IPv6 is increasingly important. If you can’t get native IPv6 to your network, you can use a tunnel to reach IPv6 address space and provide IPv6 to your clients. I’ll cover acquiring and configuring such a tunnel in this chapter.

Finally, OpenBSD can combine network connections into trunks or split them into virtual local area networks (VLANs). This chapter covers both approaches.

You’ll probably want to use hostnames rather than IP addresses, so that you’ll be able to browse to http://www.cnn.com/ instead of http://157.166.255.18. Unix-like systems use the resolver to accomplish this feat.

Most hosts use two tools to map between IP addresses and hostnames: the hosts file and DNS. (Different operating systems support additional name services, such as YP, LDAP, NIS, and so on, but dang near every system supports these two.)

The hosts file is a text file on the local machine that contains static IP address and hostname lists. DNS is a more dynamic service that reaches across the network to find information. You can specify DNS servers by IP address, but we’ll look at the hosts file in a little more detail.

What if you prefer IPv4 or IPv6 addresses? Or you want the hosts file to override DNS? Maybe you have a default domain that your queries should use. The resolver searches until it either finds the first answer or has exhausted its information sources, so these questions matter. Tell your resolver your needs in /etc/resolv.conf.

The /etc/resolv.conf File

You configure the resolver behavior in /etc/resolv.conf. A system without /etc/resolv.conf can find only hostnames listed in the hosts file. Because the hosts file starts off empty, that’s probably not what you want. Start by specifying domain names.

Default Search Domains

If you wanted to ping a host on a remote network, you might expect to need to specify the whole domain. Entering ping www.openbsd.org should work. But if you wanted to ping your company’s web server, it would make more sense to just type ping www. And you can, because OpenBSD allows you to specify default domains, so that when you type in a short hostname, it will try to find the proper host.

For example, if you have only one local domain, you would list the domain keyword in /etc/resolv.conf like this:

domain michaelwlucas.com

Now, when I enter ping ftp, the resolver should get the IP address of the host ftp.michaelwlucas.com.

If you have more than one local domain, use the search keyword and a list of domains, like this:

search michaelwlucas.com openbsd.org

If I enter ping ftp now, the resolver should get the IP of the host ftp.michaelwlucas.com. Once the resolver learns that no such host exists, it will check for ftp.openbsd.org. Because that host exists, ping will start to work. The search keyword can have up to six domains, and can be no longer than 1024 characters.

The /etc/hosts file matches IP addresses to hostnames. While the hosts file is very simple, its contents are available only on the local machine. A hosts file is most useful on a small private network, such as in your home or test lab. You can also use a hosts file to override data from the DNS server, such as when you want to test a new system.

Each line in /etc/hosts represents one host. The first entry on each line is an IP address. The second is the fully qualified domain name of the host. Following these two entries, you can have an arbitrary number of aliases for that host. I often add comments at the end of the line, prefixed with a hash mark (#).

There was a time when I had a small network at home with only four machines: the proxy/firewall, the wife’s desktop, my laptop, and the crash machine where I did stupid things. The hosts file looked like this:

192.0.2.1 1nat.blackhelicopters.org    2nat firewall gateway
192.0.2.8   boss.blackhelicopters.org     boss wife  3#don't crash
192.0.2.20  crashbox.blackhelicopters.org crashbox test
192.0.10.21 laptop.blackhelicopters.org   laptop mwlucas

The machine nat.blackhelicopters.org at 1 also had the names firewall and gateway at 2. I added a note to remind myself at 3 not to run security scanners against my wife’s desktop. (The machine crashbox is also called test.)

Any machine with this hosts table could find any machine listed in the hosts table by name. For example, I could run ping boss or ssh crashbox and reach the desired machine.

The hosts file works just fine for finding networked hosts, but whenever you add, remove, or change a machine, you must edit /etc/hosts on every computer. And every time you change an IP address, you must edit /etc/hosts on every machine.

Ethernet is a shared network, meaning that many different machines can connect to the same Ethernet and can communicate directly with each other. I’m going to assume that you’re using Ethernet as found in an average office or datacenter. Also, although Ethernet has been implemented over many different physical media, I’ll assume you’re working with CAT5 or better cable—today’s most popular choice. If you use some unusual media type, or your card supports multiple media, you might need to manually set your preferred media on your interface.

Ethernet is a broadcast protocol, which means that every packet you transmit can be sent to every host on the network (although most Ethernet hardware limits recipients). Either your network card or your device driver separates the data intended for your computer from the data meant for other computers. A section of Ethernet where all hosts can communicate directly with all other hosts, without involving a router, is called a collision domain or segment.

You connect Ethernet segments with hubs, which are hardware items that can physically connect many Ethernet hosts. Network hubs forward all received frames to all other network devices, and each host is responsible for filtering traffic. This is old-school Ethernet, which can be useful for debugging network issues.

Switches have largely supplanted hubs. Every Ethernet connection needs a unique identifier, called a MAC address (or sometimes an Ethernet address), which is a 48-bit number. Switches control the traffic sent to each host by filtering on the MAC and IP address of attached devices and (mostly) forwarding frames only to the devices they are meant for. Switching reduces the amount of traffic and load on each individual system by decreasing the amount of traffic each host must sort through.

On i386 and amd64 hardware, the MAC address is a property of the card. On some other platforms, such as SPARC, the MAC address is a property of the server itself. Both IPv4 and IPv6 use the MAC address to find other hosts on the local network.

Ethernet supports a variety of speeds. The slowest speed you’re likely to find today is 10 megabits per second (Mbps), but it’s quickly disappearing. Most people use either 10/100Mbps or 1 gigabit per second (Gbps), although you’ll see 10Gbps, 40Gbps, and 100Gbps Ethernet emerging.

The hosts and switch it’s connected to on your network must agree on the speed of their connection. If the OpenBSD host thinks that it’s connected at 100Mbps, but the switch thinks that the connection is 1Gbps, the connection will be flaky. While autonegotiation usually makes both sides agree on common settings (and is absolutely required for gigabit connections), you can manually set duplex and speed for 10/100Mbps connections. Although some switch vendors are notorious for poor autonegotiation, you should let your Ethernet configure itself whenever possible.

Duplex determines if a card can both transmit and receive data simultaneously. A half-duplex connection means that the Ethernet card is either transmitting or receiving at a given instant; it cannot do both. A full-duplex connection can both send and receive simultaneously. As with connection speed, if the switch and host disagree on the duplex setting, the connection will be flaky. Gigabit Ethernet connections involve much more than speed and duplex, and they must be autonegotiated.

Just because a device says that it can use the protocol defined as 10/100Mbps Ethernet doesn’t mean that it can use that protocol with any speed. Also, a card labeled “1Gbps” might not actually pass a gigabit per second. Some network cards will pass their stated amount of traffic, while others will stagger and stumble at a few percent of that. Switch quality varies widely, too.

This may make more sense if you think of an Ethernet’s stated speed as a language. For example, I could claim that I speak Russian and German, but I stopped studying foreign languages in 1985. When I went to Germany in 2007, I managed about three words a minute—with the aid of a translation card and phrase book. If I were an Ethernet card, the manufacturer would claim I spoke German and Russian, and ship me to Siberia.[33]

Get decent hardware. Don’t ask on the OpenBSD mailing list, though. Someone has asked about hardware recommendations in the past few months. Check the archives. The advice hasn’t changed.

Configuring Ethernet

When configuring Ethernet for client computers, if your IPv4 network offers DHCP, you should be able to plug right in. If you’re using IPv6, you should be able to attach the cable and let autoconfiguration take over.

If a particular machine will be a server, a static IP address probably makes more sense. Before assigning a static address, you’ll need the following:

Armed with this information, attach your system to the network and keep reading. I’ll first discuss using ifconfig(8) and route(8) to perform changes manually, and then review how to set these automatically at boot. In any case, you must configure the resolver as discussed at the beginning of this chapter.

If you installed OpenBSD over a network, your Ethernet connection should already be working, but it might not be set up exactly the way you like. To manage your network interfaces, use the ifconfig(8) tool.

Let’s look at your Ethernet card and see what it has to say. Start by asking your system about all of the interfaces it has installed, by running ifconfig.

All OpenBSD systems have three logical interfaces out of the box: lo0, enc0, and pflog0. The lo0 interface is the loopback interface, referring to the local machine. The enc0 interface is an encapsulation interface, intended for IPsec traffic. Finally, pflog0 is for logging PF traffic, as discussed in Chapter 22. The rest of the interfaces are physical ones.

Unlike some operating systems, OpenBSD network interfaces are named after the device driver of the underlying hardware. Here’s a sample list:

$ ifconfig
fxp0: flags=8843<1UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:16:36:c0:58:a5
        priority: 0
        groups: egress
        media: Ethernet autoselect (100baseTX full-duplex)
     2 status: active
     3 inet 192.0.2.226 netmask 0xffffff00 broadcast 192.0.2.255
        inet6 2001:db8::216:36ff:fec0:58a5 prefixlen 64
        inet6 fe80::216:36ff:fec0:58a5%fxp0 prefixlen 64 scopeid 0x2

The interface fxp0 uses the fxp(4) device driver, which the man page says is an Intel EtherExpress PRO 10/100 card. As you can see at 1, the interface is up, meaning that it’s active and ready to use. The lladdr is the link local address, or the MAC address of the card. This card is in the egress group. OpenBSD uses interface groups in several places, including the packet filter, as discussed in Chapter 22.

To see the type of physical media underlying the connection, check the media line. This particular connection runs at 100Mbps full-duplex. The connection is active, as shown at 2; the physical layer has not only been configured, but it also has a link light and is ready to go. The connection has been assigned an IPv4 address and netmask, as shown at 3. You can see on the two lines that follow that both an IPv6 address and a link local IPv6 address have been assigned.

Use ifconfig to assign, change, or remove IP addresses from a network interface. The OpenBSD installer offers to configure your network cards at boot, but if you didn’t configure all of your interfaces during installation, or if you add or remove network interfaces after installation, you will need to do so manually.

One network interface can respond to requests for multiple IP addresses, which is important because a server might support hundreds or thousands of domains and need an IP address for each. (This isn’t so important for plain websites, but it can be important for SSL-based websites and protocols that rely on reverse DNS.)

To add extra IP addresses to an interface, use IP aliases. IP aliases tell a network card to “answer requests for this IP address as well as your own.” To add aliased IP addresses, use ifconfig with the keyword alias after the interface name to tell ifconfig this is an alias. Be sure to always use a netmask of 255.255.255.255, or /32, for alias addresses.

# ifconfig fxp0 alias 192.0.2.230/32
# ifconfig fxp0
…
        inet 192.0.2.226 netmask 0xfffffff0 broadcast 192.0.2.239
        inet 192.0.2.230 netmask 0xffffffff

The interface listed here has a main IP address of 192.0.2.226 and an alias IP address of 192.0.2.230.

When working with IPv6, add the inet6 keyword, like this:

# ifconfig fxp0 inet6 alias 2001:db8:0:12::3/64

It’s important to realize that all outgoing connections on a host with one network connection use the host’s primary IP address. For example, you might have 2000 IP addresses bound to one interface, but when you ssh out, the connection comes from the primary address. Remember this when writing firewall rules and access control lists, because while some programs have an option to set a different source IP address, they’re the exception.

The OpenBSD kernel doesn’t really differentiate between the primary IP addresses and aliases—it just keeps a list of IP addresses—but it will use the first address on its list as the source address unless told otherwise. If a host has multiple network connections, the source address of outgoing connections is the main IP address of the network interface on which packets leave the system.

To remove an alias, use the delete option of ifconfig and give the IP address, without the netmask.

# ifconfig fxp0 delete 192.0.2.230

For IPv6, use inet6 delete instead.

# ifconfig fxp0 inet6 delete 2001:db8:0:12::3

While ifconfig(8) is fine for changes on the fly, your system should configure its interfaces correctly at boot, including any aliases on the interface, any routes added when the interface comes up, and so on.

Each interface has a configuration file, /etc/hostname.interfacename, generically called hostname.if. The fxp0 interface on my desktop uses a configuration file /etc/hostname.fxp0, my wireless interface wpi0 uses /etc/hostname.wpi0, and so on. At boot, OpenBSD’s /etc/netstart script reads all of the hostname.if files and, if it finds a matching physical interface or can create a matching logical interface, it configures the interface accordingly.

To configure an interface’s IPv4 address, enter a line in hostname.if in this format:

 inet ipaddress netmask broadcastaddress ifconfig-options

The broadcast address and options are optional. To use options but not specify a broadcast address, use NONE for the broadcast address. You can also use a slash for the netmask instead of the decimal equivalent.

Similarly, add an IPv6 address with the following:

inet6 ipv6address/prefix ifconfig-options

To give fxp0 the IPv4 address of 192.0.2.226 255.255.255.240 and the IPv6 address of 2001:db8:0:12::2/64 at boot, use the following in /etc/hostname.fxp0:

inet 192.0.2.226 255.255.255.240 NONE description 'top card'
inet6 2001:db8:0:12::2/64

Here, I also define an interface description that will show up in ifconfig output.

To create an IP address alias at boot, use the alias keyword in hostname.if.

inet alias 192.0.2.230/32
inet6 alias 2001:db8:0:12::3/64

To run a command when the interface comes up, put an exclamation point in front of the command. Any commands run must be available on the root partition (for example, in /bin or /sbin). This feature is most commonly used for routing, but you could use other commands as well.

!route add 192.0.2.128/25 192.0.2.2

To configure an interface dynamically, via DHCP (IPv4) or rtsol (IPv6), put the string dhcp or rtsol on a line by itself.

dhcp
rtsol

Anything that’s not formatted as shown here is passed unedited to ifconfig(8). For example, to run a specific ifconfig command, put the arguments on their own line in hostname.if.

description 'lower card'

If you simply want to activate a card, but not configure it, use the word up on a line by itself to activate the interface.

up

And remember, you can test hostname.if changes with /etc/netstart, specifying an interface name if appropriate, like so:

# /bin/sh /etc/netstart fxp0

Not including the interface name reconfigures all interfaces on the system.

Servers can have redundant hard drives, power supplies, and so on. OpenBSD supports redundant network connections by combining multiple Ethernet links into a single virtual link, or trunk. You might also know of this as link aggregation, network adapter teaming, or bonding.

To use multiple physical links as a single large link, you need a way to distribute traffic between the links. OpenBSD supports five different ways to distribute frames between trunk members, though not all will work in all environments. For a complete list see trunk(4), but the protocols I recommend for real-world use are Link Aggregation Control Protocol (LACP), roundrobin, and failover. LACP is the industry standard for link aggregation. The physical interfaces are bonded into a single virtual interface with roughly the same bandwidth as the sum of the individual interfaces. LACP is very fault-tolerant, and just about every high-end managed switch should support it. If your switch supports LACP, use it, but you must configure LACP on the switch ports before this kind of trunk will pass traffic.

In the roundrobin method, OpenBSD sends frames across the trunk’s active connections using a roundrobin scheduler. The trunk accepts incoming packets on any port, and a roundrobin scheduler rotates between the trunk connections, with error and edge handling added on top. Roundrobin trunks don’t need any special switch configuration; they just need two ports in the same VLAN.

In the case of failover, OpenBSD sends and receives all traffic over the first port in the trunk, and if that port fails, it switches to another active port. The failover method doesn’t give you any additional bandwidth, but requires absolutely no support from the switch, and it even works on old-fashioned hubs.

VLANs are a way to get multiple Ethernet segments on a single piece of wire. You’ll sometimes see this referred to as 802.1q, tagging, or a combination of these terms.

In OpenBSD terms, one wire can carry multiple networks, and by configuring an additional interface, you can talk to those additional networks as if they had their own private wire. The wire can still carry only so much data, however, so all VLANs and the regular network (or native VLAN) that share the wire share the same pool of bandwidth.

VLAN frames that arrive at your network card are like regular Ethernet frames, with an additional header before the Ethernet frame that says “This is part of VLAN number such-and-such.” Each VLAN is identified by a number. VLAN number 1 is usually the native VLAN—the VLAN that arrives without any tagging whatsoever. For convenience, I’ll use the word “tagged” to describe how the VLAN is delivered to your host.

How would you use VLANs in OpenBSD? Perhaps you have a network divided into multiple Ethernet segments, such as outside the firewall, server area, and desktop clients. Or you might have one OpenBSD host that needs direct access to all of these segments. You could route all of these networks over a single physical wire. You might eventually hit bandwidth problems, but if you’re pushing more than 1Gpbs through your server, you can afford a second network card.

Let’s say you’ve taken my badgering to heart and decided to experiment with IPv6, but your ISP doesn’t offer IPv6. How can you play with IPv6 when all you get is an IPv4 feed?

Many companies offer a free IPv6 tunnel service, where they will route you through an IPv6 tunnel over IPv4. They will even give you an IPv6 /64 at no charge, so you can configure your home network for IPv6.

While I generally avoid recommending vendors in this book, I do recommend Hurricane Electric’s IPv6 tunnel service at http://www.tunnelbroker.net/. Its web interface is intuitive, and it even provides configurations for OpenBSD clients.

You should now have some understanding of managing IPv4 and IPv6 on OpenBSD. While your brain is recovering from all this stuff, we’ll turn to the topic of managing add-on software in OpenBSD.



[33] Many people offer to ship me to Siberia. But they all forget to include a return ticket. Strange.