imthenachoman/How-To-Secure-A-Linux-Server

An evolving how-to guide for securing a Linux server.

How To Secure A Linux Server

An evolving how-to guide for securing a Linux server that, hopefully, also teaches you a little about security and why it matters.

raw.githubusercontent.com/imthenachoman/How-To-Secure-A-Linux-Server/master

Table of Contents

Introduction

Guide Objective

Why Secure Your Server

Why Yet Another Guide

Other Guides

To Do / To Add

Guide Overview

About This Guide

My Use-Case

Editing Configuration Files - For The Lazy

Contributing

Before You Start

Identify Your Principles

Picking A Linux Distribution

Installing Linux

Pre/Post Installation Requirements

Other Important Notes

Using Ansible Playbooks to secure your Linux Server

The SSH Server

Important Note Before You Make SSH Changes

SSH Public/Private Keys

Create SSH Group For AllowGroups

Secure /etc/ssh/sshd_config

Remove Short Diffie-Hellman Keys

2FA/MFA for SSH

The Basics

Limit Who Can Use sudo

Limit Who Can Use su

Run applications in a sandbox with FireJail

NTP Client

Securing /proc

Force Accounts To Use Secure Passwords

Automatic Security Updates and Alerts

More Secure Random Entropy Pool (WIP)

Add Panic/Secondary/Fake password Login Security System

The Network

Firewall With UFW (Uncomplicated Firewall)

iptables Intrusion Detection And Prevention with PSAD

Application Intrusion Detection And Prevention With Fail2Ban

Application Intrusion Detection And Prevention With CrowdSec

The Auditing

File/Folder Integrity Monitoring With AIDE (WIP)

Anti-Virus Scanning With ClamAV (WIP)

Rootkit Detection With Rkhunter (WIP)

Rootkit Detection With chrootkit (WIP)

logwatch - system log analyzer and reporter

ss - Seeing Ports Your Server Is Listening On

Lynis - Linux Security Auditing

OSSEC - Host Intrusion Detection

The Danger Zone

The Miscellaneous

MSMTP (Simple Sendmail) with Google

Gmail and Exim4 As MTA With Implicit TLS

Separate iptables Log File

Left Over

Contacting Me

Helpful Links

Acknowledgments

License and Copyright

(TOC made with nGitHubTOC)

Introduction

Guide Objective

This guides purpose is to teach you how to secure a Linux server.

There are a lot of things you can do to secure a Linux server and this guide will attempt to cover as many of them as possible. More topics/material will be added as I learn, or as folks contribute.

Ansible playbooks of this guide are available at How To Secure A Linux Server With Ansible by moltenbit.

(Table of Contents)

Why Secure Your Server

I assume you're using this guide because you, hopefully, already understand why good security is important. That is a heavy topic onto itself and breaking it down is out-of-scope for this guide. If you don't know the answer to that question, I advise you research it first.

At a high level, the second a device, like a server, is in the public domain -- i.e. visible to the outside world -- it becomes a target for bad-actors. An unsecured device is a playground for bad-actors who want access to your data, or to use your server as another node for their large-scale DDOS attacks.

What's worse is, without good security, you may never know if your server has been compromised. A bad-actor may have gained unauthorized access to your server and copied your data without changing anything, so you'd never know. Or your server may have been part of a DDOS attack, and you wouldn't know. Look at many of the large scale data breaches in the news -- the companies often did not discover the data leak or intrusion until long after the bad-actors were gone.

Contrary to popular belief, bad-actors don't always want to change something or lock you out of your data for money. Sometimes they just want the data on your server for their data warehouses (there is big money in big data) or to covertly use your server for their nefarious purposes.

(Table of Contents)

Why Yet Another Guide

This guide may appear duplicative/unnecessary because there are countless articles online that tell you how to secure Linux, but the information is spread across different articles, that cover different things, and in different ways. Who has time to scour through hundreds of articles?

As I was going through research for my Debian build, I kept notes. At the end I realized that, along with what I already knew, and what I was learning, I had the makings of a how-to guide. I figured I'd put it online to hopefully help others learn, and save time.

I've never found one guide that covers everything -- this guide is my attempt.

Many of the things covered in this guide may be rather basic/trivial, but most of us do not install Linux every day, and it is easy to forget those basic things.

(Table of Contents)

Other Guides

There are many guides provided by experts, industry leaders, and the distributions themselves. It is not practical, and sometimes against copyright, to include everything from those guides. I recommend you check them out before starting with this guide.

• The Center for Internet Security (CIS) provides benchmarks that are exhaustive, industry trusted, step-by-step instructions for securing many flavors of Linux. Check their About Us page for details. My recommendation is to go through this guide (the one you're reading here) first and THEN CIS's guide. That way their recommendations will trump anything in this guide.

• For distribution specific hardening/security guides, check your distributions documentation.

security.utexas.edu/os-hardening-checklist/linux-7 - Red Hat Enterprise Linux 7 Hardening Checklist

cloudpro.zone/index.php/2018/01/18/debian-9-3-server-setup-guide-part-1 - # Debian 9.3 server setup guide

blog.vigilcode.com/2011/04/ubuntu-serve...ial-security-quick-secure-setup-part-i - Ubuntu Server Initial Security guide

tldp.org/LDP/sag/html/index.html

seifried.org/lasg

news.ycombinator.com/item

wiki.archlinux.org/index.php/Security - many folks have also recommended this one

securecompliance.co/linux-server-hardening-checklist

(Table of Contents)

To Do / To Add

Custom Jails for Fail2ban

• MAC (Mandatory Access Control) and Linux Security Modules (LSMs)

wiki.archlinux.org/index.php/security

• Security-Enhanced Linux / SELinux

en.wikipedia.org/wiki/Security-Enhanced_Linux

linuxtechlab.com/beginners-guide-to-selinux

linuxtechlab.com/replicate-selinux-policies-among-linux-machines

teamignition.us/how-to-stop-being-a-scrub-and-learn-to-use-selinux.html

• AppArmor

wiki.archlinux.org/index.php/AppArmor

security.stackexchange.com/questions/29...omparison-between-apparmor-and-selinux

insanitybit.com/2012/06/01/why-i-like-apparmor-more-than-selinux-5

• disk encryption

• Rkhunter and chrootkit

chkrootkit.org

rkhunter.sourceforge.net

cyberciti.biz/faq/howto-check-linux-rootkist-with-detectors-software

tecmint.com/install-rootkit-hunter-scan-for-rootkits-backdoors-in-linux

• shipping/backing up logs - news.ycombinator.com/item

• CIS-CAT - learn.cisecurity.org/cis-cat-landing-page

• debsums - blog.sleeplessbeastie.eu/2015/03/02/how-to-verify-installed-packages

(Table of Contents)

Guide Overview

About This Guide

This guide...

• ...is a work in progress.

• ...is focused on at-home Linux servers. All of the concepts/recommendations here apply to larger/professional environments but those use-cases call for more advanced and specialized configurations that are out-of-scope for this guide.

• ...does not teach you about Linux, how to install Linux, or how to use it. Check linuxjourney.com if you're new to Linux.

• ...is meant to be Linux distribution agnostic.

• ...does not teach you everything you need to know about security nor does it get into all aspects of system/server security. For example, physical security is out of scope for this guide.

• ...does not talk about how programs/tools work, nor does it delve into their nook and crannies. Most of the programs/tools this guide references are very powerful and highly configurable. The goal is to cover the bare necessities -- enough to whet your appetite and make you hungry enough to want to go and learn more.

• ...aims to make it easy by providing code you can copy-and-paste. You might need to modify the commands before you paste so keep your favorite text editor handy.

• ...is organized in an order that makes logical sense to me -- i.e. securing SSH before installing a firewall. As such, this guide is intended to be followed in the order it is presented, but it is not necessary to do so. Just be careful if you do things in a different order -- some sections require previous sections to be completed.

(Table of Contents)

My Use-Case

There are many types of servers and different use-cases. While I want this guide to be as generic as possible, there will be some things that may not apply to all/other use-cases. Use your best judgement when going through this guide.

To help put context to many of the topics covered in this guide, my use-case/configuration is:

• A desktop class computer...

• With a single NIC...

• Connected to a consumer grade router...

• Getting a dynamic WAN IP provided by the ISP...

• With WAN+LAN on IPV4...

• And LAN using NAT...

• That I want to be able to SSH to remotely from unknown computers and unknown locations (i.e. a friend's house).

(Table of Contents)

Editing Configuration Files - For The Lazy

I am very lazy and do not like to edit files by hand if I don't need to. I also assume everyone else is just like me. 😃

So, when and where possible, I have provided code snippets to quickly do what is needed, like add or change a line in a configuration file.

The code snippets use basic commands like echo, cat, sed, awk, and grep. How the code snippets work, like what each command/part does, is out of scope for this guide -- the man pages are your friend.

Note: The code snippets do not validate/verify the change went through -- i.e. the line was actually added or changed. I'll leave the verifying part in your capable hands. The steps in this guide do include taking backups of all files that will be changed.

Not all changes can be automated with code snippets. Those changes need good, old-fashioned, manual editing. For example, you can't just append a line to an INI type file. Use your favorite Linux text editor.

(Table of Contents)

Contributing

I wanted to put this guide on GitHub to make it easy to collaborate. The more folks that contribute, the better and more complete this guide will become.

To contribute you can fork and submit a pull request or submit a new issue.

(Table of Contents)

Before You Start

Identify Your Principles

Before you start you will want to identify what your Principles are. What is your threat model? Some things to think about:

• Why do you want to secure your server?

• How much security do you want or not want?

• How much convenience are you willing to compromise for security and vice-versa?

• What are the threats you want to protect against? What are the specifics to your situation? For example:

• Is physical access to your server/network a possible attack vector?

• Will you be opening ports on your router so you can access your server from outside your home?

• Will you be hosting a file share on your server that will be mounted on a desktop class machine? What is the possibility of the desktop machine getting infected and, in turn, infecting the server?

• Do you have a means of recovering if your security implementation locks you out of your own server? For example, you disabled root login or password protected GRUB.

These are just a few things to think about. Before you start securing your server you will want to understand what you're trying to protect against and why so you know what you need to do.

(Table of Contents)

Picking A Linux Distribution

This guide is intended to be distribution agnostic so users can use any distribution they want. With that said, there are a few things to keep in mind:

You want a distribution that...

• ...is stable. Unless you like debugging issues at 2 AM, you don't want an unattended upgrade, or a manual package/system update, to render your server inoperable. But this also means you're okay with not running the latest, greatest, bleeding edge software.

• ...stays up-to-date with security patches. You can secure everything on your server, but if the core OS or applications you're running have known vulnerabilities, you'll never be safe.

• ...you're familiar with. If you don't know Linux, I would advise you play around with one before you try to secure it. You should be comfortable with it and know your way around, like how to install software, where configuration files are, etc...

• ...is well-supported. Even the most seasoned admin needs help every now and then. Having a place to go for help will save your sanity.

(Table of Contents)

Installing Linux

Installing Linux is out-of-scope for this guide because each distribution does it differently and the installation instructions are usually well documented. If you need help, start with your distribution's documentation. Regardless of the distribution, the high-level process usually goes like so:

1. download the ISO

2. burn/copy/transfer it to your install medium (e.g. a CD or USB stick)

3. boot your server from your install medium

4. follow the prompts to install

Where applicable, use the expert install option so you have tighter control of what is running on your server. Only install what you absolutely need. I, personally, do not install anything other than SSH. Also, tick the Disk Encryption option.

(Table of Contents)

Pre/Post Installation Requirements

• If you're opening ports on your router so you can access your server from the outside, disable the port forwarding until your system is up and secured.

• Unless you're doing everything physically connected to your server, you'll need remote access so be sure SSH works.

• Keep your system up-to-date (i.e. sudo apt update && sudo apt upgrade on Debian based systems).

• Make sure you perform any tasks specific to your setup like:

• Configuring network

• Configuring mount points in /etc/fstab

• Creating the initial user accounts

• Installing core software you'll want like man

• Etc...

• Your server will need to be able to send e-mails so you can get important security alerts. If you're not setting up a mail server check Gmail and Exim4 As MTA With Implicit TLS.

• I would also recommend you read through the CIS Benchmarks before you start with this guide just to digest/understand what they have to say. My recommendation is to go through this guide (the one you're reading here) first and THEN CIS's guide. That way their recommendations will trump anything in this guide.

(Table of Contents)

Other Important Notes

• This guide is being written and tested on Debian. Most things below should work on other distributions. If you find something that does not, please contact me. The main thing that separates each distribution will be its package management system. Since I use Debian, I will provide the appropriate apt commands that should work on all Debian based distributions. If someone is willing to provide the respective commands for other distributions, I will add them.

• File paths and settings also may differ slightly -- check with your distribution's documentation if you have issues.

• Read the whole guide before you start. Your use-case and/or principals may call for not doing something or for changing the order.

• Do not blindly copy-and-paste without understanding what you're pasting. Some commands will need to be modified for your needs before they'll work -- usernames for example.

(Table of Contents)

Using Ansible playbooks to secure your Linux Server

Ansible playbooks of this guide are available at How To Secure A Linux Server With Ansible.

Make sure to edit the variables according to your needs and read all tasks beforehand to confirm it does not break your system. After running the playbooks ensure that all settings are configured to your needs!

1. Install Ansible

2. git clone How To Secure A Linux Server With Ansible

3. Create SSH-Public/Private-Keys

1. Change all variables in group_vars/variables.yml according to your needs.

2. Enable SSH root access before running the playbooks:

1. Recommended: configure static IP address on your system.

2. Add your systems IP address to hosts.yml.

Run the requirements playbook using the root password you specified while installing the server:

Run the main playbook with the new users password you specified in the variables.yml file:

If you need to run the playbooks multiple times remember to use the SSH key and the new SSH port:

(Table of Contents)

The SSH Server

Important Note Before You Make SSH Changes

It is highly advised you keep a 2nd terminal open to your server before you make and apply SSH configuration changes. This way if you lock yourself out of your 1st terminal session, you still have one session connected so you can fix it.

Thank you to Sonnenbrand for this idea.

SSH Public/Private Keys

Why

Using SSH public/private keys is more secure than using a password. It also makes it easier and faster, to connect to our server because you don't have to enter a password.

How It Works

Check the references below for more details but, at a high level, public/private keys work by using a pair of keys to verify identity.

1. One key, the public key, can only encrypt data, not decrypt it

2. The other key, the private key, can decrypt the data

For SSH, a public and private key is created on the client. You want to keep both keys secure, especially the private key. Even though the public key is meant to be public, it is wise to make sure neither keys fall in the wrong hands.

When you connect to an SSH server, SSH will look for a public key that matches the client you're connecting from in the file ~/.ssh/authorized_keys on the server you're connecting to. Notice the file is in the home folder of the ID you're trying to connect to. So, after creating the public key, you need to append it to ~/.ssh/authorized_keys. One approach is to copy it to a USB stick and physically transfer it to the server. Another approach is to use ssh-copy-id to transfer and append the public key.

After the keys have been created and the public key has been appended to ~/.ssh/authorized_keys on the host, SSH uses the public and private keys to verify identity and then establish a secure connection. How identity is verified is a complicated process but Digital Ocean has a very nice write-up of how it works. At a high level, identity is verified by the server encrypting a challenge message with the public key, then sending it to the client. If the client cannot decrypt the challenge message with the private key, the identity can't be verified and a connection will not be established.

They are considered more secure because you need the private key to establish an SSH connection. If you set PasswordAuthentication no in /etc/ssh/sshd_config, then SSH won't let you connect without the private key.

You can also set a pass-phrase for the keys which would require you to enter the key pass-phrase when connecting using public/private keys. Keep in mind doing this means you can't use the key for automation because you'll have no way to send the passphrase in your scripts. ssh-agent is a program that is shipped in many Linux distros (and usually already running) that will allow you to hold your unencrypted private key in memory for a configurable duration. Simply run ssh-add and it will prompt you for your passphrase. You will not be prompted for your passphrase again until the configurable duration has passed.

We will be using Ed25519 keys which, according to linux-audit.com/using-ed25519-openssh-keys-instead-of-dsa-rsa-ecdsa:

It is using an elliptic curve signature scheme, which offers better security than ECDSA and DSA. At the same time, it also has good performance.

Goals

• Ed25519 public/private SSH keys:

• private key on your client

• public key on your server

Notes

• You'll need to do this step for every computer and account you'll be connecting to your server from/as.

References

ssh.com/ssh/public-key-authentication

help.ubuntu.com/community/SSH/OpenSSH/Keys

linux-audit.com/using-ed25519-openssh-keys-instead-of-dsa-rsa-ecdsa

digitalocean.com/community/tutorials/un...-ssh-encryption-and-connection-process

wiki.archlinux.org/index.php/SSH_Keys

ssh.com/ssh/copy-id

• man ssh-keygen

• man ssh-copy-id

• man ssh-add

Steps

1. From the computer you're going to use to connect to your server, the client, not the server itself, create an Ed25519 key with ssh-keygen:

Note: If you set a passphrase, you'll need to enter it every time you connect to your server using this key, unless you're using ssh-agent.

2. Now you need to append the public key ~/.ssh/id_ed25519.pub from your client to the ~/.ssh/authorized_keys file on your server. Since we're presumable still at home on the LAN, we're probably safe from MIM attacks, so we will use ssh-copy-id to transfer and append the public key:

Now would be a good time to perform any tasks specific to your setup.

(Table of Contents)

Create SSH Group For AllowGroups

Why

To make it easy to control who can SSH to the server. By using a group, we can quickly add/remove accounts to the group to quickly allow or not allow SSH access to the server.

How It Works

We will use the AllowGroups option in SSH's configuration file /etc/ssh/sshd_config to tell the SSH server to only allow users to SSH in if they are a member of a certain UNIX group. Anyone not in the group will not be able to SSH in.

Goals

• a UNIX group that we'll use in Secure /etc/ssh/sshd_config to limit who can SSH to the server

Notes

• This is a prerequisite step to support the AllowGroup setting set in Secure /etc/ssh/sshd_config.

References

• man groupadd

• man usermod

Steps

1. Create a group:

2. Add account(s) to the group: You'll need to do this for every account on your server that needs SSH access.

(Table of Contents)

Secure /etc/ssh/sshd_config

Why

SSH is a door into your server. This is especially true if you are opening ports on your router so you can SSH to your server from outside your home network. If it is not secured properly, a bad-actor could use it to gain unauthorized access to your system.

How It Works

/etc/ssh/sshd_config is the default configuration file that the SSH server uses. We will use this file to tell what options the SSH server should use.

Goals

• a secure SSH configuration

Notes

• Make sure you've completed Create SSH Group For AllowGroups first.

References

• Mozilla's OpenSSH guidelines for OpenSSH 6.7+ at infosec.mozilla.org/guidelines/openssh

linux-audit.com/audit-and-harden-your-ssh-configuration

ssh.com/ssh/sshd_config

techbrown.com/harden-ssh-secure-linux-vps-server (broken; try web.archive.org/web/20200413100933/http...com/harden-ssh-secure-linux-vps-server)

serverfault.com/questions/660160/openss...n-internal-sftp-and-sftp-server/660325

• man sshd_config

• Thanks to than0s for how to find duplicate settings.

Steps

1. Make a backup of OpenSSH server's configuration file /etc/ssh/sshd_config and remove comments to make it easier to read:

2. Edit /etc/ssh/sshd_config then find and edit or add these settings that should be applied regardless of your configuration/setup: Note: SSH does not like duplicate contradicting settings. For example, if you have ChallengeResponseAuthentication no and then ChallengeResponseAuthentication yes, SSH will respect the first one and ignore the second. Your /etc/ssh/sshd_config file may already have some of the settings/lines below. To avoid issues you will need to manually go through your /etc/ssh/sshd_config file and address any duplicate contradicting settings. Note: If you are running OpenSSH 9.1 or later, uncomment the RequiredRSASize 3072 line in the configuration below. This enforces a minimum RSA key size of 3072 bits and will reject smaller RSA keys during authentication. This only affects RSA keys. If you use ED25519 or ECDSA keys, you are not affected. You can check your key type and size with ssh-keygen -l -f ~/.ssh/id_rsa. On older OpenSSH versions, leave the line commented out as it will prevent sshd from starting.

3. Then find and edit or add these settings, and set values as per your requirements:

Check man sshd_config for more details what these settings mean.

4. Make sure there are no duplicate settings that contradict each other. The below command should not have any output.

5. Restart ssh:

6. You can check verify the configurations worked with sshd -T and verify the output:

(Table of Contents)

Remove Short Diffie-Hellman Keys

Why

Per Mozilla's OpenSSH guidelines for OpenSSH 6.7+, "all Diffie-Hellman moduli in use should be at least 3072-bit-long".

The Diffie-Hellman algorithm is used by SSH to establish a secure connection. The larger the moduli (key size) the stronger the encryption.

Goals

• remove all Diffie-Hellman keys that are less than 3072 bits long

References

• Mozilla's OpenSSH guidelines for OpenSSH 6.7+ at infosec.mozilla.org/guidelines/openssh

infosec.mozilla.org/guidelines/key_management

• man moduli

Steps

1. Make a backup of SSH's moduli file /etc/ssh/moduli:

2. Remove short moduli:

(Table of Contents)

2FA/MFA for SSH

Why

Even though SSH is a pretty good security guard for your doors and windows, it is still a visible door that bad-actors can see and try to brute-force in. Fail2ban will monitor for these brute-force attempts but there is no such thing as being too secure. Requiring two factors adds an extra layer of security.

Using Two-Factor Authentication (2FA) / Multi-Factor Authentication (MFA) requires anyone entering to have two keys to enter which makes it harder for bad actors. The two keys are:

1. Their password

2. A 6 digit token that changes every 30 seconds

Without both keys, they won't be able to get in.

Why Not

Many folks might find the experience cumbersome or annoying. And, access to your system is dependent on the accompanying authenticator app that generates the code.

How It Works

On Linux, PAM is responsible for authentication. There are four tasks to PAM that you can read about at en.wikipedia.org/wiki/Linux_PAM. This section talks about the authentication task.

When you log into a server, be it directly from the console or via SSH, the door you came through will send the request to the authentication task of PAM and PAM will ask for and verify your password. You can customize the rules each doors use. For example, you could have one set of rules when logging in directly from the console and another set of rules for when logging in via SSH.

This section will alter the authentication rules for when logging in via SSH to require both a password and a 6 digit code.

We will use Google's libpam-google-authenticator PAM module to create and verify a TOTP key. fastmail.blog/2016/07/22/how-totp-authenticator-apps-work and jemurai.com/2018/10/11/how-it-works-totp-based-mfa have very good writeups of how TOTP works.

What we will do is tell the server's SSH PAM configuration to ask the user for their password and then their numeric token. PAM will then verify the user's password and, if it is correct, then it will route the authentication request to libpam-google-authenticator which will ask for and verify your 6 digit token. If, and only if, everything is good will the authentication succeed and user be allowed to log in.

Goals

• 2FA/MFA enabled for all SSH connections

Notes

• Before you do this, you should have an idea of how 2FA/MFA works and you'll need an authenticator app on your phone to continue.

• We'll use google-authenticator-libpam.

• With the below configuration, a user will only need to enter their 2FA/MFA code if they are logging on with their password but not if they are using SSH public/private keys. Check the documentation on how to change this behavior to suite your requirements.

References

github.com/google/google-authenticator-libpam

en.wikipedia.org/wiki/Linux_PAM

en.wikipedia.org/wiki/Time-based_One-time_Password_algorithm

fastmail.blog/2016/07/22/how-totp-authenticator-apps-work

jemurai.com/2018/10/11/how-it-works-totp-based-mfa

Steps

1. Install it libpam-google-authenticator. On Debian based systems:

2. Make sure you're logged in as the ID you want to enable 2FA/MFA for and execute google-authenticator to create the necessary token data:

Notice this is not run as root. Select default option (y in most cases) for all the questions it asks and remember to save the emergency scratch codes.

3. Make a backup of PAM's SSH configuration file /etc/pam.d/sshd:

4. Now we need to enable it as an authentication method for SSH by adding this line to /etc/pam.d/sshd: Note: Checkhere for what nullok means.For the lazy:

5. Tell SSH to leverage it by adding or editing this line in /etc/ssh/sshd_config:For the lazy:

6. Restart ssh:

(Table of Contents)

The Basics

Limit Who Can Use sudo

Why

sudo lets accounts run commands as other accounts, including root. We want to make sure that only the accounts we want can use sudo.

Goals

• sudo privileges limited to those who are in a group we specify

Notes

• Your installation may have already done this, or may already have a special group intended for this purpose so check first.

• Debian creates the sudo group. To view users that are part of this group (thus have sudo privileges):

• RedHat creates the wheel group

• See github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/39 for a note on some distributions making it so sudo does not require a password. Thanks to sbrl for sharing.

Steps

1. Create a group:

2. Add account(s) to the group: You'll need to do this for every account on your server that needs sudo privileges.

3. Make a backup of the sudo's configuration file /etc/sudoers:

4. Edit sudo's configuration file /etc/sudoers:

5. Tell sudo to only allow users in the sudousers group to use sudo by adding this line if it is not already there:

(Table of Contents)

Limit Who Can Use su

Why

su also lets accounts run commands as other accounts, including root. We want to make sure that only the accounts we want can use su.

Goals

• su privileges limited to those who are in a group we specify

References

• Thanks to olavim for sharing this idea

Steps

1. Create a group:

2. Add account(s) to the group: You'll need to do this for every account on your server that needs sudo privileges.

3. Make it so only users in this group can execute /bin/su:

(Table of Contents)

Run applications in a sandbox with FireJail

Why

It's absolutely better, for many applications, to run in a sandbox.

Browsers (even more the Closed Source ones) and eMail Clients are highly suggested.

Goals

• confine applications in a jail (few safe directories) and block access to the rest of the system

References

• Thanks to FireJail

Steps

1. Install the software: Note: for Debian 10 Stable, official Backport is suggested:

2. Allow an application (installed in /usr/bin or /bin) to run only in a sandbox (see few examples below here):

3. Run the application as usual (via terminal or launcher) and check if it's running in a jail:

4. Allow a sandboxed app to run again as it was before (example: firefox)

(Table of Contents)

NTP Client

Why

Many security protocols leverage the time. If your system time is incorrect, it could have negative impacts to your server. An NTP client can solve that problem by keeping your system time in-sync with global NTP servers

How It Works

NTP stands for Network Time Protocol. In the context of this guide, an NTP client on the server is used to update the server time with the official time pulled from official servers. Check pool.ntp.org/en for all of the public NTP servers.

Note: Starting with Debian 13 (Trixie), the classic ntp package has been removed. Running sudo apt install ntp will fail with "Package ntp has no installation candidate". Since this guide only uses NTP as a client (to sync the server's clock), the recommended approach on Debian 13+ is to use systemd-timesyncd, which is already pre-installed and requires no additional packages. See the Debian 13+ steps below.

Goals

• NTP client installed and keeping server time in-sync

References

cloudpro.zone/index.php/2018/01/27/debian-9-3-server-setup-guide-part-4

en.wikipedia.org/wiki/Network_Time_Protocol

pool.ntp.org/en

serverfault.com/questions/957302/securi...nt-on-linux-servers-config-file/957450

tf.nist.gov/tf-cgi/servers.cgi

Steps

Debian 13 (Trixie) and later: systemd-timesyncd

systemd-timesyncd is a lightweight SNTP client that is already included in Debian. Unlike the full ntpd daemon, it does not listen on any port, which makes it a smaller attack surface. For the purposes of this guide - keeping your server's clock in sync - it is all you need.

1. Enable NTP synchronization:

2. Verify it is working: You should see NTP service: active and System clock synchronized: yes in the output.

3. Configure trusted NTP servers. Make a backup of the configuration file and then edit it: Edit /etc/systemd/timesyncd.conf and uncomment/set the [Time] section:For the lazy:

4. Restart the service to apply the changes:

5. Check the synchronization status:

Debian 12 (Bookworm) and earlier: ntp package

Note: These steps apply to Debian 12 and earlier only. On Debian 13+, the ntp package is no longer available -- use the systemd-timesyncd steps above instead.

1. Install ntp. On Debian based systems:

2. Make a backup of the NTP client's configuration file /etc/ntp.conf:

3. The default configuration, at least on Debian, is already pretty secure. The only thing we'll want to make sure is we're the pool directive and not any server directives. The pool directive allows the NTP client to stop using a server if it is unresponsive or serving bad time. Do this by commenting out all server directives and adding the below to /etc/ntp.conf.For the lazy: Example /etc/ntp.conf:

4. Restart ntp:

5. Check the status of the ntp service:

6. Check ntp's status:

(Table of Contents)

Securing /proc

Why

To quote linux-audit.com/linux-system-hardening-adding-hidepid-to-proc/:

When looking in /proc you will discover a lot of files and directories. Many of them are just numbers, which represent the information about a particular process ID (PID). By default, Linux systems are deployed to allow all local users to see this all information. This includes process information from other users. This could include sensitive details that you may not want to share with other users. By applying some filesystem configuration tweaks, we can change this behavior and improve the security of the system.

Note: This may break on some systemd systems. Please see github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/37 for more information. Thanks to nlgranger for sharing.

Goals

• /proc mounted with hidepid=2 so users can only see information about their processes

References

linux-audit.com/linux-system-hardening-adding-hidepid-to-proc

likegeeks.com/secure-linux-server-hardening-best-practices

cyberciti.biz/faq/linux-hide-processes-from-other-users

Steps

1. Make a backup of /etc/fstab:

2. Add this line to /etc/fstab to have /proc mounted with hidepid=2:For the lazy:

3. Reboot the system: Note: Alternatively, you can remount /proc without rebooting with sudo mount -o remount,hidepid=2 /proc

(Table of Contents)

Force Accounts To Use Secure Passwords

Why

By default, accounts can use any password they want, including bad ones. pwquality/pam_pwquality addresses this security gap by providing "a way to configure the default password quality requirements for the system passwords" and checking "its strength against a system dictionary and a set of rules for identifying poor choices."

How It Works

On Linux, PAM is responsible for authentication. There are four tasks to PAM that you can read about at en.wikipedia.org/wiki/Linux_PAM. This section talks about the password task.

When there is a need to set or change an account password, the password task of PAM handles the request. In this section we will tell PAM's password task to pass the requested new password to libpam-pwquality to make sure it meets our requirements. If the requirements are met it is used/set; if it does not meet the requirements it errors and lets the user know.

Goals

• enforced strong passwords

Steps

1. Install libpam-pwquality. On Debian based systems:

2. Make a backup of PAM's password configuration file /etc/pam.d/common-password:

3. Tell PAM to use libpam-pwquality to enforce strong passwords by editing the file /etc/pam.d/common-password and change the line that starts like this: to this: The above options are:

• retry=3 = prompt user 3 times before returning with error.

• minlen=10 = the minimum length of the password, factoring in any credits (or debits) from these:

• dcredit=-1 = must have at least one digit

• ucredit=-1 = must have at least one upper case letter

• lcredit=-1 = must have at least one lower case letter

• ocredit=-1 = must have at least one non-alphanumeric character

• difok=3 = at least 3 characters from the new password cannot have been in the old password

• maxrepeat=3 = allow a maximum of 3 repeated characters

• gecoschec = do not allow passwords with the account's name

For the lazy:

(Table of Contents)

Automatic Security Updates and Alerts

Why

It is important to keep a server updated with the latest critical security patches and updates. Otherwise you're at risk of known security vulnerabilities that bad-actors could use to gain unauthorized access to your server.

Unless you plan on checking your server every day, you'll want a way to automatically update the system and/or get emails about available updates.

You don't want to do all updates because with every update there is a risk of something breaking. It is important to do the critical updates but everything else can wait until you have time to do it manually.

Why Not

Automatic and unattended updates may break your system and you may not be near your server to fix it. This would be especially problematic if it broke your SSH access.

Notes

• Each distribution manages packages and updates differently. So far I only have steps for Debian based systems.

• Your server will need a way to send e-mails for this to work

Goals

• Automatic, unattended, updates of critical security patches

• Automatic emails of remaining pending updates

Debian Based Systems

How It Works

On Debian based systems you can use:

• unattended-upgrades to automatically do system updates you want (i.e. critical security updates)

• apt-listchanges to get details about package changes before they are installed/upgraded

• apticron to get emails for pending package updates

We will use unattended-upgrades to apply critical security patches. We can also apply stable updates since they've already been thoroughly tested by the Debian community.

References

wiki.debian.org/UnattendedUpgrades

debian-handbook.info/browse/stable/sect.regular-upgrades.html

blog.sleeplessbeastie.eu/2015/01/02/how-to-perform-unattended-upgrades

vultr.com/docs/how-to-set-up-unattended-upgrades-on-debian-9-stretch

github.com/mvo5/unattended-upgrades

wiki.debian.org/UnattendedUpgrades

cyberciti.biz/faq/apt-get-apticron-send-email-upgrades-available

unixmen.com/how-to-get-email-notifications-for-new-updates-on-debianubuntu

• /etc/apt/apt.conf.d/50unattended-upgrades

Steps

1. Install unattended-upgrades, apt-listchanges, and apticron:

2. Now we need to configure unattended-upgrades to automatically apply the updates. This is typically done by editing the files /etc/apt/apt.conf.d/20auto-upgrades and /etc/apt/apt.conf.d/50unattended-upgrades that were created by the packages. However, because these file may get overwritten with a future update, we'll create a new file instead. Create the file /etc/apt/apt.conf.d/51myunattended-upgrades and add this: Notes:

• Check /usr/lib/apt/apt.systemd.daily for details on the APT::Periodic options

• Check github.com/mvo5/unattended-upgrades for details on the Unattended-Upgrade options

3. Run a dry-run of unattended-upgrades to make sure your configuration file is okay: If everything is okay, you can let it run whenever it's scheduled to or force a run with unattended-upgrade -d.

4. Configure apt-listchanges to your liking:

5. For apticron, the default settings are good enough but you can check them in /etc/apticron/apticron.conf if you want to change them. For example, my configuration looks like this:

(Table of Contents)

More Secure Random Entropy Pool (WIP)

Why

WIP

How It Works

WIP

Goals

WIP

References

• Thanks to branneman for this idea as submitted in issue #33.

hackaday.com/2017/11/02/what-is-entropy-and-how-do-i-get-more-of-it

2uo.de/myths-about-urandom

gnu.org/software/hurd/user/tlecarrour/rng-tools.html

wiki.archlinux.org/index.php/Rng-tools

howtoforge.com/helping-the-random-numbe...gh-entropy-with-rng-tools-debian-lenny

access.redhat.com/documentation/en-us/r...tion-using_the_random_number_generator

Steps

1. Install rng-tools. On Debian based systems:

2. Now we need to set the hardware device used to generate random numbers by adding this to /etc/default/rng-tools:For the lazy:

3. Restart the service:

4. Test randomness:

access.redhat.com/documentation/en-us/r...tion-using_the_random_number_generator

wiki.archlinux.org/index.php/Rng-tools

(Table of Contents)

Add Panic/Secondary/Fake password Login Security System

Why

A nice tool to add extra password security, against physical attack (In-Person) Ramson/Rob/assault methods.

How It Works

The pamduress will add to the X user a secondary password (Panic password), when this password match will start run a script (this script do what you what the user do, when he logins with THESE panic password.

Practical & real Example: "Some Robber invade a home, and steal the server (containing IMPORTANT business backups, and ownlife memories and blablabla). Not exist any disk/boot encryption. Robber have start the server on their 'safe zone' and start an bruteforce attack. He have cracked the local password by SSH with from sudoer user 'admin' success, yeah a dummy password, not THE Strong one/primary. He starts SSH session/or physical session with that cracked dummy/panic password with 'admin' sudoer. He starts feeling the server seems too much busy in less than 2 minutes until to freeze.. 'wtf!?! lets reboot and continue steal info..'.. sorry friend. all data and system was destroyed.". Conclusion, the robber cracked the dummy/panic/secondary password, and with this password its associated a script will do delete all files, config, system, boot and after than start charge the RAM and CPU to force robber reboot system.

Goals

Prevent access to malicious person to access server information when get an a password in force way (assault, gun, ransom, ...). Of course this is helpfull in other situations.

References

• Thanks to nuvious for this tool

• Thanks to hellresistor for this Lazy-Tool-Script

Steps

1. Run this (hellresistor Lazy-Tool-Script).

(Table of Contents)

The Network

Firewall With UFW (Uncomplicated Firewall)

Why

Call me paranoid, and you don't have to agree, but I want to deny all traffic in and out of my server except what I explicitly allow. Why would my server be sending traffic out that I don't know about? And why would external traffic be trying to access my server if I don't know who or what it is? When it comes to good security, my opinion is to reject/deny by default, and allow by exception.

Of course, if you disagree, that is totally fine and can configure UFW to suit your needs.

Either way, ensuring that only traffic we explicitly allow is the job of a firewall.

How It Works

The Linux kernel provides capabilities to monitor and control network traffic. These capabilities are exposed to the end-user through firewall utilities. On Linux, the most common firewall is iptables. However, iptables is rather complicated and confusing (IMHO). This is where UFW comes in. Think of UFW as a front-end to iptables. It simplifies the process of managing the iptables rules that tell the Linux kernel what to do with network traffic.

UFW works by letting you configure rules that:

• allow or deny

• input or output traffic

• to or from ports

You can create rules by explicitly specifying the ports or with application configurations that specify the ports.

Goals

• all network traffic, input and output, blocked except those we explicitly allow

Notes

• As you install other programs, you'll need to enable the necessary ports/applications.

References

launchpad.net/ufw

Steps

1. Install ufw. On Debian based systems:

2. Deny all outgoing traffic:

If you are not as paranoid as me, and don't want to deny all outgoing traffic, you can allow it instead:

3. Deny all incoming traffic:

4. Obviously we want SSH connections in. Using limit instead of allow will automatically deny connections from an IP address if it attempts to initiate 6 or more connections within a 30-second window:

5. Allow additional traffic as per your needs. Some common use-cases: Note: You'll need to allow HTTP/HTTPS for installing packages and many other things.

6. Start ufw:

7. If you want to see a status:

or

8. If you need to delete a rule

Default Applications

ufw ships with some default applications. You can see them with:

To get details about the app, like which ports it includes, type:

Custom Application

If you don't want to create rules by explicitly providing the port number(s), you can create your own application configurations. To do this, create a file in /etc/ufw/applications.d.

For example, here is what you would use for Plex:

Then you can enable it like any other app:

(Table of Contents)

iptables Intrusion Detection And Prevention with PSAD

Why

Even if you have a firewall to guard your doors, it is possible to try brute-forcing your way in any of the guarded doors. We want to monitor all network activity to detect potential intrusion attempts, such has repeated attempts to get in, and block them.

How It Works

I can't explain it any better than user FINESEC from serverfault.com did at: serverfault.com/a/447604/289829.

Fail2BAN scans log files of various applications such as apache, ssh or ftp and automatically bans IPs that show the malicious signs such as automated login attempts. PSAD on the other hand scans iptables and ip6tables log messages (typically /var/log/messages) to detect and optionally block scans and other types of suspect traffic such as DDoS or OS fingerprinting attempts. It's ok to use both programs at the same time because they operate on different level.

And, since we're already using UFW so we'll follow the awesome instructions by netson at gist.github.com/netson/c45b2dc4e835761fbccc to make PSAD work with UFW.

References

cipherdyne.org/psad

cipherdyne.org/psad/docs/config.html

thefanclub.co.za/how-to/how-install-psa...usion-detection-ubuntu-1204-lts-server

serverfault.com/a/447604/289829

serverfault.com/a/770424/289829

gist.github.com/netson/c45b2dc4e835761fbccc

• Thanks to moltenbit for catching the issue (#61) with psadwatchd.

Steps

1. Install psad. On Debian based systems:

2. Make a backup of psad's configuration file /etc/psad/psad.conf:

3. Review and update configuration options in /etc/psad/psad.conf. Pay special attention to these:

Check the configuration file psad's documentation at cipherdyne.org/psad/docs/config.html for more details.

4. Now we need to make some changes to ufw so it works with psad by telling ufw to log all traffic so psad can analyze it. Do this by editing two files and adding these lines at the end but before the COMMIT line. Make backups: Edit the files:

• /etc/ufw/before.rules

• /etc/ufw/before6.rules

And add add this at the end but before the COMMIT line: Note: We're adding a log prefix to all the iptables logs. We'll need this forseparating iptables logs to their own file. For example:

5. Now we need to reload/restart ufw and psad for the changes to take effect:

6. Analyze iptables rules for errors:

Note: If there were any issues you will get an e-mail with the error.

7. Check the status of psad:

(Table of Contents)

Application Intrusion Detection And Prevention With Fail2Ban

Why

UFW tells your server what doors to board up so nobody can see them, and what doors to allow authorized users through. PSAD monitors network activity to detect and prevent potential intrusions -- repeated attempts to get in.

But what about the applications/services your server is running, like SSH and Apache, where your firewall is configured to allow access in. Even though access may be allowed that doesn't mean all access attempts are valid and harmless. What if someone tries to brute-force their way in to a web-app you're running on your server? This is where Fail2ban comes in.

How It Works

Fail2ban monitors the logs of your applications (like SSH and Apache) to detect and prevent potential intrusions. It will monitor network traffic/logs and prevent intrusions by blocking suspicious activity (e.g. multiple successive failed connections in a short time-span).

Goals

• network monitoring for suspicious activity with automatic banning of offending IPs

Notes

• As of right now, the only thing running on this server is SSH so we'll want Fail2ban to monitor SSH and ban as necessary.

• As you install other programs, you'll need to create/configure the appropriate jails and enable them.

References

fail2ban.org

blog.vigilcode.com/2011/05/ufw-with-fail2ban-quick-secure-setup-part-ii

dodwell.us/security/ufw-fail2ban-portscan.html

howtoforge.com/community/threads/fail2ban-and-ufw-on-debian.77261

Steps

1. Install fail2ban. On Debian based systems:

2. We don't want to edit /etc/fail2ban/fail2ban.conf or /etc/fail2ban/jail.conf because a future update may overwrite those so we'll create a local copy instead. Create the file /etc/fail2ban/jail.local and add this to it after replacing [LAN SEGMENT] and [your email] with the appropriate values: Note: Your server will need to be able to send e-mails so Fail2ban can let you know of suspicious activity and when it banned an IP.

3. We need to create a jail for SSH that tells fail2ban to look at SSH logs and use ufw to ban/unban IPs as needed. Create a jail for SSH by creating the file /etc/fail2ban/jail.d/ssh.local and adding this to it:For the lazy:

4. In the above we tell fail2ban to use the ufw as the banaction. Fail2ban ships with an action configuration file for ufw. You can see it in /etc/fail2ban/action.d/ufw.conf

5. Enable fail2ban:

6. To check the status:

Custom Jails

I have not needed to create a custom jail yet. Once I do, and I figure out how, I will update this guide. Or, if you know how please help contribute.

Unban an IP

To unban an IP use this command:

[jail] is the name of the jail that has the banned IP and [IP] is the IP address you want to unban. For example, to unaban 192.168.1.100 from SSH you would do:

(Table of Contents)

Application Intrusion Detection And Prevention With CrowdSec

Why

UFW tells your server what doors to board up so nobody can see them, and what doors to allow authorized users through. PSAD monitors network activity to detect and prevent potential intrusions -- repeated attempts to get in.

CrowdSec is similar to Fail2Ban in that it monitors the logs of your applications (like SSH and Apache) to detect and prevent potential intrusions. However, CrowdSec is coupled with a community that shares threat intelligence back to CrowdSec to then distribute a Community Blocklist to all users.

How It Works

CrowdSec monitors the logs of your applications (like SSH and Apache) to detect and prevent potential intrusions. It will monitor network traffic/logs and prevent intrusions by blocking suspicious activity (e.g. multiple successive failed connections in a short time-span). Once a malicious IP is detected, it will be added to your local decision list and threat information is shared with CrowdSec to update the Community Blocklist on malicious IP addresses. Once an IP address hits a certain threshold of malicious activity, it will be automatically propogated to all other CrowdSec users to proactively block.

Goals

• network monitoring for suspicious activity with automatic banning of offending IPs

Notes

• As of right now, the only thing running on this server is SSH so we'll want CrowdSec to monitor SSH and ban as necessary.

• As you install other programs, you'll need to install additional collections and configure the appropriate acquisitions.

References

crowdsec.net

Read how CrowdSec curates the Community Blocklist

Read what threat intelligence is shared with CrowdSec

docs.crowdsec.net

Steps

1. Install CrowdSec Security Engine. (IDS) On any linux distro (including Debian based systems) Install the CrowdSec repository: Install the CrowdSec Security Engine:

Tip

if curl | sh is not your thing, you can find additional install methods here.

By default whilst CrowdSec is installing the Security Engine it will auto-discover your installed applications and install the appropriate parsers and scenarios for them. Since we know most Linux servers are running ssh out of the box CrowdSec will automatically configured this for you.

1. Install a Remediation Component. (IPS) CrowdSec by itself is a detection engine, since in most modern infrastructures you may have an upstream firewall or WAF, CrowdSec will not block the IP addresses by itself. You can install a Remediation Component to block the IP addresses detected by CrowdSec.

Tip

If your installation of UFW is not using iptables as the backend, you can alternatively install crowdsec-firewall-bouncer-nftables. There is no difference in the installed binaries, only the configuration file is different.

By default whilst the Remediation Component is installing it will auto-configure the necessary settings to work with the Security Engine if deployed on the same host (and if the security engine is not within a container environment).

1. Check detection and remediation is working as intended: CrowdSec package comes with a CLI tool to check the status of the Security Engine and the Remediation Component.

The above output can be daunting, but it's a good way to check that the Security Engine is reading logs and the Remediation Component is blocking IP addresses. So a quick breakdown of each section:

• Acquisition Metrics: This section shows the logs that the Security Engine is reading and parsing. If you see logs in the Lines unparsed column, it means the Security Engine is not able to parse the logs. This could be due to a misconfiguration or the logs are not in the expected format.

• Local API Decisions: This section shows the decisions that the Security Engine has within the datbase. If you see logs in the Count column, it means the Security Engine has detected malicious activity and has blocked the IP address.

• Orgin: This is where the decision came from. In this case, it's from the Central API (CAPI).

• Local API Metrics: This section shows the number of hits to the Local API. This is the API that the Security Engine uses to communicate with the Remediation Component.

• Local API Bouncers Metrics: This section shows the number of hits to the Local API by the Remediation Component.

• Local API Machines Metrics: This section shows the number of hits to the Local API by the Security Engine (if you run multiple Security Engine in a centralized setup you can see multiple ID's here).

• Parser Metrics: This section shows the parsers that are being used by the Security Engine. If you see logs in the Unparsed column, it means the Security Engine is not able to parse the logs. This could be due to a misconfiguration or the logs are not in the expected format.

• Scenario Metrics: This section shows the scenarios that are being used by the Security Engine. If you see logs in the Current Count column, it means the Security Engine has detected malicious activity and is tracking the IP address.

Unban an IP

To unban an IP use this command:

[IP] is the IP address you want to unban. For example, to unban 192.168.1.100 from SSH you would do:

The Auditing

File/Folder Integrity Monitoring With AIDE (WIP)

Why

WIP

How It Works

WIP

Goals

WIP

References

aide.github.io

hiroom2.com/2017/06/09/debian-8-file-integrity-check-with-aide

blog.rapid7.com/2017/06/30/how-to-install-and-configure-aide-on-ubuntu-linux

stephenrlang.com/2016/03/using-aide-for-file-integrity-monitoring-fim-on-ubuntu

howtoforge.com/how-to-configure-the-aid...ile-integrity-scanner-for-your-website

tecmint.com/check-integrity-of-file-and-directory-using-aide-in-linux

cyberciti.biz/faq/debian-ubuntu-linux-software-integrity-checking-with-aide

github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/83

Steps

1. Install AIDE. On Debian based systems:

2. Make a backup of AIDE's defaults file:

3. Go through /etc/default/aide and set AIDE's defaults per your requirements. If you want AIDE to run daily and e-mail you, be sure to set CRON_DAILY_RUN to yes.

4. Make a backup of AIDE's configuration files:

5. On Debian based systems:

• AIDE's configuration files are in /etc/aide/aide.conf.d/.

• You'll want to go through AIDE's documentation and the configuration files in to set them per your requirements.

• If you want new settings, to monitor a new folder for example, you'll want to add them to /etc/aide/aide.conf or /etc/aide/aide.conf.d/.

• Take a backup of the stock configuration files: sudo cp -pr /etc/aide /etc/aide-COPY-$(date +"%Y%m%d%H%M%S").

6. Create a new database, and install it. On Debian based systems:

7. Test everything works with no changes. On Debian based systems:

8. Test everything works after making some changes. On Debian based systems:

9. That's it. If you set CRON_DAILY_RUN to yes in /etc/default/aide then cron will execute /etc/cron.daily/aide every day and e-mail you the output.

Updating The Database

Every time you make changes to files/folders that AIDE monitors, you will need to update the database to capture those changes. To do that on Debian based systems:

(Table of Contents)

Anti-Virus Scanning With ClamAV (WIP)

Why

WIP

How It Works

• ClamAV is a virus scanner

• ClamAV-Freshclam is a service that keeps the virus definitions updated

• ClamAV-Daemon keeps the clamd process running to make scanning faster

Goals

WIP

Notes

• These instructions do not tell you how to enable the ClamAV daemon service to ensure clamd is running all the time. clamd is only if you're running a mail server and does not provide real-time monitoring of files. Instead, you'd want to scan files manually or on a schedule.

References

clamav.net/documents/installation-on-debian-and-ubuntu-linux-distributions

wiki.debian.org/ClamAV

osradar.com/install-clamav-debian-9-ubuntu-18

lisenet.com/2014/automate-clamav-to-per...-and-send-email-notifications-on-linux

howtoforge.com/tutorial/configure-clamav-to-scan-and-notify-virus-and-malware

serverfault.com/questions/741299/is-the...way-to-keep-clamav-updated-on-debian-8

askubuntu.com/questions/250290/how-do-i-scan-for-viruses-with-clamav

ngothang.com/how-to-install-clamav-and-configure-daily-scanning-on-centos

Steps

1. Install ClamAV. On Debian based systems:

2. Make a backup of clamav-freshclam's configuration file /etc/clamav/freshclam.conf:

3. clamav-freshclam's default settings are probably good enough but if you want to change them, you can either edit the file /etc/clamav/freshclam.conf or use dpkg-reconfigure: Note: The default settings will update the definitions 24 times in a day. To change the interval, check the Checks setting in /etc/clamav/freshclam.conf or use dpkg-reconfigure.

4. Start the clamav-freshclam service:

5. You can make sure clamav-freshclam running:

Note: Don't worry about that Local version line. Check serverfault.com/questions/741299/is-the...way-to-keep-clamav-updated-on-debian-8 for more details.

6. Make a backup of clamav-daemon's configuration file /etc/clamav/clamd.conf:

7. You can change clamav-daemon's settings by editing the file /etc/clamav/clamd.conf or useing dpkg-reconfigure:

Scanning Files/Folders

• To scan files/folders use the clamscan program.

• clamscan runs as the user it is executed as so it needs read permissions to the files/folders it is scanning.

• Using clamscan as root is dangerous because if a file is in fact a virus there is risk that it could use the root privileges.

• To scan a file: clamscan /path/to/file.

• To scan a directory: clamscan -r /path/to/folder.

• You can use the -i switch to only print infected files.

• Check clamscan's man pages for other switches/options.

(Table of Contents)

Rootkit Detection With Rkhunter (WIP)

Why

WIP

How It Works

WIP

Goals

WIP

References

rkhunter.sourceforge.net

cyberciti.biz/faq/howto-check-linux-rootkist-with-detectors-software

tecmint.com/install-rootkit-hunter-scan-for-rootkits-backdoors-in-linux

Steps

1. Install Rkhunter. On Debian based systems:

2. Make a backup of rkhunter' defaults file:

3. rkhunter's configuration file is /etc/rkhunter.conf. Instead of making changes to it, create and use the file /etc/rkhunter.conf.local instead:

4. Go through the configuration file /etc/rkhunter.conf.local and set to your requirements. My recommendations:

5. You want rkhunter to run every day and e-mail you the result. You can write your own script or check tecmint.com/install-rootkit-hunter-scan-for-rootkits-backdoors-in-linux for a sample cron script you can use. On Debian based system, rkhunter comes with cron scripts. To enable them check /etc/default/rkhunter or use dpkg-reconfigure and say Yes to all of the questions:

6. After you've finished with all of the changes, make sure all the settings are valid:

7. Update rkhunter and its database:

8. If you want to do a manual scan and see the output:

(Table of Contents)

Rootkit Detection With chrootkit (WIP)

Why

WIP

How It Works

WIP

Goals

WIP

References

chkrootkit.org

cyberciti.biz/faq/howto-check-linux-rootkist-with-detectors-software

askubuntu.com/questions/258658/eth0-packet-sniffer-sbin-dhclient

Steps

1. Install chkrootkit. On Debian based systems:

2. Do a manual scan:

3. Make a backup of chkrootkit's configuration file /etc/chkrootkit.conf:

4. You want chkrootkit to run every day and e-mail you the result. On Debian based system, chkrootkit comes with cron scripts. To enable them check /etc/chkrootkit.conf or use dpkg-reconfigure and say Yes to the first question:

(Table of Contents)

logwatch - system log analyzer and reporter

Why

Your server will be generating a lot of logs that may contain important information. Unless you plan on checking your server everyday, you'll want a way to get e-mail summary of your server's logs. To accomplish this we'll use logwatch.

How It Works

logwatch scans system log files and summarizes them. You can run it directly from the command line or schedule it to run on a recurring schedule. logwatch uses service files to know how to read/summarize a log file. You can see all of the stock service files in /usr/share/logwatch/scripts/services.

logwatch's configuration file /usr/share/logwatch/default.conf/logwatch.conf specifies default options. You can override them via command line arguments.

Goals

• Logwatch configured to send a daily e-mail summary of all of the server's status and logs

Notes

• Your server will need to be able to send e-mails for this to work

• The below steps will result in logwatch running every day. If you want to change the schedule, modify the cronjob to your liking. You'll also want to change the range option to cover your recurrence window. See badpenguin.org/configure-logwatch-for-weekly-email-and-html-output-format for an example.

• If logwatch fails to deliver mail due to the e-mail having long lines please check blog.dhampir.no/content/exim4-line-leng...ery-failed-returning-message-to-sender as documented in issue #29. If you followed Gmail and Exim4 As MTA With Implicit TLS then we already took care of this in step #7.

References

• Thanks to amacheema for fixing some issues with the steps and letting me know of a long line bug with exim4 as documented in issue #29.

sourceforge.net/projects/logwatch

digitalocean.com/community/tutorials/ho...tch-log-analyzer-and-reporter-on-a-vps

Steps

1. Install logwatch. On Debian based systems:

2. To see a sample of what logwatch collects you can run it directly:

3. Go through logwatch's self-documented configuration file /usr/share/logwatch/default.conf/logwatch.conf before continuing. There is no need to change anything here but pay special attention to the Output, Format, MailTo, Range, and Service as those are the ones we'll be using. For our purposes, instead of specifying our options in the configuration file, we will pass them as command line arguments in the daily cron job that executes logwatch. That way, if the configuration file is ever modified (e.g. during an update), our options will still be there.

4. Make a backup of logwatch's daily cron file /etc/cron.daily/00logwatch and unset the execute bit:

5. By default, logwatch outputs to stdout. Since the goal is to get a daily e-mail, we need to change the output type that logwatch uses to send e-mail instead. We could do this through the configuration file above, but that would apply to every time it is run -- even when we run it manually and want to see the output to the screen. Instead, we'll change the cron job that executes logwatch to send e-mail. This way, when run manually, we'll still get output to stdout and when run by cron, it'll send an e-mail. We'll also make sure it checks for all services, and change the output format to html so it's easier to read regardless of what the configuration file says. In the file /etc/cron.daily/00logwatch find the execute line and change it to:

For the lazy:

6. You can test the cron job by executing it: Note: If logwatch fails to deliver mail due to the e-mail having long lines please checkblog.dhampir.no/content/exim4-line-leng...ery-failed-returning-message-to-sender as documented in issue #29. If you followed Gmail and Exim4 As MTA With Implicit TLS then we already took care of this in step #7.

(Table of Contents)

ss - Seeing Ports Your Server Is Listening On

Why

Ports are how applications, services, and processes communicate with each other -- either locally within your server or with other devices on the network. When you have an application or service (like SSH or Apache) running on your server, they listen for requests on specific ports.

Obviously we don't want your server listening on ports we don't know about. We'll use ss to see all the ports that services are listening on. This will help us track down and stop rogue, potentially dangerous, services.

Goals

• find out non-localhost what ports are open and listening for connections

References

reddit.com/r/linux/comments/arx7st/howt...server_an_evolving_howto_guide/egrib6o

reddit.com/r/linux/comments/arx7st/howt...server_an_evolving_howto_guide/egs1rev

tecmint.com/find-open-ports-in-linux

• man ss

Steps

1. To see the all the ports listening for traffic:

Switch Explanations:

• l = display listening sockets

• n = do not try to resolve service names

• t = display TCP sockets

• u = display UDP sockets

• p = show process information

2. If you see anything suspicious, like a port you're not aware of or a process you don't know, investigate and remediate as necessary.

(Table of Contents)

Lynis - Linux Security Auditing

Why

From cisofy.com/lynis:

Lynis is a battle-tested security tool for systems running Linux, macOS, or Unix-based operating system. It performs an extensive health scan of your systems to support system hardening and compliance testing.

Goals

• Lynis installed

Notes

• CISOFY offers packages for many distributions. Check packages.cisofy.com for distribution specific installation instructions.

References

cisofy.com/documentation/lynis/get-started

packages.cisofy.com/community

thelinuxcode.com/audit-lynis-ubuntu-server

vultr.com/docs/install-lynis-on-debian-8

Steps

1. Install lynis. cisofy.com/lynis has detailed instructions on how to install it for your distribution. On Debian based systems, using CISOFY's community software repository:

2. Update it:

3. Run a security audit: This will scan your server, report its audit findings, and at the end it will give you suggestions. Spend some time going through the output and address gaps as necessary.

(Table of Contents)

OSSEC - Host Intrusion Detection

Why

From github.com/ossec/ossec-hids

OSSEC is a full platform to monitor and control your systems. It mixes together all the aspects of HIDS (host-based intrusion detection), log monitoring and SIM/SIEM together in a simple, powerful and open source solution.

Goals

• OSSEC-HIDS installed

References

ossec.net/docs

Steps

1. Install OSSEC-HIDS from sources

2. Useful commands:

Agent information

AGENT_ID by default is 000, to be sure the command sudo /var/ossec/bin/agent_control -l can be used.

Run integrity/rootkit checking

OSSEC by default run rootkit check each 2 hours.

Alerts

• All:

• Integrity check:

• Rootkit check:

(Table of Contents)

The Danger Zone

Proceed At Your Own Risk

This sections cover things that are high risk because there is a possibility they can make your system unusable, or are considered unnecessary by many because the risks outweigh any rewards.

!! PROCEED AT YOUR OWN RISK !!

!! PROCEED AT YOUR OWN RISK !!

(Table of Contents)

Table of Contents

Linux Kernel sysctl Hardening

Password Protect GRUB

Disable Root Login

Change Default umask

Orphaned Software

(Table of Contents)

Linux Kernel sysctl Hardening

!! PROCEED AT YOUR OWN RISK !!

Why

The kernel is the brains of a Linux system. Securing it just makes sense.

Why Not

Changing kernel settings with sysctl is risky and could break your server. If you don't know what you are doing, don't have the time to debug issues, or just don't want to take the risks, I would advise from not following these steps.

Disclaimer

I am not as knowledgeable about hardening/securing a Linux kernel as I'd like. As much as I hate to admit it, I do not know what all of these settings do. My understanding is that most of them are general kernel hardening and performance, and the others are to protect against spoofing and DOS attacks.

In fact, since I am not 100% sure exactly what each setting does, I took recommended settings from numerous sites (all linked in the references below) and combined them to figure out what should be set. I figure if multiple reputable sites mention the same setting, it's probably safe.

If you have a better understanding of what these settings do, or have any other feedback/advice on them, please let me know.

I won't provide For the lazy code in this section.

Notes

• Documentation on all the sysctl settings/keys is severely lacking. The documentation I can find seems to reference the 2.2 version kernel. I could not find anything newer. If you know where I can, please let me know.

• The reference sites listed below have more comments on what each setting does.

References

github.com/torvalds/linux/tree/master/Documentation

cyberciti.biz/faq/linux-kernel-etcsysctl-conf-security-hardening

geektnt.com/sysctl-conf-hardening.html

linoxide.com/how-tos/linux-server-protection

github.com/klaver/sysctl/raw/master/sysctl.conf

cloudpro.zone/index.php/2018/01/30/debian-9-3-server-setup-guide-part-5

Steps

1. The sysctl settings can be found in the linux-kernel-sysctl-hardening.md file in this repo.

2. Before you make a kernel sysctl change permanent, you can test it with the sysctl command: Example: Note: There are no spaces in key=value, including before and after the space.

3. Once you have tested a setting, and made sure it works without breaking your server, you can make it permanent by adding the values to /etc/sysctl.conf. For example:

4. After updating the file you can reload the settings or reboot. To reload:

Note: If sysctl has trouble writing any settings then sysctl -w or sysctl -p will write an error to stderr. You can use this to quickly find invalid settings in your /etc/sysctl.conf file:

(Table of Contents)

Password Protect GRUB

!! PROCEED AT YOUR OWN RISK !!

Why

If a bad actor has physical access to your server, they could use GRUB to gain unauthorized access to your system.

Why Not

If you forget the password, you'll have to go through some work to recover the password.

Goals

• auto boot the default Debian install and require a password for anything else

Notes

• This will only protect GRUB and anything behind it like your operating systems. Check your motherboard's documentation for password protecting your BIOS to prevent a bad actor from circumventing GRUB.

References

selivan.github.io/2017/12/21/grub2-pass...-for-all-but-default-menu-entries.html

help.ubuntu.com/community/Grub2/Passwords

computingforgeeks.com/how-to-protect-gr...ssword-on-debian-ubuntu-and-kali-linux

• man grub

• man grub-mkpasswd-pbkdf2

Steps

1. Create a Password-Based Key Derivation Function 2 (PBKDF2) hash of your password: The below output is from using password as the password:

2. Copy everything after PBKDF2 hash of your password is , starting from and including grub.pbkdf2.sha512... to the end. You'll need this in the next step.

3. The update-grub program uses scripts to generate configuration files it will use for GRUB's settings. Create the file /etc/grub.d/01_password and add the below code after replacing [hash] with the hash you copied from the first step. This tells update-grub to use this username and password for GRUB. For example:

4. Set the file's execute bit so update-grub includes it when it updates GRUB's configuration:

5. Make a backup of GRUB's configuration file /etc/grub.d/10_linux that we'll be modifying and unset the execute bit so update-grub doesn't try to run it:

6. To make the default Debian install unrestricted (without the password) while keeping everything else restricted (with the password) modify /etc/grub.d/10_linux and add --unrestricted to the CLASS variable.For the lazy:

7. Update GRUB with update-grub:

(Table of Contents)

Disable Root Login

!! PROCEED AT YOUR OWN RISK !!

Why

If you have sudo configured properly, then the root account will mostly never need to log in directly -- either at the terminal or remotely.

Why Not

Be warned, this can cause issues with some configurations!

If your installation uses sulogin (like Debian) to drop to a root console during boot failures, then locking the root account will prevent sulogin from opening the root shell and you will get this error:

To work around this, you can use the --force option for sulogin. Some distributions already include this, or some other, workaround.

An alternative to locking the root acount is set a long/complicated root password and store it in a secured, non-digital format. That way you have it when/if you need it.

Goals

• locked root account that nobody can use to log in as root

Notes

• Some distributions disable root login by default (e.g. Ubuntu) so you may not need to do this step. Check with your distribution's documentation.

References

bugs.debian.org/cgi-bin/bugreport.cgi

github.com/systemd/systemd/issues/7115

github.com/karelzak/util-linux/commit/7ff1162e67164cb4ece19dd809c26272461aa254

github.com/systemd/systemd/issues/11596

reddit.com/r/selfhosted/comments/aoxd4l...ed_by_me_how_to_secure_a_linux/eg4rkfi

• man systemd

Steps

1. Lock the root account:

(Table of Contents)

Change Default umask

!! PROCEED AT YOUR OWN RISK !!

Why

umask controls the default permissions of files/folders when they are created. Insecure file/folder permissions give other accounts potentially unauthorized access to your data. This may include the ability to make configuration changes.

• For non-root accounts, there is no need for other accounts to get any access to the account's files/folders by default.

• For the root account, there is no need for the file/folder primary group or other accounts to have any access to root's files/folders by default.

When and if other accounts need access to a file/folder, you want to explicitly grant it using a combination of file/folder permissions and primary group.

Why Not

Changing the default umask can create unexpected problems. For example, if you set umask to 0077 for root, then non-root accounts will not have access to application configuration files/folders in /etc/ which could break applications that do not run with root privileges.

How It Works

In order to explain how umask works I'd have to explain how Linux file/folder permissions work. As that is a rather complicated question, I will defer you to the references below for further reading.

Goals

• set default umask for non-root accounts to 0027

• set default umask for the root account to 0077

Notes

• umask is a Bash built-in which means a user can change their own umask setting.

References

linuxnix.com/umask-define-linuxunix

serverfault.com/questions/818783/which-umask-is-more-secure-in-linux-022-or-027

cyberciti.biz/tips/understanding-linux-unix-umask-value-usage.html

• man umask

Steps

1. Make a backup of files we'll be editing:

2. Set default umask for non-root accounts to 0027 by adding this line to /etc/profile and /etc/bash.bashrc:For the lazy:

3. We also need to add this line to /etc/login.defs:For the lazy:

4. Set default umask for the root account to 0077 by adding this line to /root/.bashrc:For the lazy:

(Table of Contents)

Orphaned Software

!! PROCEED AT YOUR OWN RISK !!

Why

As you use your system, and you install and uninstall software, you'll eventually end up with orphaned, or unused software/packages/libraries. You don't need to remove them, but if you don't need them, why keep them? When security is a priority, anything not explicitly needed is a potential security threat. You want to keep your server as trimmed and lean as possible.

Notes

• Each distribution manages software/packages/libraries differently so how you find and remove orphaned packages will be different. So far I only have steps for Debian based systems.

Debian Based Systems

On Debian based systems, you can use deborphan to find orphaned packages.

Why Not

Keep in mind, deborphan finds packages that have no package dependencies. That does not mean they are not used. You could very well have a package you use every day that has no dependencies that you wouldn't want to remove. And, if deborphan gets anything wrong, then removing critical packages may break your system.

Steps

1. Install deborphan.

2. Run deborphan as root to see a list of orphaned packages:

3. Assuming you want to remove all of the packages deborphan finds, you can pass it's output to apt to remove them:

(Table of Contents)

The Miscellaneous

The Simple way with MSMTP

(#msmtp-alternative)

Why

Well I will SIMPLIFY this method, to only output email using Google Mail account (and others). True Simple! 😃

DONE!! 😉 (Table of Contents)

Gmail and Exim4 As MTA With Implicit TLS

Why

Unless you're planning on setting up your own mail server, you'll need a way to send e-mails from your server. This will be important for system alerts/messages.

You can use any Gmail account. I recommend you create one specific for this server. That way if your server is compromised, the bad-actor won't have any passwords for your primary acc

添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论