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.extraUsers = 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
 | |
|       '';
 | |
|     };
 | |
| 
 | |
|   };
 | |
| 
 | |
| }
 | 
