User Tools

Site Tools


System Configuration


System startup works as follows:

  1. The BIOS decides on a boot device and loads the boot loader in its Master Boot Record (MBR), typically 512 bytes small.
  2. The boot loader (e.g. GRUB2) then starts the Linux kernel (and provides kernel parameters and boot options).
  3. Optionally: an init RAM disk (initrd) contains the most important kernel modules to load e.g. RAID controllers or file systems.
  4. After the kernel is initialized it starts the mother of all processes: init


LILO stores the disk sector where the kernel can be found in the boot loader. Therefore

  • the /boot partition must be located before sector 1024 of the hard disk, otherwise LILO can't address it;
  • LILO must be reinstalled after each kernel update;
  • it does not matter which filesystem is used, LILO completely ignores it

The main configuration file is /etc/lilo.conf

GRUB Legacy

GRUB uses two stages:

  1. stage1: the 512B in the MBR contain tools to initiate stage2
  2. stage2: with tools in /boot (supported filesystems are e.g. ext2/3/4, reiserfs) the Linux kernel is started
cat /boot/grub/menu.lst         # configuration file (with meta commands that control the behaviour of update-grub)
cat /boot/grub/       # device mapping file
cat /etc/grub.conf              # options, parameters,..
update-grub                     # tool that parses and write menu.lst



cat /boot/grub/grub.cfg         # generated configuration file (overwritten with update-grub, kernel-updates,..)
cat /etc/default/grub           # main configuration file
ls /etc/grub.d                  # directory with additional configuration files
cat /etc/grub.d/40_custom       # custom entries that update-grub will put in grub.cfg

With the following commands GRUB2 is installed in two steps - (1) generate a grub.cfg, (2) install GRUB to the MBR. Step 1 must be invoked after each kernel update - otherwise the kernel will not show up as an option during boot.

update-grub                     # generate grub.cfg (searches for installed OSes)
grub-mkconfig -o /boot/grub.cfg # same as update-grub
grub-install                    # install boot loader to MBR or partition

Shared Libraries

Shared libraries are used by most programs to save disk space, RAM space and for faster startup times (when library was already loaded by another program). Only programs for minimal environments are statically linked to avoid dependencies.

ldd program             # print required dynamic libraries of an executable
cat /etc/     # search paths for ldconfig (/lib and /var/lib are implicit)
cat /etc/    # cache with available dynamic libraries
ldconfig                # update with libraries found in paths from and $LD_LIBRARY_PATH


The host name is persisted in /etc/hostname and can be shown with hostname or (using the systemd-way) with hostnamectl.

To change the host name

  1. use sudo hostname <NAME> to set the host name now (would not survive a reboot)
  2. edit /etc/hostname to set it permanently
  3. edit /etc/hosts to properly map the new host name to localhost

Instead of the first two steps you can also use

hostnamectl set-hostname <NAME>

Date & Timezone

System Time

Linux has two clocks: hardware clock (aka BIOS clock) and a software clock (maintained by the Linux kernel). The software clock is initialized with the time of the hardware clock during boot time and written back to the hardware clock on shutdown. More details


The hardware clock can be read and set (by root only) with the hwclock command. The parameters --utc and --localtime tell if the hardware clock is / should be set to UTC or local time.

Note, however, that hwclock always prints and expects (when setting) date in local time.

hwclock (--show)         # show current setting
hwclock --systohc --utc  # set hardware clock from system clock (and use UTC)
hwclock --hctosys        # set system clock from hardware clock

Completely manual usage:

hwclock --set --date="2012-04-19 16:45:05" --utc
hwclock --set --date="2012-04-19 16:45:05" --localtime

The current time zone of the hardware clock is specified in /etc/adjtime, or UTC if the file is missing.


Changing the system clock (time + date)

date -d "2012-12-12T12:00" # print a date
date -s "2012-12-12T12:00" # set a date + time as system time
date +%T -s "14:30"        # only set the system time (not the date)

The string format interpreted as date is extremely versatile and described in info date, here are some examples:

date -d @1234567890       # Unix time / seconds since epoch
date -d "2014-01-01"      # ISO 8601
date -d "next Thursday"
date -d "2 years"         # now + 2 years
date -d "2 years ago"

The output format can be adjusted with format strings:

date +'%s'                # Unix time / seconds since epoch
date +'%Y-%m-%dT%H:%M:%S' # in ISO 8601

Network Time Protocol (NTP)

The best idea is to set the hardware clock via BIOS and let an NTP daemon take care of adjusting the system time. Ubuntu preinstalls ntpdate, but the more advanced ntpd is also available.

NTP synchronizes your system time with the ones from time servers (if it's not off by more than a few minutes). The NTP pool at provides a fail-safe address because it actually uses many different servers behind this address.


ntpdate is the standard tool to synchronize the software clock with NTP once. It requires a server to be provided at each call.

ntpdate-debian is a slightly modified version that can be configured via /etc/default/ntpdate. Ubuntu executes this program every time a network becomes available, see /etc/network/if-up.d/ntpdate.

sudo ntpdate-debian                # get NTP time from the configured server
sudo ntpdate          # get NTP time from a reliable cluster of NTP servers

The ntp daemon always runs in the background and can correct drifts slowly to avoid jumps in time.

It can be configured (e.g. change the NTP servers) via /etc/ntp.conf.

ntpq can query the status of the ntp daemon:

ntpq -p                            # print ntp peers & their state

System Time Zone

The system time zone is set in two places (which should match):

  • /etc/localtime contains the binary time zone specification (one of the files in /usr/share/zoneinfo)
  • /etc/timezone contains the human-readable POSIX timezone name

tzselect is an interactive program to let a user retrieve the appropriate POSIX timezone string for his location, e.g. “Europe/Vienna” for Austria. It does not change the time zone!

Setting via tzconfig

tzconfig was used to set the timezone, but on modern Debian / Ubuntu systems we use dpkg-reconfigure, which will run through the same questions as tzselect:

dpkg-reconfigure tzdata

This program copies the appropriate (binary) time zone info file from /usr/share/zoneinfo to /etc/localtime.

Other methods

Set the environment variable TZ to the appropriate timezone name, e.g. in ~/.profile

TZ='Europe/Vienna'; export TZ

Still more methods...

Quick Fix

Quickly fix the system time & timezone:

dpkg-reconfigure tzdata      # set proper timezone
ntpdate-debian               # get current time via NTP
hwclock --systohc --utc      # set hardware clock to (UTC) time retrieved from via NTP 


Locales enable internationalization and define e.g. number formats (LC_NUMERIC) or date and time formats (LC_TIME).

The default is set with LANG, which can be overriden with the more specialized LC_*. LC_ALL overrides everything else, and should not be set except for the execution of commands.

locale                  # print current locale settings
locale -a               # print names of available locales
locale -k LC_TIME       # print current formats for a locale setting
locale charmap          # print currently used charmap (e.g. UTF-8)

Generate locales

All available locales are listed in /usr/share/i18n/SUPPORTED. To use a locale it must be generated first with locale-gen:

locale-gen de_AT.UTF-8

Note, that locale-gen fails silently if an invalid locale is given. (return code 1)

Permanent settings

Locale variables are set in the configuration file /etc/default/locale. A great configuration for using the English language with ISO date/time format and european paper size (A4) is:


Note, that some programs ignore the settings in LC_PAPER and use /etc/papersize instead. Set a consistent format there as well, e.g. a4.

Note for KDE: the locale configuration tool will create the file ~/.kde/env/, which overrides /etc/default/locale - delete undesired settings there.

Temporary settings

To set a certain locale for one command only:

LC_TIME="en_DK.UTF-8" locale -k LC_TIME        # use specific locale for one command

It may also be useful to override all locale settings and use the most basic locale available on every machine: C or C.UTF-8:

LC_ALL=C.UTF-8 locale -k LC_TIME
LC_ALL=C.UTF-8 ssh host

More in-depth explanations

Partitioning & File Systems

In order to use a hard disk to install an operating system or store files it has to be

  1. each partition must have a file system

A special case are swap partitions (or files), which is basically very very slow RAM (memory) on the hard disk.

Filesystem Hierarchy Standard (FHS)

The Filesystem Hierarchy Standard (FHS) defines a common directory structure for Unix based OSes, which is important to be kept in mind during partitioning.

FIXME outline the basics:

  • /bin, /etc, /dev, /lib, /proc, /sbin: must be contained in one partition (used as root)
  • /boot, /home, /opt, /root, /tmp, /usr, /usr/local, /var: can be on different partitions

Creating Partitions & Filesystems


The programs fdisk and cfdisk can create a / alter the partition table in PCDOS format for disks up to 2TB.

Common partition IDs are: 5=extended, 7=ntfs, 82=swap, 83=linux.

fdisk /dev/sda                  # start partitioning of /dev/sda
fdisk -l /dev/sda               # list all partitions of /dev/sda
cfdisk /dev/sda                 # use a curses GUI for paritioning

For disks bigger than 2TB typically GPT - the GUID_Partition_Table - is used, which can be created with GNU parted. Read this good tutorial about disks with 4096 byte sectors

Create a file system
mke2fs                          # create an ext2/3/4 file system
mkfs                            # create a file system (ext and non-ext file systems) 
mkfs.ext4                       # mkfs.* are frontends that call the relevant programs to create a specific file system

The following two commands can be used to create an ext4 file system. The parameter '-n' can be used to simulate the action without actually changing anyting.

mke2fs -t ext4 /dev/sda1
mkfs.ext4 /dev/sda1
tune2fs - adjusting filesystem parameters for ext2/3/4
tune2fs -l <device>             # show stats & current value of options
tune2fs -L <name> <device>      # set volume name
tune2fs -i <interval> <device>  # interval between checks n[d|w|m], by default in days, e.g. 6m
tune2fs -c <count> <device>     # maximum mount-count between checks


The findmnt command and various files can be used to inquire the currently mounted devices and swap spaces.

lsblk                  # list block devices (i.e. no network or virtual devices)
findmnt                # show all currently mounted devices
findmnt -t ext4,cifs   # show mounted devices with a certain file system type
mount                  # show all currently mounted devices (deprecated!)
cat /etc/mtab          # ..
cat /proc/mounts       # ..
cat /proc/swaps        # show currently used swap spaces

The main configuration file is /etc/fstab:

cat /etc/fstab         # configuration of filesystems to mount (specifies location, file system type,..)
mount -a               # mount all devices in /etc/fstab except the ones set to 'noauto'
umount -a              # unmount all devices in /etc/fstab except the ones set to 'noauto'

The previously mentioned invocations and config files cover most of the daily use cases. More advanced use cases follow.

Manually mount a CDROM
mount -t iso9660 /dev/cdrom /mnt/cdrom
Manually mount an ISO file
mount -o loop -t iso9660 foo.iso /mnt/mountpoint
Manually mount a partition

Mount an ext4 partition with some restrictive mount options. See FILESYSTEM INDEPENDENT MOUNT OPTIONS in man mount for an explanation of all mount options.

mount -t ext4 -o nodev,noexec,noatime,nosuid /dev/sda1 /mnt/mountpoint 
Remount a partition read-only

This is e.g. useful for using fsck on a partition. Note, that this overwrites all mount options if the partition has been mounted manually - if there is an entry in /etc/fstab, ro will be added to the mount options specified there.

mount -o remount,ro /dev/sda1 /mnt/mountpoint
Mount certain file systems only

When combining -a with -t all file systems of a certain type in /etc/fstab can be selected (except if they are noauto of course). In this example we force (-f) unmount all cifs filesystems (Windows / Samba shares) and then mount them again.

umount -a -f -t cifs
mount -a -t cifs

Check & Monitor File Systems

The family of fsck.* (e.g. fsck.ext4) commands is used to check & monitor filesystems.

Note: file systems must be unmounted or at least mounted read-only, because fsck does not only check but also repairs the file system! Repairing a mounted file system can lead to severe problems.

fsck -N <device>                # dry run (only shows you what would be done) on a device, e.g. /dev/sda1
fsck -ARM                       # check all file systems in /etc/fstab, except root, and except all mounted ones
fsck -t ext4 -p <device>        # check a device with an ext4 filesystem and repair errors automatically (p=preen); same as fsck.ext4 -p

These two tools can be used to further inspect your ext file systems, but be careful with debufs!

debugfs <device>                # ext2/ext3/ext4 interactive file system debugger (use with care!)
dumpe2fs <device>               # dump ext2/ext3/ext4 filesystem information (super block & group information of blocks)

Disk Health


Badblocks is a utility to check disk health with either the non-destructive read-mode or the destructive (all data will be erased) write-mode.

sudo badblocks -wvs /dev/sdb

S.M.A.R.T. Monitoring

With smartctl (contained in the package smartmontools) you can check the health status of a hard disk.

sudo smartctl /dev/sda -H     # quick summary to see if HDD is OK or not
sudo smartctl /dev/sda -a     # print all SMART information

When printing all information the attributes are shown. VALUE and WORST should be above THRESH for the disk to be OK.

Vendor Specific SMART Attributes with Thresholds:
  1 Raw_Read_Error_Rate     0x002f   200   200   051    Pre-fail  Always       -       1305
  3 Spin_Up_Time            0x0027   141   141   021    Pre-fail  Always       -       3916


swapon -s      # see currently active swap partitions
mkswap         # set up swap (on a device or in a file, which must be created with dd)
(De)activate swap

For 'mounting' swap partitions or files extra commands are used:

swapon -a      # activate all swap partitions in /etc/fstab (except those with noauto set)
swapoff -a     # deactivate ..

Hint: use swapoff to move all memory back into RAM and to get a responsive system quickly (after the process that caused swapping is closed).

How to use a swap file

Create a 64M swap file in the current directory & check that it's activated

dd if=/dev/zero of=swapfile bs=1024 count=65536
chmod 600 swapfile
mkswap swapfile
swapon swapfile
cat /etc/swaps

System Startup


Runlevels were used in older distros to only partially start up the system. From single-user mode without networking, to multi-user mode with networking. Nowadays most distros don't use many different runlevels much anymore.


  • 0: halt
  • S: single user mode (often: 1)
  • 2-5: differs between distros, Ubuntu uses 2 as default
  • 6: reboot

The previous and current runlevel can be checked with runlevel. N stands for no previous runlevel.


Switching runlevels is done with telinit. In most distros init does the same.

telinit 2        # switch to runlevel 2
telinit 6        # reboot system

With shutdown reboots or shutdowns can be timed with either 'now', +<minutes> (e.g. +10), or hh:mm (e.g. 19:20). Other logged in users will be notified of a (pending) shutdown, no logins are possible five minutes before shutdown, and it is possible to specify a customized (optional) message.

shutdown -h now                                  # shutdown (halt or power off) now
shutdown -P now                                  # shutdown and power off now
shutdown -r +10 "message"                        # reboot in 10 minutes and send message
shutdown -k 20:00 "possible power outage at 8"   # 'fake' a shutdown. messages are sent, but no shutdown will be done
shutdown -c                                      # cancel pending shutdown
reboot, halt, poweroff

An alternative to the shutdown command are the following commands:

halt           # shut down OS, but do not power off (via ACPI)
poweroff       # shut down OS and power off (what you usually want)

Init Daemons

The binary /sbin/init is started first (hardcoded into the kernel) and therefore the mother of all processes. It starts all required processes during boot.

The 'original' Sysvinit is replaced in most distros as of 2013 with init systems that are event based (asynchronous).


Configuration via

/etc/init.d       # directory with startup scripts (nowadays still: legacy scripts)
/etc/inittab      # set default runlevel

Upstart is a Ubuntu-only event-based replacement for the original init daemon and brings some new tools and commands, but was replaced with systemd since Ubuntu 15.05.

Init scripts and scripts for services are contained in /etc/init. Services can be controlled like this:

service myservice start       # equivalent: start myservice
service myservice stop        # equivalent: stop myservice
service myservice reload      # equivalent: reload myservice
service myservice restart     # equivalent: restart myservice
service --status-all          # get status of all services

Modern event-based replacement for init, used by most distributions in 2015.

Init scripts are represented as service units in the form of .service files, which can be found in /lib/systemd/system (preinstalled) and /etc/systemd/system (to be edited by the admin).

Example of a .service file with the the three sections:




Starting and stopping services works as follows:

systemctl start myservice
systemctl stop myservice
systemctl status myservice

Logs of a service can be accessed via journalctl:

journalctl -u myservice

Package Management

The Linux way of (un)installing programs.

Debian (.deb)

Package management for debian is handled by the Advanced Packaging Tool (APT)

The configuration files specify (amongst others) which repositories are used for downloading packages:

/etc/apt/sources.list    # main config file
/etc/apt/sources.list.d  # directory with more configs (mostly for repositories with their own config file)

Since ~2014 the standard CLI tool is apt, which is a more modern version the older tools apt-get, apt-cache, etc. Most commands known from the older tools work in apt, but most of the times with nicer or more verbose output.

apt update        # synchronize list of available packages with server
apt search        # search for a package (partial name is OK)
apt install       # install packages (exact name required)
apt upgrade       # upgrade upgradable packages (not if new dependencies are required)
apt dist-upgrade  # upgrade upgradable packages (and install new dependencies if required)
apt list --installed # list installed packages
apt remove        # remove packages (exact name required) but leave config files
apt purge         # remove packages (exact name required) and config files

However, if you still need the stable lower-level tools they are still available too. This is also relevant for writing scripts, as of 2019 apt tells you WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

dpkg         # low-level tool to handle installations of single packages
apt-get      # medium-level tool to install / remove / update packages and their dependencies (uses dpkg)
apt-mark     # hold / unhold packages (aka apt pinning)
apt-cache    # medium-level tool to query the package cache

Finally there are also third party tools that provide similar functionality:

dselect                     # curses GUI for selecting and installing programs
aptitude                    # curses GUI and command line tool that unites apt-get, apt-cache and dselect
Advanced Usage

Some more advanced usage examples:

apt-cache depends package   # show dependencies (and suggestions) for a package
dpkg -l                     # list names of all installed packages
dpkg -L package             # list all files (full path) contained in a package
dpkg -s package             # show status of package (e.g. is it installed or not)
dpkg -S file                # show packages that contain this file (matching by name)

alien is a package converter that can convert .deb packages into .rpm and vice versa.

Red Hat (.rpm)

There is only one relevant tool for package managemnt in Red Hat: rpm. It has five basic modes:

rpm -i             # --install
rpm -U             # --upgrade
rpm -e             # --uninstall (erase)
rpm -V             # verify
rpm -q             # --query

Flags for (un)installing and upgrading:

--force            # force install/update, same as --install --force
--no-deps          # (un)install/update even if dependencies are not satisfied
--test             # just test and don't make any changes

Flags for querying:

-a  or  --all      # list all installed packages
-f  or  --file     # list the package a file belongs to
-l  or  --list     # list all files in a package
-i                 # information about an installed package
-p <package>.rpm   # query regarding the specific package-file
Advanced Usage

Some more advanced usage examples:

rpm -qR package             # show dependencies for a package
rpm -qa                     # list names of all installed packages
rpm -qlp package.rpm        # list all files (full path) contained in a package
rpm -qf file                # show packages that contain this file (matching by name)
Extract files from .rpm files

rpm packages can not be unzipped directly, but this can be achieved by using rpm2cpio and cpio. The following command extracts an rpm into the current directory:

rpm2cpio package.rpm | cpio -idmv


The 'yellowdog updater, modified' aka yum is a package management tool used in many distributions based on .rpm packages. Its usage strongly resembles aptitude:

check-update                # synchronize list of available packages with server
yum search                  # search for a package (partial name is OK)
yum update                  # update all packages
yum install                 # install packages (exact name required)
yum remove                  # remove packages (exact name required) but leave config files

yumdownloader downloads RPMs from Yum repositories. The relevant configuration file is /etc/yum.conf and the files in /etc/yum.repos.d.

User Management

user and group ids - uid & gid

Root always has uid 0, uids from 1 until e.g. 499 (RHEL) or 999 (Debian) are reserved for system use. Uids above that are used for regular users, e.g. 1000 for the first user on Debian.

The same goes for gid: root has gid 0,..

Every user has at least one group, the first group being the primary group.


User details are stored in /etc/passwd. The columns (separated by colons) are:

  1. login
  2. optional encrypted password (or 'x')
  3. uid (numerical user ID)
  4. gid (numerical group ID)
  5. comment (e.g. user name or daemon description)
  6. home
  7. shell (optional, set to /bin/false if no login should be possible)



Normally the password is not stored in /etc/passwd, but in /etc/shadow, which should only be readable by root. /etc/shadow consists of these colon-separated fields:

  1. login
  2. encrypted password (prepend with '!' to disable login)
  3. date of last password change (days since epoch)
  4. minimum password age (days)
  5. maximum password age (days)
  6. password warning period (days)
  7. password inactivity period (days) (how many days after a password change is necessary is the old password still accepted)
  8. account expiration date (days since epoch)
  9. reserved field

All fields except the first two can be left blank, thereby disabling password aging.

Example (with shortened password hash):


Get a human-readable representation of the expiration information with chage:

chage -l user

/etc/group consists of these colon-separated fields:

  1. group name
  2. encrypted password
  3. gid
  4. members (comma-separated list of users)

As for users the group password is normally not stored in /etc/group. Note, that the members in these two files are stored redundantly and must match.

/etc/gshadow consist of these colon-separated fields:

  1. group name
  2. encrypted password
  3. administrators (comma-separated list of users that can change the group password)
  4. members (comma-separated list of users)

Preferrably edit these important files with these tools to avoid concurrent editing and broken files (e.g. due to forgetting a colon).

vipw         # edit /etc/passwd
vipw -s      # edit /etc/shadow
vigr         # edit /etc/group
vigr -s      # edit /etc/gshadow

With getent you can “get entries from Name Service Switch libraries”, e.g. the passwd, group, shadow, gshadow databases. (quite similar to just greping the respective files)

getent passwd username

This directory serves as a template for home directories. When a new user account is created, the home directory will be populated with the contents of /etc/skel.

Add, remove, change users

The three standard tools are useradd, userdel and usermod.

Create a user
useradd name                # create a new user (without password; home directory is set, but not created)
useradd -m name             # also create a home directory (with contents of /etc/skel)
useradd -s /bin/bash name   # assign a shell
useradd -r name             # create a system user (uid <1000)
useradd -g gid -u uid name  # override default gid and uid (-o even allows uid-duplicates)

The password can be set with passwd or the -p option (but -p already requires the encrypted form to be stored in /etc/shadow)

Delete a user
userdel name                 # delete a user
userdel -f -r name           # force delete (even when logged in) a user and delete its home directory (-r)
Change basic user account details

usermod allows to change the parameters also available in useradd (and more):

usermod -u uid -g gid name      # change uid and gid for an existing user (ownerships in home directory are adapted as well)
usermod -d /home/newhome name   # change home directory (created if it does not exist)
usermod -md /home/newhome name  # change home directory and move all files from the old home
usermod -l newname name         # rename / change login of a user (does __not__ change the home directory)

Add, remove, change groups

The tools groupadd, groupdel and groupmod work similar to the user-counterparts:

Create a group
groupadd gname               # create a new group
groupadd -r gname            # create a system group (uid <1000)
groupadd -g gid gname        # override default gid (-o even allows uid-duplicates)
Delete a group
groupdel gname               # delete a group
Modify a group
groupmod -g gid -n newgname gname  # change gid and name of a group

Managing groups of a user

View and add groups for a user:

groups user                          # show all groups a user is part of
usermod -a -G group1,group2 user     # add user to comma-separated group(s)

Remove or exlicitily set groups for a user:

gpasswd -d user gname                # remove user from group
usermod -G "gname1,gname2" user      # explicitly set comma-separated group(s) for a user
vigr                                 # open /etc/groups in vi (locks the file & enforces correct format on save)

Group password

Groups can be assigned a password, which is stored in /etc/gshadow (or /etc/group). Group membership can then be temporarily acquired.

gpasswd gname                  # assign password to a group
newgrp gname                   # temporarily get membership for group

Group administrators are allowed to change/remove the group password and add or remove users to the group. They can be assigned as follows:

gpasswd -A "user1,user2" gname # assign administrator users to group

(Un)locking Users

Lock a user

Locking is done (by convention) by prepending a '!' to the password in either /etc/passwd or /etc/shadow, or one of these two commands:

usermod -L user
passwd -l user

Or by deleting the currently set password (this can not be undone)

passwd -d user
Unlock a user
usermod -U user
passwd -u user

User Account Limits

Account Expiration

The fields in /etc/shadow regarding passwords age or account expiration can be manipulated with chage.

After a password has been expired the user is forced to chage it at the next login. If an inactivity period is specified accounts with expired passwords will be locked after this period.

chage -m min -M max user        # set minimum and maximum nr of days between password changes
chage -I days user              # set inactivity period in days
chage -d 2014-01-01 user        # manually set date of last passwort change

An account can also have a fixed expire date:

chage -E 2014-01-01 user        # set expiration date of account, afterwards no login is possible (accuracy = days)

Passing -1 as value will erase the limits.


With the bash built-in ulimit resources allocated to a user can be limited for the current shell.

ulimit -a            # show all limits for the current user

With '-S' soft and '-H' (or no extra parameter) hard limits can be set. Soft limits can be raised up to the hard limit by the user. The hard limit can only lowered by the user.

ulimit -S -u 100     # set a soft limit for the maximum nr of processes
ulimit -n 50         # set soft & hard limit for the maximum nr of open files

A good place to set ulimits is /etc/profile, or in the config file /etc/security/limits.conf, where the configuration can be specific to a user or group (prepend @):

#<domain>      <type>  <item>         <value>
user           hard    nproc          100
@group         hard    nofile         50

sudo & su

sudo allows a normal user to execute commands as other user (also super user), with su the current user id can be changed to become super user (a root shell).

sudo passwd otheruser          # set password for otheruser usint root privileges
sudo -u www-data mkdir dir     # create a directory as user www-data

Who (or which groups) are allowed to do so is specified in /etc/sudoers, which must be edited with visudo and roughly follows the format user hostlist=(userlist) commands:

  • user: which user the permissions are for
  • hostlist: on which host (when sharing the sudoers on several hosts)
  • userlist: which identities the user may take
  • commands: which commands may be executed

Simple example:

# User privilege specification
root    ALL=(ALL:ALL) ALL
# Members of the admin group may gain root privileges
%admin  ALL=(ALL) ALL
# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

The format is quite complex, have a look in man 5 sudoers.

#On the ALPHA machines, user john may su to anyone except root 
# but he is not allowed to specify any options to the su(1) command.
john    ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*

User Monitoring

Who is/was logged in?

The programs w and who can show who is currently logged into the system.

w               # print users who are logged in and their processes
who             # print information about users who are logged in
who -b          # time and date of last system boot
who -r          # print current runlevel

last prints the last log ins (user, time,..).

last            # all recent logins
last username   # last logins of user
last tty1       # last logins on tty1

Who holds open files / ports?

fuser and lsof (list open files) can check which users or processes opened a file, file systems or ports. Note, that these programs should be run as root to get a full report (especially when checking ports)!

lsof                        # list all files opened by active processes
fuser /tmp/file             # show process ids accessing a file
fuser -v /tmp/file          # show verbose info (including user, command,..)
lsof /tmp/file
lsof +D /tmp                # list all processes that have opened a file in /tmp
fuser -m -u /mnt/usb1       # show process ids (and the user name: -u) accessing a mount point / file system
lsof /mnt/usb1
fuser -n tcp 80             # show process ids accessing port 80 (equivalent: fuser 80/tcp)
lsof -i tcp@localhost:80
lsof -p 1000                # show files opened by process with id 1000
lsof -u markus              # show files opened by user markus

fuser can also kill the identified processes, which can be useful e.g. when trying to unmount a file system.

fuser -m -k /mnt/usb1          # send SIGKILL (default for -k) to all processes accessing /mnt/usb1
fuser -m -k -SIGTERM /mnt/usb1 # send SIGTERM (see fuser -l for supported signals)

Users managing themselves

A normal user can not use usermod, but has the following possibilites.

Change password
passwd                   # interactively change password
Change login shell
chsh                     # start interactively
chsh -s /bin/bash        # change login shell
Get account & password information

Check e.g. the account or password expiry date with:

passwd -S                # oneliner
chage -l user            # more verbose

Notifying Users


Before login the contents of /etc/issue are printed.


After login users can be greeted with a message of the day in /etc/motd.


The command wall can send warning messages to all users logged into a machine.

The system has to be shut down in 5 minutes, please save your work and log out.
<Ctrl D>

In case an administrator wants to temporarily forbid logins of other users the file /etc/nologin can be created. It allows no other users than root to log in (also via SSH,..). Note, that this is dangerous and not recommended if root has no password set (as per default in Ubuntu).

Debian's Convenience Tools

Debian provides two convenience programs for adding and deleting users and groups.

However, for further tweaking of users and groups the default usermod tool must be used.

Adding users and groups

By default adduser and addgroup automatically create fully usable accounts (e.g. by creating a new home directory), asks for a password and a detailed description and assures that the gid and uid conform to Debian standards. The defaults can be changed in /etc/adduser.conf.

These simple invocations create normal (non-system) users or groups:

adduser name
addgroup name

The description field in /etc/passwd is to sused tore these properties (comma-separated):

  1. full name
  2. room number
  3. work phone
  4. home phone
  5. other
Create a system user that can not be used to log in
adduser --system --disabled-login name

Deleting users and groups

These tools remove users and groups by removing the entries from the relevant config files, but leaves the home directory intact (by default - see /etc/deluser.conf).

deluser name
delgroup name

Home directories can however be removed or archived by providing a simple argument

deluser --remove-home name       # remove home directory and mail spool
deluser --remove-all-files name  # remove all files owned by user (system-wide)

When either the home or all files are removed a backup archive can be created as well:

deluser --backup --backup-to /tmp --remove-home name

Remote login via Secure Shell (SSH)

Log in to a remote host with ssh username@host.

To use authentication keys instead of passwords:

ssh-keygen                                      # generate your public and private key (~/.ssh/id_rsa)
ssh-copy-id -i ~/.ssh/ username@host  # copy it to the ~/.ssh/authorized_keys on the remote machine
linux/installation.txt · Last modified: 2019/10/21 14:09 by mstraub