ModSecurity + SafeLine WAF for Multi-layer Defense (1)
Lulu
Posted on September 11, 2024
Start by explaining my strategy to differentiate between the two security solutions. I plan to configure two separate ports for testing the performance of each solution:
- Port 8080: Handled by Nginx and protected by ModSecurity.
- Port 80: Monitored by SafeLine WAF, which will act as the primary defense layer.
Additionally, there is an option to hide port 8080, funneling all traffic through port 80, where SafeLine WAF handles initial inspection and forwards traffic to ModSecurity for further validation. This setup aims to enhance security by combining the strengths of both tools.
One reason for choosing SafeLine is that the community version is free, and ModSecurity is open-source, making both options great for learning and research purposes.
Part 1: Why SafeLine WAF?
SafeLine is an open-source Web Application Firewall developed by Chaitin Technology, which protects against common web attacks like SQL Injection, XSS, and CSRF. One of its key advantages is its graphical interface, making it easier to manage, especially in combination with ModSecurity, which lacks this feature but offers strong detection.
Part 2: Environment Requirements
Before installing SafeLine, ensure that your system meets the following requirements:
- Operating System: Linux
- CPU Architecture: x86_64
- CPU Instruction Set: Supports SSSE3 instruction set
- Software Dependencies: Docker version 20.10.14 or later
- Software Dependencies: Docker Compose version 2.0.0 or later
- Minimum Resource Requirements: 1-core CPU / 1 GB RAM / 5 GB disk space
1. Check Local CPU Architecture
To check the CPU instruction set:
uname -m
To view CPU information:
cat /proc/cpuinfo | grep "processor"
To verify whether the CPU supports the SSSE3 instruction set:
lscpu | grep ssse3
2. Installing Docker
(Note: I am using CentOS 7 for this setup, so the following commands are specific to this system. Adjust them accordingly if you are using a different environment.)
2.1 Uninstall old versions of Docker (If not previously installed, you can skip this step):
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
If Docker was not previously installed, you'll get a "not found" message, which is normal.
2.2 Install yum-utils package:
yum install -y yum-utils
2.3 Set up the repository:
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
2.4 Install Docker:
yum install docker-ce docker-ce-cli containerd.io
2.5 Start Docker and verify the installation:
systemctl start docker
docker version
At this point, Docker is installed on CentOS.
3. Installing Docker Compose
3.1 Uninstall old versions of Docker Compose:
rm /usr/local/bin/docker-compose
Simply delete the old directory. If it was never installed, you can ignore this step. If unsure, running the command will show if the directory exists.
3.2 Download the file and move it to the bin directory:
curl -L https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-uname -s-uname -m > /usr/local/bin/docker-compose
If the download is slow, you can download it on Windows and use FTP to upload it to the bin directory.
3.3 Add execution permissions:
chmod +x /usr/local/bin/docker-compose
At this point, you should have installed the environment dependencies required for SafeLine WAF.
Part 3: SafeLine WAF Installation and Configuration
In this setup, the WAF is deployed on the local server, sharing the same machine as the backend server. However, it is not recommended to configure it this way in a production environment, as it increases the load on a single machine, making it prone to crashes and difficult to troubleshoot. In production, it is recommended to deploy SafeLine on a separate server.
1. Changing Nginx Port
First, I'll explain the current environment. I am using Nginx as middleware, with Nginx currently listening on port 80. However, I want SafeLine to protect port 80. To allow SafeLine to listen on port 80, I will change Nginx's listening port to 8080. This way, ModSecurity can protect port 8080, providing a platform to test which payloads SafeLine can block but ModSecurity cannot. This is the overall strategy.
To change Nginx's listening port:
1.1 Configure environment variables for easier execution later:
vim /etc/profile
# At the end of the file, add the following two lines:
export NGINX_HOME=/usr/local/nginx
export PATH=$PATH:$NGINX_HOME/sbin
# Save and exit, then apply the changes:
source /etc/profile
This ensures that the Nginx home directory and executable file directory are correctly configured.
1.2 Stop Nginx service:
nginx -s stop
netstat -ntlp # Check port status
You should see that port 80 is no longer being monitored.
1.3 Change Nginx's listening port to 8080 in the configuration file:
vim /usr/local/nginx/conf/nginx.conf
1.4 Restart Nginx service:
nginx -s reload
netstat -ntlp # Check the port status
After restarting, Nginx should now be listening on port 8080. If a firewall is in place, make sure to open port 8080 (error solutions are provided at the end of this article).
2. Automatically Install SafeLine WAF
To install SafeLine WAF, use the following command:
bash -c "$(curl -fsSLk https://waf.chaitin.com/release/latest/setup.sh)"
After installation, you will see how to access the SafeLine console, which uses port 9443 by default. To access the console, simply append :9443
to your server's IP address. Ensure that port 9443 is open (check both your firewall and any cloud firewall settings).
3. Initialize Account and Log In
Access the login page by navigating to port 9443. You will need to initialize the admin account:
docker exec safeline-mgt resetadmin
This will generate a username and password:
[SafeLine] Initial username: admin
[SafeLine] Initial password: **********
[SafeLine] Done
Use these credentials to log in to the SafeLine console.
4. Configure Protected Sites
In the protection site configuration, you can enter either your server’s IP address or domain name. I’ve set SafeLine to listen on port 80, with the upstream server (the origin) set to the IP address and port 8080 for Nginx. This forwards and responds to traffic accordingly.
After configuring, test your server's IP or domain via port 80. Wait a moment to see if traffic passes through SafeLine. If SafeLine is forwarding traffic, you will see request logs in SafeLine, and Nginx's access logs will show your server’s IP as the client, as SafeLine is doing SNAT (Source Network Address Translation).
5. Protection Testing
You can perform manual tests or use SafeLine's official testing tools to assess the protection. Below are some simulated attacks, substituting your own website address for https://chaitin.com/
:
- Simulate SQL injection:
https://chaitin.com/?id=1+and+1=2+union+select+1
- Simulate XSS attack:
https://chaitin.com/?id=<img+src=x+οnerrοr=alert()>
- Simulate path traversal:
https://chaitin.com/?id=../../../../etc/passwd
- Simulate code injection:
https://chaitin.com/?id=phpinfo();system('id')
- Simulate XXE attack:
https://chaitin.com/?id=<?xml version="1.0"?><!DOCTYPE foo SYSTEM "">
SafeLine should block these attacks, as shown below.
6. Interception Results
Results can be tested using SafeLine’s open-source WAF testing tool, available at https://github.com/chaitin/blazehttp. I compared the results using ModSecurity-L4 at the origin, with SafeLine as secondary protection for port 80. ModSecurity has a high detection rate, but SafeLine free edition has a lower detection rate, though its false-positive rate is much lower. Using both together allows for a comprehensive security setup. You can test the results yourself.
The article is a bit long, so I've posted it in two parts, the other half is here:ModSecurity + SafeLine WAF for Multi-layer Defense (2)
Posted on September 11, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.