Building a Simple HTTP Source for Firewall EDL

Recently, I wanted to add a list of domains to the Palo Alto DNS policy to block them from resolving. However, I soon realized that I couldn't just add a list of domains directly to the firewall, I needed to use an External Dynamic List (EDL). Palo Alto and I believe other firewalls as well, require a simple HTTP URL that hosts a list of domains or IP addresses. While there are amazing EDL projects available, in this blog post, we'll explore the simplest way to deploy an EDL.

Python HTTP Server

Python's HTTP server module lets you create a basic web server using just a single command. This server can serve files from a directory over the network, making it an excellent tool for quick testing and file sharing without the complexity of setting up a full-fledged web server.

All you need to do is create a list of domains, save it as a text file, and run python -m http.server 8085 from the directory where the file is saved. You can use any port, but remember that a lower number of ports like 80 require admin privileges. Once the server is running, navigate to http://IP_ADDRESS:8085/domains.txt in your browser.

python -m http.server 8085

You will see your list of domains. Simply pass this URL to your firewall as the EDL source.

💡
Please note that the Python HTTP server will stop if you close the terminal or disconnect your SSH session. This can be a bit annoying at times. I'm pretty sure, you can use some Linux hacks to work around this.

However, keep in mind that as long as the firewall (at least Palo Alto) fetches the list once, it can continue to use the current copy of the EDL list even if the server goes down and the firewall fails to fetch a new copy. In my example, I set the EDL to refresh daily at 20:00 To test this, I stopped the webserver just before 20:00. Despite this, the firewall still uses the old copy, so there are no concerns.

Python HTTP Server Inside Docker

We can also run the HTTP server inside a Docker container to make it more robust and easier to manage.

First, create a Dockerfile and the my_domains.txt files in the same directory.

.
├── Dockerfile
└── my_domains.txt

1 directory, 2 files
samsung.com
cnet.com
FROM python:3.10-slim
WORKDIR /app
EXPOSE 80
CMD ["python", "-m", "http.server", "80"]

The Dockerfile starts with a base image from Python 3.10-slim, sets the working directory to /app, and exposes port 80. The command to start the server uses Python’s built-in HTTP server module to serve files on port 80.

To build this Docker image, use the docker build command from the same directory where the Dockerfile is located.

docker build -t simple_edl .

Once the image is ready, you can start the server by running the docker run command.

docker run -d -p 8085:80 -v $(pwd)/my_domains.txt:/app/my_domains.txt simple_edl

This command runs the Docker container in detached mode, maps port 8085 on your host to port 80 in the container, and mounts your my_domains.txt file to the container’s /app directory. This setup ensures your EDL is always available, even if you close your SSH session or the terminal.

If you need to update the domain list, simply navigate to the directory where the text file is located, edit the file, and then refresh the page. You don't have to re-run the Docker container.

💡
If you require a solid EDL that is crucial for your environment, then I recommend looking for a more robust solution. This method is best suited for those seeking a simple solution.