Linux Network Cheat Sheet

This is an rewrite of a much older post.

Some Linux distributions use a system called iproute2 to configure network interfaces, which is a more limited version of the standard Unix system based around ifconfig. The original Linux rewrite of ifconfig was less capable, so rather than bringing it up to Unix standards it was thrown out and a new one written. This lists common tasks that are possible of both, and their equivalents. NB. “eth0” is any network interface in the format your system uses.

TaskUnix standardLinux iproute2
List all interfacesifconfigip addr
List specific interfaceifconfig eth0ip addr show dev eth0
Bring up/down interfaceifconfig eht0 up (or down)ip link set eth0 up (or down)
Set IP addressifconfig eth0 192.168.1.10/24ip addr add 192.168.1.10/24 dev eth0
Configure using DHCPdhclient eth0dhclient eth0
Set IPv6 address
(syntax works with add/delete/alias etc)
ifconfig eth0 inet6 2001:db8::1 prefixlen 64
or
ifconfig eth0 inet6 2001:db8::1/64
ip -6 addr add 2001:db8::1/64 dev eth0
Add appletalk addressifconfig eth0 atalk 45.156ip --appletalk addr add 45.156 dev eth0
Set IP + netmask + broadcast (where defaults not suitable)ifconfig eth0 192.168.1.10 netmask 255.255.255.0 broadcast 192.168.1.255ip addr add 192.168.1.10/24 broadcast 192.168.1.255 dev eth0
Add alias (not explicit on Linux)ifconfig eth0 alias 192.168.1.2 netmask 255.255.255.0ip addr add 192.168.1.2/24 dev eth0
Delete specific IP (not possible on old Linux)ifconfig eth0 delete 192.168.1.2ip addr del 192.168.1.2/24 dev eth0
Rename interfaceifconfig eht0 name wan1ip link set eth0 down
ip link set eth0 name wan1
ip link set wan1 up
Show routing tablenetstat -rnip route
Add default routeroute add default 192.168.1.1ip route add default via 192.168.1.1
Delete default routeroute delete default 192.168.1.1ip route del default via 192.168.1.1
Show DNS serverscat /etc/resolv.confresolvectl status
Add DNS serverEdit /etc/resolv.conf:
nameserver 8.8.8.8
resolvectl dns eth0 8.8.8.8
Delete all DNS serversEdit /etc/resolv.confresolvectl dns eth0 ""
Set domain search orderEdit /etc/resolv.conf:
search example.com local.example.com
resolvectl domain eth0 example.com local.example.com
Show listening socketsnetstat -anss -tulnp
Show interface statusnetstat -iip -s link
Set mtuifconfig eth0 mtu 9000ip link set dev eth0 mtu 9000
View ARP cachearp -aip neigh show
Delete ARP entryarp -d 192.168.1.65ip neigh del 192.168.1.65 dev eth0
Delete ARP cachearp -d -aip neigh flush all

Notes

Old Linux ifconfig couldn’t remove a specific IP address but could remove them all using ifconfig eth0 0.0.0.0. You can get the same effect on iproute2 using “ip addr flush dev eth0”. Unix doesn’t have a command that’s quite so destructive.

If you add an alias address on the same subnet as an existing IP address, give it a netmask of /32.

Old Linux produced a routing table using route -n (not -rn) and you’d need to use “gw” when adding or deleting one (e.g. route add default gw 192.168.1.1)

On Solaris you need to add a -p between “route” and “add” – e.g. route -p add default 192.168.1.1

Most versions of ifconfig on Unix systems accept CIDR notation as an alternative to specifying “netmask 255.255.255.255” – for example “192.168.1.1/24

The ip command will usually infer which are IPv4 and IPv6 addresses but it can be made explicit using “ip -4” or “ip -6”. Likewise ifconfig normally doesn’t require “inet” or “inet6” to figure out which kind of IP address you’re giving it. -6 and inet6 have been used above to be 100% explicit. Linux supports fewer interface types than Unix.

It is not possible to delete or edit a single DNS server using the linux ip system, but you can delete them all and add back the ones you want.

On Linux, ip can only configure interfaces for IPv4 and IPv6 (i.e. it won’t support AppleTalk, ATM, Token Ring, or IPX etc.).

Making changes persist through boot

To configure an interface on boot on BSD use sysrc ifconfig_eth0="DHCP", for a DHCP address or edit rc.conf similarly. For a static address use ifconfig_bge0="192.168.1.123/24” and defaultrouter=”192.168.1.1” and add the nameservers to /etc/resolv.conf with a line like “nameserver 192.168.1.2” For Linux it’s much more complicated using other files or databases.

Debian/Ubuntu older versions

edit /etc/network/interfaces:

auto eth0
iface eth0 inet dhcp
For static address use:
auto eth0
iface eth0 inet static
address 192.168.1.123/24
gateway 192.168.1.1
dns-nameservers 192.168.1.2 192.168.1.3

Ubuntu with Netplan

edit /etc/netplan/01-netcfg.yaml (or similar):

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: true

For static address use:

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: false
      addresses: [192.168.1.123/24]
      gateway4: 192.168.1.1
      nameservers:
        addresses: [192.168.1.2, 192.168.1.3]

Red Hat/CentOS/Fedora (using network-scripts, older versions):

Edit /etc/sysconfig/network-scripts/ifcfg-eth0:

DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=yes

For static address use:

DEVICE=eth0
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.1.123
PREFIX=24
GATEWAY=192.168.1.1
DNS1=192.168.1.2
DNS2=192.168.1.3

Systems with NetworkManager

(e.g., Fedora, Ubuntu desktop), try ip first but if you have to, use nmcli:

sudo nmcli con mod "Wired connection 1" ipv4.method auto
sudo nmcli con up "Wired connection 1"

For static address use:

sudo nmcli con mod "Wired connection 1" ipv4.method manual ipv4.addresses 192.168.1.123/24 ipv4.gateway 192.168.1.1 ipv4.dns "192.168.1.2 192.168.1.3"
sudo nmcli con up "Wired connection 1"

Replace “Wired connection 1” with your connection name (list with “nmcli con show”, get lots of stuff to tweak with “nmcli con show eth0”. You may also use the name of the ethernet interface when you find it.

Systems with systemd-networkd:

Create or edit /etc/systemd/network/20-wired.network:

[Match]
Name=eth0

[Network]
DHCP=yes

For static address use:

[Match]

Name=eth0

[Network]
Address=192.168.1.123/24
Gateway=192.168.1.1
DNS=192.168.1.2
DNS=192.168.1.3

FreeBSD/Linux as Fibre Broadband router Part 3

In parts one and two I covered making the PPP connection, firewall and the DHCP server. This just leaves DNS.

Unbound

FreeBSD has stopped providing a proper DNS server (BIND – the Berkeley Internet Name Daemon) in the base system, replacing it with “unbound”. This might be all you need if you just want to pass DNS queries through to elsewhere and have them cached. It will even allow you to configure your local name server for hosts on the LAN.

To kick off unbound once run “service local_unbound onestart“. This will clobber your /etc/resolv.conf file but it keeps a backup – note well where it’s put it! Probably /var/backups/resolv.conf.20260103.113619 (where the suffix is the date and a random number)

For some strange reason (possibly Linux related) the configuration files for unbound are stored in /var/unbound – notably unbound.conf. By default it will only resolve addresses for localhost, so you’ll need to do a bit of tweaking. Assume your LAN is 192.168.1.0/24 and this host (the gateway/router) is on 192.168.1.2 as per the earlier articles. Add the lines to the server section so it becomes:

server:
        username: unbound
        directory: /var/unbound
        chroot: /var/unbound
        pidfile: /var/run/local_unbound.pid
        auto-trust-anchor-file: /var/unbound/root.key

        interface: 192.168.1.2
        interface: 127.0.0.1
        access-control: 127.0.0.0/8 allow
        access-control: 192.168.1.0/24 allow

        # Paranoid blocking of queries from elsewhere
        access-control: 0.0.0.0/0 refuse
        access-control: ::0/0 refuse

There is a warning at the top of the file that it was auto-generated but it’s safe to edit manually in this case. The interface lines are, as you might expect, the explicit interfaces to listen on. The access-control lines are vital, as listening on an interface doesn’t mean it will respond to queries on that subnet. The paranoid blocking access-control lines are probably redundant unless you make a slip-up in configuring something somewhere else and a query slips in through the back door.

Once configured you can now use 192.168.1.2 as your LAN’s DNS resolver by setting it isc-dhcpd to issue it. A add local_unbound_enable="YES" to your /etc/rc.conf file to have it load on boot.

BIND

Unbound is a lightweight local DNS resolver, but you might want full DNS. I know I do. Therefore you’ll need to install BIND (aka named).

We’re actually looking for BIND9, so search packages for the version you one. This will currently be bind918, bind920 or bind9-devel. Personally I’ll leave someone else to play with the latest version and go for the middle (bind9 version 20).

pkg install bind920

You’ll then need to generate a key to control it using the rndc utility (more on that later)

rndc-confgen -a

Next we’ll need to edit some configuration files:

cd /usr/local/etc/namedb

Here you should find named.conf, which is identical to named.conf.sample in case it’s missing or you break it. The changes are minor.

Around line 20 there’s the listen-on option. Set this to:

listen-on { 127.0.0.1; 192.168.1.2;};

Again, this assumes that 192.168.1.2 is this machine. That’s all you need to do it you want it to provide services to the LAN. While we’re in the options section change the zone file format from modern binary to text. Binary is quicker for massive multi-zone DNS servers, but text is traditional and more convenient otherwise.

masterfile-format text;

If you’re going to do DNS properly you need to configure the local domain. At the the end of the file add the following as appropriate. In this series we’re assuming your domain is example.com and this particular local site is called mysite – i.e. mysite.example.com. All hosts on this site will therefore be named as jim.mysite.example.com, printer.mysite.example.com and so on.

zone "mysite.example.com"
{
        type primary;
        file "/usr/local/etc/namedb/primary/mysite.example.com";
};

zone "1.168.192.in-addr.arpa"
{
        type primary;
        file "/usr/local/etc/namedb/primary/1.168.192.in-addr.arpa";
};

The first file is the zone file, mapping hostnames on to IP addresses. The second is the reverse lookup file. They will look something like this:

; mysite.example.com
;
$TTL 86400      ; 1 day
mysite.example.com        IN SOA  ns0.mysite.example.com. hostmaster.example.com. (
                                2006011238 ; serial
                                18000      ; refresh (5 hours)
                                900        ; retry (15 minutes)
                                604800     ; expire (1 week)
                                36000      ; minimum (10 hours)
                                )
@                       NS      ns0.mysite.example.com.

adderview1              A       192.168.1.204
c5750                   A       192.168.1.201
canoninkjet             A       192.168.1.202
dlinkswitch             A       192.168.1.5
gateway                 A       192.168.1.2
eap245                  A       192.168.1.6
eap265                  A       192.168.1.8
fred-pc                 A       192.168.1.101
ns0                     CNAME       gateway

This is the zone file. I’m not going to explain everything about it here, just that this is a working example and the main points about it.

The first lines, starting with a ‘;’ are comments.

Next comes $TTL, which sets the default time-to-live for everything that doesn’t specify differently, and is basically the number of seconds that systems are supposed to cache the result of a lookup. You might want to reduce this to something like 30 seconds if you’re experimenting. You must specify the default TTL first thing in the file.

Then comes the SOA (Start of Authority) for the domain. It’s specifying the main name server (ns0.mysite.example.com) and the email address of the DNS administrator. However, as ‘@’ has a special meaning in zone files it’s replaced by a dot – so it really reads hostmaster@mysite.example.com. I’ve never figured out how you can have an email address with a dot in the name.

The other values are commented – just use the defaults I’ve given or look them up and tweak them. The only important one is the first number – the serial. This is used to identify which is the newest version of the zone file when it comes to replication, and the important rule is that when you update the master zone file you need to increment it. There’s a convention that you number them YYYYMMDDxx where xx allows for 100 revisions within the day. But it’s only a convention. If you only have one name server, as here, then it’s not important as it’s not replicating.

Next we define the name servers for the domain with NS records. We’ve only got one, so we only have one NS record. The @ is a macro for the current “origin” – i.e. mysite.example.com.

Note well the . on the end of names. This means start at the root – it’s important. Some web browsers allow you to omit it in URLs, and guess you always mean to start at the root – but DNS doesn’t!

Then come the A or Address records. They’re pretty self explanaitory. Because the “origin” is set as mysite.example.com the first line effectively reads:

adderview1.mysite.example.com A 192.168.1.204

This means that if someone looks up adderview1.mysite.example.com they get the IP address 192.168.1.204. Simple! You can have an AAAA record that gives the IPv6 address, but I won’t cover that here.

The last line is line an A record but is a CNAME, which is defining an alias. ns0 is aliased to gateway, which ultimately ends up as being 192.168.1.2 – i.e. the name of our router/DNS server. There is nothing stopping you from having multiple A records pointing to the same IP address – and in some ways it’s better to use an absolute address. It comes down to how you want to manage things, and my desire to get a CNAME example in here somewhere.

The corresponding reverse lookup file goes like this:

; 1.168.192.in-addr.arpa
;
$TTL 86400      ; 1 day
@        IN SOA  ns0.mysite.example.com. hostmaster.example.com. (
                                2006011231 ; serial
                                18000      ; refresh (5 hours)
                                900        ; retry (15 minutes)
                                604800     ; expire (1 week)
                                36000      ; minimum (10 hours)
                                )
@       IN NS      ns0.mysite.example.com.

2       PTR gateway.mysite.example.com.
6       PTR eap245.mysite.example.com.
8       PTR eap265.mysite.example.com.
101     PTR fred-pc.mysite.example.com.
201     PTR c5750m.mysite.example.com.
202     PTR canoninkjet.mysite.example.com.
204     PTR adderview1.mysite.example.com.

As you can see, it’s pretty much the same until you get to the PTR records. These are like A records but go in reverse. In case you’re wondering about the name, it’s important. Note it’s the first three bytes of the subnet but backwards. The last byte is the first part of the PTR line, and the last part is the FQDN to be returned if you do a reverse lookup on the IPv4 address.

Therefore, if you reverse lookup 192.168.1.101 it will look in 1.168.192.in-addr.arpa for a PTR record with 101 as the key and return fred-pc.mysite.example.com.
This all goes back to the history of the Internet, or more precisely, it’s precursor caller ARPAnet. The .arpa TLD was supposed to be temporary during the transition, but it stuck around. Just do it the way I’ve said o or fall flat on your face.

You can have a reverse lookup for IPv6 using a ip6.arpa file, but I’m not going to cover that this time.

Once you’ve made all these changes and set up your zone file, just kick it off with “service named start” (or onestart). To make it start on boot add named_enable=”yes” to /etc/rc.conf

Debugging

You can test it’s working with “host gateway.mysite.example.com 127.0.0.1” and “host gateway.mysite.example.com 192.168.1.2” – both should return 192.168.1.2.

Error messages can be found in /var/log/messages – however they’re not always that revealing! Fortunately BIND comes with some useful checking tools, such a named-checkzone.

named-checkzone mysite.example.com /usr/local/etc/namedb/primary/mysite.example.com

This sanity checks the zone file (second argument) is a proper zone file for the domain name specified in the first argument. We’ve called the file after the domain, which can be confusing but has many advantages in other situations.

You can also check the reverse lookup file in the same way:

named-checkzone 1.168.192.in-addr.arpa /usr/local/etc/namedb/primary/1.168.192.in-addr.arpa

It’ll either come up with warnings or errors, or say it would have been loaded with an OK message.

Next Stage

In Part 2 I explained how to set up the OpenBSD DHCP daemon and here I’ve explained unbound as well as BIND. But for redundancy, the full ISC DHCP Daemon and BIND are necessary as they are able to replicate so one server can carry on if the other fails. That’s the next installment.

Systemd Network Configuration

Unless you’ve been living in a very Linux-free environment for a while, you’ll know about systemd – the collection of daemons intended to replace the System V init system commonly found on Linux, with something more complicated. I’m not a fan of System V startup, but they might have done better by going for the Research Unix or BSD /etc/rc approach for robustness, simplicity and compatibility. But Linux, to many, is a launcher stub for graphical desktops running LibreOffice and games, and these probably work better with systemd syntax when controlled by a simple GUI.

Systemd is more than an init system – in fact it has daemons from everything from the keyboard to DNS resolution – and network interface configuration (networkd)

This nightmare came out of Red Hat, and Linux distributions like Debian, Ubuntu, openSUSE, Arch, and their derivatives have started using it. One result, amongst other things, is that it’s suddenly not possible to configure networks the way you used to using ifconfig and /etc/resolv.conf.

You can install the missing ifconfig and suchlike using a package called net-tools, which is present on most major Linux distributions and is installed in the appropriate way (dnf, apt, yum etc). This may be the best way to keep scripts working.

Otherwise, you might be hoping systemd-networkd has simplified things, with less to type. But I’m afraid not.

So for those who are struggling, here’s a cheat sheet.

Names

The first think you’ll have to remember is that systemd-networkd doesn’t call your Ethernet interfaces eth0:, eth1. It doesn’t even call them by their driver name+enum BSD style. Instead it mungs a name from indices provided by the firmware, PCIe slot number and even the MAC address. Look out for some very strange interface names.

The idea is that the NIC/port has a predictable name, which is great in theory. I can see two problems: Firstly this doesn’t really help you find the RJ45 any better unless you have a schematic. Secondly, if you pull the system from one host and put it in another it all goes to hell in a handcart anyway. On the plus side I guess it means that adding or removing a NIC isn’t going to change the name of the existing ports.

For what it’s worth, eno# is an onboard device, ens# is a PCI slot index, enp#s# is port number on NIC and PCI slot index. enx1122334455667788 is the MAC address but this behaviour seems to be turned off on most systems. If it can’t determine anything it will fall back to eth#.

There are ways of selecting the old behaviour using kernel parameters or knobbling the /etc/systemd/network/… something “default” depending on system but you should check that out in the man page. Oh, hang on, this is Linux there probably no man pages.

Cheat Sheet

OldNew
ifconfig eth0 192.168.1.2/24ip addr add 192.168.1.2/24 dev eth0
ifconfig eth0 192.168.1.2 deleteip addr del 192.168.1.2/24 dev eth0
ifconfig eth0 netmask 255.255.255.0? Set address and netmask together ?
ifconfig eth0 mtu 5000ip link set eht0 mtu 5000
ifconfig eth0 down (or up)ip link set eth0 down (or up)
ifconfigip a
netstatss
netstat -rip route show
routeip r
route add default 192.168.1.254ip route add default via 192.168.1.254
arp -aip n
ifconfig eht0 name wan1? Not possible from command line ?

The last entry in the table is about renaming an interface, which given the user-hostile names now generated is even more useful. I haven’t figured out how to do this from the command line, but the assumption is that all interface configuration is done in configuration files by default, which brings us neatly on to these.

Configuring at startup

At one time you could just edit /etc/network/interfaces, and it might still work (it does int he latest Debian, for example). In BSD stick simple definitions in rc.conf, but that’s too easy. Anyway, /etc/network/interfaces could look something like this:

auto eth0
iface eth0 inet static
address 192.168.1.2
netmask 255.255.255.0
gateway 192.168.1.253

auto eth1
iface eth1 inet dhcp

After editing the configuration files(s) you could restart:

/etc/init.d/networking [start | stop | restart]

But some systemd Linux distributions are different. Systemd-networkd has a directory tree full of configuration stuff and I can only scratch the surface here.

Basically a load of *.network stored in /etc/systemd/network/ get run in sort order. It’s normal to prefix each file with two digits and a dash to set this order. I don’t think there’s any reason not to use a single file, but in the Linux world people don’t, often choosing to make the rest of the filename the NIC name, such as “04-enp0s5.network“, although the name you choose is only for your reference (or that of some GUI configuration tool).

To force every NIC to configure using dhcp create a file 02-dhcpall.network:

[Match]
Name=en*
[Network]
DHCP=yes

Note the wildcard on the NIC Name=*

On the other hand if you want to make one specific card static, have a file which you might want to call 01-enp5s2.network:

[Match]
Name=enp5s2
 
[Network]
Address=192.168.1.2/24
Gateway=192.168.1.254
DNS=192.168.1.254 8.8.8.8
Domains=example.com test.example.com

This should be fairly self-explanatory. You can specify multiple Address= lines (aliases) but for some reason DNS servers tend to be listed on one line, although multiple lines do work in my experience. I’ve used IPv4 in the examples but IPv6 works too.

Domains=example.com test.example.com is basically the DNS search domains (as normally found in resolv.conf). As systemd has its own resolver, systemd-resolved, it’s not just a matter of edit one file any longer, and is also less flexible.

You can restart systemd-networkd with:

systemctl restart systemd-networkd

If you haven’t made any mistakes you might still be connected to your server.

TP-Link 8-Port Gigabit Smartswitch review

There’s a tendency with any well-designed network for someone to go and do something the designer didn’t expect. A single desk with a couple of wall ports suddenly needs three network printers and a couple of PCs and an IP camera, and you’ve run out of sockets. The easy answer is to bung in a desktop switch, but once you’ve done this you’ve lost control, and visibility, about what exactly is going on downstream of your managed switch port.

In recent years a few desktop managed switches have appeared, and I’ve been looking at a reasonably priced TP-Link 8-port Gigabit Easy Smart Switch (model TL-SG108E to be precise). TP-Link have an “Easy” smart switch, and a non-easy versions (such as the TL-SG2008). I’ve yet to get my hand on the latter. They also make a JetStream range of layer 2 “Light” Managed Switch, which have a couple of SPF slots even in the 8-port models. Confusingly, the “light” versions are actually the top-of-range models.

TP-Link kit started turning up in the UK several years ago, with appalling technical support and documentation. It did tend to work, and was keenly price. I’m happy to say that TP-Link has got its act together, with proper English documentation and apparent backup, although I have to say I’ve yet to invest in anything expensive enough to make calling on their customer service worthwhile.

Unpacking the Easy Smart Switch you find a the neatly made metal boxed switch, with a good quality feel about it. The PSU is the normal quality wall-wort type, delivering just under 1A. Cooling is by convection away from the metal box; there is no fan and no apparent need for one.

You can use this switch as self-configuring switch straight out of the box and it just works. Testing it unscientifically as a desktop switch, I’ve no complaints about the performance. I didn’t try aggregating the lines for an uplink or anything fancy, as chances are on a desktop you’ll only have one port talking to another at any one time.

After that it was time to manage it, and this is where I hit a snag. In spite of the box saying it was compatible with Windoze, Mac, Linux and so on, it turns out that you need to run some Windows-based software to do anything with it. Although it had port 80 open, the is no web management interface; and port 22 was there but lacked an SSH interface. In other words, it’s useless unless you are a Windows shop. According to TP-Link there is a version 2 of this switch which does sport proper web and SSH interfaces, but version 2 isn’t on sale  in the UK at time of writing.

If you find a Windows PC to run it, you can set the IP address over Ethernet or set it up for DHCP. Once it’s on the IP network the configuration utility can be used to configure various options and run diagnostics – and upgrade the firmware, which you may want to do immediately looking at the release notes on the TP-Link web site.

Useful features are port mirroring, rate setting and (if you can figure it out), various VLAN options in including port-based. You can throttle ports, view port statistics and run a cable diagnostic. One serious omission is that there is no way I could see to control the layer 2 routing – i.e. statically assign a MAC address to a particular port. Only dynamically learned MAC addresses are supported, which is what you get a dumb switch for.

There are a number of security and QoS options, such as storm control for ports. Whether this is going to be used on a small unstacked desktop switch is debatable. The VLAN options could be very useful as part of a more complex multi-switch network, giving granularity down to the desktop.

Another feature inherited from it’s larger siblings is link aggregation. You can bond up to four ports together for a high-speed uplink; but on a a 5 or 8-port switch, this really can’t be that useful, can it?

If you can live without the access control and incompatibility with anything non-Windows, the price of this switch makes it an excellent choice net to a dumb switch at about the same price. However, for a few pounds more you a get a TP-Link SG2008, which doesn’t seem to suffer these limitations – or indeed a D-Link model of similar specification. D-Link switches tend to be fast and trouble-free in my experience.

Pros: Have a managed switch at the same price as an unmanaged one.

Cons: Management features provided are less use on a small switch, especially as access control is missing. The management can only be done using a Windows utility – no web or SSH interface.

Conclusion: Spend a bit more on a better TP-Link model, or look at D-Link or Netgear.