Introduction
Linux is a vital part of the server and cloud infrastructure; it is reported that around 96% of the top one million web servers use Linux! Moreover, Linux powers under half (%40) of websites whose OS is unknown [1]. Those are some staggering figures.
With the market size of Linux set to reach $15.6 billion by 2027 [1], it is therefore important to know the fundamentals of the Linux operating system, and more importantly, how to navigate around it.
In this post, I will describe and explain a few of the most useful commands for typical users, or even system administrators. I am passionate about Linux and believe everybody should expand their horizons and venture into the world of open-source software.
Note The commands listed and described are in no specific order. Furthermore, I will not be listing the most basic Linux commands, such as pwd
, touch
and echo
. This blog post focuses more so on efficiency and practical uses.
shred
Shred allows you to overwrite a file and also delete it. This is useful in cases when a user wants to ensure that a file is not forensically recoverable.
Shred overwrites the file (or standard input) with random data. Typically, this is accomplished via a set of iterations using -n
which is set to three by default. To hide shredding, you can use the -z
option to overwrite the last iteration with zeroes. Typically, a user may want to remove the file, this can be done with -u
.
For example:
shred -zun 20 example.txt
Here the number of iterations is set to twenty, the file is zeroed in the last overwrite and the file is removed once completed.
usermod
Usermod allows you to modify a user account. A typical example would be adding a certain user to a group. Let's say we wanted to add the user tcincere
to the docker
group. This is accomplished via -a
and -G
which appends a user to a group or list of groups. For example:
usermod -aG docker tcincere
Here, the group name is the first positional parameter; then comes the username. A user can be added to several groups via a comma-separated list:
usermod -aG docker,lxd,wheel tcincere
Unless you are root, the command must be prefixed with sudo:
sudo usermod -aG docker tcincere
# or
sudo usermod -aG docker,lxd,wheel tcincere
Another CLI tool can then be used to remove a user from a specific group: gpasswd
. To remove a user from a group, do:
gpasswd -d user group
# For example:
gpasswd -d tcincere docker
The -d
flag stands for delete. The longhand version can be used too: `--delete``.
chsh
Chsh allows you to switch the login shell of a particular user. We can procure a list of valid login shells via: cat /etc/shells
, which on my system produces this output:
# /etc/shells: valid login shells
/bin/sh
/bin/bash
/usr/bin/bash
/bin/rbash
/usr/bin/rbash
/usr/bin/sh
/bin/dash
/usr/bin/dash
We may want our default shell to be /bin/sh
instead of bash, which is usually the default shell on most Linux systems. This can be accomplished via the -s
flag.
chsh -s /bin/sh tcincere
We can verify this worked by checking /etc/passwd
, which historically, contained the list of users and their associated hashed passwords. However, currently, the passwd
file contains a list of users, and their associated shell, along with some other information.
We can check which shell our current user uses as default via:
grep $(whoami) /etc/passwd | cut -d ":" -f 7
This uses grep
which takes the output of the whoami
command and searches for a line which matches the pattern within the passwd
file. The output:
tcincere:x:1000:1000:tcincere,,,:/home/tcincere:/bin/bash
The output is piped into cut, which cuts the input via the colon delimiter. The seventh field is selected, which contains the user's default login shell.
Security tip We can use the chsh
utility to disable users gaining access to the root account via the command-line. This means users will not be able to gain a shell as root, thus ensuring that an attacker cannot access the entire file-system. This is accomplished using the /usr/sbin/nologin
'shell'.
For example:
sudo chsh -s /usr/bin/nologin root
This can be verified via: grep root /etc/passwd
root:x:0:0:root:/root:/usr/sbin/nologin
You cannot login to a shell as the root user now!
find
find allows you to search for files or directories within a specified directory. This command becomes especially useful when searching SETUID binaries, or files of which you know the name, but are not sure where they are located. The find command typically works like this:
find directory -type f -name "name"
You first specify the directory to look into, the type (file or directory), the type (directory or file) and the name of the file. This is probably the most basic usage of find
. A practical usage is looking for any SETUID binaries; this may help in privilege escalation. To do this, we need to look throughout the entire file-system anywhere. The command is as follows:
find / -perm -4000 2>/dev/null
We first indicate with a /
that we are to search for SETUID binaries within the root file-system. Subsequently, -perm
specifies the permission bits (-4000, for SETUID binaries). Next, all stderr
output is redirected towards /dev/null
and does not get printed.
The 2
indicates stderr
, whereas 1
indicates stdout
. Here, /dev/null
is a Linux pseudo-device which acts as a void - any output does not get outputted to the terminal. In BASH, we can send all output to /dev/null
using the shorthand: &>/dev/null
.
With find
, we can also specify the current directory, and search using regular expressions. Let's say we wanted to find all files ending in .txt
.
find . -name "*.txt"
The .
refers to the current directory, and find
will recursively look through each directory (if they exist) for any files ending with .txt
. Impressive!
Below are some practical uses of find
you might need to use:
Find all hidden files in the current directory
find . -type f -name ".*"
Find empty directories
find . -type d -empty
# We can remove then using this one liner.
# Command subsitutation and a for loop to remove each empty directory
for file in $(find . -type d -empty); do rmdir $file; done
Find executable files allowed by the current user in the current directory
find . -type f -perm /u=x
chmod
chmod
allows you to change the permissions of a file or directory. We must first understand rwx
permissions which stand for read, write and execute. On a Linux system, the permissions for a directory or file can be listed using ls -l
. For example:
~/Desktop $ ls -l
total 8.0K
-rw-rw-r-- 1 tcincere tcincere 3 May 21 14:35 file.txt
drwxrwxr-x 2 tcincere tcincere 4.0K May 21 14:16 test
We can see on the left hand-side, many permissions.
-rw-rw-r--
drwxrwxr-x
The first bit is set to either a d
for a directory or a -
for a file. The next bits are broken into three components. Each component holds bits for the read, write and execute permissions.
The first component (set of three bits after the -
or -d
bit) are permissions for the user. The next three bits are for the group. And the last bits are for 'other' or 'all'; those not the user or not in the group. You may see a -
after the initial file type bit. This means no permissions are set.
We can modify permissions in two main methods, however, the easiest to comprehend is using the following syntax:
chmod u=rwx file.txt
chmod g-rw file.txt
chmod a- file.txt
I've set permissions on the user, group and others. Here, the user is gaining read, write and execute permissions on file.txt
; as evidenced by the =
. Meaning we are 'giving' permissions. The rest shows chmod removing permissions, denoted by the -
. We took away the read and write permissions for the group and took away all permissions for others. Using ls -l
we can see the new permissions.
~/Desktop $ ls -l
total 8.0K
-rwx------ 1 tcincere tcincere 3 May 21 14:35 file.txt
drwxrwxr-x 2 tcincere tcincere 4.0K May 21 14:16 test
We can see that only the tcincere user has read, write and execute permissions over the file. chmod
is especially useful when you want to dictate which permissions users, groups or others have over the file.
Method 2
Another way to issue permissions using chmod
is via numerical representation. For example:
chmod 700 file.txt
This is a shorthand to issue only read, write and execute permissions on file.txt
; leaving no permissions for group or others.
These values have a certain value assigned to them.
-
Read (r): 4
-
Write (w): 2
-
Execute (x): 1
Let's say we wanted to allow the group and others to read and execute file.txt
. It would be accomplished like this:
chmod 755 file.txt
Here, we sum the values:
-
User
- Read + Write + Execute = 4 + 2 + 1 = 7
-
Group and Other
- Read + Execute = 4 + 1 = 5
Therefore, we issue chmod 755
to file.txt. Great!
A practical example
Typically when we want to ssh
into a server, the best practice is to use a private key. However, the private key must have certain permissions, or ssh
will not allow you to log in to the server. On the private key file (generally id_rsa
) you would need to use chmod
to change the permissions. The practice is:
chmod 600 id_rsa
This means only the current user has read and write permissions, whereas the group and others have no permissions.
-
User
- Read + Write = 4 + 2 = 6
-
Group and Other
- Read + Execute + Execute = 0 + 0 + 0 = 0
Conclusion
Learning Linux is a great skill to have and it can elevate your efficiency around the command-line. Taking the time to learn these skills is rewarding and a blast!