How to secure a WordPress site with Linux Debian
Published: 2024-04-25 09:14:10

This is the first in a series of articles on practical ways to ensure that your server is secure. As an example, we'll take Linux Debian with ispmanager 6 and a WordPress site.

This article will describe:
- Security during Debian installation
- Securing the bootloader
- SSH
- Configuring the Linux kernel
- Strategies to strengthen authentication security
- Channel encryption
- Uninstalling unnecessary software
- Disabling unnecessary services
- Configuring Firewall iptables
- Configuring Fail2ban
- Profiling AppArmor

Later in the series, we will discuss:
1. The practical use of ModSecurity in Nginx
2. Tools for auditing and monitoring security
3. Data redundancy and the software needed for it

These are just basic recommendations, not an exhaustive list of ways to strengthen information security. They are nevertheless useful as a starting point to understand how to protect web projects on Linux Debian with ispmanager 6.

## Security during the Debian installation process
In this section, we'll look at the key steps – encrypting data, securely partitioning the disk, and mounting the disk.

**Disk Encryption.** Encryption protects data confidentiality in the event of unauthorized access. LUKS (Linux Unified Key Setup) is a widely used tool for encrypting entire volumes, providing strong protection against data leakage. It supports multiple keys and provides secure key management.

The Debian 11 installer provides the following encryption algorithms for use with LUKS.

**The AES** (Advanced Encryption Standard) — is one of the most common symmetric encryption algorithms, providing robustness and high performance.

**Twofish** — is another symmetric encryption algorithm that offers the same.

**Serpent** — is a symmetric encryption algorithm known for its high strength but lower efficiency than AES or Twofish.

**XTS** (XEX-based Tweaked CodeBook mode with CipherText Stealing) — is an encryption mode designed to protect data on disk, ensuring data confidentiality and integrity.

**SHA-256** — is a hashing algorithm used to verify the integrity and authenticity of data.

Implementing LUKS involves setting up encrypted volumes during or after the installation of a Linux system, as well as increasing the security of devices that are susceptible to loss or theft. Additional tools such as eCryptfs and EncFS offer encryption for specific directories or files.

**Cons of full disk encryption:**
**Performance degradation.** Encrypting and decrypting data in real-time can slow down reading and writing to disk.

**Difficulty of data recovery.** If an encrypted disk is corrupted, data recovery is more difficult and sometimes impossible.

**Forgotten password.** If you lose or forget your encryption key, you may not be able to access your data.

**Boot time.** It may take longer to boot the system due to the need to enter a password to decrypt the disk.

**Disk partitioning and mounting.** It is important to properly partition and mount disks. Using Logical Volume Manager (LVM) offers you leeway in managing partitions and improves system security.

→ **Example of disk partitioning with mount options for installing the ispmanager hosting panel**

`/boot` — the boot partition with an `ext2` file system and the specified options `nodev`, nosuid and `noexec`

`/` — is the root partition of the Linux operating system. The file system is `ext4`, mounted with the options `nodev`, `nosuid`, `noexec` The `noexec` mount option prohibits executable files from executing in the partition, increasing system security by preventing potentially malicious programs from running.

`swap` — a swap partition is used to manage virtual memory.

`/usr` — is the partition where applications are installed. It uses an `ext4` filesystem, mounted with `the nodev` option to prevent devices from being created on this filesystem.

`/usr/share` — is a partition for data shared among applications. It uses an `ext4` file system mounted with the options for banning device creation and suid bits in this directory.

`/var` — is a partition with variable data such as logs or temporary files. It uses an `ext4` file system, mounted with `nodev`, `usrquota`, `grpquota` options to prevent device creation and enabling user and group quotas.

`/tmp` — is a temporary file partition using an `ext4` file system, mounted with the options `nodev`, `nosuid`, `noexec`, `usrquota`, `grpquota` to prevent device creation, suid bit use, file execution within the directory, and to enable user and group quotas.

`/opt` — is a partition for third-party software not included in the standard distribution repositories. The file system is `ext4` mounted with the `nodev` and `nosuid` options using an.

`/var/tmp` — is a partition for temporary files, similar to `/tmp` , with `ext4` and the options `nodev`, `nosuid`, `noexec`, `usrquota`, and `grpquota`

`/var/log` — is a log partition on the `ext4` file system, mounted with the `nodev`, `nosuid`, `noexec` options to prevent device creation and suid bits from being used in this directory.

`/var/www` — is a partition for the web server, `ext4` file system, mounted with the `nodev`, `usrquota`, and `grpquota` options to prevent device creation and to enable user and group quotas.

**→ Example `/etc/fstab` file**

This describes how to mount the various partitions and file systems:

```
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# systemd generates mount units based on this file, see systemd.mount(5).
# Please run 'systemctl daemon-reload' after making changes here.
#
#                
/dev/mapper/debian-root /               ext4    rw,nosuid,nodev,noexec,relatime,errors=remount-ro 0       1
# /boot was on /dev/vda1 during installation
UUID=aba9cdb1-0f46-4356-a74f-1a726883156b /boot           ext2    nodev,nosuid,noexec 0       2
/dev/mapper/debian-tmp /tmp            ext4    nodev,nosuid,noexec,usrquota,grpquota 0       2
/dev/mapper/debian-opt /opt            ext4    nodev,nosuid 0       2
/dev/mapper/debian-usr /usr            ext4    nodev           0       2
/dev/mapper/debian-usr_share /usr/share      ext4    nodev,nosuid    0       2
/dev/mapper/debian-var /var            ext4    nodev,usrquota,grpquota 0       2
/dev/mapper/debian-var_log /var/log        ext4    nodev,nosuid,noexec 0       2
/dev/mapper/debian-var_tmp /var/tmp        ext4    nodev,nosuid,noexec,usrquota,grpquota 0       2
/dev/mapper/debian-var_www /var/www        ext4    nodev,usrquota,grpquota 0       2
/dev/mapper/debian-swap none            swap    sw              0       0
/dev/sr0        /media/cdrom0   udf,iso9660 user,noauto     0       0
#
proc /proc proc rw,nosuid,nodev,noexec,relatime,hidepid=2 0 0
tmpfs /dev/shm tmpfs nosuid,nodev,noexec 0 0
devtmpfs /dev devtmpfs defaults,nosuid,noexec,relatime,size=487424k,nr_inodes=121856,mode=755,inode64 0 0
devpts /dev/pts devpts defaults,nosuid,noexec,relatime,mode=600 0 0
```
    
Encryption and disk partitioning is a topic for a separate article.

## Protecting the bootloader
A secure bootloader is critical to operating system security because the bootloader is the first piece of software to be executed when the computer starts up. If the bootloader is compromised, attackers can inject malware, tamper with the system kernel, or bypass security mechanisms early in the boot process.

**→ Securing the bootloader in Debian 11 can be accomplished using the following steps.**

**Using a password for GRUB**

1. Open the GRUB configuration file:
`sudo nano /etc/grub.d/40_custom`

2. Add the following lines to configure password authentication:
`set superusers="admin" password_pbkdf2 admin grub.pbkdf2.sha512.10000.YOURHASH`

3. Generate the password hash with the command:
`grub-mkpasswd-pbkdf2`

and replace `YOURHASH` with the resulting hash.

**Configure Secure Boot, if supported by your hardware:**

1. Enable Secure Boot in the BIOS/UEFI settings.

2. Install the packages to work with Secure Boot:
`sudo apt install shim-signed grub-efi-amd64-signed`

3. Reinstall GRUB with Secure Boot support:
`sudo grub-install --target=x86_64-efi --uefi-secure-boot`

4. Update the GRUB configuration:
`sudo update-grub`

**Updating and protecting the kernel:**

1. Regularly update your system, including the kernel, to get the latest security patches:
`sudo apt update && sudo apt upgrade`

2. Consider using additional security modules, such as AppArmor, to restrict the rights of processes to access system resources.

These steps will help protect the Debian bootloader from unauthorized access and improve overall system security.

## SSH security
Secure SSH configuration plays a key role in securing Linux server systems. SSH (Secure Shell) is a standard remote access protocol that provides secure connection and data exchange between a client and a server.

Let's look at basic measures to improve SSH security, including setting up key authorization and disabling root login.

Configuring key-based authorization. SSH keys provide a more secure method of logging into a server than using a password, as their cryptographic nature makes brute-force authentication virtually impossible.

**→ SSHd server-side configuration:**

1. Open the SSH server configuration file `/etc/ssh/sshd_config` in a text editor with administrator privileges.

2. Find or add the following line to allow authentication by key `id_ed25519:`
`PubkeyAcceptedKeyTypes +ssh-ed25519`

3. Save the changes and restart the SSH server:
`sudo systemctl restart sshd`

**→ Configure the client machine:**

1. Create an SSH key pair. Use the `ssh-keygen` command to create a new SSH key pair. This command will create a private key and a public key. Keep the private key secure, do not share it with anyone:
`ssh-keygen -t ed25519 -C "your_email@example.com`

2. Copy the public key to the server:
`scp ~/.ssh/id_ed25519.pub username@server_ip:~/`

3. Connect to the server and add the public key to the ~/.ssh/authorized_keys file:
`ssh username@server_ipcat ~/id_ed25519.pub >> ~/.ssh/authorized_keys`

5. Set access rights for files on the server and client machine. Execute the command on the client machine. Keep the private key close to your chest:
`chmod 600 ~/.ssh/id_ed25519
`
Execute the server commands:
`chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys`

The SSH server should now accept `ed25519` keys for authentication so you can connect to the server using the `id_ed25519` key.

**Important.** It is recommended to store the private key in an encrypted state on an external medium.

**→ Enable key authorization.**

**To enable key authentication in SSH**, you need to ensure that the following settings in `/etc/ssh/sshd_config` are set as follows:

1. Ensure that the `PubkeyAuthentication` parameter is set to `yes`

This enables public key authentication: 
`PubkeyAuthentication yes`

2. By default, most systems set it to `yes` If it is set to no change it to `no`

3. Ensure that the `RSAAuthentication` or `PubkeyAcceptedKeyTypes` parameter is present for more modern settings. They should also be set to yes:
`RSAAuthentication yes`

4. Save the changes and restart the SSH server:
`sudo systemctl restart sshd`

After completing these steps, SSH key authorization will be enabled on your server.

**SSHD Server Configuration** (Secure Shell Daemon) — is responsible for providing secure remote access to the system via the SSH protocol. In this section, we will cover the basic steps to configure SSHD for security and usability.

**Disabling root authorization.** If you can't log into the system via SSH as root user, then there's a lower risk of successful attacks on the server.

→ **To disable root login via SSH**, you must modify the SSH server configuration file. This is usually `/etc/ssh/sshd_config`

1. Open `/etc/ssh/sshd_config` in a text editor with administrator privileges.

2. Find the `PermitRootLogin` line. If it is commented out: `# PermitRootLogin` uncomment it and set it to no: `# PermitRootLogin no`

3. Save the changes and restart the SSH server:
`sudo systemctl restart sshd`

Logging in as root user via SSH will be forbidden.

Use your normal user to perform administrative tasks on the server and the `sudo` command to execute privileged commands. If a `sudo` account has not already been created, it is recommended that you create one to perform administrative tasks while maintaining functionality and reducing the risk of unwanted use of the root account.

**Disabling password authorization.** Disabling password authentication in SSH improves server security by preventing brute-force password attacks. Instead, it is recommended to use key authentication, which provides a higher level of security.

**→ To disable password authentication and allow only key authentication:**

1. Open the `/etc/ssh/sshd_config` file in a text editor with administrator privileges.

2. Locate and modify the following lines:
`PasswordAuthentication no
ChallengeResponseAuthentication no`

3. Save the changes and restart the SSH server:
`sudo systemctl restart sshd`

Undergo this process with the utmost attention to avoid losing access to the server: check access to the server by key and if everything works, apply the settings. After performing these steps, password authorization will be disabled and access to the server wil only be possible using SSH keys.

**Important.** Be sure to check the SSHD configuration files before applying the settings. Use the following command to verify:
`sudo sshd -t`

**Other sshd_config settings.** The settings in the `sshd_config` file can greatly enhance the security and functionality of your SSH server by preventing password mining and limiting the ability of attackers to use SSH tunnels and redirects for attacks.

The settings offered in this file include:

`Port 1234` — the port on which the SSH server will listen. Replace "1234" with a non-standard port number, for example 2222, to reduce the number of failed connection attempts.

`Protocol 2` — use only protocol version 2, as it is more secure than the legacy protocol version 1.

`AllowUsers username1 username2` — allow only specific users to connect via SSH. Replace `username1 username2` with the real usernames.

`PermitEmptyPasswords no` — prohibit authentication with an empty password.

`LogLevel VERBOSE` — set the SSH logging level to `verbose` for more detailed logs.

`LMaxAuthTries 3` — limit the number of authentication attempts to 3 to prevent password mining.

`MaxSessions 2` — limit the number of concurrent sessions to 2 to reduce the risk of server overload.

`AllowAgentForwarding no` — disallow SSH agent-forwarding to prevent attacks through the SSH agent.

`AllowTcpForwarding no` — disallow TCP forwarding to prevent possible attacks via SSH tunnels.

`X11Forwarding no` — disable X11 forwarding to reduce security risk.

`TCPKeepAlive no` — disable sending `keepalive` acknowledgment packets to reduce network resources.

`Compression no` — disable data compression to reduce the load on the server processor.

`ClientAliveInterval 300` — send a message to the client every 300 seconds (5 minutes) to check the connection activity.

`ClientAliveCountMax 2` — allow up to 2 unanswered messages to check for connection activity before terminating the connection.

`Banner none` — disable the SSH banner to hide the SSH server version.

Before making changes to `sshd_config`, ensure you understand how they will affect the security and functionality of your server, and test the changes in a secure environment.

After making the changes, remember to restart the SSH service to apply the settings:
`sudo systemctl restart sshd`

Modify the SSH welcome message—this can make it more difficult for port scanning and other automated attacks to identify the operating system, since attackers often use standard server responses to identify the OS type and version. A customized welcome message can hide or distort these default responses, making it difficult to automatically identify the operating system and potentially reducing the effectiveness of targeted attacks.

**→ Commands to change the welcome messages when connecting to the server via SSH:**

1. Backup the `/etc/issue.net` file and install a new welcome message:
`sudo cp /etc/issue.net /etc/issue.net.old
sudo echo 'Welcome to the world of Windows 98! ;)' > /etc/issue.net`

2. Backup the `/etc/issue` file and install a new welcome message:
`sudo cp /etc/issue /etc/issue.old
sudo echo 'Welcome to the world of Windows 98! ;)' > /etc/issue`

## Linux kernel customization
Configuring the Linux kernel with `sysctl` helps to strengthen information security by restricting access to internal kernel structures, preventing the use of some dangerous functions and mechanisms, reducing the risk of network attacks, and increasing system privacy.

Let's take a closer look at each of these settings:

`kernel.kptr_restrict = 2` — restricts access to kernel pointers to prevent leaks of kernel information.

`kernel.sysrq = 0` — disables the ability to use the SysRq key combination, which can prevent unwanted actions through this mechanism.

`kernel.unprivileged_bpf_disabled = 0` — disables the ability of unprivileged processes to run programs that use BPF (Berkeley Packet Filter).

`kernel.yama.ptrace_scope = 0` — disables restrictions on using ptrace for debugging processes, which may be useful for some debugging tasks.

`net.core.bpf_jit_harden = 0` — disables JIT compilation for BPF to reduce vulnerability risk.

`kernel.modules_disabled = 1` — disables the ability to load new kernel modules into the system after it is started. This increases system security by preventing potentially malicious or unauthorized modules from being loaded. However, once enabled, this setting cannot be disabled without rebooting the system.

`kernel.core_uses_pid = 0` — disables the use of PID in the kernel filename when writing memory dumps to increase privacy.

`dev.tty.ldisc_autoload = 0` — disables automatic `ldisc` loading (line discipline) for tty devices.

`net.ipv4.conf.all.accept_redirects = 0` — this value indicates that the system will not accept ICMP redirects. This increases system security by preventing attacks that can use spoofed ICMP redirects to change traffic routing. It is generally recommended to set this value to 0, especially on routers or gateways.

`net.ipv4.conf.all.log_martians = 1` — enables logging of "Martians" packets, that is, packets that come from incorrect or impossible IP addresses for any network interface. This helps in detecting and diagnosing network anomalies or misconfigurations.

`net.ipv4.conf.all.send_redirects = 0` — disables sending ICMP redirects, which can help prevent redirect attacks.

`net.ipv4.conf.default.accept_redirects = 0` — disables accepting ICMP redirects by default to improve security.

`net.ipv4.conf.default.log_martians = 1` — enables logging of "Martian" packets for default interfaces.

`net.ipv4.tcp_timestamps = 0` — disables the use of TCP timestamps, which can help prevent some time manipulation attacks.

`net.ipv6.conf.all.accept_redirects = 0` and `net.ipv6.conf.default.accept_redirects = 0` — disables accepting ICMPv6 redirects for IPv6.

`net.ipv4.conf.all.rp_filter = 1` — enables reverse path checking to filter packets with invalid source addresses.

`net.ipv4.conf.default.accept_source_route = 0` — disables accepting packets with a route containing the source route to prevent packet spoofing attacks.

`net.ipv4.conf.all.proxy_arp = 0` — disables proxy ARP, which can help prevent some network attacks.

These settings can be added to the `/etc/sysctl.conf` file and applied with the command :
`sysctl -p`

Before applying the changes, it is recommended to familiarize yourself with their impact and test them on a test system.

Disabling kernel modules such as `ohci1394`, `sbp2`, `dv1394`, `raw1394`, `video1394 `helps reduce the attack surface of the server and reduces the risk of vulnerability exploitation in these modules. This makes it easier to secure and manage the server and focus on keeping the components being used up to date and secure.

**→ Disabling USB Storage kernel modules and selecting the classic FireWire stack before the new CONFIG_FIREWIRE:**

1. For USB Storage:

Create the configuration file `/etc/modprobe.d/usb-storage.con` with the following contents:
`install usb-storage /bin/true`

1. For FireWire:

Configured in `/etc/modprobe.d/blacklist-firewire.conf` :
```
blacklist ohci1394
blacklist sbp2
blacklist dv1394
blacklist raw1394
blacklist video1394
```
    
**Configuring** `auditd` **auditing in Linux**. Lets you monitor and record any security events that occur on your system, providing detailed auditing of important system components and files. This helps to quickly identify unauthorized actions, security breaches, and configuration changes.

Setting up `auditd` checks in Linux lets you create detailed audit logs to monitor user actions and system events. A file automatically generated from `/etc/audit/rules.d` efines the audit rules for monitoring various actions on the system.

**→ Here are my auditd audit settings in Linux:**

```
apt install auditd -y
systemctl enable auditd
echo '
## This file is automatically generated from /etc/audit/rules.d
-D
-b 8192
-f 1
--backlog_wait_time 60000
-w /var/log/audit/ -k auditlog
-w /etc/audit/ -p wa -k auditconfig
-w /etc/libaudit.conf -p wa -k auditconfig
-w /etc/audisp/ -p wa -k audispconfig
-w /sbin/auditctl -p x -k audittools
-w /sbin/auditd -p x -k audittools
-a exit,always -F arch=b32 -S mknod -S mknodat -k specialfiles
-a exit,always -F arch=b64 -S mknod -S mknodat -k specialfiles
-a exit,always -F arch=b32 -S mount -S umount -S umount2 -k mount
-a exit,always -F arch=b64 -S mount -S umount2 -k mount
-a exit,always -F arch=b32 -S adjtimex -S settimeofday -S stime -S clock_settime -k time
-a exit,always -F arch=b64 -S adjtimex -S settimeofday -S clock_settime -k time
-w /etc/localtime -p wa -k localtime
-w /etc/cron.allow -p wa -k cron
-w /etc/cron.deny -p wa -k cron
-w /etc/cron.d/ -p wa -k cron
-w /etc/cron.daily/ -p wa -k cron
-w /etc/cron.hourly/ -p wa -k cron
-w /etc/cron.monthly/ -p wa -k cron
-w /etc/cron.weekly/ -p wa -k cron
-w /etc/crontab -p wa -k cron
-w /var/spool/cron/crontabs/ -k cron
-w /etc/group -p wa -k etcgroup
-w /etc/passwd -p wa -k etcpasswd
-w /etc/gshadow -k etcgroup
-w /etc/shadow -k etcpasswd
-w /etc/security/opasswd -k opasswd
-w /usr/bin/passwd -p x -k passwd_modification
-w /usr/sbin/groupadd -p x -k group_modification
-w /usr/sbin/groupmod -p x -k group_modification
-w /usr/sbin/addgroup -p x -k group_modification
-w /usr/sbin/useradd -p x -k user_modification
-w /usr/sbin/usermod -p x -k user_modification
-w /usr/sbin/adduser -p x -k user_modification
-w /etc/login.defs -p wa -k login
-w /etc/securetty -p wa -k login
-w /var/log/faillog -p wa -k login
-w /var/log/lastlog -p wa -k login
-w /var/log/tallylog -p wa -k login
-w /etc/hosts -p wa -k hosts
-w /etc/network/ -p wa -k network
-w /etc/inittab -p wa -k init
-w /etc/init.d/ -p wa -k init
-w /etc/init/ -p wa -k init
-w /etc/ld.so.conf -p wa -k libpath
-w /etc/sysctl.conf -p wa -k sysctl
-w /etc/modprobe.conf -p wa -k modprobe
-w /etc/pam.d/ -p wa -k pam
-w /etc/security/limits.conf -p wa  -k pam
-w /etc/security/pam_env.conf -p wa -k pam
-w /etc/security/namespace.conf -p wa -k pam
-w /etc/security/namespace.init -p wa -k pam
-w /etc/puppetlabs/puppet/ssl -p wa -k puppet_ssl
-w /etc/aliases -p wa -k mail
-w /etc/postfix/ -p wa -k mail
-w /etc/ssh/sshd_config -k sshd
-a exit,always -F arch=b32 -S sethostname -k hostname
-a exit,always -F arch=b64 -S sethostname -k hostname
-w /etc/issue -p wa -k etcissue
-w /etc/issue.net -p wa -k etcissue
-a exit,always -F arch=b64 -F euid=0 -S execve -k rootcmd
-a exit,always -F arch=b32 -F euid=0 -S execve -k rootcmd
-a exit,always -F arch=b64 -S open -F dir=/etc -F success=0 -k unauthedfileacess
-a exit,always -F arch=b64 -S open -F dir=/bin -F success=0 -k unauthedfileacess
-a exit,always -F arch=b64 -S open -F dir=/home -F success=0 -k unauthedfileacess
-a exit,always -F arch=b64 -S open -F dir=/var/www -F success=0 -k unauthedfileacess
-a exit,always -F arch=b64 -S open -F dir=/sbin -F success=0 -k unauthedfileacess
-a exit,always -F arch=b64 -S open -F dir=/srv -F success=0 -k unauthedfileacess
-a exit,always -F arch=b64 -S open -F dir=/usr/bin -F success=0 -k unauthedfileacess
-a exit,always -F arch=b64 -S open -F dir=/usr/local/bin -F success=0 -k unauthedfileacess
-a exit,always -F arch=b64 -S open -F dir=/usr/sbin -F success=0 -k unauthedfileacess
-a exit,always -F arch=b64 -S open -F dir=/var -F success=0 -k unauthedfileacess
-w /bin/su -p x -k priv_esc
-w /usr/bin/sudo -p x -k priv_esc
-w /etc/sudoers -p rw -k priv_esc
-w /sbin/halt -p x -k power
-w /sbin/poweroff -p x -k power
-w /sbin/reboot -p x -k power
-w /sbin/shutdown -p x -k power
-e 2
' > /etc/audit/rules.d/audit.rules
auditctl -R /etc/audit/audit.rules
```
I'd be happy to hear how you do it or how I could improve my practice.

## Strategy for strengthening authentication security
To strengthen the security of your Linux system, it is important to enable strong authentication.

This includes the following:

**Strong password rules.** Ensure that each user account uses passwords that are at least 12 characters long, including uppercase and lowercase letters, numbers, and unique characters. Avoid using easily predictable words or phrases.

**Regular password changes.** Enforce a policy of changing passwords at specific intervals, such as every 90 days, to reduce the risk of credentials getting compromised.

**Two-Factor Authentication (2FA)**. Add an extra layer of security by requiring another form of authentication in addition to a password, such as a code sent to a cell phone, a fingerprint, or a physical security key.

**Password Management.** Use strong password managers to securely store and manage passwords, allowing users to use different and complex passwords without having to memorize them.

These strategies can significantly reduce the likelihood of unauthorized access to your Linux system and protect your important information from cyber threats.

**→ Two-step authentication in ispmanager**

By default, only a login and password are required to log in to the control panel. However, to improve account security, it is recommended to use two-step authentication.

When this feature is enabled, the user will need to provide the following authorization details:

- Login and password.

- A one-time numeric password that is generated by the Google Authenticator mobile app.

For more information on setting up two-step authentication, see the [official documentation →](https://www.ispmanager.com/docs/ispmanager/two-step-authentication)

## Channel encryption
Channel encryption using OpenVPN and WireGuard helps strengthen information security by ensuring the confidentiality and integrity of data transmitted, protecting it from interception and modification by intruders during transmission over the network.

**OpenVPN.** Uses the OpenSSL library, which supports multiple encryption algorithms.

The most commonly used OpenVPN algorithms include:

→ AES (Advanced Encryption Standard). The most popular encryption algorithm used in OpenVPN. Commonly used variants are AES-128, AES-192, and AES-256, where the numbers denote the key size in bits.

→ Blowfish. This is a symmetric block encryption algorithm that was one of the first algorithms supported by OpenVPN. However, it is considered less secure than AES.

→ Camellia. This is a symmetric block encryption algorithm similar to AES. Camellia is less commonly used but offers a similar degree of security.

**WireGuard.** Uses a proprietary set of cryptographic primitives known as the Noise Protocol Framework.

The main algorithms used in WireGuard include:

→ ChaCha20. This is a symmetric stream encryption algorithm that is used to encrypt data. ChaCha20 provides high speed and security.

→ Poly1305. This is an algorithm for creating a message authentication code (MAC) that is used in conjunction with ChaCha20 to ensure data integrity and authentication.

→ Curve25519. This is an algorithm for the Elliptic Curve Diffie-Hellman (ECDH) key exchange, used to establish a secret key shared between two parties.

→ BLAKE2s. This is the hashing algorithm used for various internal operations in WireGuard.

Configuring WireGuard in ispmanager 6 is described in the [official documentation →](https://www.ispmanager.com/docs/ispmanager/vpn)

Both protocols offer strong encryption but use different approaches and algorithms. Which one to choose depends on your specific security, performance, and compatibility requirements.

I choose WireGuard for its easy setup, high speed, and advanced encryption algorithms. This tool provides strong security and high performance, making it the ideal choice for creating secure VPN connections.

Of course, there are other ways to protect data transmitted over a network. I have described some reliable and easy-to-use solutions. Client applications are available for various operating systems, including Windows, macOS, Linux, Android, and iOS.

## Uninstalling unwanted software
Fewer programs means fewer vulnerable points and a more efficient use of resources.

**Steps to remove unwanted software:**

**1. Identify unneeded applications.** Use tools such as `dpkg-query` to list installed packages and identify those that can be removed. You can output a list of installed packages with the command:
`dpkg-query -l or dpkg-query -l | awk '{print $2}'`.

To view information about a particular installed package, use the command:
`dpkg-query -l apache2`

**2. Remove unused software through the package manager.** Use commands such as:
`sudo apt remove [package_name]`

**3. Complete removal of packages.** To remove even configuration files of unnecessary packages, use:
`sudo apt purge [package_name] or sudo apt purge ~c`

to remove all packages marked as obsolete.

**4. Clean up dependencies.** Use:
`sudo apt autoremove`

to remove packages that were installed to satisfy dependencies of other packages but are no longer needed.

**5. Regular checks.** Periodically check and uninstall programs that are no longer needed to ensure system security and efficiency.

**In the ispmanager 6 interface:**
1. Go to the "Settings" section.
2. Select Software Configuration.
3. Find the service you need, in the example, apache2 and the web server (WWW).
4. Click: "Edit".

![How to secure a WordPress site with Linux Debian](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8vuvo88n5tn4iennuxre.png)

Go to "Software Setup → Web Server (WWW)" and set "Do Not Use".

![How to secure a WordPress site with Linux Debian](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t1z1uumiqzuhy0nga9kq.png)

## Disabling unnecessary services
Disabling unnecessary services reduces the attack surface of the system and reduces the number of potential vulnerabilities.

First, determine which services are running to decide which ones can be disabled. To get a list of all services and their statuses, use the `service` command with the argument `status-all` as shown below:
`sudo service --status-all`

In this list, running services are marked with a + symbol and services that are disabled are marked with a - symbol.

If the service is disabled but not stopped, it will continue until the next reboot.

To stop a service before disabling it, use the `systemctl` command with the `stop` argument followed by the service name:
`sudo systemctl stop`

For example, to stop the apache2 service, run the command:
`sudo systemctl stop apache2`

To completely disable a service and prevent it from starting on the next reboot, use the `systemctl` command with the disable argument and the service name:
`sudo systemctl disable`

For example, to disable the apache2 service and prevent it from restarting on the next reboot, run the command:
`sudo systemctl disable apache2`

**In the ispmanager interface:**
1. Go to the Monitoring and Logs section.
2. Select "Services."
3. Find the service you need, for example, apache2.
4. Click the appropriate button for the task: "Start", "Stop", "Restart" or "Enable/Disable Autorun".
![How to secure a WordPress site with Linux Debian](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q2947egj4qbuk047fmv7.png)

## Configuring Firewall iptables
Configuring iptables by closing unnecessary ports and configuring server access policies helps control traffic and restrict access to services.

**Closing open ports.** To close port 3306/tcp (the default port for MySQL) using iptables and ip6tables, do the following.

1. Check the current iptables rules.

For IPv4:
`sudo iptables -L`

For IPv6:
`sudo ip6tables -L`

2. If necessary, add a rule to block port 3306.

For IPv4:
`sudo iptables -A INPUT -p tcp --destination-port 3306 -j DROP`

For IPv6:
`sudo ip6tables -A INPUT -p tcp --destination-port 3306 -j DROP`

3. Verify that the rule has been added by running the commands to verify the rules.

4. Save the changes so that they are applied after reboot.

For IPv4:
`sudo iptables-save > /etc/ispiptable.conf`

For IPv6:
`sudo iptables-save > /etc/ispip6table.conf`

Port 3306/tcp will now be blocked and will not be accessible from the outside.

Open access for IP White List. To open access to port 3306/tcp (MySQL) for a specific IP address 1.2.3.4 in iptables and ip6tables, follow these steps.

1. Check the current rules as described in the chapter above.

2. Add a rule to allow access to port 3306 from IP address 1.2.3.4 and `fe12::3456:ff:fe89:10`

For IPv4:
`sudo iptables -A INPUT -p tcp --dport 3306 -s 1.2.3.4 -j ACCEPT`

For IPv6:
`ip6tables -A INPUT -p tcp --dport 3306 -s fe12::3456:ff:fe89:10 -j ACCEPT`

3. Ensure that the rule is added as described in the chapter above.

4. Save the changes so that they are applied after reboot as described in the section above.

Now, IPv4 address 1.2.3.4 and IPv6 address `fe12::3456:ff:fe89:10` will have access to port 3306/tcp of the MySQL server.

Ready-made iptables configuration for ispmanager 6. The `/etc/ispiptable.conf` file is presented below. The `/etc/ispip6table.conf` configuration will be discussed in a separate article dedicated to configuring iptables in ispmanager.

Copy the text and paste it into a terminal with root or administrator privileges:
```
sudo echo '
# Generated by iptables-save v1.8.7 on Sun Mar 24 01:54:11 2024
*filter
:INPUT DROP [0:0]

:FORWARD DROP [0:0]

:OUTPUT ACCEPT [0:0]

:ispmgr_allow_ip - [0:0]

:ispmgr_allow_sub - [0:0]

:ispmgr_deny_ip - [0:0]

:ispmgr_deny_sub - [0:0]

:ispmgr_limit_req - [0:0]

-A INPUT -j ispmgr_deny_ip

-A INPUT -j ispmgr_allow_ip

-A INPUT -j ispmgr_allow_sub

-A INPUT -j ispmgr_deny_sub

# Change ispmgr_limit_req to ispmgr_limit_req6
# -A INPUT -m set --match-set ispmgr_limit_req6 src -j DROP
-A INPUT -m set --match-set ispmgr_limit_req src -j DROP

-A INPUT -i lo -j ACCEPT 
 
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # Web server

-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # FTP сервер

-A INPUT -p tcp -m tcp --dport 21 -j ACCEPT

-A INPUT -p tcp -m tcp --dport 49152:65534 -j ACCEPT
 
# SSH port
-A INPUT -p tcp -m tcp --dport 1234 -j ACCEPT 

# Mail server
-A INPUT -p tcp -m tcp --dport 143 -j ACCEPT

-A INPUT -p tcp -m tcp --dport 993 -j ACCEPT

-A INPUT -p tcp -m tcp --dport 110 -j ACCEPT

-A INPUT -p tcp -m tcp --dport 995 -j ACCEPT

-A INPUT -p tcp -m tcp --dport 25 -j ACCEPT

-A INPUT -p tcp -m tcp --dport 465 -j ACCEPT

-A INPUT -p tcp -m tcp --dport 587 -j ACCEPT

#Hosting panel 
# I don't recommend opening the hosting panel access to all IPs, replace 1.2.3.4 with your IP 
# -A INPUT -s 1.2.3.4 -p tcp -m tcp --dport 1500 -j ACCEPT 

#  To avoid losing access to the hosting panel, I commented out the rule above. 
#  If you want to activate this rule, edit it by removing the comment character at the beginning of the line 
# and then delete this rule: `-A INPUT -p tcp -m tcp --dport 1500 -j ACCEPT`.
-A INPUT -p tcp -m tcp --dport 1500 -j ACCEPT

# DNS 
-A INPUT -p udp -m udp --dport 53 -j ACCEPT

COMMIT
# Completed on Sun Mar 24 01:54:11 2024' > /etc/ispiptable.conf
```
    
To quickly apply the settings, run the following command:

For IPv4:
`sudo iptables-restore < /etc/ispiptable.conf`

For IPv6:
`sudo ip6tables-restore < /etc/ispip6table.conf`

To use the sudo command, you must install and configure the appropriate package.

If you encounter the error:
`-bash: sudo: command not found`

execute the commands with root user privileges without using `sudo`. Or you can install `sudo` by running this command as root user:
`apt install sudo`

After that, `sudo` should work as expected.

## Fail2ban Configuration
Fail2ban analyzes application logs, protects Linux from various types of attacks, including brute-force attacks and port scans, and automatically blocks IP addresses from which suspicious requests originate.

**Installing Fail2ban**

1. System upgrade:
`sudo apt update sudo apt upgrade -y`

2. Installing Fail2ban:
`sudo apt install fail2ban -y`

**Configuring Fail2ban for SSH protection**

1. Create a copy of the configuration file.

Fail2ban reads configuration files in the following order:
`fail2ban.conf`, `fail2ban.local`, `jail.conf`, `jail.d/*.conf`, `jail.local`, `jail.d/*.local`

It is best practice to create `.local` files to modify your settings so that they are not overwritten when the package is upgraded:
`sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local`

2. Configure the `/etc/fail2ban/jail.d/defaults-debian.local` file for SSH protection:

Open the file in an editor:
`sudo nano /etc/fail2ban/jail.d/defaults-debian.local`

Locate the `[sshd]` section and ensure it is enabled with `[sshd] = true`. You can customize the settings to suit your needs, e.g:

```
[sshd]
enabled = true
# Here, I changed the default port 
port    = 1234
filter  = sshd
maxretry = 5
bantime = 600
```
Here, `maxretry` is the number of login attempts before getting blocked and bantime is the how long attempts will remain blocked in seconds.

3. Restarting Fail2ban:
`sudo systemctl restart fail2ban or sudo fail2ban-client restart`

**Checking the status of Fail2ban**

Check the status of Fail2ban and active SSH rules:
`sudo fail2ban-client status sudo fail2ban-client status sshd`

Fail2ban will now monitor SSH logs and block IP addresses that make too many failed login attempts, thus protecting your server from brute-force attacks.

**→ Installing and configuring Fail2ban in ispmanager 6**

**Installation.** Usually, Fail2ban is already pre-installed in the system when you install ispmanager 6. If for some reason Fail2ban is missing, you can easily install it via the panel interface:

1. Go to Settings → Software Configuration.
2. Find Fail2ban in the list, check it.
3. Click on the "Install" button.

An example of the installation process is shown below.
![How to secure a WordPress site with Linux Debian](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/egtg9kt837xqnwlxe50v.png)

**Setup.** Network services play a key role in enabling communication between devices on a network, such as computers and other network equipment. For example, the SSH service (sshd) allows you to connect to a server using the SSH protocol, and the web server service (httpd) manages web connections.

The following settings are available in the Network Services section of ispmanager:

- Configuration of access rules for your server's network services.

- Setting up protection against brute-force attacks using the Fail2ban service.

To work with this module, go to Monitoring and Logs → Network Services.
![IHow to secure a WordPress site with Linux Debian](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/18pklu8uso5k9jhr6bs5.png)

More information and detailed instructions can be found in the official [ispmanager documentation →](https://www.ispmanager.com/docs/ispmanager/network-services)

Configuring Fail2ban is a broad topic covering not only sshd protection but also services such as Exim, Dovecot, Proftpd, and other services. If you are interested in a detailed description of this topic, please mark it in the comments and I will prepare materials on configuring Fail2ban for different services.

## AppArmor profiling
Profiling in AppArmor allows you to restrict what programs can do by creating and configuring profiles to control how applications access system resources.

An example of an AppArmor php-fpm profile for securing a website on WordPress:

```
# Last Modified: Tue Mar 19 09:44:20 2024
include 

/opt/php74/sbin/php-fpm {
  include 
  include 
  include 
  include 
  include 

  capability chown,
  capability kill,
  capability net_admin,
  capability setgid,
  capability setuid,

  network inet dgram,
  network inet6 dgram,

  /etc/ImageMagick-6/coder.xml r,
  /etc/ImageMagick-6/magic.xml r,
  /etc/hosts r,
  /opt/php74/sbin/php-fpm mr,
  /run/*.sock w,
  /run/mysqld/mysqld.sock rw,
  /run/systemd/resolve/stub-resolv.conf r,
  /usr/share/ImageMagick-6/english.xml r,
  /usr/share/ImageMagick-6/locale.xml r,
  /var/www/*/data/logs/.log w,
  owner /etc/ImageMagick-6/log.xml r,
  owner /etc/ImageMagick-6/policy.xml r,
  owner /opt/php74/conf.d/ r,
  owner /opt/php74/etc/* r,
  owner /opt/php74/etc/*/ r,
  owner /opt/php74/etc/php-fpm.d/* r,
  owner /opt/php74/lib/php/extensions/ mr,
  owner /opt/php74/mods-available/* r,
  owner /opt/php74/var/log/php-fpm.log w,
  owner /opt/php74/var/run/php-fpm.pid w,
  owner /proc/sys/kernel/random/boot_id r,
  owner /run/*.sock rw,
  owner /run/systemd/notify w,
  owner /run/systemd/userdb/ r,
  owner /run/systemd/userdb/io.systemd.DynamicUser rw,
  owner /var/www/*/data/tmp/* rwk,
  owner /var/www/*/data/mod-tmp/* rwk,
  owner /var/www/*/data/www/*/ r,
  owner /var/www/*/data/www/*/sap-logs/logs-*.txt w,
  owner /var/www/*/data/www/*/wp-content/cache/ w,
  owner /var/www/*/data/www/*/wp-content/uploads/.gif w,
  owner /var/www/*/data/www/*/wp-content/uploads/.jpg w,
  owner /var/www/*/data/www/*/wp-content/uploads/.mp4 w,
  owner /var/www/*/data/www/*/wp-content/uploads/.png w,
  owner /var/www/*/data/www/*/wp-content/webp-express/webp-images/doc-root/wp-content/uploads/ w,
  owner /var/www/*/data/www/*/wp-content/webp-express/webp-images/doc-root/wp-content/uploads/.jpg.webp w,
  owner /var/www/*/data/www/*/wp-content/wflogs/*.php rwk,
  owner /var/www/*/data/www/*/wp-content/wflogs/config.tmp.* wk,
  owner /var/www/*/data/www/*/wp-content/temp-write-* w,
  owner /var/www/*/data/www/*/wp-content/uploads/temp-write-test-* w,
}
```
    
This AppArmor profile is designed to manage the permissions of the php-fpm process used in web servers.

Here are some key aspects of the profile:
**Inclusion of abstractions.** A profile includes various AppArmor abstractions such as apache2-common, base, openssl, php, and user-tmp that provide common access rules used across many profiles.

**Capabilities.** The profile provides php-fpm with certain capabilities such as chown, kill, net_admin, setgid, and setuid , allowing it to change the owner of files, send signals to processes, manage network settings, and change group and user IDs.

**Network access.** Network access via inet and inet6 (IPv4 and IPv6 respectively) for datagrams (dgram) is enabled, allowing php-fpm to communicate with the network

**File and Directory Access.** The profile defines rules for accessing various files and directories, including configuration files, logs, temporary files, and files and directories associated with websites on WordPress. For example, read access to ImageMagick configuration files, writing to website logs, and reading and writing to a WordPress cache and upload directories are allowed.

**Protecting log and configuration files.** The profile restricts access to php-fpm log and configuration files, allowing writing only to specific files and directories.

This AppArmor profile is configured to keep php-fpm running securely, limiting its capabilities and access to the file system. However, security profiles may vary depending on the installed plugins in WordPress.

Customizing AppArmor is a vast topic that requires more than one article to detail the process of creating profiles for services such as Apache, Nginx, MySQL, Exim, Dovecot, Proftpd, Redis, Memcached, and others. If you are interested in this topic, please mention it in the comments and I will prepare detailed materials on how to customize AppArmor.

Let us know what other aspects of security for Linux Debian with ispmanager 6 you would like to discuss.

Later in the series, we will discuss:
1. The practical use of ModSecurity in Nginx
2. Tools for auditing and monitoring security
3. Data redundancy and the software needed for it

Want more articles like this? Subscribe [to our newsletter](https://9ce5ba7f.sibforms.com/serve/MUIFADo9TWiTfGbIQS2_6jvU1if3z-K6845WSmXxJOUoLHCEFzrofp-PTPVqQiNhh2Di3xDLMXG-lVfMoRRPkDt64Z_DwSm2yQPIkQVACt--A3R7My3LQnbONtZ7W4W6uaj0ramr9JLDJ3reMAmf7z-lS16D4qAfrlYcD5GUhGNfqfIi0YKkqO5niM7X6TRjUBll72vLzapyY_by)

_This article was originally published on the [ispmanager blog →](https://www.ispmanager.com/news/how-to-secure-a-wordpress-site-with-linux-debian-and-ispmanager-6)_