In this tutorial, learn to review security on your Linux system. Learn to:
- Audit a system to find files with the suid/sgid bit set.
- Set or change user passwords and password aging information.
- Use nmap and netstat to discover open ports on a system.
- Set up limits on user login events, processes, and memory usage.
- Determine which users have logged in to the system or are currently logged in.
- Use and configure sudo.
Basic security in Linux
Your Linux system requires protection from malicious outsiders and also abuse from legitimate users. Learn the basics of protecting your Linux system.
This tutorial helps you prepare for Objective 110.1 in Topic 110 of the Linux Administrator (LPIC-1) exam 101. The objective has a weight of 3. This tutorial reflects the Version 5.0 objectives as updated on October 29, 2018.
To get the most from the tutorials in this series, you need a basic knowledge of Linux and a working Linux system on which you can practice the commands that are covered in this tutorial. You should also be familiar with material covered in our tutorials Learn Linux, 101: File and directory management,Learn Linux, 101: Manage file permissions and ownership, and Learn Linux, 101: Manage user and group accounts and related system files. Sometimes, different versions of a program format output differently, so your results might not always look exactly like the listings and figures that are shown here.
The examples in this tutorial come from Fedora 33, Slackware 14.2, and Ubuntu 20.04.1 LTS.
Find files with the suid/sgid bit set
Recall that the
passwd command saves your updated password in an encrypted form in /etc/shadow. If you look at the permissions on /etc/shadow, it has no permissions, meaning that only the owner (root) can read or update it. You probably wouldn’t want other people to read even an encrypted password, let alone change it. So, this behavior is reasonable. How does the
passwd command manage to update /etc/shadow? The answer is the
suid permission bit in the file attributes for the
passwd command. Listing 1 shows the file permissions on the three basic files related to passwords. I have used the
stat command to show both the usual and the octal file permissions. The more usual
ls command cannot display octal permissions. Make a note of the
'%#a formatting option to add a leading 0 to the octal permissions.
Listing 1. File permissions related to the passwd command
[ian@attic5-f33 ~]$ stat -c '%A %#a %U %G %n' /etc/shadow /etc/passwd /usr/bin/passwd ---------- 0 root root /etc/shadow -rw-r--r-- 0644 root root /etc/passwd -rwsr-xr-x 04755 root root /usr/bin/passwd
-rwsr-xr-x permission bits include ‘s’ in the user section, or equivalently 4000 in the octal form. This tells you that the program is run with permissions as if the root user had invoked it. That is how it is allowed to access /etc/shadow. Obviously any executable that can access any part of the file system with root authority is a potential security exposure. How many such files are there? Use the
find command with the
-perm option to locate files with specific permission bits set. Listing 2 shows how to find the total number of files with the suid bit set starting at the root of the file system. You will need to run this command with root authority. For this section of the tutorial, I use a terminal session with the root login environment on my Fedora 33 system. For many systems, particularly Debian-based systems such as Ubuntu, it is more normal to use these commands using the
sudo command. I will cover
sudo and its configuration later in this tutorial. If you are not already familiar with using
sudo, you can skip ahead to that section and then return here.
Listing 2. How many files have suid set?
[root@attic5-f33 ~]# find / -perm -4000|wc find: ‘/run/user/1000/gvfs’: Permission denied find: ‘/proc/49464/task/49464/fd/5’: No such file or directory find: ‘/proc/49464/task/49464/fdinfo/5’: No such file or directory find: ‘/proc/49464/fd/6’: No such file or directory find: ‘/proc/49464/fdinfo/6’: No such file or directory 26 26 618
So I have 26 files on my system with the suid bit set. Not too many to check. Notice the specification of the permission bits to match as
-4000. The leading hyphen ‘-‘ tells
find to match any file that has all the specified bits set. If you want to look for files with multiple bits all set this is fine and in this case, there is only one bit to check. If you want to find files that have either suid or sgid bits set you should use the ‘/’ prefix, which matches any permission setting with at least one of the specified bits set.
There are several lines of output on stderr. If you are performing a security audit, you should at least review these to be sure that there are no surprises.
find command normally prints output to stdout. Use the
-printf option to format it, for example to include specific output fields. Use
-fprintf to print output to a file. Listing 3 shows how to generate a list of files in the file system with the suid bit set. I format the output to include the octal permission with a leading 0 (
%#m), the owning user (
%u) and the file name relative the the starting point (
Listing 3. Generating a list of files with suid set
[root@attic5-f33 ~]# find / -perm /4000 -fprintf /root/suid.txt '%#m %u %p\n' 2>/dev/null [root@attic5-f33 ~]# ls -l /root/suid.txt -rw-r--r--. 1 root root 904 Dec 4 17:25 /root/suid.txt [root@attic5-f33 ~]# wc /root/suid.txt 26 78 904 /root/suid.txt [root@attic5-f33 ~]# head -n 3 /root/suid.txt 04755 root /usr/bin/newgrp 04755 root /usr/bin/vmware-user-suid-wrapper 04755 root /usr/bin/chage
find command supports multiple output expressions separated by the ‘,’ operator. Listing 4 shows how to generate two file lists, one with the suid set and another with the sgid set. For this example in Listing 4, I use symbolic permissions for both search and output.
Listing 4. Generating suid and sgid lists in a single traversal
[root@attic5-f33 ~]# find / \ > \( -perm /4000 -fprintf /root/suid.txt '%#m %u %p\n' \) , \ > \( -perm -g=s -fprintf /root/sgid.txt '%#M %u %p\n' \) 2>/dev/nnull [root@attic5-f33 ~]# head -n 3 /root/sgid.txt drwxrwsr-x tss /run/tpm2-tss/eventlog drwxr-sr-x root /run/log/journal -rwxr-sr-x root /usr/bin/write
Set or change user passwords and password aging
Most users authenticate with a password when logging in to a system. Use the
passwd command to change your password. You must know your current password in order to change it to something else. A system administrator can also use the
passwd command to reset a forgotten password, set a temporary password that must be changed by a user during next login, specify the maximum number of days that a password can be used before it must be changed, lock a user out of the system, and other related tasks. The system administrator does not need to know a user’s current password. The passwords are actually stored in /etc/shadow in an encrypted form, so not even root can extract them.
If a user forgets his or her password, the system administrator will usually generate a temporary password that is not too complex and communicate this temporary password to the user in some fashion that doesn’t require logging into the account, perhaps face-to-face, telephone, text or email to some account not associated with the lost password. In most such case the administrator will generate a password that includes some random elements. In Listing 5, I show one simple example to generate a partially random password using the
mktemp command, and then set it for user brendan who has lost his password. I use the
--stdin option to read the password from stdin rather than typing it and then retyping it.
Listing 5. Resetting a user password
[root@attic5-f33 ~]# mktemp -u Pass0-XXX Pass0-2Pr [root@attic5-f33 ~]# echo Pass0-n0R | passwd --stdin brendan Changing password for user brendan. passwd: all authentication tokens updated successfully.
If you want a user to change the password before further using the system, use the
-e or the
--expire option to expire the password as shown in Listing 6.
Listing 6. Expiring a password
[root@attic5-f33 ~]# info passwd [root@attic5-f33 ~]# passwd -e brendan Expiring password for user brendan. passwd: Success
Listing 7 shows what user brendan’s next login might look like.
Listing 7. Logging in when your password is expired
[ian@attic5-f33 l-lpic1-110-1]$ ssh brendan@attic5-f33 brendan@attic5-f33's password: You are required to change your password immediately (administrator enforced). You are required to change your password immediately (administrator enforced). Last login: Mon Dec 7 22:49:43 2020 from 192.168.1.25 WARNING: Your password has expired. You must change your password now and login again! Changing password for user brendan. Current password: New password: Retype new password: passwd: all authentication tokens updated successfully. Connection to attic5-f33 closed.
You can set the maximum number of days a user is allowed to use a password before changing it, as well as the number of days in advance to issue a warning and the number of days (grace period) before the account is locked. You can also set the minimum number of days between password changes. You might want to do this if your system uses Pluggable Authentication Modules (PAMs) and you have set up rules that require a password not to match any of say the last twelve passwords. With this example requirement in place, a minimum password change period of 1 day ensures that a user cannot go back to a previously used password for at least 12 days. You can also display the current values for each duration. Either the
chage command will do these tasks for you, although the parameter names differ between them. You can use
chage interactively if you prefer. Listing 8 shows some examples of each command. Consult the man or info pages for full details on all parameters.
Listing 8. Using passwd and chage to set password duration
[root@attic5-f33 ~]# # Set brendan's minimum and maximum password lifetime [root@attic5-f33 ~]# passwd -n 1 -x 90 brendan Adjusting aging data for user brendan. passwd: Success [root@attic5-f33 ~]# # Set a 7 day warning period and a 14 day grace period [root@attic5-f33 ~]# chage -W 8 -I 14 brendan [root@attic5-f33 ~]# # Compare the settings for brendan and ian [root@attic5-f33 ~]# passwd -S brendan brendan PS 2020-12-07 1 90 8 14 (Password set, SHA512 crypt.) [root@attic5-f33 ~]# passwd -S ian ian PS 2020-12-01 0 99999 7 -1 (Password set, SHA512 crypt.) [root@attic5-f33 ~]# # list settings using chage [root@attic5-f33 ~]# chage -l brendan Last password change : Dec 08, 2020 Password expires : Mar 08, 2021 Password inactive : Mar 22, 2021 Account expires : never Minimum number of days between password change : 1 Maximum number of days between password change : 90 Number of days of warning before password expires : 8
Are you surprised that the output for
chage -l shows that brendan’s account never expires? The grace (or inactivity) period is the number of days after the password expires and before the password can no longer be used. The
-u options of
passwd respectively lock or unlock the password. Password locking is accomplished by prepending the encrypted password in /etc/shadow with a ‘!’ character, which renders it invalid but can be easily reversed. The second output field in
passwd -S changes to
LK to indicate a locked password. Because the encrypted password is invalid, the user will see a message such as “Permission denied, please try again.” when attempting to log in. Listing 9 shows some examples.
Listing 9. Locking and unlocking a password
[root@attic5-f33 ~]# passwd -l brendan Locking password for user brendan. passwd: Success [root@attic5-f33 ~]# passwd -S brendan brendan LK 2020-11-17 1 90 8 14 (Password locked.) [root@attic5-f33 ~]# grep brendan /etc/shadow brendan:!!$6$Pjwv1j/M63 ... iOOQ/ct/:18584:1:90:8:14:: [root@attic5-f33 ~]# passwd -u brendan Unlocking password for user brendan. passwd: Success
If a user has other means of logging in such as Secure Shell (SSH) authentication tokens, these can still be used to access the account. The
-E option of
chage is used to either set an expiration date after which the account can no longer be used, or reinstate it (using a value of -1). Finally, the
-d option of
chage allows you to set the date that a user last changed a password. Listing 10 shows how to set the last password change date and also disable the account. The second part of the listing shows what happens when brendan attempts to log in.
Listing 10. Disabling an account using chage
[root@attic5-f33 ~]# date +%F 2020-12-08 [root@attic5-f33 ~]# chage -d $(date -d '20 days ago' +%F) brendan [root@attic5-f33 ~]# chage -E $(date -d '2 days ago' +%F) brendan [root@attic5-f33 ~]# chage -l brendan Last password change : Nov 18, 2020 Password expires : Feb 16, 2021 Password inactive : Mar 02, 2021 Account expires : Dec 06, 2020 Minimum number of days between password change : 1 Maximum number of days between password change : 90 Number of days of warning before password expires : 8 [ian@attic5-f33 l-lpic1-110-1]$ ssh brendan@attic5-f33 brendan@attic5-f33's password: Your account has expired; please contact your system administrator. Connection closed by 192.168.1.25 port 22
chage commands listed above require root authority. Unprivileged users can use
passwd to change their own passwords and
chage with the
-l option to display their password status. So they can find out when their password expires without having to wait for a warning.
Some of these functions can also be done with the
usermod command. The
-U options lock and unlock a password by prepending a ‘!’ in /etc/shadow similar to the
-u options of the
passwd command. Check the man or info pages for more information and note, in particular, the
-e (expire date),
-f (inactive days), and
-p (password – not recommended) options.
Discover open ports on your system
Open ports on a system are ports that have some application listening. For example, web servers will usually have ports open for HTTP and HTTPS protocols and I have an SSH port open for administrative purposes. Use the
nmap command to probe open ports on a system. Some functions of
nmap work with non-root access, but many will require you to have root access. I use root access in these examples whether it is actually needed or not. Listing 11 shows the result of using
nmap on the local address and the Ethernet address for my Fedora 33 system. Use either a host name or an IP address for the system to scan.
Listing 11.Basic nmap examples
[root@attic5-f33 ~]# nmap localhost Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-10 18:59 EST Nmap scan report for localhost (127.0.0.1) Host is up (0.000015s latency). Other addresses for localhost (not scanned): ::1 Not shown: 998 closed ports PORT STATE SERVICE 22/tcp open ssh 631/tcp open ipp Nmap done: 1 IP address (1 host up) scanned in 0.12 seconds [root@attic5-f33 ~]# [root@attic5-f33 ~]# nmap 192.168.1.25 Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-10 18:59 EST Nmap scan report for attic5-f33 (192.168.1.25) Host is up (0.000011s latency). Not shown: 999 closed ports PORT STATE SERVICE 22/tcp open ssh Nmap done: 1 IP address (1 host up) scanned in 0.17 seconds
If you don’t recognize a port number, try using the
grep command with /etc/services as shown in Listing 12.
Listing 12. What port is that?
[root@attic5-f33 ~]# grep '[[:blank:]]22\/' /etc/services ssh 22/tcp # The Secure Shell (SSH) Protocol ssh 22/udp # The Secure Shell (SSH) Protocol ssh 22/sctp # SSH [root@attic5-f33 ~]# grep '[[:blank:]]631\/' /etc/services ipp 631/tcp # Internet Printing Protocol ipp 631/udp # Internet Printing Protocol
These examples show that local users on my system can use
sftp over port 22 and connect a web browser to port 631 to manage printers using the CUPS graphical interface. From outside ,you can only access my system using
Listing 13 shows some additional examples; first my local Slackware system and then two well-known web servers.
Listing 13. Mapping additional systems
[root@attic5-f33 ~]# # Check my Slackware system [root@attic5-f33 ~]# nmap attic4 Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-10 18:49 EST Nmap scan report for attic4 (192.168.1.24) Host is up (0.000041s latency). Not shown: 997 closed ports PORT STATE SERVICE 22/tcp open ssh 37/tcp open time 113/tcp open ident MAC Address: 84:16:F9:04:7A:2A (Tp-link Technologies) Nmap done: 1 IP address (1 host up) scanned in 0.16 seconds [root@attic5-f33 ~]# # check a couple of web servers [root@attic5-f33 ~]# nmap www.ibm.com Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-10 18:50 EST Nmap scan report for www.ibm.com (220.127.116.11) Host is up (0.020s latency). Other addresses for www.ibm.com (not scanned): 2600:1408:5c00:3a2::b3a 2600:1408:5c00:384::b3a rDNS record for 18.104.22.168: a104-102-193-57.deploy.static.akamaitechnologies.com Not shown: 998 filtered ports PORT STATE SERVICE 80/tcp open http 443/tcp open https Nmap done: 1 IP address (1 host up) scanned in 4.62 seconds [root@attic5-f33 ~]# nmap www.lpi.org Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-10 18:50 EST Nmap scan report for www.lpi.org (22.214.171.124) Host is up (0.035s latency). Not shown: 997 filtered ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 443/tcp open https Nmap done: 1 IP address (1 host up) scanned in 5.19 seconds
You may have noticed in these examples messages such as “Not shown: 998 filtered ports” or “Not shown: 997 closed ports”. By default,
nmap scans 1000 or the most commonly used ports and displays only the open ones. A port is reported as closed if the host responds with a TCP reset message, while a port is reported as filtered if there is no response (for example, when a firewall simply drops packets). Most systems today disallow Telnet connections as these are very insecure. You can check a specific port using the
-p option with either the port number or the port’s common name. This option supports a single port, a range or ports (such as 21-25, or a comma separated list, where list members may be individual ports or ranges. Use ‘*’ for a wildcard specification such as ‘http*’. Escape or quote the wildcard character to avoid shell interpretation of it. Listing 14 shows an example.
Listing 14. Checking specific ports
[root@attic5-f33 ~]# [root@attic5-f33 ~]# nmap -p 22-25,ntp,'http*' lpi.org Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-11 21:47 EST Nmap scan report for lpi.org (126.96.36.199) Host is up (0.039s latency). PORT STATE SERVICE 22/tcp open ssh 23/tcp filtered telnet 24/tcp filtered priv-mail 25/tcp filtered smtp 80/tcp open http 123/tcp filtered ntp 280/tcp filtered http-mgmt 443/tcp open https 591/tcp filtered http-alt 593/tcp filtered http-rpc-epmap 4180/tcp filtered httpx 8000/tcp filtered http-alt 8008/tcp filtered http 8080/tcp filtered http-proxy 8443/tcp filtered https-alt 8990/tcp filtered http-wmap 8991/tcp filtered https-wmap Nmap done: 1 IP address (1 host up) scanned in 1.59 seconds
If you wish to limit the scan to only UDP or only TCP, prefix a port or port range with U: or T: as appropriate, for example
If you want to see more detail use the
-d option. Use it two times if you want to see even more verbose detail. Listing 15 shows comparison output for an open port and a filtered port.
Listing 15. Using the -d option with nmap
[root@attic5-f33 ~]# nmap -p 22-23 -d lpi.org Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-11 21:51 EST --------------- Timing report --------------- hostgroups: min 1, max 100000 rtt-timeouts: init 1000, min 100, max 10000 max-scan-delay: TCP 1000, UDP 1000, SCTP 1000 parallelism: min 0, max 0 max-retries: 10, host-timeout: 0 min-rate: 0, max-rate: 0 --------------------------------------------- Initiating Ping Scan at 21:51 Scanning lpi.org (188.8.131.52) [4 ports] Packet capture filter (device enp9s0): dst host 192.168.1.25 and (icmp or icmp6 or ((tcp or udp or sctp) and (src host 184.108.40.206))) We got a TCP ping packet back from 220.127.116.11 port 443 (trynum = 0) Completed Ping Scan at 21:51, 0.07s elapsed (1 total hosts) Overall sending rates: 60.82 packets / s, 2311.29 bytes / s. mass_rdns: Using DNS server 127.0.0.53 Initiating Parallel DNS resolution of 1 host. at 21:51 mass_rdns: 0.00s 0/1 [#: 1, OK: 0, NX: 0, DR: 0, SF: 0, TR: 1] Completed Parallel DNS resolution of 1 host. at 21:51, 0.00s elapsed DNS resolution of 1 IPs took 0.00s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0] Initiating SYN Stealth Scan at 21:51 Scanning lpi.org (18.104.22.168) [2 ports] Packet capture filter (device enp9s0): dst host 192.168.1.25 and (icmp or icmp6 or ((tcp or udp or sctp) and (src host 22.214.171.124))) Discovered open port 22/tcp on 126.96.36.199 Completed SYN Stealth Scan at 21:51, 1.32s elapsed (2 total ports) Overall sending rates: 2.27 packets / s, 99.90 bytes / s. Nmap scan report for lpi.org (188.8.131.52) Host is up, received syn-ack ttl 52 (0.036s latency). Scanned at 2020-12-11 21:51:56 EST for 1s PORT STATE SERVICE REASON 22/tcp open ssh syn-ack ttl 52 23/tcp filtered telnet no-response Final times for host: srtt: 36474 rttvar: 28663 to: 151126 Read from /usr/bin/../share/nmap: nmap-payloads nmap-services. Nmap done: 1 IP address (1 host up) scanned in 1.50 seconds Raw packets sent: 7 (284B) | Rcvd: 2 (88B)
nmap command first attempts to ping the target system. Some systems, including my Microsoft® Windows® 10 system do not respond to a ping (ICMP ECHO). The
-Pm option allows you to suppress the ping and continue with the scan anyway.
nmap command has a vast array of other options, including options to attempt detection of the operating system type of the target system and the level of software listening on the port. Consult the man or info pages for more details or refer to the online documentation listed in the Resources section for this tutorial.
You can find additional information about ports on your own system using the
netstat command. If you run it without any parameters, you will find a large number of UNIX® domain sockets within your system that are connected. Because you will most likely be interested in TCP or UDP connections to or from the outside world, you will generally want to use parameters such as
-t for TCP connections,
-u for UDP connections, or
-l for ports that are listening but not connected. By default, the report uses the service name, if known. Use the
-n option if you want numeric port numbers such as 22 instead of
ssh. Listing 16 shows an example on my Fedora 33 system.
Listing 16. Basic use of netstat
[root@attic5-f33 ~]# netstat -t Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 attic5-f33:47540 attic4:ssh ESTABLISHED tcp 0 0 attic5-f33:39120 ec2-54-173-95-250:https ESTABLISHED tcp 0 0 attic5-f33:37244 stackoverflow.com:https ESTABLISHED tcp 0 0 attic5-f33:50860 ec2-52-37-190-150:https ESTABLISHED tcp 1 0 attic5-f33:35326 ec2-3-211-216-81.:https CLOSE_WAIT tcp 0 0 attic5-f33:40864 server-99-86-230-:https ESTABLISHED tcp 0 0 attic5-f33:ssh attic4:38340 ESTABLISHED tcp 0 0 attic5-f33:45014 ec2-54-158-98-5.c:https ESTABLISHED tcp6 1 0 2603-6081-1902-7d:50684 iad23s87-in-x03.1:https CLOSE_WAIT tcp6 1 0 2603-6081-1902-7d:43824 2606:4700::6812:1:https CLOSE_WAIT tcp6 1 0 2603-6081-1902-7d:50336 2600:9000:2191:a0:https CLOSE_WAIT tcp6 1 0 2603-6081-1902-7d:43728 2606:4700:10::681:https CLOSE_WAIT [root@attic5-f33 ~]# netstat -tn Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 192.168.1.25:47540 192.168.1.24:22 ESTABLISHED tcp 0 0 192.168.1.25:39120 184.108.40.206:443 ESTABLISHED tcp 0 0 192.168.1.25:37244 220.127.116.11:443 ESTABLISHED tcp 0 0 192.168.1.25:50860 18.104.22.168:443 ESTABLISHED tcp 1 0 192.168.1.25:35326 22.214.171.124:443 CLOSE_WAIT tcp 0 0 192.168.1.25:40864 126.96.36.199:443 ESTABLISHED tcp 0 0 192.168.1.25:22 192.168.1.24:38340 ESTABLISHED tcp 0 0 192.168.1.25:45014 188.8.131.52:443 ESTABLISHED tcp6 1 0 2603:6081:1902:7d:50684 2607:f8b0:4004:829::443 CLOSE_WAIT tcp6 1 0 2603:6081:1902:7d:43824 2606:4700::6812:173:443 CLOSE_WAIT tcp6 1 0 2603:6081:1902:7d:50336 2600:9000:2191:a00::443 CLOSE_WAIT tcp6 1 0 2603:6081:1902:7d:43728 2606:4700:10::6814::443 CLOSE_WAIT [root@attic5-f33 ~]# netstat -u Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State udp 0 0 attic5-f33:bootpc _gateway:bootps ESTABLISHED udp 0 0 attic5-f33:bootpc _gateway:bootps ESTABLISHED [root@attic5-f33 ~]# netstat -l |wc 96 769 8200
In this example, you see several HTTPS connections from my browser as well as two SSH connections, one into my Slackware system, 192.168.1.24, and one out. In both cases the other end is my Fedora 33 system, 192.168.1.25.
Notice that there a few tcp6 entries signifying IPv6. Specify the -4 or -6 options if you want to see only IPv4 or IPv6 information. Listing 17 shows an example for IPv6 connections on the same system.
Listing 17. Displaying IPv6 connections using netstat
[root@attic5-f33 ~]# netstat -t -6 Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp6 1 0 2603-6081-1902-7d:50684 iad23s87-in-x03.1:https CLOSE_WAIT tcp6 1 0 2603-6081-1902-7d:43824 2606:4700::6812:1:https CLOSE_WAIT tcp6 1 0 2603-6081-1902-7d:50336 2600:9000:2191:a0:https CLOSE_WAIT tcp6 1 0 2603-6081-1902-7d:43728 2606:4700:10::681:https CLOSE_WAIT [root@attic5-f33 ~]# netstat -u -6 Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State [root@attic5-f33 ~]# netstat -l -6 Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp6 0 0 [::]:hostmon [::]:* LISTEN tcp6 0 0 [::]:ssh [::]:* LISTEN tcp6 0 0 localhost:ipp [::]:* LISTEN udp6 0 0 localhost:323 [::]:* udp6 0 0 attic5-f3:dhcpv6-client [::]:* udp6 0 0 [::]:60698 [::]:* udp6 0 0 [::]:mdns [::]:* udp6 0 0 [::]:hostmon [::]:* raw6 0 0 [::]:ipv6-icmp [::]:* 7 raw6 0 0 [::]:ipv6-icmp [::]:* 7
By now you know to use the man or info pages to find more information and additional parameters that you can use.
Limit user login events, processes, and memory usage
A very long time ago in the early 1970s, I was writing Fortran code to design shock tunnel nozzles for supersonic gas flow experiments at the Australian National University. I would often work at nights during which time I discovered that my jobs would work for a while and then I could no longer start them. Somebody doing math algorithms was able to expand the memory available to his program until there was not enough memory left in the system for any other user to launch a job. Can you stop such a behavior on a multiuser Linux system? The answer is yes, using the
ulimit command. Perhaps the simplest way to introduce
ulimit is to use the command with the
-a option to list all the limits you have for your own account. Listing 18 shows an example from my Slackware system.
Listing 18. Showing various limits with ulimit
ian@attic4-sl42:~$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 31590 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 31590 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
User limits fall into two categories: Soft limits and hard limits. A soft limit allow users to increase or decrease their own limit up to the hard limit. A hard limit is exactly that limit beyond which non-system users cannot raise their own limits.
As an example of
ulimit in action, I will set the maximum soft and hard files sizes. The sizes are specified in blocks which are 1024 bytes each on my Slackware system. Listing 19 shows how to check the block size and then set the soft limit to 10,000 blocks and the hard limit to 25,000 blocks.
Listing 19. Setting soft and hard limits with ulimit
root@attic4-sl42:~# df /home Filesystem 1K-blocks Used Available Use% Mounted on /dev/root 70425980 10505884 56319616 16% / root@attic4-sl42:~# ulimit -Sf 10000 root@attic4-sl42:~# ulimit -Hf 25000 root@attic4-sl42:~# ulimit -Sa core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) 10000 pending signals (-i) 31590 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 31590 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited root@attic4-sl42:~# ulimit -Hf 25000
Now consider what happens if user joe tries to create a 30 MB file filled with random data as shown in Listing 20.
Listing 20. How ulimit affects a user
joe@attic4-sl42:~$ head -c 30M </dev/urandom >testfile File size limit exceeded joe@attic4-sl42:~$ ls -l testfile -rw-r--r-- 1 joe users 10240000 Dec 14 13:44 testfile joe@attic4-sl42:~$ ulimit -Sf 40000 -su: ulimit: file size: cannot modify limit: Invalid argument joe@attic4-sl42:~$ ulimit -Hf 25000 joe@attic4-sl42:~$ ulimit -Sf $(ulimit -Hf) # Set to maximum allowed joe@attic4-sl42:~$ head -c 30M </dev/urandom >testfile File size limit exceeded joe@attic4-sl42:~$ ls -l testfile -rw-r--r-- 1 joe users 25600000 Dec 14 13:46 testfile joe@attic4-sl42:~$ echo $(( 25000 * 1024 )) # 25000 blocks of 1K 25600000
The limits you set using
ulimit apply to all non-system users. If your system uses PAM authentication you also have some finer control over limits. Look at the file /etc/security/limits.conf or see the man or info pages for limits.conf.
Who has logged in and who is currently logged in
Often you want to know who all are using your system and what they are using. Linux usually maintains two files that contain information about logged-in users. The utmp file is often located in /var/run/utmp. It contains information about users who are currently using the system. There may also be other users as some programs do not use utmp logging. The wtmp file is usually located at /var/log/wtmp. The wtmp file records all login and logout activities as well as recording system reboots with a pseudo user of ‘~’. Both utmp and wtmp contain binary records in an identical format. A third file, btmp, if it exists, records failed login attempts. It is usually located at /var/log/btmp. Listing 21 shows these files on my Fedora 33 system.
Listing 21. Login recording files
[root@attic5-f33 ~]# ls -l /var/log/*tmp /var/run/utmp -rw-rw----. 1 root utmp 4992 Dec 14 15:12 /var/log/btmp -rw-rw-r--. 1 root utmp 134016 Dec 15 12:05 /var/log/wtmp -rw-rw-r--. 1 root utmp 2688 Dec 15 12:05 /var/run/utmp
Four commands are commonly used to display information from these files.
whocommand by default displays information from the utmp file about currently logged-in users. A non-option parameter may specify another file such as wtmp.
wcommand combines information from the utmp file and the /proc file system to display more information about logged in users.
lastcommand displays data about a current or a previous login activity from the wtmp file.
lasstbcommand displays information about failed login attempts from the btmp file (if this file exists).
Listing 22 shows basic usage of the
w commands. Add the
-a option to who to see additional information, including system reboot time. Add the
-H option to display column headings.
Listing 22. Using who and w
[root@attic5-f33 ~]# who ian tty2 2020-11-29 16:44 (tty2) ian pts/2 2020-12-08 19:19 (192.168.1.24) brendan pts/4 2020-12-15 12:04 (192.168.1.25) brendan tty4 2020-12-15 12:05 [root@attic5-f33 ~]# who -a system boot 2020-11-29 14:40 run-level 5 2020-11-29 14:40 ian + tty2 2020-11-29 16:44 old 1810 (tty2) ian + pts/2 2020-12-08 19:19 00:53 118838 (192.168.1.24) pts/3 2020-12-10 17:36 144621 id=ts/3 term=0 exit=0 brendan + pts/4 2020-12-15 12:04 00:53 215341 (192.168.1.25) brendan + tty4 2020-12-15 12:05 00:05 215433 [root@attic5-f33 ~]# who -a -H NAME LINE TIME IDLE PID COMMENT EXIT system boot 2020-11-29 14:40 run-level 5 2020-11-29 14:40 ian + tty2 2020-11-29 16:44 old 1810 (tty2) ian + pts/2 2020-12-08 19:19 00:56 118838 (192.168.1.24) pts/3 2020-12-10 17:36 144621 id=ts/3 term=0 exit=0 brendan + pts/4 2020-12-15 12:04 00:56 215341 (192.168.1.25) brendan + tty4 2020-12-15 12:05 00:08 215433 [root@attic5-f33 ~]# w 13:00:29 up 15 days, 22:20, 4 users, load average: 0.25, 0.36, 0.35 USER TTY LOGIN@ IDLE JCPU PCPU WHAT ian tty2 29Nov20 15days 0.04s 0.04s /usr/libexec/gnome-session-binary ian pts/2 08Dec20 56:30 0.07s 0.01s ssh firstname.lastname@example.org brendan pts/4 12:04 56:21 0.04s 0.04s -bash brendan tty4 12:05 8:29 0.04s 0.00s cat
Both commands have several options that are further described in the man or info pages. One useful variant for
who am i to find out who is using a terminal or terminal session. The
-m option does the same thing.
last command formats data from the wtmp file or another file such as utmp if the
-f option is specified. This can be a lot of output, so you can limit it to a specified number or the most recent entries using the
-num) option. Listing 23 shows an example.
Listing 23. Basic use of the last command
ian@attic4-sl42:~$ last -n 10 ian pts/3 192.168.1.25 Sat Dec 12 21:05 still logged in ian pts/4 :0 Sat Dec 12 21:02 - 21:04 (00:01) ian pts/3 192.168.1.25 Thu Dec 10 16:52 - 21:05 (2+04:12) ian pts/2 :0 Tue Dec 8 18:26 still logged in ian pts/2 192.168.1.25 Wed Dec 2 12:58 - 12:58 (00:00) ian pts/3 192.168.1.25 Tue Nov 24 17:50 - 17:54 (00:03) ian pts/2 192.168.1.25 Tue Nov 24 13:50 - 13:50 (5+00:00) ian pts/2 127.0.0.1 Tue Nov 24 13:15 - 13:16 (00:00) ian pts/1 :0 Tue Nov 24 13:15 still logged in ian pts/0 :0 Tue Nov 24 13:15 still logged in wtmp begins Sun Nov 19 15:48:30 2017
-t (until time) option of the
last command to see who all logged in at a specific time. The time is specified as YYYYMMDDHHMMSS, although some newer systems allow more general time formats such as ‘yesterday’ or ‘3 days ago’. Users logged in at that time show as ‘still logged in’. Some versions of
last also have a
-s (since time) option to list users logged in since the specified time. In such cases, the
-p option combines the effect of
-t to display users logged in at the specific time. Some examples from Fedora 33 are shown in Listing 24.
Listing 24. Using times with last
[root@attic5-f33 ~]# last -t 20200525150000 ian tty2 tty2 Mon May 25 14:32 - down (00:17) reboot system boot 5.6.13-300.fc32. Mon May 25 14:31 - 14:49 (00:17) ian tty2 tty2 Fri May 22 18:29 - down (2+18:53) ian tty2 tty2 Fri May 22 18:24 - 18:29 (00:04) reboot system boot 5.6.13-300.fc32. Fri May 22 18:24 - 13:22 (2+18:58) ian tty2 tty2 Fri May 22 18:21 - down (00:02) reboot system boot 5.6.13-300.fc32. Fri May 22 18:21 - 18:23 (00:02) ian tty2 tty2 Fri May 22 17:39 - down (00:41) reboot system boot 5.6.13-300.fc32. Fri May 22 17:39 - 18:20 (00:41) ian tty2 tty2 Fri May 22 16:54 - down (00:40) reboot system boot 5.6.6-300.fc32.x Fri May 22 16:54 - 17:35 (00:41) ian tty2 tty2 Fri May 22 10:45 - down (00:30) reboot system boot 5.6.13-300.fc32. Fri May 22 10:44 - 11:15 (00:30) ian tty2 tty2 Thu May 21 19:05 - down (15:38) reboot system boot 5.6.6-300.fc32.x Thu May 21 19:03 - 10:44 (15:40) wtmp begins Thu May 21 19:03:56 2020 [root@attic5-f33 ~]# last -s '7 days ago' brendan tty4 Tue Dec 15 12:05 still logged in brendan pts/4 192.168.1.25 Tue Dec 15 12:04 still logged in brendan pts/4 192.168.1.25 Mon Dec 14 15:16 - 16:38 (01:22) ian pts/4 192.168.1.28 Sat Dec 12 08:51 - 08:51 (00:00) ian pts/4 192.168.1.25 Thu Dec 10 13:45 - 13:45 (00:00) ian pts/3 192.168.3.22 Thu Dec 10 13:41 - 17:36 (03:54) ian pts/2 192.168.1.24 Tue Dec 8 19:19 still logged in wtmp begins Thu May 21 19:03:56 2020 [root@attic5-f33 ~]# last -p '7 days ago' ian tty2 tty2 Sun Nov 29 16:44 still logged in reboot system boot 5.8.17-200.fc32. Sun Nov 29 14:40 still running wtmp begins Thu May 21 19:03:56 2020
lastb command has the same options as the
last command. It is not part of this set of objectives but I mention it for completeness. It requires the /var/log/btmp file to exist and to not be writable by others. If you have an SSH port open, or forwarded through your router to your system, you can use
lastb to see how many people are trying to hack into your system using brute-force attacks. Check out an intrusion prevention system, such as fail2ban, to help block some of these attacks.
Who is using files
Sometimes you need to know who is using a file and keeping it open such that you cannot cleanly do something such as unmount a file system. The
lsof command can list every open file on your system. This includes sockets and can include a large amount of data. So you generally want to have a specific purpose in mind when using
lsof. You can restrict output by user using the file, by name of the command using the file, and by port, among many other possibilities. Listing 25 shows how many lines of output the
lsof command produces on my system with no options.
Listing 25. How much lsof output?
[root@attic5-f33 ~]# lsof | wc lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs Output information may be incomplete. lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1001/gvfs Output information may be incomplete. 311816 3392503 43770989
You can exclude the error messages caused by the permission settings for the gvfs file systems using the
-e option Listing 26 shows how to list the open connections on port 22, the files open that are associated with a user running the
cat command, and the status of a specific file.
Listing 26. Using lsof
[root@attic5-f33 ~]# lsof -e /run/user/1000/gvfs -e /run/user/1001/gvfs -i TCP:22 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 916 root 5u IPv4 37936 0t0 TCP *:ssh (LISTEN) sshd 916 root 6u IPv6 37944 0t0 TCP *:ssh (LISTEN) sshd 223142 root 5u IPv4 3212396 0t0 TCP attic5-f33:ssh->attic4:40920 (ESTABLISHED) sshd 223147 ian 5u IPv4 3212396 0t0 TCP attic5-f33:ssh->attic4:40920 (ESTABLISHED) [root@attic5-f33 ~]# lsof -e /run/user/1000/gvfs -e /run/user/1001/gvfs -c cat COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME cat 218180 brendan cwd DIR 8,9 4096 2878760 /home/brendan cat 218180 brendan rtd DIR 8,9 4096 2 / cat 218180 brendan txt REG 8,9 37000 392787 /usr/bin/cat cat 218180 brendan mem REG 8,9 223542144 392527 /usr/lib/locale/locale-archive cat 218180 brendan mem REG 8,9 3222128 392896 /usr/lib64/libc-2.32.so cat 218180 brendan mem REG 8,9 264360 392801 /usr/lib64/ld-2.32.so cat 218180 brendan 0u CHR 4,4 0t0 2070 /dev/tty4 cat 218180 brendan 1w REG 8,9 0 2878082 /home/brendan/test-data cat 218180 brendan 2u CHR 4,4 0t0 2070 /dev/tty4 [root@attic5-f33 ~]# lsof -e /run/user/1000/gvfs -e /run/user/1001/gvfs ~brendan/test-data COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME cat 218180 brendan 1w REG 8,9 0 2878082 /home/brendan/test-data
Another common use of
lsof is to find out which user or process might be stopping you from unmounting a file system. I keep all my LPIC-1 tutorials and research data on a separate file system that I can mount across several different systems as I work. Suppose I decide to unmount that file system mounted at ~ian/data. Listing 27 shows one way I might do it and how to use
lsof to find out who is stopping me.
Listing 27. Who is stopping umount?
[root@attic5-f33 ~]# df ~ian/data Filesystem 1K-blocks Used Available Use% Mounted on /dev/sdb2 128491172 72405540 49515648 60% /home/ian/data [root@attic5-f33 ~]# umount /dev/sdb2 umount: /home/ian/data: target is busy. [root@attic5-f33 ~]# lsof -e /run/user/1000/gvfs -e /run/user/1001/gvfs /dev/sdb2 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME oosplash 3204 ian cwd DIR 8,18 4096 4591924 /home/ian/data/lpic-1/l-lpic1-110-1 soffice.b 3239 ian cwd DIR 8,18 4096 4591924 /home/ian/data/lpic-1/l-lpic1-110-1 soffice.b 3239 ian 31uW REG 8,18 40186 4591941 /home/ian/data/lpic-1/l-lpic1-110-1/l-lpic1-110-1.odt
Not surprisingly, it is I who have an open document as I write this tutorial!
lsof package comes with a file called 00QUICKSTART with a large number of useful examples. It is probably located at /usr/share/doc/lsof/00QUICKSTART. If not, try running the
locate 00QUICKSTART command to find it.
Note: You may need to install the mlocate package to run the
fuser command to find the process that is using one or more particular files. Use the
-a option if you want the output for all the files in your list, even if nobody is using any of them. Use the
-k option if you want to kill the process. Use the
-u option to see the username associated with the process ID. Figure 28 shows some basic examples. As usual, consult the man or info pages for additional information on other options.
Listing 28. Using fuser
[root@attic5-f33 ~]# fuser -a ~ian/bashrc ~brendan/test-data Specified filename /home/ian/bashrc does not exist. /home/ian/bashrc: /home/brendan/test-data: 218180 [root@attic5-f33 ~]# fuser -u ~brendan/test-data /home/brendan/test-data: 218180(brendan) [root@attic5-f33 ~]# fuser -uk ~brendan/test-data /home/brendan/test-data: 218180(brendan) [root@attic5-f33 ~]# fuser -a ~brendan/test-data /home/brendan/test-data:
Use and configure sudo
When you need to administer a system you usually need to run some commands with root authority. You already saw that the suid permission would allow you to do this, but there are only a limited number of special purpose commands that have this permission set. So your choices are to log in as root, become root temporarily, or gain root access for a single command. You may absolutely need to log in as the root user to fix problems, such as the one I had tonight when one of my hard drives failed. The system would not boot into graphical mode until I took that mount out of /etc/fstab. However, logging in as the root user, particularly with a graphical desktop, is not a great idea if you don’t need to do it. And if you connect to a system using SSH, you should generally not allow root login. Most SSH server installations today disallow this by default.
After you have logged in as a regular user, you can use the
su command to temporarily become another user, or the
sudo command to run a command as another user. These are rather loose descriptions of the differences between the commands, but many old system admins see them that way. In fact, either allow you to run a single command as another user or become another user for a series of commands. One major difference between the
sudo commands is that you need the password of the user you want to become in order to use
su while you use your own password to authenticate using
sudo. When you use the
su command, provide a user name as a parameter. If no user name is provided, you are assumed to be a root user.. If no command is provided, you enter an interactive shell. If you use the
--login options, the shell will be started as a login shell with an environment similar to a real login. Use the
-c option if you want to run a single command or script. Look at how some of the environment variables and the current working directory change in the examples in Listing 29.
Listing 29. Basic use of su
mian@attic5-u20:~$ su mary -c 'echo $HOME;pwd' Password: /home/mary /home/ian ian@attic5-u20:~$ su - mary -c 'echo $HOME;pwd' Password: /home/mary /home/mary ian@attic5-u20:~$ su - mary Password: mary@attic5-u20:~$ echo $HOME;pwd /home/mary /home/mary mary@attic5-u20:~$ # Use ctrl-d or logout to exit mary@attic5-u20:~$ logout
Debian-based systems use the ‘!’ password in /etc/shadow for the root user as I described when discussing about locking passwords in the section, Set or change user passwords and password aging. So it is not possible to become root on such a system using
su. You will see an authentication failure as shown in Listing 30 on my Ubuntu 20.04 LTS system.
Listing 30. Using su – on Debina-based systems
ian@attic5-u20:~$ su - -c 'echo $HOME;pwd' Password: su: Authentication failure ian@attic5-u20:~$ su - Password: su: Authentication failure
For such systems you must use
sudo to do administrative tasks that you might otherwise do by logging in or becoming the root user. Other than having different parameters, there are some subtle differences between
sudo. In particular, all environment variables may not be set as you might expect, even if you use the
--login option to run the shell specified by the target user’s /etc/passwd entry as a login shell. Consider the differences between running a single command and launching an interactive shell for another user as shown in Listing 31.
Listing 31. Using sudo
ian@attic5-u20:~$ sudo -u mary echo '$HOME';pwd [sudo] password for ian: $HOME /home/ian ian@attic5-u20:~$ sudo -i -u mary echo '$HOME';pwd /home/mary /home/ian ian@attic5-u20:~$ sudo -i -u mary mary@attic5-u20:~$ echo $HOME;pwd /home/mary /home/mary mary@attic5-u20:~$ logout
Notice that I only entered my password once for all three invocations of
sudo as compared to having to enter it for each invocation of
su. Credentials are usually cached for a configurable amount of time, usually a few minutes. That makes it easier to run several commands in succession using
Another difference between
sudo is that it is configurable and commands that run using
sudo can be logged. Default installations often set up an initial user as a member of the admin group or the wheel group. These groups are often configured to give members full root authority. Other users, say database administrators or web server operators, may be limited in the commands they are allowed to run. Some users (such as mary in my examples) may have no authority at all as I show in Listing 32.
Listing 32. User mary trying to use sudo
mary@attic5-u20:~$ sudo -u ian ls [sudo] password for mary: mary is not in the sudoers file. This incident will be reported.
The configuration for
sudo is usually in /etc/sudoers with additional files possibly included from the /etc/sudoers.d directory. The permission bits on these files should be 0440 (ug=r) as shown in Listing 33.
Listing 33. Sudoers files and their permissions
ian@attic5-u20:~$ ls -l /etc/sudoers* -r--r----- 1 root root 755 Feb 3 2020 /etc/sudoers /etc/sudoers.d: total 8 -r--r----- 1 root root 91 Jul 10 09:59 99-snapd.conf -r--r----- 1 root root 958 Feb 3 2020 README
These files are read-only and need to be edited using the
visudo command. Traditionally, this used the
vi editor, but today other editors,such as
nano, may be the default. A plug-in model is used for
sudo. The plug-in configuration is either defaulted or found in sudo.conf.
The info pages for sudo run to nearly 3000 lines on my Ubuntu 20.04 LTS system. Much of the specification is in Extended Backus-Naur Form (EBNF) which is briefly explained within the pages. The main components of the sudoers file are aliases and user specifications. Aliases are essentially variables that can be combined in various ways to create user specifications. User specifications say who can do what and where. The file also contains some default values and specifications if logging is enabled.
There are four kinds of aliases: User_Alias, Runas_Alias, Host_Alias, and Cmnd_Alias. User aliases and runas aliases include user names, user numbers, groups and group IDs. Host aliases include host names and IP addresses. Cmnd (command) aliases are lists of commands that a user may run. The alias ALL for any of these matches all instances. A user specification is a line of the form: who where = (as_whom) what. The default sudoers entries on my Ubuntu 20.04 LTS system look as shown in Listing 34.
Listing 34. Typical default sudoers user specifications
# 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
For a brief introduction to explain how all this works together, I will create a rather trivial file /etc/sudoers/88-lpic-1 which will allow user mary to run the
apt command to install packages. This file illustrates the use of aliases and how to set up logging so that all
sudo commands and sessions are logged, except those for the
sudoreplay commands. The
visudo command will check the syntax of your sudoers files on exit, but you can also check it with the
-c option. The example file and a check are shown in Listing 35. Note that alias names allow only upper case letters, numbers, and underscores. It must start with an uppercase letter.
Listing 35. Adding sudoer definitions and logging
ian@attic5-u20:~$ sudo cat /etc/sudoers.d/88-lpic-1 ## Simple example for tutorial for LPIC-1 topic 110.1 User_Alias INSTALLERS = ian,mary Cmnd_Alias PKGMGR = /usr/bin/apt INSTALLERS ALL = (ALL) PKGMGR ## Enable logging Defaults log_output Defaults! /usr/bin/sudoreplay !log_output Defaults! /sbin/reboot !log_output ## ian@attic5-u20:~$ sudo visudo -c /etc/sudoers: parsed OK /etc/sudoers.d/88-lpic-1: parsed OK /etc/sudoers.d/README: parsed OK
If other specifications are absent,
sudo input or output is logged in the /var/log/sudo-io/ directory.
Users can run the
sudoreplay command to list all available sessions and to replay them. The list may be long so you can filter by command name, username, from date or to date, and other criteria. Listing 36 shows some examples.
Listing 36. Using sudoreplay
an@attic5-u20:~$ sudo sudoreplay -l todate "Dec 16 17:51:27" Dec 16 17:40:56 2020 : ian : TTY=/dev/pts/0 ; CWD=/home/ian ; USER=root ; TSID=000001 ; COMMAND=/usr/sbin/visudo -c Dec 16 17:41:15 2020 : mary : TTY=/dev/pts/1 ; CWD=/home/mary ; USER=root ; TSID=000002 ; COMMAND=/usr/bin/apt install mlocate Dec 16 17:42:33 2020 : ian : TTY=/dev/pts/0 ; CWD=/home/ian ; USER=root ; TSID=000003 ; COMMAND=/usr/bin/ls /var/log/sudo-io Dec 16 17:51:04 2020 : ian : TTY=/dev/pts/0 ; CWD=/home/ian ; USER=root ; TSID=000004 ; COMMAND=/usr/bin/cat /etc/sudoers/88-lpic-1 Dec 16 17:51:27 2020 : ian : TTY=/dev/pts/0 ; CWD=/home/ian ; USER=root ; TSID=000005 ; COMMAND=/usr/bin/cat /etc/sudoers/88-lpic-1 ian@attic5-u20:~$ info sudoreplay ian@attic5-u20:~$ sudo sudoreplay -l user mary Dec 16 17:41:15 2020 : mary : TTY=/dev/pts/1 ; CWD=/home/mary ; USER=root ; TSID=000002 ; COMMAND=/usr/bin/apt install mlocate ian@attic5-u20:~$ sudo sudoreplay 000002 Replaying sudo session: /usr/bin/apt install mlocate Reading package lists... Done Building dependency tree Reading state information... Done mlocate is already the newest version (0.26-3ubuntu3). 0 upgraded, 0 newly installed, 0 to remove and 6 not upgraded.
The man or info pages for
sudoreplay provide much more information than I can include in this tutorial. The Sudo Main Page (see Resources) is also a wealth of information.
This concludes your introduction to Topic 110.1: Perform security administration tasks.