3 Days of Networking Troubleshooting – Day 2: Hand building a wired connection with and without DHCP support
Most Linux distros today will automatically configure your network as soon as you boot, more often than not, even while you install. However, you may find yourself on the wrong end of a configuration gone awry and be forced to set up networking on your computer by hand.
Conventions used in this guide
Throughout our command line tutorials, we use $
to indicate you can run the command shown as a regular user, and #
to indicate you must run the instruction as superuser/root or using sudo
.
When we show both the instruction and its output, what you have to actually type is shown in bold
.
In the first part of this series you saw how to troubleshoot your hardware and restart the network subsystem on your computer to get your network connectivity working. If you haven’t already done so, you should probably go and read that article now before tackling this one.
Done? Good.
Notwithstanding the above, it may so happen that the networking subsystem itself is messed up, or the servers on your network are not doing their job, or have crashed and burned. If you’re in that kind of situation, you will have no choice but to get down and dirty with the command line and configure stuff the… er… “new” old way. This will makes more sense in a minute, especially to GNU/Linux veterans.
If you have a typical home or small office set up, you’ll have a modem/router somewhere on your network running a DHCP server spewing IP addresses. The router will broadcast to the rest of the machines on the network and as soon as the networking hardware starts within your machine, it picks up the broadcast and requests an IP number from the router. Your router also tells your computer to use it to route packages to other networks, including the Internet — the name of the device is kind of a giveaway here.
It also typically designates itself as your DNS server, taking its cue from a couple or more online DNS servers usually set by your Internet provider. In short, if all works as planned, everything is done for you and Bob’s your uncle.
However, multiple obstacles can be thrown in your way to impede you claiming your legal status as Mr Robert’s nephew. If your router is switched on and your hardware is kosher, but you still can’t seem to connect to the internal net or the Internet, you may be suffering from one or several of the following three maladies:
- Your machine doesn’t have an IP address that identifies your machine on the network
- Your machine may not know of a valid route to guide its packages out onto the Internet
- Your machine may not have the address of a DNS server that allows it to identify sites using their URLs
To check for number 1, note that ifconfig
has been superseded by ip
(ifconfig
is still available in most distros, but it will be removed at some point, so we’ll focus on ip
). The ip
tool is the current Swiss army knife for nearly all things net related.
For example, run
$ ip addr
to get a list of network interfaces.
Now is when things get slightly tricky, because, as with the tools used for net-configuring, the interface naming system is in a state of flux. The Linux world is transitioning from the traditional eth0, eth1, and so on, to the new predictable naming convention — see the box on below — that names interfaces with monikers as apparently cryptic as enp5s0 or wlp4s0u1.
From ethX to enpXsY
The reason the naming system is changing is because the new convention helps developers predict what an interface will be called by the system form where it is connected on the hardware, hence the new system is known as predictable naming.
The old naming system was friendly enough towards end-users. It was easy to see at a glance that interfaces dubbed ethX mapped to Ethernet ports, and interfaces with wlanX in their names refered to WiFi devices. It may seem that making things apparently more complicated would be a step backwards from usability.
However, as the need for end users to configure networks through the command line has dwindled nearly to nil over the years, the slightly more complex naming conventions of the predictable system is not that big a deal, and it does simplify things for programming and scripting by a lot.
Say you had two or more wired network cards on one machine — common in, for example, racked servers. With the old system, it was awfully hard to know in what order the system would number them until after the fact. The new predictable system allows administrators and developers to know beforehand what name the system will give each interface and prepare scripts and programs with that in mind.
For example, in Arch, a distro at the forefront of implementing the new system, the default naming precedence rules are as follows:
- Names incorporating Firmware/BIOS provided index numbers for on-board devices (
ID_NET_NAME_ONBOARD
, example: eno1) - Names incorporating Firmware/BIOS provided PCI Express hotplug slot index numbers (
ID_NET_NAME_SLOT
, example: ens1) - Names incorporating physical/geographical location of the connector of the hardware (
ID_NET_NAME_PATH
, example: enp2s0) - Names incorporating the interfaces’s MAC address (
ID_NET_NAME_MAC
, example: enx78e7d1ea46da) - Classic, unpredictable kernel-native ethX naming (example: eth0)
Rule 4, by the way, is usually disabled in Arch by default.
From this, we can deduce that my very own enp5s0 interface corresponds to a card on PCI bus 5, slot 0, something you can quickly check by running lspci
:
$ lspci | grep Ethernet 05:00.0 Ethernet controller: Qualcomm Atheros AR8151 v2.0 Gigabit Ethernet (rev c0)
The 05:00
at the beginning of the line is giving you the bus and the slot for the network hardware.
This means that some distros, such as Debian Ubuntu, will still use the old system, and some, such as Arch, will use the new naming system. My own personal OpenSUSE seems to be in two minds about the whole matter and gives me
$ ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: enp5s0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000 link/ether 54:04:a6:7c:85:37 brd ff:ff:ff:ff:ff:ff 3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 74:e5:0b:96:33:62 brd ff:ff:ff:ff:ff:ff
In the output above, you can see three interfaces: the internal loopback interface lo that points a machine back to itself (you can always ping your own machine from your own machine); enp5s0, which would’ve been listed as eth0 (and still is in the likes of Debian or Ubuntu) in the olden days, is the interface to the Ethernet card; wlan0 is confusingly named using the old convention, and is the interface to my WiFi.
Whatever. The thing to focus on here is the information the output is giving us. Under the enp5s0 tag, you can see the interface is DOWN
and it has no IP address assigned to it. This means connection to the network is not going to work through that interface.
To get it up and running, you can try requesting an IP by executing
# dhclient
as root.
The dhclient application will run though your interfaces and look for DHCP broadcasts on the local network. When it finds one, it will request an IP and the other information your network needs to work properly.
As is, dhclient will not work with your WiFi interface because it doesn’t know what wireless network to hook up to or what password to use (we’ll see how this is dealt with in the third installment of this series), but it will work with your wired connection.
In the machine above, after running dhclient
the ip
output looks like this:
$ ip addr show dev enp5s0 2: enp5s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 54:04:a6:7c:85:37 brd ff:ff:ff:ff:ff:ff inet 192.168.1.100/24 brd 192.168.1.255 scope global enp5s0 valid_lft forever preferred_lft forever inet6 fe80::5604:a6ff:fe7c:8537/64 scope link valid_lft forever preferred_lft forever
Woohoo! The wired link enp5s0 is up and has an IP (192.168.1.100) assigned to it. To all effects, everything is now working: you can access the internal network and the Internet, since the DHCP takes care of configuring IP, routing, and DNS servers.
As the proof is in the pudding, now try pinging, say, google.com.
$ ping google.com PING google.com (216.58.211.238) 56(84) bytes of data. 64 bytes from google.com (216.58.211.238): icmp_seq=1 ttl=54 time=20.1 ms 64 bytes from google.com (216.58.211.238): icmp_seq=2 ttl=54 time=20.7 ms ...
Yep, we’re up.
DHCP Down!
If running dhclient
doesn’t work for you, it may mean you don’t have a working DHCP server on your network, or it is misconfigured, or has crashed for some reason. This forces you through the rite of passage every sysadmin has to face sooner or later, namely having to configure your wired network interface entirely by hand.
To do this you will need to know…
- … your router’s IP
- … the IP range used in your local network.
To avoid collisions, i.e. to avoid assigning an IP to your machine that is already being used by another computer on your network, you may also have to find out the IPs currently in use.
You can usually do all of the above by accessing your router’s web interface and checking out the network configuration section. My router is located at 192.168.1.1. Digging around the different tabs and menus, I discover that that the router assigns dynamic IPs from 192.168.1.100 to 192.168.1.254 for the DHCP to deal out. This means that we can safely use IPs 192.168.1.2 to 192.168.1.99 for manual configurations. I can also see that there are 11 machines using the network, and their IPs are all neatly listed on a table.
That was easy.
Starting from the scenario shown above, i.e. an unconfigured, downed wired network interface with no IP, the first step is to manually assign a random IP, say 192.168.1.66, to enp5s0. You do this by again using your trusty ip
tool, this time as root:
# ip addr add 192.168.1.66/24 dev enp5s0
Check the IP list and you should see something like this:
$ ip addr show enp5s0 2: enp5s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 54:04:a6:7c:85:37 brd ff:ff:ff:ff:ff:ff inet 192.168.1.66/24 scope global enp5s0 valid_lft forever preferred_lft forever
Notice that you can’t actually connect to anything yet since the interface is still down. Let’s sort that out:
# ip link set dev enp5s0 up
You can now ping the internal network — in this example, IPs between 192.168.1.1 and 192.168.1.254. If your router is 192.168.1.1, try pinging that.
At this stage you still can’t access anything outside your internal home network, that includes the whole of the Internet.
Route to Somewhere
Routing tells the interface where to go if it needs to send or receive packages beyond your internal network. In modern GNU/Linux systems you again use ip
to set this up:
# ip route add 0/0 via 192.168.1.1 dev enp5s0
This tells the networking subsystem to send and receive all packets for all networks (0/0
) through 192.168.1.1
, i.e. the router, using the enp5s0
interface.
You can now ping outside your network. Try pinging Google’s IP shown above (216.58.211.238), for example.
We’re nearly done. Just one more thing.
Domains
The DNS or Domain Name Service made up by one or more machines on a network that act like an automated telephone directory, associating URLs, commonly referred to (but somewhat incorrectly) as website names, to IP numbers.The DNS allows you to, for example, input the name of a website into your web browser, say ocsmag.com and have our website automagically pop up on you screen. Behind the scenes, what is really happening is that the DNS is looking up ocsmag.com in its databases. It finds the IP number of our servers, and directs your browser to that.
If your network configuration was so messed up you didn’t even have an IP for your computer, it is likely that you will not have DNSs configured correctly. This means that you won’t be able to, for example, ping Google by using its URL, google.com.
Try
$ ping google.com
and if that doesn’t work, you have this problem.
To set the DNSs, you need to edit the /etc/resolv.conf file. Open it up with your favourite text editor as root and add in the IP of a DNS server at the end of the file like this:
nameserver 8.8.8.8
You can now ping all the things!!!! In fact, your connection should now work normally.
You can, and maybe should, add in several more DNS server IPs to resolv.conf, just in case one fails. If one goes down, the networking subsystem will just pick up the next one in the list and you’ll never even know.
The DNS shown above belongs to Google, but there are plenty of lists of DNS servers online, even classified by country and reliability, if you would prefer to use something else.
Checklist
So, to recap, the steps to get your wired interface working are:
- Assign an IP to your wired interface with
ip addr
- Bring up the interface
ip link
- Configure routing with
ip route
- Set DNS servers by adding them to /etc/resolv.conf
Notice this configuration is temporary. As soon as your reboot or, indeed, restart the networking system with systemctl
, your networking will go down again, because, presumably, the problem is in the configuration somewhere.
But, hey! You’re online now, right? Learning how to fix your networking permanently is easy when you have Internet access.
Part 1 of this tutorial deals with checking your hardware and making sure the modules (drivers) to make it work were available. We also see how to restart the network subsystem in case it has crashed or failed to start.
Read here the third and final part of this series. In this installment we turn our sights onto WiFi connections. You learn step by step how to troubleshoot and set up a wireless connection manually, which in itself is a whole new kettle of fish.