235 lines
6.1 KiB
Nix
235 lines
6.1 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
|
|
inherit (pkgs) 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 (lib.mdDoc "NNTP-Proxy");
|
|
|
|
upstreamServer = mkOption {
|
|
type = types.str;
|
|
default = "";
|
|
example = "ssl-eu.astraweb.com";
|
|
description = lib.mdDoc ''
|
|
Upstream server address
|
|
'';
|
|
};
|
|
|
|
upstreamPort = mkOption {
|
|
type = types.port;
|
|
default = 563;
|
|
description = lib.mdDoc ''
|
|
Upstream server port
|
|
'';
|
|
};
|
|
|
|
upstreamMaxConnections = mkOption {
|
|
type = types.int;
|
|
default = 20;
|
|
description = lib.mdDoc ''
|
|
Upstream server maximum allowed concurrent connections
|
|
'';
|
|
};
|
|
|
|
upstreamUser = mkOption {
|
|
type = types.str;
|
|
default = "";
|
|
description = lib.mdDoc ''
|
|
Upstream server username
|
|
'';
|
|
};
|
|
|
|
upstreamPassword = mkOption {
|
|
type = types.str;
|
|
default = "";
|
|
description = lib.mdDoc ''
|
|
Upstream server password
|
|
'';
|
|
};
|
|
|
|
listenAddress = mkOption {
|
|
type = types.str;
|
|
default = "127.0.0.1";
|
|
example = "[::]";
|
|
description = lib.mdDoc ''
|
|
Proxy listen address (IPv6 literal addresses need to be enclosed in "[" and "]" characters)
|
|
'';
|
|
};
|
|
|
|
port = mkOption {
|
|
type = types.port;
|
|
default = 5555;
|
|
description = lib.mdDoc ''
|
|
Proxy listen port
|
|
'';
|
|
};
|
|
|
|
sslKey = mkOption {
|
|
type = types.str;
|
|
default = "key.pem";
|
|
example = "/path/to/your/key.file";
|
|
description = lib.mdDoc ''
|
|
Proxy ssl key path
|
|
'';
|
|
};
|
|
|
|
sslCert = mkOption {
|
|
type = types.str;
|
|
default = "cert.pem";
|
|
example = "/path/to/your/cert.file";
|
|
description = lib.mdDoc ''
|
|
Proxy ssl certificate path
|
|
'';
|
|
};
|
|
|
|
prohibitPosting = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
description = lib.mdDoc ''
|
|
Whether to prohibit posting to the upstream server
|
|
'';
|
|
};
|
|
|
|
verbosity = mkOption {
|
|
type = types.enum [ "error" "warning" "notice" "info" "debug" ];
|
|
default = "info";
|
|
example = "error";
|
|
description = lib.mdDoc ''
|
|
Verbosity level
|
|
'';
|
|
};
|
|
|
|
users = mkOption {
|
|
type = types.attrsOf (types.submodule {
|
|
options = {
|
|
username = mkOption {
|
|
type = types.str;
|
|
description = lib.mdDoc ''
|
|
Username
|
|
'';
|
|
};
|
|
|
|
passwordHash = mkOption {
|
|
type = types.str;
|
|
example = "$6$GtzE7FrpE$wwuVgFYU.TZH4Rz.Snjxk9XGua89IeVwPQ/fEUD8eujr40q5Y021yhn0aNcsQ2Ifw.BLclyzvzgegopgKcneL0";
|
|
description = lib.mdDoc ''
|
|
SHA-512 password hash (can be generated by
|
|
`mkpasswd -m sha-512 <password>`)
|
|
'';
|
|
};
|
|
|
|
maxConnections = mkOption {
|
|
type = types.int;
|
|
default = 1;
|
|
description = lib.mdDoc ''
|
|
Maximum number of concurrent connections to the proxy for this user
|
|
'';
|
|
};
|
|
};
|
|
});
|
|
description = lib.mdDoc ''
|
|
NNTP-Proxy user configuration
|
|
'';
|
|
|
|
default = {};
|
|
example = literalExpression ''
|
|
{
|
|
"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.nntp-proxy = {
|
|
isSystemUser = true;
|
|
group = "nntp-proxy";
|
|
description = "NNTP-Proxy daemon user";
|
|
};
|
|
users.groups.nntp-proxy = {};
|
|
|
|
systemd.services.nntp-proxy = {
|
|
description = "NNTP proxy";
|
|
after = [ "network.target" "nss-lookup.target" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
serviceConfig = { User="nntp-proxy"; };
|
|
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
|
|
'';
|
|
};
|
|
|
|
};
|
|
|
|
}
|