Introduction to Linux Hardening
Tags: security, linux
Published: 2019-04-22 12:08:42

---
title: Introduction to Linux Hardening
published: true
description: Let's take a look at a simple Linux Hardening.
tags: security, linux
---


It's been a while! I've been working on so many projects recently, but one of the most important ones is related with **Linux Hardening**. This week I'm going to give a speech about it and I'd love to share a bit beforehand.

First of all, Linux Hardening is to enhance the security level of the system, mostly through low level commands to check and edit the basic/default OS values. 

![](http://img.webme.com/pic/i/ilja-spb/tux_the_warrior_1.png)

## Encrypt

We can use LUKS for disk and volumes encryption. On the other hand we can count on `openssl` or `gpg` for encrypt different kind of files. Let's take a look at these two options:

```
$ gpg --output nombre_salida --passphrase nuestra_contraseña --batch --no-tty --symmetric archivo_a_cifrar
$ openssl rsautl -encrypt -pubin -inkey miclave.pub -ssl -in archivo_a_cifrar -out salida
```
First one let us encrypt large files using a passphrase, while the second one uses a public key but can't encrypt large files.

## Permits

The command `ls -ahl /home/ 2>/dev/null` let us check `home` permits. We can review all writting permitis unless in one directory (let's call it "example") and its content using `find / -perm -222 -type d -not -path "/ejemplo/*"` and execution permits using `find / -executable -type d`. The `find` tool basically allow us looking for directories and files, `-type d` option search for directories, there are a lot of options:

* b    block (buffered) special
* c    character (unbuffered) special
* d    directory
* p    pipe (FIFO)
* f    regular file
* l    symbolic link
* s    socket
* D    door (Solaris)

It's very important to check for empty password in accounts. We can check this information in `/etc/shadows`. This is an example of an user account:

```
ejemplousuario:$6$XOivHvJZ$DthDIzmVnzMigsByXQ2diHJZ9LFbROkyGyXnZ.98t5vpECl96Jmk621hquET/z8fbS9L5n4sFvTsvMtkBSWJM/:17911:0:99999:7:::
```
Basically, in order we find: username, password algorithm, password, last time it was changed (since 1 of January of 1970), minimum days that must pass until password is changed, maximum days password is valid, days until the user is told to change the password, password expiration (not in the example) and absolute expiration date (not in the example). Although, we can check relevant password policy easier using 
`grep "^PASS_MAX_DAYS\|^PASS_MIN_DAYS\|^PASS_WARN_AGE\|^ENCRYPT_METHOD" /etc/login.defs 2>/dev/null`.

```
awk -F: '($2 == "") {print}' /etc/shadow
``` 
This command let us check if an account has an empty password checking the second value of the structure explained. We can also use:

```
awk -F: '($3 == "0") {print}' /etc/passwd
```
to check that only `root` has UID 0, if not we should take care of it.

## Physical security

We shall not forget systems must be physically protected too! Let's use a password for both BIOS and GRUB Boot Loader. Disable USB boot, too. Fedora, CentOS and others can interactively startup using l key, we can disable it editing `/etc/sysconfig/init` and changing prompt to "no" in `PROMPT=no` line. If we disable USB Mass Storage driver we are limiting the USB devices in the system, avoiding attacks through rubber ducky, bad usb and such. 

```
$ ls -l /lib/modules/$(uname -r)/kernel/drivers/usb/storage/usb-storage.ko
```
We can also have a blacklist of devices configuring a `blacklist.conf` in `/etc/modprobe.d/`.

## SSH

We can check if root allows login via SSH using:

```
$ grep "PermitRootLogin " /etc/ssh/sshd_config 2>/dev/null | grep -v "#" | awk '{print  $2}'
```
Speaking of which, it's recommended to use a public key in order to perform a secure login.

```
$ ssh-keygen -t key_type -b bits -C "comentario"
$ ssh-keygen -t ed25519 -C "Login al cluster de produccion"
$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_aws_$(date +%Y-%m-%d) -C "AWS para clientes"
```

To install a key, we can use `ssh-copy-id`. We can also limit access using `AllowUsers` and `DenyUsers`, as well as `PermitEmptyPasswords no` to disable empty passwords.

## Cron Jobs

Using `ls -la /etc/cron*` we can quickly check jobs programmed hourly, dayly monthly and weekly. We can see `cron.d`, for a modular scan of crontab files, but if we want to check individual live crontabs we can use `ls -la /var/spool/cron/crontabs`.

## Others

We could also like to check who else is connected at that time, using `w 2>/dev/null`. We can also check users and groups with `root` priviledges using `grep -v -e '^$' /etc/sudoers |grep -v "#"`. We use that in order to avoid commented lines (`#`). Also `/etc/login.defs` contains interesting information of general user information, `useradd` and `groupadd` for example uses values from this file. We could also try and check umask values using `umask -S & umask` (symbolic `-S` and octal values). In order to avoid SNMP Reflection attack we can check default ports of SNMP using `cat /etc/services | grep -i snmp`.

I encourage you all to experiment, script and play with this information, for the shake of security! :)