236 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			236 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{ config, lib, pkgs, ... }:
 | 
						|
 | 
						|
with lib;
 | 
						|
 | 
						|
let
 | 
						|
 | 
						|
  inherit (pkgs) nntp-proxy;
 | 
						|
 | 
						|
  proxyUser = "nntp-proxy";
 | 
						|
 | 
						|
  cfg = config.services.nntp-proxy;
 | 
						|
 | 
						|
  configBool = b: if b then "TRUE" else "FALSE";
 | 
						|
 | 
						|
  confFile = pkgs.writeText "nntp-proxy.conf" ''
 | 
						|
    nntp_server:
 | 
						|
    {
 | 
						|
      # NNTP Server host and port address
 | 
						|
      server = "${cfg.upstreamServer}";
 | 
						|
      port = ${toString cfg.upstreamPort};
 | 
						|
      # NNTP username
 | 
						|
      username = "${cfg.upstreamUser}";
 | 
						|
      # NNTP password in clear text
 | 
						|
      password = "${cfg.upstreamPassword}";
 | 
						|
      # Maximum number of connections allowed by the NNTP
 | 
						|
      max_connections = ${toString cfg.upstreamMaxConnections};
 | 
						|
    };
 | 
						|
 | 
						|
    proxy:
 | 
						|
    {
 | 
						|
      # Local address and port to bind to
 | 
						|
      bind_ip = "${cfg.listenAddress}";
 | 
						|
      bind_port = ${toString cfg.port};
 | 
						|
 | 
						|
      # SSL key and cert file
 | 
						|
      ssl_key = "${cfg.sslKey}";
 | 
						|
      ssl_cert = "${cfg.sslCert}";
 | 
						|
 | 
						|
      # prohibit users from posting
 | 
						|
      prohibit_posting = ${configBool cfg.prohibitPosting};
 | 
						|
      # Verbose levels: ERROR, WARNING, NOTICE, INFO, DEBUG
 | 
						|
      verbose = "${toUpper cfg.verbosity}";
 | 
						|
      # Password is made with: 'mkpasswd -m sha-512 <password>'
 | 
						|
      users = (${concatStringsSep ",\n" (mapAttrsToList (username: userConfig:
 | 
						|
        ''
 | 
						|
          {
 | 
						|
              username = "${username}";
 | 
						|
              password = "${userConfig.passwordHash}";
 | 
						|
              max_connections = ${toString userConfig.maxConnections};
 | 
						|
          }
 | 
						|
        '') cfg.users)});
 | 
						|
    };
 | 
						|
  '';
 | 
						|
 | 
						|
in
 | 
						|
 | 
						|
{
 | 
						|
 | 
						|
  ###### interface
 | 
						|
 | 
						|
  options = {
 | 
						|
 | 
						|
    services.nntp-proxy = {
 | 
						|
      enable = mkEnableOption "NNTP-Proxy";
 | 
						|
 | 
						|
      upstreamServer = mkOption {
 | 
						|
        type = types.str;
 | 
						|
        default = "";
 | 
						|
        example = "ssl-eu.astraweb.com";
 | 
						|
        description = ''
 | 
						|
          Upstream server address
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      upstreamPort = mkOption {
 | 
						|
        type = types.int;
 | 
						|
        default = 563;
 | 
						|
        description = ''
 | 
						|
          Upstream server port
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      upstreamMaxConnections = mkOption {
 | 
						|
        type = types.int;
 | 
						|
        default = 20;
 | 
						|
        description = ''
 | 
						|
          Upstream server maximum allowed concurrent connections
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      upstreamUser = mkOption {
 | 
						|
        type = types.str;
 | 
						|
        default = "";
 | 
						|
        description = ''
 | 
						|
          Upstream server username
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      upstreamPassword = mkOption {
 | 
						|
        type = types.str;
 | 
						|
        default = "";
 | 
						|
        description = ''
 | 
						|
          Upstream server password
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      listenAddress = mkOption {
 | 
						|
        type = types.str;
 | 
						|
        default = "127.0.0.1";
 | 
						|
        example = "[::]";
 | 
						|
        description = ''
 | 
						|
          Proxy listen address (IPv6 literal addresses need to be enclosed in "[" and "]" characters)
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      port = mkOption {
 | 
						|
        type = types.int;
 | 
						|
        default = 5555;
 | 
						|
        description = ''
 | 
						|
          Proxy listen port
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      sslKey = mkOption {
 | 
						|
        type = types.str;
 | 
						|
        default = "key.pem";
 | 
						|
        example = "/path/to/your/key.file";
 | 
						|
        description = ''
 | 
						|
          Proxy ssl key path
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      sslCert = mkOption {
 | 
						|
        type = types.str;
 | 
						|
        default = "cert.pem";
 | 
						|
        example = "/path/to/your/cert.file";
 | 
						|
        description = ''
 | 
						|
          Proxy ssl certificate path
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      prohibitPosting = mkOption {
 | 
						|
        type = types.bool;
 | 
						|
        default = true;
 | 
						|
        description = ''
 | 
						|
          Whether to prohibit posting to the upstream server
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      verbosity = mkOption {
 | 
						|
        type = types.enum [ "error" "warning" "notice" "info" "debug" ];
 | 
						|
        default = "info";
 | 
						|
        example = "error";
 | 
						|
        description = ''
 | 
						|
          Verbosity level
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      users = mkOption {
 | 
						|
        type = types.attrsOf (types.submodule {
 | 
						|
          options = {
 | 
						|
            username = mkOption {
 | 
						|
              type = types.str;
 | 
						|
              default = null;
 | 
						|
              description = ''
 | 
						|
                Username
 | 
						|
              '';
 | 
						|
            };
 | 
						|
 | 
						|
            passwordHash = mkOption {
 | 
						|
              type = types.str;
 | 
						|
              default = null;
 | 
						|
              example = "$6$GtzE7FrpE$wwuVgFYU.TZH4Rz.Snjxk9XGua89IeVwPQ/fEUD8eujr40q5Y021yhn0aNcsQ2Ifw.BLclyzvzgegopgKcneL0";
 | 
						|
              description = ''
 | 
						|
                SHA-512 password hash (can be generated by
 | 
						|
                <code>mkpasswd -m sha-512 <password></code>)
 | 
						|
              '';
 | 
						|
            };
 | 
						|
 | 
						|
            maxConnections = mkOption {
 | 
						|
              type = types.int;
 | 
						|
              default = 1;
 | 
						|
              description = ''
 | 
						|
                Maximum number of concurrent connections to the proxy for this user
 | 
						|
              '';
 | 
						|
            };
 | 
						|
          };
 | 
						|
        });
 | 
						|
        description = ''
 | 
						|
          NNTP-Proxy user configuration
 | 
						|
        '';
 | 
						|
 | 
						|
        default = {};
 | 
						|
        example = literalExample ''
 | 
						|
          "user1" = {
 | 
						|
            passwordHash = "$6$1l0t5Kn2Dk$appzivc./9l/kjq57eg5UCsBKlcfyCr0zNWYNerKoPsI1d7eAwiT0SVsOVx/CTgaBNT/u4fi2vN.iGlPfv1ek0";
 | 
						|
            maxConnections = 5;
 | 
						|
          };
 | 
						|
          "anotheruser" = {
 | 
						|
            passwordHash = "$6$6lwEsWB.TmsS$W7m1riUx4QrA8pKJz8hvff0dnF1NwtZXgdjmGqA1Dx2MDPj07tI9GNcb0SWlMglE.2/hBgynDdAd/XqqtRqVQ0";
 | 
						|
            maxConnections = 7;
 | 
						|
          };
 | 
						|
        '';
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
  };
 | 
						|
 | 
						|
  ###### implementation
 | 
						|
 | 
						|
  config = mkIf cfg.enable {
 | 
						|
 | 
						|
    users.users = singleton
 | 
						|
      { name = proxyUser;
 | 
						|
        uid = config.ids.uids.nntp-proxy;
 | 
						|
        description = "NNTP-Proxy daemon user";
 | 
						|
      };
 | 
						|
 | 
						|
    systemd.services.nntp-proxy = {
 | 
						|
      description = "NNTP proxy";
 | 
						|
      after = [ "network.target" "nss-lookup.target" ];
 | 
						|
      wantedBy = [ "multi-user.target" ];
 | 
						|
      serviceConfig = { User="${proxyUser}"; };
 | 
						|
      serviceConfig.ExecStart = "${nntp-proxy}/bin/nntp-proxy ${confFile}";
 | 
						|
      preStart = ''
 | 
						|
        if [ ! \( -f ${cfg.sslCert} -a -f ${cfg.sslKey} \) ]; then
 | 
						|
          ${pkgs.openssl.bin}/bin/openssl req -subj '/CN=AutoGeneratedCert/O=NixOS Service/C=US' \
 | 
						|
          -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout ${cfg.sslKey} -out ${cfg.sslCert};
 | 
						|
        fi
 | 
						|
      '';
 | 
						|
    };
 | 
						|
 | 
						|
  };
 | 
						|
 | 
						|
}
 |