Skip to content
DBDeependra Bhatta~/notes
Linux#bash · #cheat-sheet · #linux · #security

Linux Users, Permissions and Package Management

Manage users, groups, sudo, file permissions, links, apt packages, archives and processes on Ubuntu, with the commands and the files behind each one.

· updated · 18 min read
ON THIS PAGE

Every service you deploy needs an account to run as, the right file permissions, its packages installed, and a way to inspect it once it is running. This part covers that administration layer on Ubuntu: users and groups, sudo rules, permissions and special bits, links, APT and dpkg, archives, and process monitoring. Everyday file and text commands are in Essential Linux Commands for DevOps.

Users and groups

Linux is a multi-user system: many users can work on one machine at the same time, and permissions isolate each user from the others.

Types of users

TypeExampleUID / GIDHomeShell
Root (superuser)root0/root/bin/bash
Regulardeependra, vagrant1000 and above/home/username/bin/bash
System (service)www-data, sshd, tomcat1 to 999varies, for example /var/www/usr/sbin/nologin

System users are created by software packages (installing Apache creates www-data on Ubuntu) so services do not run as root. Only root can create or remove users.

The files behind users

/etc/passwd has one line per user with seven :-separated fields:

TXTPlain text
root:x:0:0:root:/root:/bin/bash
FieldValue hereMeaning
1rootUsername
2xPassword placeholder; the real hash is in /etc/shadow
30User ID (UID)
40Primary group ID (GID)
5rootComment, usually the full name
6/rootHome directory
7/bin/bashLogin shell (/usr/sbin/nologin blocks interactive login)

/etc/shadow stores password hashes and password ageing rules. Only root can read it.

TXTPlain text
root:*:19229:0:99999:7:::
FieldMeaning
1Username
2Password hash (* or ! means password login is not possible)
3Date of the last password change, in days since 1 January 1970
4Minimum days before the password can be changed
5Maximum days before the password must be changed
6Days of warning before the password expires
7Days after expiry before the account is disabled
8Account expiry date, in days since 1 January 1970
9Reserved

/etc/group has one line per group, with the group's members at the end. Defaults for new users are in /etc/default/useradd (print them with useradd -D).

Creating and changing users

adduser (Debian and Ubuntu) is interactive: it creates the home directory, copies the default files from /etc/skel, and asks for a password. useradd is the low-level tool and does only what its options specify, which makes it the right choice for scripts.

terminal
$ sudo adduser dipen
$ sudo useradd -c "Dipendra" -m -d /var/dipen -e 2023-01-05 -g staff -G hr,admin -s /bin/bash -u 2000 dipendra
useradd / usermod optionMeaning
-cComment
-mCreate the home directory (useradd does not create it without this)
-dHome directory path
-eAccount expiry date (YYYY-MM-DD)
-gPrimary group
-GSecondary groups (comma-separated)
-sLogin shell
-uUser ID

usermod takes the same options to change an existing user, plus a few of its own:

terminal
$ sudo usermod -e 2023-01-30 -s /bin/sh -u 3000 dipen
$ sudo usermod -l dipendra dipen
$ sudo usermod -L dipen
$ sudo usermod -U dipen
$ sudo usermod -aG docker dipen

-l renames the login, -L locks the account, -U unlocks it, and -aG adds a secondary group.

Other user commands:

CommandWhat it does
su - usernameSwitches to another user (with -, you get their login environment)
sudo userdel usernameDeletes a user
sudo userdel -r usernameDeletes the user plus their home directory and mail spool
id usernameShows UID, GID and groups
groups usernameShows the user's groups
sudo passwd usernameSets another user's password
whoUsers logged in right now
lastHistory of logins
lsof -u usernameFiles the user has open

Password ageing with chage

terminal
$ sudo chage -l dipen
$ sudo chage -m 1 -M 14 -W 2 -I 3 -E 2023-02-02 dipen
OptionSets
-lLists the current rules
-mMinimum days between password changes
-MMaximum days a password is valid
-WDays of warning before the password expires
-IGrace days after expiry before the account is locked
-EAccount expiry date

Run chage username without options to set each value interactively.

Groups

terminal
$ sudo groupadd staff
$ sudo groupdel staff
$ sudo gpasswd -d dipen staff

gpasswd -d removes a user from a group. Editing /etc/group by hand also works, but the commands validate the format and are safer.

sudo

sudo lets a normal user run a command as root, or as another user, after entering their own password. It is safer than sharing the root password: every use is logged, and each user can be limited to specific commands.

CommandWhat it does
sudo commandRuns one command as root
sudo -u www-data commandRuns a command as another user
sudo -iOpens a root login shell in /root
sudo suOpens a root shell but stays in your current directory

Giving a user sudo rights

On Ubuntu, members of the sudo group can run any command (older releases also used admin):

terminal
$ sudo usermod -aG sudo username

For finer control, write a rule file in /etc/sudoers.d/. Always edit sudoers files with visudo: it checks the syntax before saving, and a broken sudoers file can lock everyone out of sudo.

terminal
$ sudo visudo -f /etc/sudoers.d/dipen

A rule has this shape:

TXTPlain text
root ALL=(ALL:ALL) ALL
PartMeaning
rootThe user the rule applies to (%groupname for a group)
ALL=On all hosts
(ALLMay run commands as any user
:ALL)May run commands as any group
ALLMay run any command

Examples:

TXTdipen
etcsudoers.ddipen
# Only allow two specific commands
dipen ALL=(ALL:ALL) /usr/bin/df, /usr/bin/du
 
# Any program directly inside /usr/bin (note the trailing slash)
dipen ALL=(ALL:ALL) /usr/bin/
 
# A whole group, without a password prompt
%devops ALL=(ALL) NOPASSWD: ALL

Vagrant boxes ship with vagrant ALL=(ALL) NOPASSWD: ALL, which is why vagrant ssh users can run sudo without a password.

Aliases group users and commands so rules stay short:

TXTtrusted
etcsudoers.dtrusted
User_Alias TRUSTED = rabindra, pankaj
Cmnd_Alias LIMITED = /usr/sbin/useradd, /usr/bin/passwd
TRUSTED ALL = ALL, !LIMITED

This lets rabindra and pankaj run everything except the commands in LIMITED. Host_Alias works the same way for groups of machines.

File permissions

Every file has an owner, a group, and three sets of permissions: for the user (owner), the group, and others.

PermissionOn a fileOn a directory
r read (4)View the contentsList the files inside
w write (2)Change the contentsCreate, delete and rename files inside
x execute (1)Run it as a program or scriptEnter it with cd and access files inside
-No permissionNo permission

The number form adds the values: 7 = rwx, 6 = rw-, 5 = r-x, 4 = r--. So -rw-r--r-- is 644.

chmod: change permissions

terminal
$ chmod 644 notes.txt
$ chmod 755 script.sh
$ chmod u+x script.sh
$ chmod o-x /path/file
$ chmod -R 755 /path/dir
  • 644: owner can read and write; group and others can only read. The standard for files.
  • 755: owner has full access; group and others can read and execute. The standard for directories and scripts.
  • u+x / o-x change one permission and leave the rest. u user, g group, o others, a all.
  • -R applies the change to everything inside a directory. chmod -R 755 also makes every regular file executable, so apply it deliberately.

chown and chgrp: change ownership

terminal
$ sudo chown -R dipen /home/dipen/testdir1
$ sudo chgrp -R testgroup1 testdir1
$ sudo chown -R apache:apache /data/dipen.com.np

chown user:group changes both at once. The old user.group form with a dot is deprecated; use the colon.

Special permissions

BitSet withEffectReal example
Sticky bitchmod 1777 dir or chmod +t dirIn that directory, users can delete only their own files/tmp
SUIDchmod u+s file (remove with u-s)The program runs with the file owner's rights, not the caller's/usr/bin/passwd runs as root so it can write /etc/shadow
SGIDchmod g+s dirNew files in the directory get the directory's groupShared team folders

They show up in ls -l as t or s in place of x, for example drwxrwxrwt on /tmp.

Inodes

An inode (index node) is the record the file system keeps for each file. It holds everything about the file except its name and contents: type and permissions, owner and group, size, timestamps, link count, and pointers to the data blocks on disk. A directory is a list that maps names to inode numbers. See inode numbers with ls -i or stat file.

Soft (symbolic) linkHard link
What it isA small file that points to a path, like a Windows shortcutAnother name for the same inode
Inode numberDifferent from the originalSame as the original
If the original is deletedThe link breaksThe data is still there through the link
Works for directoriesYesNo
Works across file systemsYesNo

The syntax is ln [-s] TARGET LINK_NAME:

terminal
$ ln -s /home/student/abc.txt /tmp/slabc.txt
$ ln /home/student/xyz.txt /home/student/hlxyz.txt
$ ls -li /tmp/slabc.txt /home/student/hlxyz.txt
$ unlink /tmp/slabc.txt
$ unlink /home/student/hlxyz.txt

Package management

Ubuntu and Debian use .deb packages, with two layers of tools:

  • dpkg is the low-level tool. It installs, removes and inspects .deb files, but it does not download packages or resolve their dependencies.
  • APT (Advanced Package Tool) is the high-level tool. It downloads packages from repositories and installs their dependencies automatically.

apt

apt is the newer command designed for interactive use. apt-get and apt-cache cover the same operations with output that stays stable for scripts.

CommandWhat it does
sudo apt updateDownloads the latest package lists from the repositories
sudo apt upgradeUpgrades installed packages (run update first)
sudo apt install pkgInstalls a package and its dependencies
sudo apt install ./file.debInstalls a local .deb file and pulls in its dependencies
sudo apt remove pkgRemoves a package but keeps its config files
sudo apt purge pkgRemoves a package and its config files
sudo apt autoremoveRemoves dependencies that nothing needs any more
sudo apt cleanDeletes downloaded .deb files from the cache in /var/cache/apt/archives
apt search pkg / apt-cache search pkgSearches package names and descriptions
apt show pkg / apt-cache show pkgShows version, dependencies and description

When an install fails because of a wrong package name, apt-cache search finds the correct one. In my lab it located the PyMySQL package for Python 3:

Terminal output of apt-cache search pymysql listing python3-pymysql and related packages

aptitude is another high-level front end with the same subcommands (install, remove, search, show) and a text menu interface. It is not installed by default.

dpkg

CommandWhat it does
sudo dpkg -i file.debInstalls a .deb file (fails if dependencies are missing)
dpkg -lLists installed packages
sudo dpkg --configure -aFinishes configuring packages left half-installed, for example after an interrupted upgrade
sudo dpkg-reconfigure pkgRuns the setup questions again for an installed package

Files behind APT

PathWhat it is
/etc/apt/sources.list and /etc/apt/sources.list.d/The repositories APT uses (Ubuntu 24.04 uses /etc/apt/sources.list.d/ubuntu.sources)
/var/lib/apt/lists/Package lists downloaded by apt update
/var/lib/dpkg/statusDatabase of installed packages
/var/log/apt/history.logHistory of apt commands

To list every package installed with apt install, search the history log:

terminal
$ grep " install " /var/log/apt/history.log

Terminal output of grep on apt history.log showing install commands for python3, docker-ce, tmux and terminator

Archiving and compressing

Archiving joins many files and folders into one file; it does not make them smaller. Compression makes a file smaller by removing repeated data. tar archives and can compress at the same time; zip always does both.

CommandWhat it does
tar -cvf backup.tar dir1 file1Creates an archive
tar -czvf backup.tar.gz dir1 file1Creates a gzip-compressed archive
tar -tvf backup.tarLists what is inside
tar -xvf backup.tarExtracts an archive
tar -xzvf backup.tar.gz -C /tmpExtracts a compressed archive into /tmp
zip -r hello.zip testdirectoryZips a directory
unzip hello.zipExtracts a zip file
gzip file / gunzip file.gzCompresses / decompresses a single file

tar flags: c create, x extract, t list, v verbose, f archive file name (must come last before the name), z gzip. Other compression tools are bzip2 (j in tar) and xz (J in tar).

Without -r, zip adds only the empty directory and none of the files inside it.

Processes

top

top shows a live view of the system and its processes. The capture below comes from a lab VM running Jenkins and Tomcat:

top process list with Jenkins and two Tomcat java processes near the top, plus sshd and kernel workers

How to read the header:

TXTPlain text
top - 04:10:44 up 1 day, 2:41, 3 users, load average: 0.09, 0.09, 0.06
Tasks: 196 total, 1 running, 195 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.2 us, 0.5 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 3843.4 total, 1682.4 free, 1658.1 used, 735.4 buff/cache
  • up: time since boot. users: logged-in sessions.
  • load average: average number of processes running or waiting for CPU over the last 1, 5 and 15 minutes. Compare it with the number of CPU cores (nproc): a load of 2.0 on a 2-core machine means it is fully busy.
  • Tasks: sleeping processes are waiting for input or I/O; zombie processes have finished but are still in the process table.
  • %Cpu: us user programs, sy kernel, ni low-priority (niced) processes, id idle, wa waiting for disk or network I/O, hi/si hardware/software interrupts, st time taken by the hypervisor on a VM.
  • Mem: buff/cache is memory used for disk cache; the kernel gives it back when programs need it.

Process columns:

ColumnMeaning
PIDProcess ID
USEROwner
PR / NIPriority / nice value (-20 is the highest priority, 19 the lowest)
VIRTVirtual memory the process has mapped
RESPhysical RAM in use
SHRPart of RES shared with other processes
SState: R running, S sleeping, I idle kernel thread, T stopped, Z zombie
%CPU / %MEMCPU and memory share
TIME+Total CPU time used

Keys inside top: M sort by memory, P sort by CPU, T sort by run time, R reverse the order, k kill a process by PID, h help, q quit.

ps

ps prints a snapshot of processes and exits.

CommandWhat it does
ps auxAll processes: a all users, u user-oriented columns, x include processes without a terminal
ps -efAll processes in full format (-e every process, -f full)
ps -ef | grep apache2Finds a process by name
ps -u usernameProcesses owned by one user
ps -T -p 1234Threads of process 1234
ps aux --sort=-%memSorted by memory, highest first
ps aux --sort=-%cpuSorted by CPU, highest first

Names in square brackets in ps aux, such as [kworker/0:1], are kernel threads.

Stopping processes

kill PID sends SIGTERM, which asks the process to shut down cleanly. kill -9 PID sends SIGKILL, which ends it at once with no clean-up, so use it only when SIGTERM does not work.

This pipeline kills every apache2 process. grep -v grep drops the grep command itself from the list, and awk prints the PID column:

terminal
$ ps -ef | grep apache2 | grep -v grep | awk '{print $2}' | xargs kill -9

sudo pkill apache2 does the same in one step. For anything managed by systemd, sudo systemctl stop apache2 is the correct method.

Zombie and orphan processes

  • Zombie: a process that has finished, but its parent has not yet read its exit status, so it still has an entry in the process table.
  • Orphan: a child process that is still running after its parent has exited. The init process (PID 1, systemd) adopts it.

Common mistakes

  • usermod -G group user without -a removes the user from all other secondary groups.
  • Editing /etc/sudoers with a normal editor: one typo can break sudo. Use visudo.
  • Using double quotes around an awk program (awk "{print $2}"): the shell replaces $2 before awk sees it. Use single quotes.
  • apt purge is not "remove plus clean": it removes the package's config files, while apt clean empties the download cache.

Key takeaways

  • User data lives in /etc/passwd, password hashes in /etc/shadow, groups in /etc/group.
  • Give sudo rights with group membership or a file in /etc/sudoers.d/, always edited with visudo.
  • 644 for files and 755 for directories and scripts cover most cases; avoid 777.
  • APT resolves dependencies, dpkg does not; apt install ./file.deb gives you both.
  • top for a live view, ps for a snapshot, and SIGTERM before kill -9.

Next in this series: Bash Shell Scripting Basics with an EC2 Automation Script.