Showing only posts tagged nginx. Show all posts.

Enabling Post-Quantum Key Agreements with Nginx

Both Google Chrome¹ and CloudFlare² have announced that they are going to spend effort migrating to quantum-resistant cryptography. As one of the first steps both have implemented Kyber768 + X25519 KEM support.

Thankfully these improvements are not only available to Google and CloudFlare customers. Basically everyone can enable X25519Kyber768(Draft00) support in their web server. If they are using relatively modern OpenSSL 3.x. People at OpenQuantumSafe have written a provider for OpenSSL 3.x that provides amongst many others, Kyber and its hybrid KEM schemes. You can find the provider from here: https://github.com/open-quantum-safe/oqs-provider

Building OQS provider

All you have to do is clone the repository, build and install it.

For example:

git clone https://github.com/open-quantum-safe/oqs-provider
          cd oqs-provider
          mkdir build && cd build
          cmake -S ..
          cmake --build .
          sudo cmake --install .

Enabling OQS provider

Open your OpenSSL configuration (on Ubuntu it's located at /etc/ssl/openssl.cnf).

Just enable the provider by-default, this avoids the need to force software to specifically enable the OQS provider.

# List of providers to load
          [provider_sect]
          default = default_sect
          oqsprovider = oqsprovider_sect
          ...

          [default_sect]
          activate = 1

          [oqsprovider_sect]
          activate = 1

You can check the results using openssl list -kem-algorithms, it should list at least x25519_kyber768 @ oqsprovider.

Allowing Kyber hybrid KEMs

Next step is to enable the KEM in nginx's TLS configuration. No other changes need to be made if your distribution and nginx uses OpenSSL 3.

Locate the line that says ssl_ecdh_curve auto; and replace it with:

ssl_ecdh_curve x25519_kyber768:p384_kyber768:x25519:secp384r1:x448:secp256r1:secp521r1;

The first preference now being X25519Kyber768, then P384Kyber768 for Edge, X25519 for regular clients and the usual for compatibility after that.

After this change, just restart nginx (sudo systemctl restart nginx).

Checking if your browser has PQ KEM support

X25519Kyber768 has been available in Chrome since Chrome 115 (dev trial) and behind a flag after 118 (chrome://flags#enable-tls13-kyber). It's also behind a flag in Edge (edge://flags#edge-post-quantum-kyber). Chrome has also started a gradual rollout and they're at 10% (as of 30.11.2023).

You can test if your browser has Kyber enabled by visiting CloudFlare's test page. You should see kex=X25519Kyber768Draft00.

Besides this site I'm not aware of any that would allow one to test both QUIC and PQ KEMs simultaneously.

Firefox does not yet support X25519Kyber768Draft00, there has been some effort.

Result

If you visit your website with an enabled browser you should be seeing Kyber786 being used.

A secure QUIC connection using X25519Kyber768Draft00 as the key exchange, ECDSA with SHA-384 as the server signature and AES_256_GCM as the cipher. (QUIC + X25519Kyber768Draft00)

Edge will display something like this:

A secure HTTP/TLSv1.3 connection using P384Kyber768 (P384KYBER) as the key exchange, ECDSA with SHA-384 as the server signature and AES_256_GCM as the cipher.

CloudFlare PQ origin pulls

If you use CloudFlare as a reverse proxy, then you can also enable X25519Kyber768 on the first attempt (to save a round trip) using their API:

curl --request PUT \
          --url https://api.cloudflare.com/client/v4/zones/[ ZONE_ID ]/id/cache/origin_post_quantum_encryption \
          --header 'Content-Type: application/json' \
          --header 'Authorization: Bearer [ API_TOKEN ]' \
          --data '{"value": "preferred"}'

External references

Installing modsecurity as a static nginx module

This is a super minimal guide how to recompile nginx on Ubuntu 16.04/14.04 for ModSecurity.

External references

Instructions

I started with downloading nginx's sources and extracting them: .. code-block:: bash

wget https://nginx.org/download/nginx-1.13.12.tar.gz tar -xf nginx-1.13.12.tar.gz

Then I took the compilation flags of my current nginx build with nginx -V, modified to include modsecurity and to excude useless modules (you can always find the sources of the modules online and pray they work with newer nginx, remove --add-module=./modules/ngx_brotli if you want nginx without brotli):

./configure --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --sbin-path=/usr/sbin/nginx --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_flv_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_mp4_module --with-http_perl_module --with-http_random_index_module --with-http_secure_link_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module --with-stream --with-stream_ssl_module --with-threads --add-module=./modules/headers-more-nginx-module --add-module=./modules/ModSecurity-nginx --add-module=./modules/ngx_brotli --with-compat

Building it is easy after that: .. code-block:: bash

make -j3 make install

Then I only had to restart nginx: .. code-block:: bash

sudo systemctl restart nginx

Configuration is left as an excercise for the reader :)

Usability

I tested it out for a while, it has a few bugs and the documentation is really lacking in terms of how to write brand-new rules for it. It's also super annoying to detect false-positives and I found the rule syntax vomit-worthy. I decided to drop using modsecurity, it just wasn't worth it, especially not just for fun™.

This also seems to hold true in 2023 as it did back in 2018.

Posted by TaaviE on in Linux. updated Tags: nginx.