DEV Community

Lulu
Lulu

Posted on

Building a Secure WordPress Site with Docker, Nginx, and SafeLine WAF

I recently purchased a new cloud server and set out to create a WordPress website using a decoupled architecture. The goal was to implement a split between the web and database servers, utilize Docker for containerization, and set up Nginx as a reverse proxy. Additionally, I wanted to enhance security by deploying SafeLine WAF locally to filter and monitor incoming traffic.

Architecture Overview

Image description

The architecture is built on Docker, providing the virtual environment for the web service. I used Portainer as a graphical management interface for Docker containers. Nginx, installed directly on the server, acts as a reverse proxy. The server listens on port 81, with SafeLine WAF binding to the domain on port 80. SafeLine filters the incoming traffic and forwards it back to port 81, then routes it to port 8080, eventually reaching the WordPress container.

Technical Details

  • SSH to Ubuntu Server

    The default username for Ubuntu is ubuntu, and the root account is not configured with a password by default during installation.

  • Docker Mapping and Communication

    Docker mappings can be defined using the -v parameter to specify mount points. For instance, if you have a hard drive /data, you can mount it to the /var/www/html directory inside the WordPress container as follows:

  docker run -v /data:/var/www/html <your_wordpress_image>
Enter fullscreen mode Exit fullscreen mode
  • Configuring MySQL Container After starting the MySQL container, external access needs to be configured. Here's how you can set it up:
  docker exec -it mysql5.7 bash
  mysql -u root -p
  GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
  FLUSH PRIVILEGES;
Enter fullscreen mode Exit fullscreen mode

However, configuring MySQL this way might be insecure. It’s better to set up a more secure password and user for MySQL.

  • Linking Docker to the Local Database Host To connect to a local database host, use host.docker.internal. For MySQL downloaded via Docker, connect using the database's IP address, which you can find with:
  docker inspect <mysql-container-name> | grep IPAddress
Enter fullscreen mode Exit fullscreen mode
  • Nginx Reverse Proxy Configuration I encountered two issues while configuring Nginx as a reverse proxy:
  1. Redirection Loop:

    If you simply add proxy_pass http://<host_ip>:8080; in the location block, it might cause a redirection loop, making the website inaccessible. The solution is to add the following configuration:

     proxy_set_header Host $host;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
  2. Bypassing the WAF:

    If users click on a button or link that redirects them to another port, it may bypass the WAF. To prevent this, I temporarily resolved the issue with the following configuration:

Image description

Conclusion

By carefully configuring Docker, Nginx, and SafeLine WAF, I was able to create a secure and efficient WordPress site. The steps shared in this guide can help others implement a similar setup, ensuring that web traffic is properly filtered and monitored while maintaining performance.

Top comments (0)