Foundations / Chapter 2

By the end of this chapter you should be able to

  • Log in over SSH and explain roughly what happened when you did
  • Find out what the machine is, what it is running, and what is listening on the network
  • Read the storage layout and say why the root filesystem may be smaller than the disk
  • Chase down three things on your own machine that you cannot immediately explain

Spend an hour surveying the machine before you install anything on it. Half of the "why is this broken" moments in the next ten chapters are things that were already true and nobody looked.

The installer also made decisions for you. Some are fine, some you will want to change, and you cannot tell which without looking.

Getting in #

The tool for this is ssh, short for secure shell. It gives you a shell on another machine over an encrypted connection, and it is thirty years old. The implementation nearly everyone runs is OpenSSH, and its manual pages are unusually good if you ever want the authoritative answer. If you already log in with ssh every day, skip ahead. If not, here is the shape of it.

$ ssh admin@192.168.1.20

That says: connect to the machine at that address, and log in as that user. If your network gives your server a name you can use that instead of the address. You will be asked for a password, or not, depending on what the installer set up.

You need the address

If you do not know it, the easiest ways are your router's list of connected devices, or plugging a screen and keyboard into the server once and running ip -brief addr. Later chapters give the machine a stable name so you stop caring about this.

Six things happen in order, and knowing them turns most SSH problems into "which stage failed".

Two details from that sequence matter later. The host key check happens before you authenticate, so a warning about a changed host key is not a login problem: your client is telling you the machine is not the one it met last time. Your identity is checked last, which is why a firewall problem hangs or refuses while a wrong password just asks again.

I cannot get in at all

Work out which stage of the connection is failing

Paste this into a new agent session. It carries everything the agent needs to know about where you are, and asks it to walk you through the problem rather than fix it for you.

I am trying to ssh into my server on my local network and it is not working. I do not know whether the problem is the network, the address, the SSH service, or my credentials.

Who am I, and what is this? #

Everything from here on runs on the server, in that SSH session.

Start with the machine's own idea of itself:

$ hostnamectl

That name is whatever the installer chose; chapter 3 changes it to one you picked.

hostnamectl is part of systemd, the thing that starts and supervises everything on a modern Linux system. You are going to meet it a lot, and its documentation is worth a browse once you have seen it in action. Four things from that output: the machine's name, the distribution and version, the kernel version, and the architecture. Those four facts decide which packages you can install and which documentation applies to you.

Now who you are:

$ id

Record three things from your output: the numeric user ID, which is what the kernel uses; the primary group; and the supplementary groups. Confirm that sudo is listed, because that is what permits this account to run approved commands as root.

Why not just log in as root?Show me why

Because root has no guard rails, and because everything you do as root leaves a log entry that says "root did it" rather than which person did it. Running as yourself and reaching for sudo when you need it means the dangerous commands are a deliberate act, and it means a mistake in a normal command cannot touch the system. The inconvenience is small and it prevents a whole category of mistakes.

Then the hardware:

$ lscpu | grep -E 'Model name|^CPU\(s\)|Architecture'
$ free -h
$ lspci | grep -i -E 'vga|ethernet|network'

Write down the CPU model, the core count, and the total memory. Memory is the resource you will run out of first, and knowing whether you have 8 GB or 32 GB decides how ambitious you can be about running a photo library with machine learning in it.

What is it running? #

A fresh server install is not empty. Ask systemd what it has started:

$ systemctl list-units --type=service --state=running

That is usually twenty to forty services. You do not need to understand all of them, but scan the list and see if anything surprises you. A desktop environment. A printing service. A database you did not install. Every one of those is software you have to keep patched.

Now the more pointed question:

$ systemctl list-units --state=failed

On a healthy machine that prints nothing. If it prints something, you have found your first puzzle, and I want you to chase it rather than ignore it. A failed unit on day one is the cheapest possible introduction to reading logs, because nothing depends on it yet.

Investigate every failed unit

A failed unit may be harmless, such as a service waiting for hardware that is absent, or it may be the first visible fault. Read its status and journal before deciding.

The tool for finding out why is journalctl, systemd's log reader:

$ systemctl status <the-unit-name>
$ journalctl -u <the-unit-name> -b --no-pager

-b means "this boot only", which is almost always what you want. The output is dense the first time. There is a short guide to reading it without drowning:

Side readingReading journalctl without drowningThe six flags that turn systemd's log from a wall of text into a useful answer.

Who can reach it right now? #

This is question one from the last chapter, and here is how you actually answer it.

$ ss -tlnp

The Process column is empty without sudo, which is the first thing to try if you were expecting names.

ss lists sockets, and it is the modern replacement for netstat (man page). The flags mean: -t TCP only, -l only things listening for new connections, -n show port numbers rather than guessing at names, -p name the process (which needs sudo to show anything useful).

The column that matters is Local Address. Read it as "which of my addresses will accept a connection on this port":

  • 127.0.0.1 or 127.0.0.53 is loopback. Only this machine can reach it. Something listening here is invisible to your network, which is often exactly right.
  • 0.0.0.0 means every local IPv4 address. Reachability still depends on routes and filters between the client and this host.
  • [::] is the IPv6 wildcard. A globally routed IPv6 address may be internet-reachable without IPv4-style port forwarding, so inspect and test both address families.

Classify every listener in your own output by address, port and process. On a fresh installation, account for SSH and any local resolver rather than assuming those are the only listeners.

A service is listening on 0.0.0.0:8080. Is it reachable from the internet?Show answer

Not necessarily. 0.0.0.0 means it accepts IPv4 connections on every interface of this machine. Internet reachability depends on upstream routing, NAT and filtering. A globally routed IPv6 listener does not need an IPv4-style port forward. Check the host firewall, router, public IPv4 and global IPv6 separately.

Then the network itself:

$ ip -brief addr
$ ip route

ip -brief addr lists the interfaces and their addresses; ip route shows where traffic goes by default. What you are looking for: which interface is actually up, what address it has (192.168.1.20 in this book), how big the subnet is, and which gateway it uses (192.168.1.1 here, and almost certainly your router). Note whether you are on wired or wireless, because wireless is convenient and slower and drops out, and moving to wired later will change the interface name and possibly the address.

Addresses move

Most home routers hand out addresses by DHCP with a lease. Your server can get a different one after a reboot, which breaks anything that referred to the old one. Two fixes exist: reserve the address in your router, or give the machine a static address. Either is fine, and a later chapter makes the whole question mostly irrelevant.

Where would data live? #

Question three. Storage mistakes take about a year to hurt.

$ lsblk -o NAME,SIZE,TYPE,MOUNTPOINTS
$ df -h /

Plain lsblk prints a few more columns and draws the tree with box characters; the explicit -o keeps it to what matters here.

Read lsblk as a tree of physical devices, partitions and any mapped volumes. Identify which branch ends at the filesystem mounted on / and compare that filesystem's size with the containing disk.

That last line is lvm, the Logical Volume Manager. Ubuntu's introduction to it is a decent half-page read. Instead of putting a filesystem directly on a partition, the installer put a volume group on it, and then carved a logical volume out of the group for the root filesystem. Logical volumes can be grown and snapshotted without touching partitions. Shrinking depends on the filesystem: ext4 can be shrunk offline with care, while XFS cannot be shrunk in place.

The logical volume can be smaller than its volume group on purpose. In that case lsblk shows the containing device while df shows the filesystem, and the difference can look like missing storage.

$ sudo vgs
$ sudo lvs

VFree is the answer: space in the group that no volume has claimed yet.

Why would you leave space unallocated?Show me why

Two reasons. Growing a filesystem is usually an online operation; shrinking may require downtime or may be unsupported, so claim space only when you need it. Snapshots also need free extents. An LVM snapshot gives you a crash-consistent block-level view. Quiesce or dump a database when you need application consistency, as chapter 11 does.

If your root volume already fills the group, nothing is wrong; you have given up snapshots and easy growth. And if you have unallocated space and want it, sudo lvextend followed by a filesystem resize will grow the volume while it is mounted. Do not do it yet. There is no data to run out of space for, and this chapter changes nothing.

Anything else worth knowing #

Two quick ones that matter later.

Time, because certificates, logs and authentication all care:

$ timedatectl

Check that the clock is synchronised and note the timezone. A server on UTC is perfectly sensible; a server whose clock is wrong will produce authentication failures that make no sense at all.

And graphics hardware, if you plan to serve video:

$ ls -l /dev/dri
$ lspci -k | grep -A3 -i vga

If /dev/dri/renderD128 exists, the kernel has bound a driver to a GPU and video transcoding on hardware is at least possible. The Kernel driver in use line tells you which driver got it. A device file existing does not prove anything works. Chapter 7 tests it properly. But its absence tells you now, cheaply, not to plan on it.

Your three puzzles #

Yours has oddities that documentation does not. Find them now.

Chase these down on your own machine

  • Any failed unit. Find out what it is for, why it failed, and whether you care. Write down the conclusion.
  • Something in lsblk you cannot identify. Small unexplained devices are common: card readers, firmware partitions, extra logical units on the same physical storage. Work out what yours are before you go anywhere near a command that writes to a disk.
  • The firewall. Run sudo ufw status verbose. It may say inactive, or active with rules you did not write. Either way, find out what it currently allows. Do not change it yet; chapter 4 configures it.

I found something I cannot explain

Investigate an oddity on my machine without changing anything

Paste this into a new agent session. It carries everything the agent needs to know about where you are, and asks it to walk you through the problem rather than fix it for you.

While surveying my server I found something I do not understand and I want to work out what it is before I touch anything. I will paste what I saw. Please help me identify it with read-only commands, and tell me whether it matters.

Write it down #

Fill this in as you go. Later chapters will ask you for these numbers, and future you will be grateful. It saves in your browser, and the copy button gives you a block of text you can paste into any of the prompts in this book.

Done when

  • You can log in over SSH without looking up the command
  • You can name your distribution, kernel version, CPU, memory and disk size from memory or your notes
  • You know exactly which ports are listening, on which addresses, and why
  • You know whether your machine is on wired or wireless, its address, and its subnet
  • You can explain why lsblk and df disagree about the size of your storage
  • You have investigated every failed unit rather than assuming it is fine
  • You know what your firewall currently allows
  • The fact sheet is filled in

What you picked up

  • Survey before you change. Most later surprises are things that were already true.
  • SSH does six things in order, and knowing which one failed is most of debugging it.
  • ss -tlnp answers "who can reach it" concretely. The listening address is the part that matters.
  • 0.0.0.0 covers local IPv4 addresses; [::] covers IPv6. Routes and filters determine who can reach either listener.
  • LVM is why your root filesystem can be smaller than your disk, and leaving space unclaimed buys you snapshots and room to grow.
  • Investigate failed units on day one, while nothing depends on them.

Settings

Your values

The book is written with placeholder names so it makes sense to everybody. Put your own in and every chapter, every command and every copy-paste prompt updates to match.

Nothing here is sent anywhere. It is saved in this browser, so it comes back next time. A different browser or a private window gets the placeholders again.

Live preview

$ ssh admin@192.168.1.20
$ sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp
$ sudo hostnamectl set-hostname homeserver
$ sudo timedatectl set-timezone Europe/Paris

Real commands from chapters 2, 3 and 4. They change as you type.

The account you log in as. Not root, and not necessarily the same name you use on your laptop.

Introduced in Chapter 2, Meet your server

The book's placeholder is admin

What the machine calls itself. You choose it, and it shows up in your shell prompt and your logs.

Introduced in Chapter 3, A safe front door

The book's placeholder is homeserver

The IP address your server has on your home network, from ip -brief addr.

Introduced in Chapter 2, Meet your server

The book's placeholder is 192.168.1.20

The address range and prefix shown by ip route or ip -brief addr, written in CIDR form. Copy the real prefix; do not guess /24.

Introduced in Chapter 2, Meet your server

The book's placeholder is 192.168.1.0/24

The address traffic goes to on its way out of your house, from ip route.

Introduced in Chapter 2, Meet your server

The book's placeholder is 192.168.1.1

In Region/City form, or Etc/UTC if you would rather read logs in UTC.

Introduced in Chapter 3, A safe front door

The book's placeholder is Europe/Paris

A registered name you control. Chapter 8 uses it for the LAN route; chapter 12 uses a separate private Tailscale name remotely.

Introduced in Chapter 8, One door, many rooms

The book's placeholder is example.com

The email identity allowed to administer the tagged server in your Tailscale policy.

Introduced in Chapter 10, Your own private network

The book's placeholder is you@example.com

The mailbox that should receive actionable home-server alerts.

Introduced in Chapter 14, Knowing it is alive

The book's placeholder is alerts@example.com

Once you save, the prose and the commands read with your names, the copy buttons copy your values, and the copy-paste prompts describe your machine accurately. That last one matters: an assistant told your network is 192.168.1.0/24 when it is not will send you chasing the wrong thing.

Anything you leave empty keeps the book's placeholder.