| 
									
										
										
										
											2016-02-26 15:19:46 +01:00
										 |  |  | { 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 { | 
					
						
							| 
									
										
										
										
											2016-11-16 22:36:53 +09:00
										 |  |  |         type = types.enum [ "error" "warning" "notice" "info" "debug" ]; | 
					
						
							| 
									
										
										
										
											2016-02-26 15:19:46 +01:00
										 |  |  |         default = "info"; | 
					
						
							|  |  |  |         example = "error"; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							| 
									
										
										
										
											2016-11-16 22:36:53 +09:00
										 |  |  |           Verbosity level | 
					
						
							| 
									
										
										
										
											2016-02-26 15:19:46 +01:00
										 |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       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 = ''
 | 
					
						
							| 
									
										
										
										
											2016-03-03 21:31:00 +01:00
										 |  |  |                 SHA-512 password hash (can be generated by | 
					
						
							|  |  |  |                 <code>mkpasswd -m sha-512 <password></code>) | 
					
						
							| 
									
										
										
										
											2016-02-26 15:19:46 +01:00
										 |  |  |               '';
 | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             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 { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-30 01:58:35 +02:00
										 |  |  |     users.users = singleton | 
					
						
							| 
									
										
										
										
											2016-02-26 15:19:46 +01:00
										 |  |  |       { 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 | 
					
						
							| 
									
										
										
										
											2016-04-10 22:51:13 +03:00
										 |  |  |           ${pkgs.openssl.bin}/bin/openssl req -subj '/CN=AutoGeneratedCert/O=NixOS Service/C=US' \ | 
					
						
							| 
									
										
										
										
											2016-02-26 15:19:46 +01:00
										 |  |  |           -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout ${cfg.sslKey} -out ${cfg.sslCert}; | 
					
						
							|  |  |  |         fi | 
					
						
							|  |  |  |       '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |