Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nginx: Enable HSTS when forceSSL is on #26681

Closed
wants to merge 1 commit into from

Conversation

kirelagin
Copy link
Member

No description provided.

@mention-bot
Copy link

@kirelagin, thanks for your PR! By analyzing the history of the files in this pull request, we identified @globin, @domenkozar and @fadenb to be potential reviewers.

@@ -170,6 +170,9 @@ let
ssl_certificate ${vhost.sslCertificate};
ssl_certificate_key ${vhost.sslCertificateKey};
''}
${optionalString vhost.forceSSL ''
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be definitely mentioned in both documention for forceSSL and nixos release changelog. There might be also the use case for people wanting a redirect, but no HSTS (yet), when testing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree that some people might want that. At the same time my point is that, if not for testing, compulsory redirect without HSTS is useless in terms of security.

How would you suggest to implement that? Have a completely separate config option? Have a separate config option, enabled by default by forceSSL and mentioned in its documentation? Other ideas?

Copy link
Member

@fpletz fpletz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is very dangerous. We thought about adding HSTS when we implemented forceSSL but did not because it could break websites and should therefore be a conscious user choice. Including includeSubDomains by default would also probably break other sites unexpectedly.

The only option I think is feasible to create a separate option to enable HSTS and maybe make max-age and includeSubDomains configurable.

@kirelagin
Copy link
Member Author

The only option I think is feasible to create a separate option to enable HSTS and maybe make max-age and includeSubDomains configurable.

Ok, in this case I’ll add a separate option and mention it in the documentation for forceSSL.

@domenkozar
Copy link
Member

It's very easy to lock users out of the website, I would never enable HSTS by default, but we can make it optional.

@kirelagin
Copy link
Member Author

It's very easy to lock users out of the website

Well, personally I do not think that HSTS is that scary, it does not pin a certificate and obtaining a valid certificate nowadays is incredibly easy.

Anyway, I’m thinking about something like:

virtualHosts."example.com" = {
  sslStrict = {
    enable = false;
    maxAge = 31536000;
    includeSubDomains = true;
  };
};

I am also inclined towards always sending the header, but setting max-age=0 if enable is false. That way changing enable to false will actually disable HSTS, not just stop sending the header.

@kirelagin
Copy link
Member Author

Might it be a good idea to rename forceSSL to sslRedirect or something, to make it less confusing?

@kirelagin
Copy link
Member Author

In case someone wonders, I still hope to get to this some time soon.

@Ekleog
Copy link
Member

Ekleog commented Sep 9, 2018

(triage) @kirelagin, do you still plan to get back to this? :)

(also, the PR title may need an update now that the objective has changed, something like “nginx: add an option to enable HSTS” maybe?)

@JohnAZoidberg
Copy link
Member

Anyway, I’m thinking about something like:

virtualHosts."example.com" = {
  sslStrict = {
    enable = false;
    maxAge = 31536000;
    includeSubDomains = true;
  };
};

Yeah, that looks good!
We probably shouldn't, like the others mentioned, turn it on by default. But I think we can make the case that recommendedTlsSettings turns it on.
Oh and includeSubDomains should be false by default.
We should also probably set the default maxAge to a low number (like an hour) and also recommend in the docs to set it higher. (Which recommendedTlsSettings could do)

I am also inclined towards always sending the header, but setting max-age=0 if enable is false. That way changing enable to false will actually disable HSTS, not just stop sending the header.

Hmm, no I think people wouldn't expect that. You don't want to mess with the entire domain if not explicitly opted in.

@solson
Copy link
Member

solson commented Jul 4, 2019

Given the complications around disabling HSTS, I wouldn't like to see it enabled implicitly (like by recommendedTlsSettings), but I would love to have an option just like the suggested sslStrict for doing it manually, but easily.

(Incidentally, are there any functions in nixpkgs for dealing with units of time? It would be cool to have maxAge = lib.daysToSeconds 365 (or something more structured) instead of 31536000.)

Is anyone else working on this? If not, I will make a PR for sslStrict when I find the time.

About sending max-age=0 by default

I am also in favor of not sending the header at all if enable = false (i.e. by default). I'm not an expert on this, but I believe in some imperfect configurations, some pages on a domain might provide max-age=31536000 while other pages (perhaps served by a different server) serve no HSTS header at all - the browser will still force those non-HSTS pages to load as HTTPS as long as it has seen any HSTS page on the domain previously within the max-age window. But if those non-HSTS pages were to send max-age=0 by default, without the sysadmin's knowledge, HSTS would effectively be getting turned on and off depending on which pages are visited.

tl;dr: We should only send max-age=0 when the sysadmin specifically chooses to do so, because I think it's a non-trivial decision and we can't be certain the default won't cause problems.

@stale
Copy link

stale bot commented Jun 1, 2020

Thank you for your contributions.
This has been automatically marked as stale because it has had no activity for 180 days.
If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity.
Here are suggestions that might help resolve this more quickly:

  1. Search for maintainers and people that previously touched the
    related code and @ mention them in a comment.
  2. Ask on the NixOS Discourse. 3. Ask on the #nixos channel on
    irc.freenode.net.

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jun 1, 2020
@Mic92
Copy link
Member

Mic92 commented Jun 2, 2020

I would prefer this to be a seperate option rather than beeing included by default.

@Mic92 Mic92 closed this Jun 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md 6.topic: nixos
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants