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.
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
The -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
2626618
Show more
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.
The 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 (%p).
Listing 3. Generating a list of files with suid set
The 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
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.
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 userbrendan.
passwd: Success
Show more
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.
Show more
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 passwd or 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 brendanAdjustingagingdataforuserbrendan.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 brendanbrendanPS2020-12-07 190814(Passwordset,SHA512crypt.)
[root@attic5-f33~]# passwd -S ianianPS2020-12-01 0999997-1(Passwordset,SHA512crypt.)
[root@attic5-f33~]# # list settings using chage
[root@attic5-f33~]# chage -l brendanLast password change :Dec08,2020Password expires :Mar08,2021Password inactive :Mar22,2021Account expires :neverMinimum number of days between password change :1Maximum number of days between password change :90Number of days of warning before password expires :8
Show more
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 -l and -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 brendanLocking password for user brendan.
passwd:Success
[root@attic5-f33 ~]# passwd -S brendan
brendan LK2020-11-17190814 (Password locked.)
[root@attic5-f33 ~]# grep brendan /etc/shadowbrendan:!!$6$Pjwv1j/M63 ... iOOQ/ct/:18584:1:90:8:14::
[root@attic5-f33 ~]# passwd -u brendanUnlocking password for user brendan.
passwd:Success
Show more
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 +%F2020-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 : Dec06, 2020
Minimum number of days between password change : 1
Maximum number of days between password change : 90Number 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
Show more
The passwd and 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 -L and -U options lock and unlock a password by prepending a '!' in /etc/shadow similar to the -l and -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 ~]# nmaplocalhostStartingNmap7.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): ::1Notshown: 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).
Notshown: 999 closed ports
PORT STATE SERVICE
22/tcp open ssh
Nmap done: 1 IP address (1 host up) scanned in 0.17 seconds
Show more
If you don't recognize a port number, try using the grep command with /etc/services as shown in Listing 12.
These examples show that local users on my system can use ssh, scp, or 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 ssh.
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 ~]# # CheckmySlackwaresystem[root@attic5-f33 ~]# nmapattic4StartingNmap7.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).
Notshown: 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 (104.102.193.57)
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 104.102.193.57: a104-102-193-57.deploy.static.akamaitechnologies.com
Notshown: 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 (65.39.134.146)
Host is up (0.035s latency).
Notshown: 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
Show more
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 (65.39.134.146)
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
Show more
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 -p U:53,111,137,T:21-25,80.
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-p22-23-dlpi.orgStartingNmap7.80 ( https://nmap.org ) at 2020-12-11 21:51 EST
--------------- Timing report ---------------
hostgroups: min 1, max 100000rtt-timeouts: init 1000, min 100, max 10000max-scan-delay: TCP 1000, UDP 1000, SCTP 1000parallelism: min 0, max 0max-retries: 10, host-timeout: 0min-rate: 0, max-rate: 0
---------------------------------------------
Initiating Ping Scan at 21:51
Scanning lpi.org (65.39.134.146) [4 ports]
Packet capture filter (device enp9s0): dst host 192.168.1.25and (icmp or icmp6 or ((tcp or udp or sctp) and (src host 65.39.134.146)))
We got a TCP ping packet back from 65.39.134.146 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:51mass_rdns: 0.00s0/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 (65.39.134.146) [2 ports]
Packet capture filter (device enp9s0): dst host 192.168.1.25and (icmp or icmp6 or ((tcp or udp or sctp) and (src host 65.39.134.146)))
Discovered open port 22/tcp on 65.39.134.146
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 (65.39.134.146)
Host is up, received syn-ack ttl 52 (0.036s latency).
Scanned at 2020-12-1121:51:56 EST for 1s
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 5223/tcp filtered telnet no-response
Final times for host: srtt: 36474rttvar: 28663to: 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)
Show more
The 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.
The 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 00 attic5-f33:47540 attic4:ssh ESTABLISHED
tcp 00 attic5-f33:39120 ec2-54-173-95-250:https ESTABLISHED
tcp 00 attic5-f33:37244 stackoverflow.com:https ESTABLISHED
tcp 00 attic5-f33:50860 ec2-52-37-190-150:https ESTABLISHED
tcp 10 attic5-f33:35326 ec2-3-211-216-81.:https CLOSE_WAIT
tcp 00 attic5-f33:40864 server-99-86-230-:https ESTABLISHED
tcp 00 attic5-f33:ssh attic4:38340 ESTABLISHED
tcp 00 attic5-f33:45014 ec2-54-158-98-5.c:https ESTABLISHED
tcp6 102603-6081-1902-7d:50684 iad23s87-in-x03.1:https CLOSE_WAIT
tcp6 102603-6081-1902-7d:43824 2606:4700::6812:1:https CLOSE_WAIT
tcp6 102603-6081-1902-7d:50336 2600:9000:2191:a0:https CLOSE_WAIT
tcp6 102603-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 00 192.168.1.25:47540192.168.1.24:22 ESTABLISHED
tcp 00 192.168.1.25:3912054.173.95.250:443 ESTABLISHED
tcp 00 192.168.1.25:37244198.252.206.25:443 ESTABLISHED
tcp 00 192.168.1.25:5086052.37.190.150:443 ESTABLISHED
tcp 10 192.168.1.25:353263.211.216.81:443 CLOSE_WAIT
tcp 00 192.168.1.25:4086499.86.230.113:443 ESTABLISHED
tcp 00 192.168.1.25:22192.168.1.24:38340 ESTABLISHED
tcp 00 192.168.1.25:4501454.158.98.5:443 ESTABLISHED
tcp6 102603:6081:1902:7d:50684 2607:f8b0:4004:829::443 CLOSE_WAIT
tcp6 102603:6081:1902:7d:43824 2606:4700::6812:173:443 CLOSE_WAIT
tcp6 102603:6081:1902:7d:50336 2600:9000:2191:a00::443 CLOSE_WAIT
tcp6 102603: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 00 attic5-f33:bootpc _gateway:bootps ESTABLISHED
udp 00 attic5-f33:bootpc _gateway:bootps ESTABLISHED
[root@attic5-f33 ~]# netstat -l |wc
967698200
Show more
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
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
Show more
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
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 1413: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 1413:46 testfile
joe@attic4-sl42:~$ echo $(( 25000 * 1024 )) # 25000 blocks of 1K25600000
Show more
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
Show more
Four commands are commonly used to display information from these files.
The who command by default displays information from the utmp file about currently logged-in users. A non-option parameter may specify another file such as wtmp.
The w command combines information from the utmp file and the /proc file system to display more information about logged in users.
The last command displays data about a current or a previous login activity from the wtmp file.
The lasstb command displays information about failed login attempts from the btmp file (if this file exists).
Listing 22 shows basic usage of the who and 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 brendan@192.168.1.25
brendan pts/4 12:04 56:21 0.04s 0.04s -bash
brendan tty4 12:05 8:29 0.04s 0.00s cat
Show more
Both commands have several options that are further described in the man or info pages. One useful variant for who is who am i to find out who is using a terminal or terminal session. The -m option does the same thing.
The 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 -n (or -num) option. Listing 23 shows an example.
Listing 23. Basic use of the last command
ian@attic4-sl42:~$ last -n 10ian pts/3192.168.1.25 Sat Dec 1221:05 still logged in
ian pts/4 :0 Sat Dec 1221:02 - 21:04 (00:01)
ian pts/3192.168.1.25 Thu Dec 1016:52 - 21:05 (2+04:12)
ian pts/2 :0 Tue Dec 818:26 still logged in
ian pts/2192.168.1.25 Wed Dec 212:58 - 12:58 (00:00)
ian pts/3192.168.1.25 Tue Nov 2417:50 - 17:54 (00:03)
ian pts/2192.168.1.25 Tue Nov 2413:50 - 13:50 (5+00:00)
ian pts/2127.0.0.1 Tue Nov 2413:15 - 13:16 (00:00)
ian pts/1 :0 Tue Nov 2413:15 still logged in
ian pts/0 :0 Tue Nov 2413:15 still logged in
wtmp begins Sun Nov 1915:48:302017
Show more
Use the -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 -s and -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
Show more
The 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.
311816339250343770989
Show more
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.
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 UsedAvailableUse%Mounted on
/dev/sdb2 128491172724055404951564860%/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
COMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAME
oosplash 3204 ian cwd DIR8,1840964591924/home/ian/data/lpic-1/l-lpic1-110-1
soffice.b 3239 ian cwd DIR8,1840964591924/home/ian/data/lpic-1/l-lpic1-110-1
soffice.b 3239 ian 31uW REG8,18401864591941/home/ian/data/lpic-1/l-lpic1-110-1/l-lpic1-110-1.odt
Show more
Not surprisingly, it is I who have an open document as I write this tutorial!
The 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 locate command.
Use 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-dataSpecified 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:
Show more
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 su and 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 -, -l or --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
Show more
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
Show more
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 su and sudo. In particular, all environment variables may not be set as you might expect, even if you use the -i or --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
Show more
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 sudo.
Another difference between su and 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.
Show more
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
Show more
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 admingroup may gain root privileges
%adminALL=(ALL) ALL
# Allow members ofgroup sudo toexecuteany command
%sudo ALL=(ALL:ALL) ALL
Show more
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 reboot or 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
Show more
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 toremoveand 6 not upgraded.
Show more
The man or info pages for su, sudoers, visudo, and sudoreplay provide much more information than I can include in this tutorial. The Sudo Main Page (see Resources) is also a wealth of information.
Conclusion
This concludes your introduction to Topic 110.1: Perform security administration tasks.
About cookies on this siteOur websites require some cookies to function properly (required). In addition, other cookies may be used with your consent to analyze site usage, improve the user experience and for advertising.For more information, please review your cookie preferences options. By visiting our website, you agree to our processing of information as described in IBM’sprivacy statement. To provide a smooth navigation, your cookie preferences will be shared across the IBM web domains listed here.