Nginx config testing with Gixy

Learn how you can use a simple setup to test your nginx config with Gixy (getpagespeed/gixy)

TL;DR

  1. Put your nginx config (mostly contents of /etc/nginx) under version control (private repository)
  2. Use the official Gixy docker image to test your configuration with Gixy
  3. Use docker to verify your nginx config is working with nginx -t. You will need to craft a Dockerfile that can be different depending on your needs
  4. Optional: Simplify your local workflow with a justfile and handy recipes like test-nginx-gixy or test-nginx-t

What is Gixy? And what does it test?

You can think of Gixy as a static nginx config analyzer. As stated on the official website, Gixy reviews nginx configuration for security risks, misconfigurations, and missed hardening opportunities.

For all issues, Gixy can detect, getpagespeed.com also offers a comprehensive documentation. When I started using Gixy, it for example found, that I had a weak SSL/TLS configuration. After running Gixy in the terminal, you get a report printed to the CLI. Each issue also has a link to the documentation. For my example, that would be: https://gixy.getpagespeed.com/checks/weak-ssl-tls/. Apart from an explanation what was detected, you will mostly also find examples on good and bad configurations.

Project setup

I chose a “keep it simple” approach and versioned my /etc/nginx directory content. I then can easily pass all the nginx config files to the Gixy docker container via a volume mount.

Tip

Depending on your server setup, you might need to add some more mounts.

If files are missing, because they are included in your nginx config but not located at /etc/nginx, Gixy will point that out to you in the report as well. It is important that you add those files, because they might have config that is important but would be missing in the Gixy analysis (although applied in production).

Understand Gixy CLI output

After you execute docker run --rm -v /path/to/your/etc/nginx:/etc/nginx:ro getpagespeed/gixy /etc/nginx/nginx.conf, Gixy will print a report to your CLI.

What you see first is the summary at the end:

==================== Summary ===================
Total issues:
    Unspecified: 0
    Low: 1
    Medium: 5
    High: 3

Issues look like this:

------------------------------------------------

>> Problem: [weak_ssl_tls] Server cipher preference enabled unnecessarily
Severity: LOW
Description: Using outdated TLS protocols (TLSv1.0, TLSv1.1) or weak cipher suites exposes your server to attacks such as POODLE, BEAST, and SWEET32. Modern configurations should use TLSv1.2+ with strong AEAD ciphers.
Additional info: https://gixy.getpagespeed.com/checks/weak-ssl-tls/
Reason: ssl_prefer_server_ciphers is on, forcing server cipher order. With modern cipher lists (all strong AEAD ciphers), client cipher preference improves performance — mobile clients without AES-NI benefit from choosing ChaCha20-Poly1305 over AES-GCM. Mozilla and nginx maintainers recommend off.
Pseudo config:
ssl_prefer_server_ciphers on;

I think the most valuable information is the “Additional info” and the “Pseudo config” section. While the first one aids you with a link to the Gixy documentation where you will find details about the reason for the issue pointed out as well as examples on how to fix it, the “Pseudo config” section helps you pinpoint the location of the issue and apply the fix.

Dockerfile for testing nginx config with nginx -t

Gixy is a static analyzer. It cannot tell you, if your nginx config is valid and thus a restart of nginx after applying configuration changes is safe. Nginx has a built in command to check the config for such issues, nginx -t. To be able to run it locally, when testing your config, you need to create a custom Dockerfile and add SSL certificates. In order to be close to production, you can check your nginx version on your server and use the official nginx docker image with the according version.

Warning

This exemplary Dockerfile might aid you in your setup, but you can most likely not just copy/paste it. Depending on your nginx version, used ciphers and SSL certificate provider, it might differ.

FROM nginx:your.production.version

# required if you use DHE ciphers
RUN mkdir -p /etc/letsencrypt && openssl dhparam -out /etc/letsencrypt/ssl-dhparams.pem 2048

# generate certificates and place them at the right location; specific for letsencrypt
RUN for d in your-domain-config-under-test.com; do \
    mkdir -p /etc/letsencrypt/live/$d; \
    openssl req -new -newkey rsa:2048 -days 7 -nodes -x509 \
    -subj "/CN=$d" \
    -keyout /etc/letsencrypt/live/$d/privkey.pem -out /etc/letsencrypt/live/$d/fullchain.pem; \
    done

Justfile for convenience

[private]
@default:
    just --list

# build custom nginx image
build:
    docker build . -t nginx-test

# validate nginx config with nginx -t
test-nginx-t: build
    docker run --rm -v {{justfile_directory()}}:/etc/nginx:ro -v {{justfile_directory()}}/options-ssl-nginx.conf:/etc/letsencrypt/options-ssl-nginx.conf:ro nginx-test nginx -t

# test nginx config with Gixy
test-nginx-gixy:
    docker run --rm -v {{justfile_directory()}}:/etc/nginx:ro -v {{justfile_directory()}}/options-ssl-nginx.conf:/etc/letsencrypt/options-ssl-nginx.conf:ro getpagespeed/gixy /etc/nginx/nginx.conf

# preview potential Gixy auto-fixes
fix-nginx-dry-run:
    docker run --rm -v {{justfile_directory()}}:/etc/nginx:ro getpagespeed/gixy --fix-dry-run /etc/nginx/nginx.conf

# apply Gixy autofixes
fix-nginx:
    docker run --rm -v {{justfile_directory()}}:/etc/nginx:ro getpagespeed/gixy --fix /etc/nginx/nginx.conf
Built with Hugo
Theme Stack designed by Jimmy