- Purpose
- Supported Environment
- Warning
- Quick Install
- Run Security Check
- Installed Packages
- Quick Note - Package
- Quick Note - Fail2ban flow
- Quick Note - Fail2ban all detailed status
- Install SSL (Letsencrypt) - A+
- Log analyzer
- Performance monitor
- CHANGELOG
This presumes that you've done with ubuntu_preparation
- This is used for check if your linux server is being hacked.
- This could also help you to enhance your servers' security with firewall (ufw) and fail2ban.
- This is also designed for PRODUCTION single server, which means this is suit for small business.
- Ubuntu 24.04
- ubuntu_security
- release :
main
v2.x.x
- release :
- ubuntu_security
- Ubuntu 22.04
- ubuntu_security
- release :
v1.x.x
- release :
- ubuntu_security
- If you found something is weired and not sure if you've been hacked. You'd better reinstall your server.
- ClamAV (clamscan) - if you're going to scan virus through clamscan (ClamAV), which is installed by default (ubuntu_security)
clamscan
is a memory monster- RAM (Physical + SWAP) Capacity recommendations for clamscan (ClamAV): >= 4GB
- (Tip) mkswap if RAM is insufficient to run clamscan
- If your physical memory is <= 1GB, be sure stop some service before getting started
-
(Nginx) is needed when TLS (certbot) certificates is required
systemctl list-unit-files |grep -E 'mariadb\.service|php[[:print:]]*fpm\.service|puma[[:print:]]*\.service' | awk '{print $1}' | xargs | xargs -I{} bash -c "echo --- Stop and Disable {} ---; systemctl stop {} ; systemctl disable {}; echo"
-
Nginx is not needed, when NO TLS certificates required
systemctl list-unit-files |grep -E 'mariadb\.service|php[[:print:]]*fpm\.service|puma[[:print:]]*\.service|nginx\.service' | awk '{print $1}' | xargs | xargs -I{} bash -c "echo --- Stop and Disable {} ---; systemctl stop {} ; systemctl disable {}; echo"
-
-
Download and run check
apt install -y git git clone https://github.com/charlietag/ubuntu_security.git
-
Make sure config files exists , you can copy from sample to modify.
cd databag ls |xargs -i bash -c "cp {} \$(echo {}|sed 's/\.sample//g')"
-
Mostly used configuration :
-
DEV use (server in Local)
-
NO NEED to setup config, just
./start -a
without config, by default, the following will be executedfunctions/ ├── F_00_list_os_users ├── F_01_CHECK_01_os ├── F_01_CHECK_02_failed_login ├── F_01_CHECK_03_last_login ├── F_01_CHECK_04_ssh_config ├── F_02_PKG_02_install_perf_tools ├── F_02_PKG_04_ufw_01_install ├── F_02_PKG_05_fail2ban_01_install
-
-
DEV use (server in Cloud)
- It would be better to work with VPS Firewall for more secure enviroment
- Firewall(ufw) + Fail2ban + VPS Firewall (Vultr / DigitalOcean)
databag/ ├── F_02_PKG_01_install_log_analyzer.cfg ├── F_02_PKG_04_ufw_02_setup.cfg (rementer add customized port for dev, like 8000 for laravel, 3000 for rails) ├── F_02_PKG_05_fail2ban_02_setup.cfg ├── F_02_PKG_05_fail2ban_03_nginx_check_banned.cfg ├── F_02_PKG_07_nginx_01_ssl_enhanced.cfg ├── F_02_PKG_08_redmine_01_fail2ban.cfg ├── F_03_CHECK_01_check_scripts.cfg └── _postfix.cfg
F_02_PKG_21_install_clamav.cfg_nginx_modules.cfg
- It would be better to work with VPS Firewall for more secure enviroment
-
Production use (server in Local)
databag/ ├── F_02_PKG_01_install_log_analyzer.cfg └── _postfix.cfg
F_02_PKG_21_install_clamav.cfg
-
Production use (server in Cloud)
databag/ ├── _certbot.cfg ├── F_02_PKG_01_install_log_analyzer.cfg ├── F_02_PKG_04_ufw_02_setup.cfg ├── F_02_PKG_05_fail2ban_02_setup.cfg ├── F_02_PKG_05_fail2ban_03_nginx_check_banned.cfg ├── F_02_PKG_07_nginx_01_ssl_enhanced.cfg ├── F_02_PKG_07_nginx_02_ssl_site_config.cfg ├── F_02_PKG_08_redmine_01_fail2ban.cfg ├── F_03_CHECK_01_check_scripts.cfg └── _postfix.cfg
F_02_PKG_21_install_clamav.cfg_nginx_modules.cfg
-
-
Verify config files (with syntax color).
cd databag echo ; \ ls *.cfg | xargs -i bash -c " \ echo -e '\e[0;33m'; \ echo ---------------------------; \ echo {}; \ echo ---------------------------; \ echo -n -e '\033[00m' ; \ echo -n -e '\e[0;32m'; \ cat {} | grep -vE '^\s*#' |sed '/^\s*$/d'; \ echo -e '\033[00m' ; \ echo "
-
Verify ONLY modified config files (with syntax color).
cd databag echo ; \ ls *.cfg | xargs -i bash -c " \ echo -e '\e[0;33m'; \ echo ---------------------------; \ echo {}; \ echo ---------------------------; \ echo -n -e '\033[00m' ; \ echo -n -e '\e[0;32m'; \ cat {} | grep -v 'plugin_load_databag.sh' | grep -vE '^\s*#' |sed '/^\s*$/d'; \ echo -e '\033[00m' ; \ echo "
-
First time finish ubuntu_preparation, be sure to do a REBOOT, before installing ubuntu_security
-
Run ALL to do the following with one command
- ./start -a
- Run security check
- Install security package "firewall (ufw)" , "fail2ban" , "letsencrypt" , "nginx waf" , "nginx header"
-
To avoid running ALL, to APPLY and DESTROY letsencrypt cert at the same time.DO NOT run ./start.sh -a
-
Command
./start.sh -i \ F_00_debug \ F_00_list_os_users \ F_01_CHECK_01_os \ F_01_CHECK_02_failed_login \ F_01_CHECK_03_last_login \ F_01_CHECK_04_ssh_config \ F_01_CHECK_05_hosts_config \ ...
-
Check OS
- Verify os basic command (ls,cp, etc..) using
/var/lib/dpkg/info/$pkg.md5sums
(F_01_CHECK_01_os.sh)`
- Verify os basic command (ls,cp, etc..) using
-
Check failed loging
- Check failed attempt ssh login
-
Check ssh config
- Check if root permit
- Check if ssh port set to default 22
-
List os users
- Check current how many common user created
-
Check last login
- Check latest successfully login
-
Check hosts file (/etc/hosts)
127.0.0.1 original content ::1 original content 127.0.0.1 $(hostname) ::1 $(hostname)
- Firewall(ufw)
- Allowed port
- http
- https
- 2222
- Allowed port
- Fail2ban
- Default filtered
- sshd (mode=aggressive)
- nginx-limit-req
- nginx-botsearch
- Default filtered
- limit_req_zone
- This is installed by default on my ubuntu_preparation repo
- This would prevent your server from DDOS attacks.
https://www.nginx.com/resources/wiki/modules/
-
Headers More
more_set_headers "Server: CharlieTag"; # Default=> Nginx: "nginx" , Apache: "Apache"
-
ModSecurity
... modsecurity on; ...
-
ModSecurity - supported policies
-
OWASP CRS
- https://github.com/SpiderLabs/owasp-modsecurity-crs
- Memory consumption
- 100 MB / per nginx process
- Should reference Azure config, to Avoid False Positive
-
https://docs.microsoft.com/en-us/azure/application-gateway/waf-overview
curl -s https://docs.microsoft.com/zh-tw/azure/application-gateway/waf-overview |grep -Eo "REQUEST-[[:digit:]]+" |sort -n | uniq | sed ':a;N;$!ba;s/\n/|/g'
-
if you really need OWASP
-
if you have time to maintain WAF rules (OWASP-CRS) yourself
-
- Reference: REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example , RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example
-
REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example
-
Usage
# ModSecurity Rule Exclusion: Disable all SQLi and XSS rules SecRule REQUEST_FILENAME "@beginsWith /admin" \ "id:1004,\ phase:2,\ pass,\ nolog,\ ctl:ruleRemoveById=941000-942999" # This would cause error # ...no SecRule specified... # ctl:ruleRemoveById=941000-942999"
-
-
RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example
-
Usage
SecRuleRemoveById 949100 949110 959100
-
-
-
COMODO
- https://waf.comodo.com
- Memory consumption
- 300 MB / per nginx process
- Recommended: COMODO (register an account for 1-year-free, require renew 1-year-free order every year)
- OWSASP would have false positive while:
- Wordpress , updating articles
- Redmine , Click between pages
-
Website Vulnerability Scanner
-
nikto
-
Install
apt install -y nikto
-
Start to scan
nikto -h myrails.ubuntu22.localdomain
-
-
skipfish
-
How to use
-
Start to scan (output_result_folder must be an empty folder)
skipfish -o output_result_folder http://myrails.ubuntu22.localdomain
-
-
-
- ufw vs systemctl
-
ufw
- systemctl
- start - trigger ufw initial procedure
- ufw.conf (enable onboot)
- start ufw service
- ufw.conf (disable onboot)
- do nothing
- ufw.conf (enable onboot)
- stop
- trigger ufw instance stop,
NOT change
ufw.conf
- trigger ufw instance stop,
- systemctl enable ufw
- trigger ufw initial procedure onboot
- systemctl disable ufw
- DO NOT trigger ufw initial procedure onboot
- start - trigger ufw initial procedure
- ufw enable
- start ufw instance and
change
ufw.conf (enable onboot)
- start ufw instance and
- ufw disable
- stop ufw instance and
change
ufw.conf (disable onboot)
- stop ufw instance and
- systemctl
-
ufw config default save path (not like firewalld using xml)
- /etc/ufw/user.rules
-
ufw default (/etc/default/ufw)
-
In case someone changed the defaults, you need to change back to ufw default: (run commands In ORDER !)
-
ufw --force reset
will do NOTHING about default config, so do the following again if NEEDED -
These two default commands changed files:
/etc/default/ufw
,/etc/ufw/user.rules
ufw default deny incoming ufw default allow outgoing
-
-
ufw status
verbose
root@ubuntu22 (Ubuntu 22.04.1) 04:13:35 /etc/ufw # ufw status verbose Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- 2222 LIMIT IN Anywhere 443 ALLOW IN Anywhere 80/tcp ALLOW IN Anywhere 2222 (v6) LIMIT IN Anywhere (v6) 443 (v6) ALLOW IN Anywhere (v6) 80/tcp (v6) ALLOW IN Anywhere (v6)
- Default block all traffic, except rules you define below
-
Allow/revoke specific service
ufw allow http ufw delete allow http
-
Allow/revoke specific port
ufw allow 2222/tcp ufw delete allow 2222/tcp
-
List all current rules setting
ufw status verbose
-
List all current rules with number and remove policy easier
# ufw status numbered Status: active To Action From -- ------ ---- [ 1] 80/tcp ALLOW IN Anywhere [ 2] 443 ALLOW IN Anywhere # ufw delete 2
-
After running this installation, your firewall(ufw) will only allow http , https , customized ssh port
- Setting: port, in fail2ban configuration is based on firewall(ufw) services name.
- Determine if rules of fail2ban is inserted into nft via firewall(ufw) command
-
Confirm fail2ban works with nft well
nft list ruleset | grep {banned_ip}
-
List fail2ban status
fail2ban-client status
-
List detailed status for specific JAIL NAME, including banned IP
fail2ban-client status nginx-botsearch
-
Unban banned ip for specific JAIL NAME
fail2ban-client set nginx-botsearch unbanip 192.168.1.72
-
Unban banned specific ip for all JAIL NAME
fail2ban-client unban 192.168.1.72 ... 192.168.1.72
-
List banned ip timeout for specific JAIL NAME using
ipset
(deprecated)ipset list fail2ban-nginx-botsearch
-
Fail2ban keeps showing WARN
2019-12-11 16:23:53,108 fail2ban.ipdns [4812]: WARNING Unable to find a corresponding IP address for xxx.xxx.xxx.xxx.server.com: [Errno -5] No address associated with hostname
-
Solutionfail2ban-client unban --allfail2ban-client restart
-
Root cause (Not verified)
- fail2ban will dns lookup / dns reserve lookup hostname, this will trigger this error message
- fail2ban will not dns lookup / dns reserve lookup 127.0.0.1
- And why VM test server will not show this err message
- The hostname of VM test server is not in
/etc/hosts
but also not in dns. So all the results when dns resolves. areNXDOMAIN
, the same result... PASS
- The hostname of VM test server is not in
-
Solution 1
-
make sure
hostname
is in/etc/hosts
(both ipv4 and ipv6 is needed)# cat /etc/hosts 127.0.0.1 web.example.com ::1 web.example.com
-
-
Solution 2
- make sure DNS record is correct
- A record
web.example.com A xxx.xxx.xxx.xxx
- PTR record (reverse record)
xxx.xxx.xxx.xxx PTR web.example.com
- A record
- make sure DNS record is correct
-
-
(Procedure) Be sure to start "Firewall(ufw) / Fail2ban" in the following order
systemctl stop fail2ban ufw disable ufw enable systemctl start fail2ban
-
List all jail detailed status in faster way
Command
# fail2ban-client status|tail -n 1 | cut -d':' -f2 | sed "s/\s//g" | tr ',' '\n' |xargs -i bash -c "echo \"----{}----\" ;fail2ban-client status {} ; echo "
Result
----nginx-botsearch---- Status for the jail: nginx-botsearch |- Filter | |- Currently failed: 0 | |- Total failed: 0 | `- File list: /var/log/nginx/error.log /var/log/nginx/default.error.log /var/log/nginx/redmine.ubuntu22.localdomain.error.log /var/log/nginx/myrails.ubuntu22.localdomain.error.log /var/log/nginx/mylaravel.ubuntu22.localdomain.error.log `- Actions |- Currently banned: 1 |- Total banned: 1 `- Banned IP list: 10.255.255.254 ----nginx-limit-req---- Status for the jail: nginx-limit-req |- Filter | |- Currently failed: 0 | |- Total failed: 0 | `- File list: /var/log/nginx/error.log /var/log/nginx/default.error.log /var/log/nginx/redmine.ubuntu22.localdomain.error.log /var/log/nginx/myrails.ubuntu22.localdomain.error.log /var/log/nginx/mylaravel.ubuntu22.localdomain.error.log `- Actions |- Currently banned: 1 |- Total banned: 1 `- Banned IP list: 10.255.255.254 ----nginx-modsecurity---- Status for the jail: nginx-modsecurity |- Filter | |- Currently failed: 0 | |- Total failed: 1 | `- File list: /var/log/nginx/error.log /var/log/nginx/default.error.log /var/log/nginx/redmine.ubuntu22.localdomain.error.log /var/log/nginx/myrails.ubuntu22.localdomain.error.log /var/log/nginx/mylaravel.ubuntu22.localdomain.error.log `- Actions |- Currently banned: 1 |- Total banned: 1 `- Banned IP list: 10.255.255.254 ----nginx-redmine---- Status for the jail: nginx-redmine |- Filter | |- Currently failed: 0 | |- Total failed: 0 | `- File list: /home/rubyuser/rails_sites/redmine/log/production.log `- Actions |- Currently banned: 1 |- Total banned: 1 `- Banned IP list: 10.255.255.254 ----sshd---- Status for the jail: sshd |- Filter | |- Currently failed: 0 | |- Total failed: 0 | `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd `- Actions |- Currently banned: 1 |- Total banned: 1 `- Banned IP list: 10.255.255.254
This will automatically setup after installation
Also you will get a score "A+" in SSLTEST
Default : TLS 1.2 1.3 enabled
You will need 2 privileges
- Web server control , to install ssl certificates.
- DNS control , to do ACME verification using TXT record.
-
Sign certificate (RECOMMEND), verified by DNS txt record
certbot --agree-tos -m $certbot_email --no-eff-email certonly --manual --preferred-challenges dns -d {domain}
-
Sign certificate , verified by web server root
certbot --agree-tos -m $certbot_email --no-eff-email certonly --webroot -w /{PATH}/laravel/public -d {domain} -n
-
Display all certificates
certbot certificates
-
Renew all certificates
certbot renew
-
Revoke and delete certificate
certbot revoke --cert-path /etc/letsencrypt/live/{domain}/cert.pem certbot delete --cert-name {domain}
-
New site - url : gen nginx site config + apply letsencrypt ssl only
./start.sh -i F_02_PKG_07_nginx_02_ssl_site_config
Before going on, be sure http port is reachable, otherwise webroot will fail (limitation for webroot verification!)
./start.sh -i F_02_PKG_06_certbot_02_apply_webroot
-
New site - url (wildcard) : gen nginx site config + apply letsencrypt ssl only
./start.sh -i F_02_PKG_07_nginx_02_ssl_site_config ./start.sh -i F_02_PKG_06_certbot_02_apply_dns-cloudflare
- Generate nginx http log report in html.
Reference the official description GoAccess
cat xxx.access.log | goaccess > xxx.html
- View log analysis report.
logwatch
- View log analysis of postfix. (not installed by default, use logwatch instead)
/usr/sbin/pflogsumm -d yesterday /var/log/maillog
- Just like command "top", but more than that.
glances
- Just like command "top", but just for IO.
iotop
- Start from Ubuntu 24.04. This is a virtual package of pcp
- Just like command "top", but just for IO.
dstat
- 2022/12/04
- tag: v0.0.0
- Initial Ubuntu Security
- tag: v0.0.0
- 2023/01/30
- tag: v1.0.0
- changelog: https://github.com/charlietag/ubuntu_security/compare/v0.0.0...v1.0.0
- First release of ubuntu_security
- changelog: https://github.com/charlietag/ubuntu_security/compare/v0.0.0...v1.0.0
- tag: v1.0.1
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.0...v1.0.1
- Modified Readme ToC (Table of markdown content)
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.0...v1.0.1
- tag: v1.0.2
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.1...v1.0.2
- Fix crontab for postfix
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.1...v1.0.2
- tag: v1.0.3
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.2...v1.0.3
- Add atop
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.2...v1.0.3
- tag: v1.0.4
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.3...v1.0.4
- fix typo - disabling atop systemd services
- Add notes about
/etc/default/ufw
- Fix typo - README
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.3...v1.0.4
- tag: v1.0.0
- 2023/01/31
- tag: v1.0.5
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.4...v1.0.5
- disable certbot renew timer
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.4...v1.0.5
- tag: v1.0.5
- 2023/02/01
- tag: v1.0.6
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.5...v1.0.6
- Fix nginx waf module error
- Remove
atop
glances
nmon
htop
- Make sure
apache2
is stopped and disabledsystemctl mask apache2
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.5...v1.0.6
- tag: v1.0.6
- 2023/02/02
- tag: v1.0.7
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.6...v1.0.7
- Fix logical error while checking fail2ban config status
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.6...v1.0.7
- tag: v1.0.7
- 2023/02/14
- tag: v1.0.8
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.7...v1.0.8
- Add nginx default ssl server
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.7...v1.0.8
- tag: v1.0.9
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.8...v1.0.9
- Add nginx default ssl server with http2 supported
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.8...v1.0.9
- tag: v1.0.10
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.9...v1.0.10
- Nginx self signed ssl generation without prompt
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.9...v1.0.10
- tag: v1.0.8
- 2023/02/14
- tag: v1.0.11
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.10...v1.0.11
- Refine README doc
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.10...v1.0.11
- tag: v1.0.11
- 2024/05/12
- tag: v2.0.0
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.11...v2.0.0
- Change tag version to
v2.x.x
for Ubuntu 24.04
- Change tag version to
- changelog: https://github.com/charlietag/ubuntu_security/compare/v1.0.11...v2.0.0
- tag: v2.0.1
- changelog: https://github.com/charlietag/ubuntu_security/compare/v2.0.0...v2.0.1
- Ubuntu 24.04, dstat ---> pcp (pmlogger, pcproxy, etc.). So stop installing dstat by default
- changelog: https://github.com/charlietag/ubuntu_security/compare/v2.0.0...v2.0.1
- tag: v2.0.0
- 2024/05/19
- tag: v2.0.2
- changelog: https://github.com/charlietag/ubuntu_security/compare/v2.0.1...v2.0.2
- Ubuntu 24.04, fail2ban default is version 1.0.x , which is lack of python3 module asynchat, and this module is removed from python 3.12. Install
fail2ban 1.1 version instead
Fail2ban
:allowipv6 = no
- Ubuntu 24.04, fail2ban default is version 1.0.x , which is lack of python3 module asynchat, and this module is removed from python 3.12. Install
- changelog: https://github.com/charlietag/ubuntu_security/compare/v2.0.1...v2.0.2
- tag: v2.0.3
- changelog: https://github.com/charlietag/ubuntu_security/compare/v2.0.2...v2.0.3
f2b_nginx_check_banned.sh
: no more restart nginxcheck_fail2ban.sh
: no more warning
- changelog: https://github.com/charlietag/ubuntu_security/compare/v2.0.2...v2.0.3
- tag: v2.0.4
- changelog: https://github.com/charlietag/ubuntu_security/compare/v2.0.3...v2.0.4
f2b_nginx_check_banned.sh
: typocheck_fail2ban.sh
: typo
- changelog: https://github.com/charlietag/ubuntu_security/compare/v2.0.3...v2.0.4
- tag: v2.0.5
- changelog: https://github.com/charlietag/ubuntu_security/compare/v2.0.4...v2.0.5
- Check OS command: fix command location error
- changelog: https://github.com/charlietag/ubuntu_security/compare/v2.0.4...v2.0.5
- tag: v2.0.2