Andrey's Blog

Linux: System Configuration

Table of Contents

  1. What “System Configuration” Covers
  2. System Logging
  3. Users and Groups
  4. System Time
  5. Scheduling Tasks
  6. Cheat Sheet

1. What “System Configuration” Covers

Besides the kernel and services started at boot, a working Linux system depends on:

This note covers four areas built on those pieces: logging, users, time, and periodic tasks.


2. System Logging

Anatomy of a log message

A log message usually contains a timestamp, the host, the process name, its process ID (PID), and the message itself:

Aug 19 17:59:48  duplex  sshd[484]:  Server listening on 0.0.0.0 port 22.
└──────┬──────┘ └──┬──┘ └─┬─┘└┬┘   └───────────────┬───────────────┘
   Timestamp     Host  Process PID              Message

journald and syslog

On systemd distributions, systemd-journald collects messages from the kernel, services (their stdout/stderr) and the syslog API, and stores them in a binary journal. Some systems also run a traditional syslog daemon (e.g. rsyslogd) that writes plain-text files in /var/log.

 ┌─────────┐  ┌──────────────────┐  ┌─────────────┐
 │ Kernel  │  │ Services (stdout,│  │ syslog() API│
 │ (kmsg)  │  │ stderr)          │  │ (/dev/log)  │
 └────┬────┘  └────────┬─────────┘  └──────┬──────┘
      └────────────────┼───────────────────┘
                       ▼
             ┌───────────────────┐
             │  systemd-journald │
             └─────────┬─────────┘
          ┌────────────┴─────────────┐
          ▼                          ▼ (optional forwarding)
 ┌──────────────────────┐   ┌─────────────────────┐
 │ Binary journal       │   │ rsyslogd            │
 │ /var/log/journal     │   │ → text files in     │
 │ (or /run/log/journal)│   │   /var/log/…        │
 └──────────┬───────────┘   └─────────────────────┘
            ▼
       journalctl

Priorities (severity levels)

LevelNameLevelName
0emerg4warning
1alert5notice
2crit6info
3err7debug

journalctl -p err shows levels 0–3 (everything at err or more severe).

journalctl

With no options, journalctl shows the whole journal, oldest first, in a pager.

Filter by time

journalctl -S -4h                          # since 4 hours ago
journalctl -S 06:00:00                     # since 06:00 today
journalctl -S 2026-09-27                   # since a date
journalctl -S '2026-09-27 11:30:00'        # since date + time (quote it)
journalctl -S 2026-09-27 -U 2026-09-28     # -U = until

Filter by boot

journalctl -b             # current boot
journalctl -b -1          # previous boot
journalctl -r -b -1       # previous boot, newest first (-r = reverse)
journalctl --list-boots   # all boots in the journal

Filter by unit, field and content

journalctl -u cron.service          # one unit (= --unit=cron.service)
journalctl _PID=1                   # match a journal field: messages from PID 1
journalctl -N                       # list all field names in the journal
journalctl -F _SYSTEMD_UNIT         # list all values of one field
journalctl -g 'kernel.*memory'      # grep messages by regex
journalctl -k                       # kernel messages only (like dmesg)
journalctl -p err                   # priority err and worse

-g is case-insensitive when the pattern is all lowercase.

Output and maintenance

journalctl -f                       # follow live (like tail -f)
journalctl -e                       # jump to the end
journalctl -o verbose               # show all fields of each entry
journalctl -o json-pretty           # structured output
journalctl --disk-usage             # space used by the journal
sudo journalctl --vacuum-time=2weeks   # delete entries older than 2 weeks
sudo journalctl --vacuum-size=500M     # shrink the journal to 500 MB

Filters combine: journalctl -u sshd -b -p warning -S -1h.


3. Users and Groups

The kernel only knows numeric user IDs (UIDs) and group IDs (GIDs). User-space files map those numbers to names and store login details.

FileContentsReadable by
/etc/passwdUsers: name, UID, GID, home, shellEveryone
/etc/shadowPassword hashes and agingroot only
/etc/groupGroups and their extra membersEveryone
/etc/gshadowGroup passwordsroot only

/etc/passwd

One line per user, seven fields separated by colons:

juser:x:3119:1000:J. Random User:/home/juser:/bin/bash
└─┬─┘ │ └┬─┘ └┬─┘ └──────┬─────┘ └────┬────┘ └───┬───┘
  │   │  │    │          │            │          └── Shell
  │   │  │    │          │            └───────────── Home directory
  │   │  │    │          └────────────────────────── Real name (GECOS)
  │   │  │    └───────────────────────────────────── Primary group ID
  │   │  └────────────────────────────────────────── User ID
  │   └───────────────────────────────────────────── Password
  └───────────────────────────────────────────────── Login name

Password field values:

ValueMeaning
xThe real hash is in /etc/shadow (the normal case)
*The account cannot log in with a password
(empty)No password needed. Dangerous, avoid

UID ranges:

The exact boundaries come from UID_MIN / SYS_UID_MAX in /etc/login.defs.

/etc/shadow

juser:$y$j9T$...:20358:0:99999:7:::
└─┬─┘ └───┬───┘ └─┬─┘ │ └─┬─┘ │ │││
  │       │       │   │   │   │ ││└─ Reserved
  │       │       │   │   │   │ │└── Account expiration date
  │       │       │   │   │   │ └─── Days of inactivity allowed after expiry
  │       │       │   │   │   └───── Days of warning before expiry
  │       │       │   │   └───────── Maximum days between changes
  │       │       │   └───────────── Minimum days between changes
  │       │       └───────────────── Last change (days since 1970-01-01)
  │       └───────────────────────── Password hash
  └───────────────────────────────── Login name

/etc/group

disk:*:6:juser,beazley
└┬─┘ │ │ └─────┬─────┘
 │   │ │       └─── Additional members (comma-separated)
 │   │ └─────────── Group ID
 │   └───────────── Password (rarely used)
 └───────────────── Group name

The member list holds only supplementary members. A user whose primary GID (from /etc/passwd) is this group belongs to it even if their name isn’t listed.

Tools — don’t edit these files by hand

Editing /etc/passwd directly risks corrupting it, and other programs may write to it at the same time. Use the tools instead.

TaskCommand
Change your passwordpasswd
Set another user’s passwordsudo passwd juser
Change login shellchsh
Change GECOS/real namechfn
Create a usersudo useradd -m -s /bin/bash juser (adduser on Debian is friendlier)
Add user to a groupsudo usermod -aG wheel juser (-a is important: without it, all other supplementary groups are removed)
Delete a user (+ home)sudo userdel -r juser
Create a groupsudo groupadd devs
Add or remove a group membersudo gpasswd -a juser devs / -d
Safely edit the filessudo vipw, sudo vipw -s (shadow), sudo vigr
Show your IDs and groupsid, groups
Look up any user or groupgetent passwd juser, getent group disk

getent asks the system’s name service (NSS), so it also finds users from LDAP, SSSD or alternative files, not just /etc/passwd.

Group changes only apply to new logins. Log out and back in, or use newgrp groupname in the current shell.

Becoming another user

CommandEffect
su - juserStart a login shell as juser (needs juser’s password)
sudo commandRun one command as root (needs your password; rules in /etc/sudoers, edit with visudo)
sudo -iRoot login shell

Authentication itself (checking passwords, 2FA, etc.) is handled by PAM (Pluggable Authentication Modules), configured in /etc/pam.d/.


4. System Time

Two clocks

┌──────────────────────────┐              ┌──────────────────────────┐
│ Hardware clock (RTC)     │  read at     │ System clock (kernel)    │
│ battery-backed, keeps    │  boot ─────► │ what `date` shows, used  │
│ time while powered off   │              │ by all programs          │
│ (should be set to UTC)   │ ◄───── sync  │                          │
└──────────────────────────┘  hwclock     └────────────▲─────────────┘
                              --systohc                │ adjusts gradually
                                                       │
                                          ┌────────────┴─────────────┐
                                          │ NTP client               │
                                          │ chronyd (Fedora/RHEL) or │
                                          │ systemd-timesyncd        │
                                          └────────────▲─────────────┘
                                                       │
                                               NTP servers (network)

Commands

date                                   # current local time
date -u                                # current UTC time
timedatectl                            # time, zone, RTC, NTP status overview
sudo timedatectl set-timezone Europe/Berlin
sudo timedatectl set-ntp true          # enable NTP synchronization
timedatectl list-timezones
chronyc tracking                       # chrony: current offset/accuracy
chronyc sources -v                     # chrony: NTP servers in use
sudo hwclock --show                    # read the RTC
sudo hwclock --systohc                 # copy system clock → RTC

5. Scheduling Tasks

ToolUse for
cronClassic recurring jobs
systemd timersRecurring or delayed jobs with systemd features (logging, dependencies, catch-up)
at / systemd-runRun something once at a later time

cron

Each user has a crontab, which cron checks every minute.

crontab -e      # edit your crontab
crontab -l      # list it
crontab -r      # remove it entirely (no confirmation)

Crontab line format:

15 09 * * 1-5  /home/juser/bin/backup.sh
│  │  │ │  │   └── Command
│  │  │ │  └────── Day of week   (0–7, 0 and 7 = Sunday; 1-5 = Mon–Fri)
│  │  │ └───────── Month         (1–12)
│  │  └─────────── Day of month  (1–31)
│  └────────────── Hour          (0–23)
└───────────────── Minute        (0–59)
SyntaxMeaningExample
*Every value* * * * * = every minute
a,bList0 8,20 * * * = 08:00 and 20:00
a-bRange0 9 * * 1-5 = weekdays at 09:00
*/nStep*/15 * * * * = every 15 minutes
@daily, @reboot, …Shortcuts@reboot ~/start.sh

Notes:

systemd timer units

A timer is a pair of units: a .timer says when, and a .service with the same name says what.

┌─────────────────────────┐   activates   ┌─────────────────────────┐
│ backup.timer            │ ────────────► │ backup.service          │
│ [Timer]                 │               │ [Service]               │
│ OnCalendar=*-*-* 03:00  │               │ Type=oneshot            │
│ Persistent=true         │               │ ExecStart=/usr/local/   │
│ [Install]               │               │   bin/backup.sh         │
│ WantedBy=timers.target  │               └─────────────────────────┘
└─────────────────────────┘

/etc/systemd/system/backup.timer:

[Unit]
Description=Nightly backup

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target

/etc/systemd/system/backup.service:

[Unit]
Description=Run backup script

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

Enable the timer, not the service:

sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers                              # next/last run of all timers
systemd-analyze calendar 'Mon..Fri 09:15'          # test an OnCalendar expression
journalctl -u backup.service                       # job output is logged automatically

Useful [Timer] options:

OptionMeaning
OnCalendar=Wall-clock schedule (daily, weekly, Mon *-*-* 09:00)
OnBootSec=Time after boot
OnUnitActiveSec=Interval after the service last started
Persistent=trueRun a missed job at the next boot (like anacron)
RandomizedDelaySec=Random delay to spread load

Timers vs cron:

User timers go in ~/.config/systemd/user/ and are managed with systemctl --user. To let them run while you’re logged out, run loginctl enable-linger $USER.

One-time jobs

# at (needs the atd service running)
echo "/home/juser/bin/report.sh" | at 22:30
at now + 2 hours        # then type commands, finish with Ctrl-D
atq                     # list pending jobs
atrm 3                  # remove job 3

# systemd alternative: transient timer
systemd-run --on-active=30m /home/juser/bin/report.sh
systemd-run --on-calendar='2026-10-05 08:00' --unit=report /usr/bin/touch /tmp/ok

6. Cheat Sheet

TaskCommand
Logs from current / previous bootjournalctl -b / journalctl -b -1
Logs of one servicejournalctl -u name.service
Logs since a timejournalctl -S -4h, journalctl -S '2026-09-27 11:30:00'
Follow logs livejournalctl -f
Only errorsjournalctl -p err
Search messagesjournalctl -g 'regex'
List field names / valuesjournalctl -N / journalctl -F FIELD
Journal size / cleanupjournalctl --disk-usage / --vacuum-size=500M
Who am I, which groupsid
Look up a user or groupgetent passwd user, getent group name
Add user to a groupsudo usermod -aG group user
Edit passwd/group safelysudo vipw, sudo vigr
Password agingchage -l user
Time and NTP statustimedatectl
Set time zonesudo timedatectl set-timezone Europe/Berlin
Edit crontabcrontab -e
List systemd timerssystemctl list-timers
Test a calendar expressionsystemd-analyze calendar 'expr'
Run once laterat 22:30 / systemd-run --on-active=30m cmd