How to secure your server (Debian/Linux) and WordPress

Basic steps to secure your server from DDOS and BruteForce attacks.

Creating strong passwords i would recommend using a browser extensions as password generator.

-Configuring Auto-Update:

apt install unattended-upgrades
systemctl enable unattended-upgrades
systemctl status unattended-upgrades

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

Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Verbose "true";

nano /etc/apt/apt.conf.d/20auto-upgrades

systemctl restart unattended-upgrades
unattended-upgrade --dry-run --debug


Install UFW:
apt install ufw
Allow only your ip to connect to ssh port: 
 ufw deny ssh/tcp
ufw allow from  to any port 22

ufw limit 22/tcp

ufw allow 80/tcp
ufw allow 443/tcp
ufw default deny incoming
ufw default deny  outgoing

systemctl enable ufw.service
systemctl start ufw.service
ufw status
ufw enable
MaxAuthTries 2
MaxSessions 2
PermitRootLogin no
Uncomment >>
enable spoof
block ping ICMP  
add net.ipv4.icmp_echo_ignore_all = 1
not a router
martian packet

/sbin/sysctl -p

Fail2ban – Bruteforce:

apt-get install fail2ban
systemctl enable fail2ban
systemctl restart fail2ban.service 

nano /etc/fail2ban/filter.d/http-get-dos.conf

# Fail2Ban configuration file
# Option: failregex 
 # Note: This regex will match any GET entry in your logs, so basically all valid and not valid entries are a match. 
# You should set up in the jail.conf file, the maxretry and findtime carefully in order to avoid false positives. 
 failregex = ^<HOST> -.*"(GET|POST).* 
 # Option: ignoreregex
 ignoreregex =

nano /etc/fail2ban/jail.local

##Block the failed login attempts on the SSH server.
enable = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 2
findtime = 300000
bantime = 300000
ignoreip =

##Block the remote host that is trying to request suspicious URLs.
 enabled = true
 port = http,https
 filter = apache-overflows
 logpath = /var/log/apache2/*error.log
 maxretry = 2
 bantime = 30000
 ignoreip =

##Stop DOS attack from remote host. 
 enabled = true
 port = http,https
 filter = http-get-dos
 logpath = /var/log/apache2/access.log
 maxretry = 50
 findtime = 400
 bantime = 200000
 ignoreip =
 action = iptables[name=HTTP, port=http, protocol=tcp]

##Block the remote host that is trying to search for scripts on the website to $
 enabled = true
 port = http,https
 filter = apache-noscript
 logpath = /var/log/apache2/*error.log
 maxretry = 2
 bantime = 30000
 ignoreip =

fail2ban-client status sshd / http-get-dos /apache-overflows /apache-badbots /apache-noscript

IpTables: N/D


-Install Mod-evasive:

apt install libapache2-mod-evasive

-Install Mod-Security:

apt install libapache2-mod-security2 apt install modsecurity-crs

How to Set up & Configure ModSecurity on Apache

Not very friendly with WordPress I would recommend check log errors and start from there:

tail /var/log/apache2/error.log

-Apache/wordpress security:

nano /etc/apache2/apache2.conf

<Directory /var/www/dstaffieri>
        AllowOverride All
        Options -Indexes
        ServerSignature Off

-Setting up Apache authentications:

apt install apache2-utils 
htpasswd -c /etc/apache2/.htpasswd "user"
cd wp-admin/
nano .htaccess
AuthName "Admin Login"
AuthUserFile /et/apache2/.htpasswd
AuthType basic
Require valid-user
chmod 0444 .htaccess
systemctl restart apache2


-Disable file editing nano /var/www/html/..wp-config.php

/** Disable file editing
chmod 0444 wp-config.php
chmod 0444 .htaccess 

-Disable directory listening

nano .htaccess 
Options -Indexes
systemctl restart apache2
apt install modsecurity-crs 

-Disable Php uploads

cd ../wp-content/uploads/
nano .htaccess
<Files *.php>
deny from all
chmod 0444 .htaccess

apt install auditd


-Install ClamAV
apt install clamav clamav-daemon
systemctl stop clamav-freshclam
systemctl start clamav-daemon.service 
systemctl start clamav-freshclam.service
clamscan -i -r -v /
clamscan -i -r -v  --remove /

-Automatic scanning:

crontab -e
0 01 * * 1 date >> /var/log/clamav_log
0 01 * * 1 clamscan --exclude-dir=/proc/* --exclude-dir=/sys/* -i -r / >> /var/log/rsync_log
crontab -l

-Install Rkhunter

apt install rkhunter
rkhunter --check
nano /etc/default/rkhunter 

-Install Lynis

apt install lynis
lynis audit system
lynis --pentest
grep Suggestion /var/log/lynis.log 
Review the result and make the change 

-Install aide

apt-get install aide -y
cp /var/lib/aide/ /var/lib/aide/aide.db
cp /var/lib/aide/aide.conf.autogenerated /etc/aide/aide.conf
aide -c /etc/aide/aide.conf --check

-Automated Backup

-Website Backup

rsync -av  /var/www/html/ /backups/website/$(date +\%Y\%m\%d)
crontab -e
00 01 * * 1 rsync -avz  /var/www/html/ /backups/website/$(date +\%Y\%m\%d) >> /var/log/cronjob1.log 2>&1

-MySQL Security

bind-address =
chmod 644 /etc/my.cnf

-MySQL Backup

mysqldump -u root -p'xxx' wordpress | gzip -c > /backups/database/$(date +\%Y\%m\%d).sql.gz
crontab -e
00 01 * * * mysqldump -u root -p'93zcsb43' wordpress | gzip -c > /backups/database/wordpress$(date +\%Y\%m\%d).sql.gz >> /var/log/cronjob2.log 2>&1

grep CRON /var/log/syslog


mysql -u root p'password' database_name < /path/to/[database_name].sql

-Cloudfare: Set up your DNS to Prevent RDNS and ddos - free account

-Wordpress Install Wordfence Plugin and Loginizer Brute Force Block Ip bruteforce attack



-DDOS usefull commands:

number of connections

netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
netstat -alpn | grep :80 | awk '{print $5}' |awk -F: '{print $(NF-1)}' |sort | uniq -c | sort -nr
netstat -an | grep :80 | grep -v | awk '{ print $5 }' | sort | awk -F: '{ print $1, $4 }' | uniq -c | awk ' $1 > 100 { print $1, $2 }' > /tmp/blackname.txt
grep 'sshd' /var/log/auth.log
grep 'http' /var/log/auth.log
grep 'https' /var/log/auth.log

awk '{print $1}' /var/log/apache2/access.log | sort -u

-Block the attacking network

ufw deny from to any
ufw reject from to any 
iptables -A INPUT -s <Source IP> -j DROP