Update request for `/etc/letsencrypt/options-ssl-nginx.conf`?

So I've found this really cool tool, https://testssl.sh/ (which is also secured by LetsEncrypt, neat). It gives a really great, long, and somewhat overwhelming output about the SSL securing a site. I noticed in the report for my website, https://codedragon.dev, that the server has no preference for server cipher order - which was highlighted by red text; so I assume that that means it is not a good thing. Anyway, upon going to look around, I noticed that the issue was in /etc/letsencrypt/options-ssl-nginx.conf on line 12: ssl_prefer_server_ciphers off;. Is there a reason for this, is it smart to override it, and how can I override it without changing line 12 of that file?

P.S something else was also highlighted in red. Apparently my server has no security headers in the HTTP response, but I am not asking for help with that (though help is not unwelcome). Just letting you know that I am aware of that if anyone runs this tool against my domain and notices it as well.

I am using certbot v1.19.0 as my ACME client. /etc/letsencrypt/options-ssl-nginx.conf is a file, not a directory; but it contains the following:

# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file.

ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;


For clarity and reference, please show:
[you can just edit your post to include this]

  • The ACME client and version used.
  • ls -l /etc/letsencrypt/options-ssl-nginx.conf

On the HTTP security headers...
Start your security journey at: Analyse your HTTP response headers (securityheaders.com)

Hi @CodeDragon5793,

Certbot takes its defaults for this file from the Mozilla configuration generator at


because, while we tried to research this ourselves, we ended up feeling that Mozilla was on top of the matter and had people keeping the recommendations up to date. The rationale for their defaults, although brief, is at


In this case they do provide an item about why ssl_prefer_server_ciphers defaults to off:

  • The cipher suites are all strong and so we allow the client to choose, as they will know best if they have support for hardware-accelerated AES

That is, some clients have AES hardware acceleration like AES-NI

in their CPUs, while others don't. I guess the Mozilla team believes that platforms that don't might prefer ChaCha20/Poly1305, because it is faster to implement in pure software compared to AES.

Certbot allows you to change this configuration file yourself, if you have a preference that is different from the defaults. If you do that, Certbot won't update it for you in the future if Mozilla provides new recommended defaults that get incorporated into a future Certbot release.

It might be better to see if you could persuade the scanner developer that the Mozilla defaults are actually fine, or else persuade Mozilla that they're not, as the discrepancy in assessing the security of this default seems to be intentional on both sides rather than an artifact of obsolete software or an obsolete configuration or something.


I figured it'd be something like that tbh. That's why I wanted to ask before I went around changing stuff. And yeah, I noticed that they were very strong ciphers, and felt that the test script was being pedantic xD.

1 Like

Cool! I strongly encourage people to ask these questions, because that's what keeps us from getting stuck with obsolete defaults.

Like, imagine if someone in 2010 or 2011 had asked "hey, why are we still defaulting to fixed 1024-bit Diffie-Hellman in TLS? didn't people say a few years ago that there's a huge precomputation available that would then make individual exchanges cheap to attack?".


1 Like

It also says that OCSP stapling is not enabled for my site, but it is as verified by both Qualys SSL Labs and OpenSSL via the command openssl s_client -connect codedragon.dev:443 -status | grep OCSP.

Though hey, giving the Certbot Nginx Plugin the ability to add OCSP Stapling by default would be nice. The infrastructure is there, so I do not know why it doesn't automatically add these directives.

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;

I think the OCSP stapling issue is probably about site reliability—the Apache version, at least, would cause site outages if Apache was restarted and had a transitory inability to get a fresh OCSP status from the CA. I thought I heard that the nginx version had something of the same issue, but I'm not positive.

There was another thread on the forum about wishing for other servers to get a more reliable OCSP stapling implementation, like Caddy's. :slight_smile:

1 Like

Okay, so this is slightly off-topic, but I have a subdomain with a highly lax CORS policy. It doesn't do much as it's just a resource I put together for a font that I really liked. (At the time it wasn't on Google Fonts, and I don't care to use that service anyway). I was planning on using it across subdomains and didn't want to copy the CSS and the fonts all the time. I've put it at https://fonts.codedragon.dev, and I thought I could add to it as I found more and more cool fonts. Well apparently the extremely lax CORS policy is messing up the security headers (but only on that subdomain). Why is it causing the security headers to be ignored by the client (as those security headers are placed in the main /etc/nginx config file), and is relaxed CORS actually hurting a site with nothing but a CSS file pointing to the location of some fonts?

Sounds like time for some research...

[deja vu]

Have you been there?
Has it led you down any rabbit holes (yet)?

Yes. The headers work on all subdomains except for that one.

Takes a stab in the dark!
[I can say that because it is 3am and very dark outside now]

Have you tried accessing?:

[not as a replacement - just as an alternate means of access and for testing]

What's with this?:
[formatting on this line looks off]

securityheaders.com told me how to fix some headers; but for others, I didn't know what to set them to, so I googled it and found this guide: How to configure Security Headers in Nginx and Apache

Making progress...

Yeah, I think there was a bit of miscommunication here. There wasn't really a problem with my headers working on my root domain. And for the most part, they all work on my other subdomains. However, I am experiencing a weird issue with redirects when Nginx is being used as a reverse proxy for a particular subdomain. I am not sure what is causing it to do this though. For example, Nginx is set to proxy_pass http://localhost:3000; for https://git.codedragon.dev. If that domain refreshes for whatever reason, then it will try to redirect to localhost:3000/full/uri

# The Full server block for the above follows:
server {
    listen  443 ssl http2;
    listen  [::]:443 ssl http2;
    server_name git.codedragon.dev;

    location / {
        proxy_pass                              http://localhost:3000;
        proxy_redirect                          off;
        proxy_set_header Host                   $http_host;
        proxy_set_header X-REAL-IP              $remote_addr;
        proxy_set_header X-Forwarded-For        $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto      $scheme;
        proxy_set_header X-Forwarded-Protocol   $scheme;
        proxy_set_header X-Url_Scheme           $scheme;

    include /etc/nginx/ssl-options.conf.d/codedragon.dev.conf;


# HTTP PORT 80 Configuration

server {
    if ($host = git.codedragon.dev) {
        return 301 https://$host$request_uri;

    server_name git.codedragon.dev;
    listen 80;
    listen [::]:80;
    return 404;

P.S. I also need to find a new value for the Content-Security-Policy because what I had before is causing an issue with another subdomain.

I've also set the security headers in the main Nginx Configuration file, /etc/nginx.conf:

    add_header  Strict-Transport-Security   "max-age=31536000; includeSubDomains; preload" always;
    #add_header  Content-Security-Policy     "default-src 'self'; font-src *;img-src * data:; script-src *; style-src *";
    add_header  X-XSS-Protection            "1; mode=block";
    add_header  X-Frame-Options             "SAMEORIGIN";
    add_header  X-Content-Type-Options      "nosniff";
    add_header  Referrer-Policy             "strict-origin";
    add_header  Permissions-Policy          "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()";

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.