diff --git a/config/fudo/git.nix b/config/fudo/git.nix index 9479582..68cedac 100644 --- a/config/fudo/git.nix +++ b/config/fudo/git.nix @@ -25,35 +25,50 @@ let }; }; + sshOpts = { ... }: with types; { + options = { + listen-ip = mkOption { + type = str; + description = "IP on which to listen for SSH connections."; + }; + + listen-port = mkOption { + type = port; + description = "Port on which to listen for SSH connections, on ."; + default = 22; + }; + }; + }; + in { - options.fudo.git = { + options.fudo.git = with types; { enable = mkEnableOption "Enable Fudo git web server."; hostname = mkOption { - type = types.str; + type = str; description = "Hostname at which this git server is accessible."; example = "git.fudo.org"; }; site-name = mkOption { - type = types.str; + type = str; description = "Name to use for the git server."; default = "Fudo Git"; }; database = mkOption { - type = (types.submodule databaseOpts); + type = (submodule databaseOpts); description = "Gitea database options."; }; repository-dir = mkOption { - type = types.path; + type = path; description = "Path at which to store repositories."; example = /srv/git/repo; }; state-dir = mkOption { - type = types.path; + type = path; description = "Path at which to store server state."; example = /srv/git/state; }; @@ -63,6 +78,18 @@ in { description = "System user as which to run."; default = "git"; }; + + local-port = mkOption { + type = port; + description = "Local port to which the Gitea server will bind. Not globally accessible."; + default = 3543; + }; + + ssh = mkOption { + type = nullOr (submodule sshOpts); + description = "SSH listen configuration."; + default = null; + }; }; config = mkIf cfg.enable { @@ -78,14 +105,23 @@ in { name = cfg.database.name; user = cfg.database.user; passwordFile = cfg.database.password-file; + type = "postgres"; }; domain = cfg.hostname; httpAddress = "127.0.0.1"; - httpPort = 3543; + httpPort = cfg.local-port; repositoryRoot = toString cfg.repository-dir; stateDir = toString cfg.state-dir; rootUrl = "https://${cfg.hostname}/"; user = mkIf (cfg.user != null) cfg.user; + extraConfig = mkIf (cfg.ssh != null) '' + [server] + START_SSH_SERVER = true + SSH_DOMAIN = ${cfg.hostname} + SSH_PORT = ${toString cfg.ssh.listen-port} + SSH_LISTEN_PORT = ${toString cfg.ssh.listen-port} + SSH_LISTEN_HOST = ${cfg.ssh.listen-ip} + ''; }; nginx = { @@ -97,15 +133,15 @@ in { forceSSL = true; locations."/" = { - proxyPass = "http://127.0.0.1:3543"; + proxyPass = "http://127.0.0.1:${toString cfg.local-port}"; extraConfig = '' - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-By $server_addr:$server_port; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header X-Forwarded-Proto $scheme; - ''; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-By $server_addr:$server_port; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + ''; }; }; }; diff --git a/config/fudo/mail-container.nix b/config/fudo/mail-container.nix index aa7edb5..e12b9ff 100644 --- a/config/fudo/mail-container.nix +++ b/config/fudo/mail-container.nix @@ -160,21 +160,21 @@ in rec { }; }; - users = { - users = { - ${container-mail-user} = { - isSystemUser = true; - uid = container-mail-user-id; - group = "mailer"; - }; - }; + # users = { + # users = { + # ${container-mail-user} = { + # isSystemUser = true; + # uid = container-mail-user-id; + # group = "mailer"; + # }; + # }; - groups = { - ${container-mail-group} = { - members = ["mailer"]; - }; - }; - }; + # groups = { + # ${container-mail-group} = { + # members = ["mailer"]; + # }; + # }; + # }; fudo.mail-server = { enable = true; @@ -193,10 +193,12 @@ in rec { dovecot = { ssl-certificate = "/etc/${container-dovecot-cert}"; ssl-private-key = "/etc/dovecot-certs/key.pem"; - ldap-ca = "/etc/${container-fudo-ca-cert}"; - ldap-urls = cfg.dovecot.ldap-urls; - ldap-reader-dn = cfg.dovecot.ldap-reader-dn; - ldap-reader-passwd = cfg.dovecot.ldap-reader-passwd; + ldap = { + # ca = "/etc/${container-fudo-ca-cert}"; + server-urls = cfg.dovecot.ldap.server-urls; + reader-dn = cfg.dovecot.ldap.reader-dn; + reader-passwd = cfg.dovecot.ldap.reader-passwd; + }; }; local-domains = cfg.local-domains; diff --git a/config/fudo/mail/dovecot.nix b/config/fudo/mail/dovecot.nix index 9d8f1cf..ae994b7 100644 --- a/config/fudo/mail/dovecot.nix +++ b/config/fudo/mail/dovecot.nix @@ -53,30 +53,33 @@ let } ''; - ldapOpts = with types; { - ca = mkOption { - type = str; - description = "The path to the CA cert used to sign the LDAP server certificate."; - }; + ldapOpts = { + options = with types; { + ca = mkOption { + type = nullOr str; + description = "The path to the CA cert used to sign the LDAP server certificate."; + default = null; + }; - server-urls = mkOption { - type = listOf str; - description = "A list of LDAP server URLs used for authentication."; - }; + server-urls = mkOption { + type = listOf str; + description = "A list of LDAP server URLs used for authentication."; + }; - reader-dn = mkOption { - type = str; - description = '' + reader-dn = mkOption { + type = str; + description = '' DN to use for reading user information. Needs access to homeDirectory, uidNumber, gidNumber, and uid, but not password attributes. ''; - }; + }; - reader-pw = mkOption { - type = str; - description = '' + reader-passwd = mkOption { + type = str; + description = '' Password for the user specified in ldap-reader-dn. ''; + }; }; }; @@ -204,7 +207,7 @@ in { auth_mechanisms = login plain ${optionalString (cfg.dovecot.ldap != null) - (ldap-conf cfg.dovecot.ldap)} + (ldap-passwd-entry cfg.dovecot.ldap)} userdb { driver = static args = uid=${toString cfg.mail-user-id} home=${cfg.mail-directory}/%u diff --git a/config/fudo/minecraft-server.nix b/config/fudo/minecraft-server.nix index 06f9c67..9ee5474 100644 --- a/config/fudo/minecraft-server.nix +++ b/config/fudo/minecraft-server.nix @@ -43,6 +43,10 @@ in { }; config = mkIf cfg.enable { + environment.systemPackages = [ + cfg.package + ]; + services.minecraft-server = { enable = true; package = cfg.package; diff --git a/config/fudo/system.nix b/config/fudo/system.nix index b25aaf4..5303a6c 100644 --- a/config/fudo/system.nix +++ b/config/fudo/system.nix @@ -20,6 +20,12 @@ in { default = []; example = ["redis.service"]; }; + + tmpOnTmpfs = mkOption { + type = types.bool; + description = "Put tmp filesystem on tmpfs (needs enough RAM)."; + default = true; + }; }; config = mkIf cfg.disableTransparentHugePages { diff --git a/config/fudo/vpn.nix b/config/fudo/vpn.nix new file mode 100644 index 0000000..bd0908b --- /dev/null +++ b/config/fudo/vpn.nix @@ -0,0 +1,79 @@ +{ pkgs, lib, config, ... }: + +with lib; +let + cfg = config.fudo.vpn; + + peerOpts = { peer-name, ... }: { + options = with types; { + public-key = mkOption { + type = str; + description = "Peer public key."; + }; + + allowed-ips = mkOption { + type = listOf str; + description = "List of allowed IP ranges from which this peer can connect."; + example = [ "10.100.0.0/16" ]; + default = []; + }; + }; + }; + +in { + options.fudo.vpn = with types; { + enable = mkEnableOption "Enable Fudo VPN"; + + ips = mkOption { + type = str; + description = "IP range to assign this interface."; + default = "10.100.0.0/16"; + }; + + private-key-file = mkOption { + type = str; + description = "Path to the secret key (generated with wg [genkey/pubkey])."; + example = "/path/to/secret.key"; + }; + + listen-port = mkOption { + type = port; + description = "Port on which to listen for incoming connections."; + default = 51820; + }; + + peers = mkOption { + type = listOf str; + description = "A list of peers for which to generate config files."; + default = []; + }; + + peers = mkOption { + type = loaOf (submodule peerOpts); + description = "A list of peers allowed to connect."; + default = {}; + example = { + peer0 = { + public-key = "xyz"; + allowed-ips = ["10.100.1.0/24"]; + }; + }; + }; + }; + + config = mkIf cfg.enable { + networking.wireguard = { + enable = true; + interfaces.wgtun0 = { + generatePrivateKeyFile = false; + ips = [ cfg.ips ]; + listenPort = cfg.listen-port; + peers = mapAttrsToList (peer-name: peer-config: { + publicKey = peer-config.public-key; + allowedIPs = peer-config.allowed-ips; + }) cfg.peers; + privateKeyFile = cfg.private-key-file; + }; + }; + }; +} diff --git a/config/local.nix b/config/local.nix index a3e43b2..9bae47d 100644 --- a/config/local.nix +++ b/config/local.nix @@ -22,6 +22,7 @@ with lib; ./fudo/secure-dns-proxy.nix ./fudo/slynk.nix ./fudo/system.nix + ./fudo/vpn.nix ./fudo/webmail.nix ./informis/cl-gemini.nix diff --git a/defaults.nix b/defaults.nix index 8ddfe0f..7635608 100644 --- a/defaults.nix +++ b/defaults.nix @@ -53,6 +53,7 @@ lispPackages.cl-ppcre lispPackages.clx lispPackages.quicklisp + lsof lshw mkpasswd ncurses5 @@ -68,7 +69,6 @@ pinentry.curses pv pwgen - racket ruby rustc sbcl @@ -142,6 +142,7 @@ openssh = { enable = true; startWhenNeeded = true; + permitRootLogin = "prohibit-password"; extraConfig = '' GSSAPIAuthentication yes GSSAPICleanupCredentials yes @@ -165,12 +166,13 @@ security.pam = { enableSSHAgentAuth = true; # TODO: add yubico? - services.sshd = { - # This should only ask for a code if ~/.google_authenticator exists, but it asks anyway. - # googleAuthenticator.enable = true; - makeHomeDir = true; - # Fails! - # requireWheel = true; + services = { + sshd = { + # This should only ask for a code if ~/.google_authenticator exists, but it asks anyway. + # googleAuthenticator.enable = true; + makeHomeDir = true; + sshAgentAuth = true; + }; }; }; diff --git a/fudo/profiles/common-ui.nix b/fudo/profiles/common-ui.nix index 48cdbd6..e016ef8 100644 --- a/fudo/profiles/common-ui.nix +++ b/fudo/profiles/common-ui.nix @@ -34,6 +34,7 @@ let mplayer mpv pdftk + racket redshift rhythmbox shotwell @@ -139,6 +140,7 @@ in mkIf ((profile == "desktop") || (profile == "laptop")) { terminus_font ubuntu_font_family ucsFonts + ultimate-oldschool-pc-font-pack unifont vistafonts xlibs.fontadobe100dpi diff --git a/fudo/profiles/server.nix b/fudo/profiles/server.nix index 7e1b7c3..b99c451 100644 --- a/fudo/profiles/server.nix +++ b/fudo/profiles/server.nix @@ -53,8 +53,9 @@ in { systemPackages = with pkgs; [ ldns ldns.examples - test-config + racket-minimal reboot-if-necessary + test-config ]; noXlibs = true; @@ -66,8 +67,8 @@ in { networking = { networkmanager.enable = mkForce false; - }; - + } +; boot.tmpOnTmpfs = true; services.xserver.enable = false; diff --git a/hosts/france.nix b/hosts/france.nix index f5d8a8d..4158f01 100644 --- a/hosts/france.nix +++ b/hosts/france.nix @@ -7,7 +7,7 @@ let mail-hostname = hostname; host_ipv4 = "208.81.3.117"; # Use a special IP for git.fudo.org, since it needs to be SSH-able - docker_ipv4 = "208.81.3.126"; + git_ipv4 = "208.81.3.126"; all-hostnames = []; acme-private-key = hostname: "/var/lib/acme/${hostname}/key.pem"; @@ -34,6 +34,15 @@ in { ../defaults.nix ]; + # services.openssh = { + # listenAddresses = [ + # { + # addr = host_ipv4; + # port = 22; + # } + # ]; + # }; + fudo.common = { # Sets some server-common settings. See /etc/nixos/fudo/profiles/... profile = "server"; @@ -118,12 +127,6 @@ in { fudo_git = "ALL PRIVILEGES"; }; }; - gitlab_postgres = { - password = fileContents "/srv/gitlab/secure/db.passwd"; - databases = { - gitlab = "ALL PRIVILEGES"; - }; - }; grafana = { password = fileContents "/srv/grafana/secure/db.passwd"; databases = { @@ -151,7 +154,6 @@ in { databases = { fudo_git = ["niten"]; - gitlab = ["niten"]; grafana = ["niten"]; mattermost = ["niten"]; webmail = ["niten"]; @@ -237,11 +239,13 @@ in { state-directory = "${system-mail-directory}/var"; mail-directory = "${system-mail-directory}/mailboxes"; - dovecot.ldap-reader-dn = "cn=user_db_reader,dc=fudo,dc=org"; - dovecot.ldap-reader-passwd = fileContents /srv/ldap/secure/user_db.passwd; + dovecot.ldap = { + reader-dn = "cn=user_db_reader,dc=fudo,dc=org"; + reader-passwd = fileContents /srv/ldap/secure/user_db.passwd; - # FIXME: use SSL once I can figure out Acme SSL cert CA for LDAP. - dovecot.ldap-urls = [ "ldap://france.fudo.org" ]; + # FIXME: use SSL once I can figure out Acme SSL cert CA for LDAP. + server-urls = [ "ldap://france.fudo.org" ]; + }; clamav.enable = true; @@ -270,27 +274,27 @@ in { "webmail.test.fudo.org" = { title = "Fudo Webmail"; favicon = "/etc/nixos/static/fudo.org/favicon.ico"; - mail-server = mail-hostname; - domain = "test.fudo.org"; + mail-server = "mail.fudo.org"; + domain = "fudo.org"; edit-mode = "Plain"; database = { name = "webmail"; hostname = "localhost"; user = "webmail"; - password-file = /srv/webmail/secure/db.passwd; + password-file = "/srv/webmail/secure/db.passwd"; }; }; "webmail.test.selby.ca" = { title = "Selby Webmail"; favicon = "/etc/nixos/static/selby.ca/favicon.ico"; - mail-server = mail-hostname; - domain = "test.selby.ca"; + mail-server = "mail.selby.ca"; + domain = "selby.ca"; database = { name = "webmail"; hostname = "localhost"; user = "webmail"; - password-file = /srv/webmail/secure/db.passwd; + password-file = "/srv/webmail/secure/db.passwd"; }; }; }; @@ -314,7 +318,7 @@ in { fudo.git = { enable = true; - hostname = "git.test.fudo.org"; + hostname = "git.fudo.org"; site-name = "Fudo Git"; user = "fudo_git"; database = { @@ -325,6 +329,10 @@ in { }; repository-dir = /srv/git/repo; state-dir = /srv/git/state; + ssh = { + listen-ip = git_ipv4; + listen-port = 2222; + }; }; networking = { @@ -368,7 +376,7 @@ in { macAddress = "02:6d:e2:e1:ad:ca"; ipv4.addresses = [ { - address = docker_ipv4; + address = git_ipv4; prefixLength = 28; } ]; @@ -449,42 +457,7 @@ in { isNormalUser = false; uid = 8006; }; - - gitlab = { - isNormalUser = false; - uid = 8002; - }; - - gitlab_postgres = { - isNormalUser = false; - group = config.fudo.postgresql.socket-group; - uid = 8003; - }; - - gitlab_redis = { - isNormalUser = false; - group = "redis-local"; - uid = 8004; - }; - - gitlab_www = { - isNormalUser = false; - group = "nogroup"; - uid = 8005; - }; }; - - extraGroups = { - redis-local = { - members = ["redis"]; - gid = 7001; - }; - }; - }; - - boot.kernel.sysctl = { - # For Redis - "vm.overcommit_memory" = 1; }; fudo.system = { @@ -492,10 +465,6 @@ in { postHugePageServices = ["redis.service"]; }; - systemd.services.redis.postStart = '' - chgrp redis-local ${config.services.redis.unixSocket} - ''; - security.acme.certs = { "archiva.fudo.org".email = config.fudo.common.admin-email; "git.fudo.org".email = config.fudo.common.admin-email; @@ -503,15 +472,6 @@ in { services = { - redis = { - enable = true; - bind = "127.0.0.1"; - unixSocket = "/run/redis/redis.socket"; - extraConfig = '' - unixsocketperm 770 - ''; - }; - nginx = { enable = true; recommendedGzipSettings = true; @@ -534,22 +494,6 @@ in { ''; }; }; - - "git.fudo.org" = { - enableACME = true; - forceSSL = true; - - locations."/" = { - proxyPass = "http://127.0.0.1:8002"; - extraConfig = '' - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-By $server_addr:$server_port; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header X-Forwarded-Proto $scheme; - ''; - }; - }; }; }; }; @@ -568,60 +512,15 @@ in { SSL_ENABLED = "false"; }; }; - - gitlab = { - image = "gitlab/gitlab-ce:12.8.1-ce.0"; - ports = [ - "127.0.0.1:8002:80" - "${docker_ipv4}::22" - ]; - # user = toString config.users.users.gitlab.uid; - volumes = [ - "/run/redis:/var/opt/gitlab/redis" - "/srv/gitlab/builds:/var/opt/gitlab/gitlab-ci/builds" - "/srv/gitlab/config:/etc/gitlab" - "/srv/gitlab/logs:/var/log/gitlab" - "/srv/gitlab/gitlab:/var/opt/gitlab" - "${config.fudo.postgresql.socket-directory}:/run/postgresql" - "${config.fudo.postgresql.socket-directory}:/var/opt/gitlab/postgresql" - ]; - extraDockerOptions = [ - "--hostname=git.fudo.org" - ]; - }; }; - systemd.services.docker-gitlab-config = let - gitlab-config = pkgs.writeText "gitlab-config.rb" '' - gitlab_rails['db_adapter'] = "postgresql" - gitlab_rails['db_encoding'] = "unicode" - gitlab_rails['db_database'] = "gitlab" - gitlab_rails['db_username'] = "gitlab_postgres" - gitlab_rails['db_password'] = "${fileContents /srv/gitlab/secure/db.passwd}" - - user['uid'] = "${toString config.users.users.gitlab.uid}" - user['gid'] = "${toString config.users.groups.redis-local.gid}" - - # Provided externally - redis['enable'] = false - postgresql['enable'] = false - - web_server['uid'] = "${toString config.users.users.gitlab_www.uid}" - web_server['gid'] = "${toString config.users.groups.nogroup.gid}" - ''; - in { - # before = ["docker-gitlab.service"]; - script = "cp -f ${gitlab-config} /srv/gitlab/config/gitlab.rb"; - }; - systemd.services.docker-gitlab.requires = ["docker-gitlab-config.service"]; - ### # Minecraft ### fudo.minecraft-server = { enable = true; - package = pkgs.minecraft-server_1_15_2; + package = pkgs.minecraft-server_1_16_1; data-dir = minecraft-data-dir; world-name = "selbyland"; motd = "Welcome to the Selby Minecraft server."; diff --git a/hosts/procul.nix b/hosts/procul.nix index 2276e63..ead5d09 100644 --- a/hosts/procul.nix +++ b/hosts/procul.nix @@ -55,6 +55,13 @@ in { }; }; + # For WireGuard + nat = { + enable = true; + externalInterface = "extif0"; + internalInterfaces = [ "wgtun0" ]; + }; + interfaces = { extif0 = { # result of: @@ -119,6 +126,8 @@ in { ]; }; + system.tmpOnTmpfs = false; + secure-dns-proxy = { enable = true; upstream-dns = [ "https://cloudflare-dns.com/dns-query" ]; @@ -263,6 +272,26 @@ in { }; }; + fudo.vpn = { + enable = true; + ips = "10.100.0.0/16"; + private-key-file = "/srv/wireguard/secure/secret.key"; + peers = { + peter = { + allowed-ips = [ "10.100.1.0/24" ]; + public-key = "d1NfRFWRkcKq2gxvqfMy7Oe+JFYf5DjomnsTyisvgB4="; + }; + ken = { + allowed-ips = [ "10.100.2.0/24" ]; + public-key = "y294rTCK0iSRhA6EIOErPzEuqzJMuYAG4XbHasySMVU="; + }; + helen = { + allowed-ips = [ "10.100.3.0/24" ]; + public-key = "7Hdko6RibhIYdoPLWXGwmElY5vKvZ+rURmqFTDUfC2w="; + }; + }; + }; + informis.cl-gemini = { enable = true; diff --git a/packages/local.nix b/packages/local.nix index 51d8693..7e72555 100644 --- a/packages/local.nix +++ b/packages/local.nix @@ -22,6 +22,19 @@ }; }); + # DON'T LEAVE THE HASH--Nix will think the package hasn't changed + minecraft-server_1_16_1 = let + version = "1.16.1"; + url = "https://launcher.mojang.com/v1/objects/a412fd69db1f81db3f511c1463fd304675244077/server.jar"; + sha256 = "0nwkdig6yw4cnm2ld78z4j4xzhbm1rwv55vfxz0gzhsbf93xb0i7"; + in (pkgs.minecraft-server.overrideAttrs (oldAttrs: rec { + name = "minecraft-server-${version}"; + inherit version; + src = pkgs.fetchurl { + inherit url sha256; + }; + })); + postgresql_11_gssapi = pkgs.postgresql_11.overrideAttrs (oldAttrs: rec { configureFlags = oldAttrs.configureFlags ++ [ "--with-gssapi" ]; buildInputs = oldAttrs.buildInputs ++ [ pkgs.krb5 ];