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

nixos/httpd: add locations option to virtualHosts #76583

Merged
merged 1 commit into from Jan 30, 2020

Conversation

aanderse
Copy link
Member

@aanderse aanderse commented Dec 27, 2019

Motivation for this change
Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.
Notify maintainers

cc @

@aanderse
Copy link
Member Author

@zimbatm how familiar are you with nginx configuration on NixOS? I'm adding a locations option to the httpd service, which is pretty much a copy+paste of the nginx code. Due to the differences in httpd and nginx configuration I figure a locations option won't be sufficient, and a directories option will be required too.

Thanks to your explanation of unsafeDiscardStringContext I'm now trying to decide if a directories option is "worth it" or not. I think overall it is, though maybe with some documented caveats.

A simple example of using directories safely with no problem:

services.httpd = {
  enable = true;
  virtualHosts.localhost = {
    directories."/var/www" = {
      alias = "/";
      index = "index.html";
      extraConfig = "Require all granted";
    };
  };
};

An example which might not be so safe:

services.httpd = {
  enable = true;
  virtualHosts.localhost = {
    directories."${builtins.unsafeDiscardStringContext pkgs.someWebApp}" = {
      alias = "/";
      index = "index.html";
      extraConfig = "Require all granted";
    };
  };
};

Usually web app modules will reference pkg.someWebApp elsewhere in the module, so practically speaking this probably isn't an issue.

I appreciate any and all feedback @zimbatm. Thanks!

@zimbatm
Copy link
Member

zimbatm commented Dec 28, 2019

Avoid using unsafeDiscardStringContext unless you can prove that it will work as intended. For example in your second example, because the only reference to pkgs.someWebApp is without context, nixos-rebuild switch won't build pkgs.someWebApp and the httpd config will be left with a dangling reference in there. So it's quite risky.

Probably the best approach is to copy the nginx model and have a set of HTTP aliases that map back to roots. Collect all the roots into a list and then generate the read-only directory entries.

@aanderse
Copy link
Member Author

aanderse commented Dec 28, 2019

I'm not familiar with nginx so I'll have to do some research. Thank you for your advice!

@aanderse
Copy link
Member Author

@zimbatm I've looked through nginx documentation and understand what it is doing more specifically now. The approaches taken by the two web servers are fundamentally different it appears. With httpd you should never manage permissions with Location directives, only Directory directives. Not all Directory directives have one-to-one virtual mappings, so this doesn't quite line up with only a locations option.

A quick example of where generating both Directory and Location directives from a single virtualHosts.<name>.locations option would fall short:

DocumentRoot /var/www
<Directory /var/www>
  Require valid-user
</Directory>

With httpd you want to be able to specify real file level paths without having to specify a virtual mapping and this is why I continue to think that a directories option is appropriate. I guess the question becomes: is there a better way to implement a directories option than I have, that doesn't depend on unsafeDiscardStringContext 🤔

As always, feedback is greatly appreciated. Thanks!

@zimbatm
Copy link
Member

zimbatm commented Dec 28, 2019

Fundamentally we are trying to map the httpd config format to JSON-like data structures. I don't remember the syntax well enough but I think it's not completely straight-forward. Which is why the current state of the art is to write the config by hand.

Try and take a look at the syntax and thing how it could be represented in pure nix data.

Alternatively the directories could also be transformed into lists to bypass that specific problem:

services.httpd = {
  // A list of directory configs
  virtualHosts.localhost.directories = [
    {
      path = pkgs.someWebApp;
      alias = "/";
      index = "index.html";
      extraConfig = "Require all granted";
    };
  ];
};

@aanderse
Copy link
Member Author

@zimbatm part of the problem I'm trying to solve is making directories and locations able to merge. The httpd already has a list of directories. Once you declare a directory in a list it can't be accessed and modified, or merged with something else.

@zimbatm
Copy link
Member

zimbatm commented Dec 28, 2019

What should happen if two different modules set values for the same location? Should they merge, fail or the last one wins? Potentially this could be handled by a filter operation after the fact.

@aanderse
Copy link
Member Author

I would expect some merging and mkForce semantics. extraConfig is lines so merge by default. index, etc... are nullOr so I imagine in many cases nothing required as its mostly extraConfig you want to modify.

extraConfig = "Require all granted" -> extraConfig = "Require valid-user, for example.

@aanderse aanderse changed the title nixos/httpd: add locations and directories options to virtualHosts nixos/httpd: add locations option to virtualHosts Jan 24, 2020
@aanderse aanderse marked this pull request as ready for review January 24, 2020 02:45
@aanderse
Copy link
Member Author

@zimbatm I'm not satisfied I have the best answer for directories yet, so leaving that out for now and just going ahead with locations.

Look good?

@aanderse aanderse requested a review from ivan January 28, 2020 16:27
@aanderse
Copy link
Member Author

@GrahamcOfBorg test upnp

@aanderse
Copy link
Member Author

🤷‍♂️

@aanderse aanderse merged commit 596e0fc into NixOS:master Jan 30, 2020
@aanderse aanderse deleted the httpd-locations branch January 30, 2020 02:01
anna328p pushed a commit to anna328p/nixpkgs that referenced this pull request Feb 2, 2020
nixos/httpd: add locations option to virtualHosts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants