NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
18.05k stars 14.1k forks source link

NixOS is compatible with federated networks, but it's profiles are not optimized for load-balancing which increases the complexity of federated integration #139772

Open Kreyren opened 3 years ago

Kreyren commented 3 years ago

TL;DR: Set nixpkgs's profiles default values to provide services on e.g. nextcloud.hostname.systems.domain.tld with redirect from nextcloud.domain.tld through alt-svc HTTP header to enable easier integration of load-balancing and federated/decentralized networks while keeping compatibility with non-loadbalanced networks.

The solution should be discussed as it's integration is complicated.


Federated networks are clusters of computers that collectively work on one task which name resolution is usually defined as service.hostname.systems.domain.tld that is then redirected on service.domain.tld through e.g. alt-svc HTTP header which makes the browser display e.g. https://fsfe.org while you are using https://hostname.fsfe.org.

Think of it as load-balancing (explained on https://www.youtube.com/watch?t=86&v=gMIslJN44P0) which members provide services that pose as online clients that interact with a database that is federated (data of the database is spread across multiple systems).

Currently i have to make lot of custom profiles with expressions alike:

services.nextcloud.hostName = "nextcloud" + "." + config.networking.fqdn;

because NixOS's profiles are not optimized for this runtime which increases the complexity of the integration.

Proposal

Proposing to optimize NixOS for these networks using e.g.

# modules/services/web-apps/nextcloud.nix
options.services.nextcloud = {
  enable = mkEnableOption "nextcloud";
  hostName = mkOption {
    type = types.str;
    default = if config.networking.fqdn then
            "nextcloud" + "." + config.networking.fqdn
        else if config.networking.domain then
            "nextcloud" + "." + config.networking.domain
        else
            throw "Neither of `config.networking.fqdn` or `config.networking.domain` is set. Unable to set name resolution on which to provide nextcloud instance";
    description = "FQDN for the nextcloud instance.";
  };

With the default redirect handling as:

Redirect method

webserver (e.g. NGINX) defining defaults with that are compatible with non-federated while making is painless to integrate on federated:

services.nginx = {
  virtualHosts = {
    "nextcloud.${config.networking.domain}" = {
      extraConfig = ''
        return 301 https://nextcloud.${config.networking.fqdn};
      '';
  };
};

Which redirects user from service.domain.tld on service.hostname.domain.tld and service.hostname.systems.domain.tld.

This changes the URL in the browser which might be unwanted

Alternative Service HTTP header (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Alt-Svc)

webserver (e.g. NGINX) defining defaults with:

services.nginx = {
  virtualHosts = {
    "nextcloud.${config.networking.domain}" = {
      extraConfig = ''
        add_header alt-svc 'h2="alt.domain.tld:443", h2=":443"';
      '';
  };
};

Real life example:

# Alternative service redirect for Torbrowser users on facebook
[kreyren@leonid:~]$ torsocks curl -v https://www.facebook.com/
...
< Alt-Svc: h2="facebook22esateyt47yqg6mzpwcnnoi4xims3yqe5b4peowxkilsyyd.onion:443"; ma=86400
# Uses different server when accessed from clearweb
[kreyren@leonid:~]$ curl -v --http1.1 https://www.facebook.com/
...
< Alt-Svc: h3=":443"; ma=3600, h3-29=":443"; ma=3600,h3-27=":443"; ma=3600

Additional informations

  1. I've notice this issue with all nixpkgs profiles namely discourse and nextcloud.

  2. This configuration is also required for load-balancing rl-example: https://invidious.snopyta.org

hmenke commented 3 years ago

I think this needs an RFC.

Ma27 commented 3 years ago

The thing is, we have the module system for a reason, namely extensibility. I don't really understand why we should make our configurations even more complicated and thus shift the workload towards the maintainers (for use-cases - or at least solutions - I don't consider really common). This sounds pretty much like the job of a systems engineer who's responsible to design such an environment and not like the job of a Linux distribution.

stale[bot] commented 2 years ago

I marked this as stale due to inactivity. → More info