Compare commits

...

18 Commits

Author SHA1 Message Date
Inex Code 40f92d15d3 feat: Migrate to flakes 2024-01-19 14:50:25 +03:00
Inex Code 2c2bb80006 Merge pull request 'add nix experimental-features for flakes' (#49) from experimental-features into master
Reviewed-on: #49
Reviewed-by: Inex Code <inex.code@selfprivacy.org>
2023-11-09 15:43:17 +02:00
Alexander Tomokhov 5685a9e128 add nix experimental-features for flakes 2023-11-09 17:35:24 +04:00
Inex Code f8befb0e3d Merge pull request 'Disable password auth and allow serving static files at root domain' (#48) from inex-oct-31 into master
Reviewed-on: #48
2023-10-31 18:28:19 +02:00
Inex Code 1464d7f3bd feat(nginx): Allow serving static files at root domain 2023-10-31 17:27:46 +03:00
Inex Code d02524bb8f refactor(ssh): Disable password auth by default 2023-10-31 17:22:15 +03:00
Inex Code 23155b3c96 feat(ssh): Allow ecdsa-sha2-nistp256 keys 2023-10-03 16:34:47 +03:00
Inex Code 6c07cc024b fix: permissions for vaultwarden backups were too broad 2023-08-25 13:56:01 +03:00
Inex Code 5710f5892b fix(email): make sure /var/sieve owned my mail user 2023-07-28 03:41:06 +03:00
Inex Code 325dc40f34 fix(acme): add dns propagation check exceptions 2023-07-28 03:01:30 +03:00
Inex Code 25d7bc6ec5 fix(acme): enable DNS propagation check 2023-07-22 00:01:29 +03:00
Inex Code 29b855818d fix: acme retrieval 2023-07-21 20:59:34 +03:00
Inex Code e0ad80b4ca Revert "fix: rename the cert name"
This reverts commit e8a25ec565.
2023-07-21 20:36:40 +03:00
Inex Code e8a25ec565 fix: rename the cert name 2023-07-21 20:35:37 +03:00
Inex Code d41cf6a4db fix: do not use DNS challenge for root domain TLS
Previous solution made ACME create two TXT records
on the same subdomain, creating the conflict
2023-07-21 20:32:03 +03:00
Inex Code 2f0107ce3b refactor: remove unused restic-related code 2023-07-21 17:51:12 +03:00
Inex Code 8f72f60286 refactor: remove restic credentials from post-installation scripts
These are handled by API now.
2023-07-20 19:58:54 +03:00
Inex Code 58e4f3acd8 feat: update API deps 2023-07-20 19:52:24 +03:00
10 changed files with 48 additions and 104 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
userdata/userdata.json userdata/userdata.json
userdata/tokens.json userdata/tokens.json
hardware-configuration.nix hardware-configuration.nix
networking.nix networking.nix
/result

View File

@ -18,19 +18,6 @@ in
Enable SelfPrivacy API service Enable SelfPrivacy API service
''; '';
}; };
enableSwagger = mkOption {
default = false;
type = types.bool;
description = ''
Enable Swagger UI
'';
};
b2Bucket = mkOption {
type = types.str;
description = ''
B2 bucket
'';
};
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
@ -40,8 +27,6 @@ in
inherit (config.environment.sessionVariables) NIX_PATH; inherit (config.environment.sessionVariables) NIX_PATH;
HOME = "/root"; HOME = "/root";
PYTHONUNBUFFERED = "1"; PYTHONUNBUFFERED = "1";
ENABLE_SWAGGER = (if cfg.enableSwagger then "1" else "0");
B2_BUCKET = cfg.b2Bucket;
} // config.networking.proxy.envVars; } // config.networking.proxy.envVars;
path = [ path = [
"/var/" "/var/"
@ -53,11 +38,14 @@ in
pkgs.gitMinimal pkgs.gitMinimal
config.nix.package.out config.nix.package.out
pkgs.nixos-rebuild pkgs.nixos-rebuild
pkgs.rclone
pkgs.restic pkgs.restic
pkgs.mkpasswd pkgs.mkpasswd
pkgs.util-linux pkgs.util-linux
pkgs.e2fsprogs pkgs.e2fsprogs
pkgs.iproute2 pkgs.iproute2
pkgs.fuse-overlayfs
pkgs.fuse
]; ];
after = [ "network-online.target" ]; after = [ "network-online.target" ];
wantedBy = [ "network-online.target" ]; wantedBy = [ "network-online.target" ];
@ -74,8 +62,6 @@ in
inherit (config.environment.sessionVariables) NIX_PATH; inherit (config.environment.sessionVariables) NIX_PATH;
HOME = "/root"; HOME = "/root";
PYTHONUNBUFFERED = "1"; PYTHONUNBUFFERED = "1";
ENABLE_SWAGGER = (if cfg.enableSwagger then "1" else "0");
B2_BUCKET = cfg.b2Bucket;
PYTHONPATH = pkgs.selfprivacy-graphql-api.pythonPath + ":${pkgs.selfprivacy-graphql-api}/lib/python3.10/site-packages/"; PYTHONPATH = pkgs.selfprivacy-graphql-api.pythonPath + ":${pkgs.selfprivacy-graphql-api}/lib/python3.10/site-packages/";
} // config.networking.proxy.envVars; } // config.networking.proxy.envVars;
path = [ path = [
@ -88,11 +74,14 @@ in
pkgs.gitMinimal pkgs.gitMinimal
config.nix.package.out config.nix.package.out
pkgs.nixos-rebuild pkgs.nixos-rebuild
pkgs.rclone
pkgs.restic pkgs.restic
pkgs.mkpasswd pkgs.mkpasswd
pkgs.util-linux pkgs.util-linux
pkgs.e2fsprogs pkgs.e2fsprogs
pkgs.iproute2 pkgs.iproute2
pkgs.fuse-overlayfs
pkgs.fuse
]; ];
after = [ "network-online.target" ]; after = [ "network-online.target" ];
wantedBy = [ "network-online.target" ]; wantedBy = [ "network-online.target" ];

View File

@ -2,8 +2,6 @@
{ {
services.selfprivacy-api = { services.selfprivacy-api = {
enable = true; enable = true;
enableSwagger = config.services.userdata.api.enableSwagger;
b2Bucket = config.services.userdata.backup.bucket;
}; };
users.users."selfprivacy-api" = { users.users."selfprivacy-api" = {

View File

@ -1,29 +0,0 @@
{ config, pkgs, ... }:
let
cfg = config.services.userdata;
in
{
services.restic.backups = {
options = {
passwordFile = "/etc/restic/resticPasswd";
repository = "s3:s3.anazonaws.com/${cfg.backup.bucket}";
initialize = true;
paths = [
"/var/dkim"
"/var/vmail"
];
timerConfig = {
OnCalendar = [ "daily" ];
};
user = "restic";
pruneOpts = [
"--keep-daily 5"
];
};
};
users.users.restic = {
isNormalUser = false;
isSystemUser = true;
group = "restic";
};
}

View File

@ -1,6 +1,6 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
let let
url-overlay = "https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nix-repo/archive/22-11.tar.gz"; url-overlay = "https://git.selfprivacy.org/SelfPrivacy/selfprivacy-nix-repo/archive/test-migration.tar.gz";
nix-overlay = (import (builtins.fetchTarball url-overlay)); nix-overlay = (import (builtins.fetchTarball url-overlay));
in in
{ {
@ -18,7 +18,6 @@ in
./social/pleroma.nix ./social/pleroma.nix
./letsencrypt/acme.nix ./letsencrypt/acme.nix
./letsencrypt/resolve.nix ./letsencrypt/resolve.nix
./backup/restic.nix
./passmgr/bitwarden.nix ./passmgr/bitwarden.nix
./webserver/nginx.nix ./webserver/nginx.nix
./webserver/memcached.nix ./webserver/memcached.nix
@ -74,7 +73,7 @@ in
openFirewall = false; openFirewall = false;
}; };
programs.ssh = { programs.ssh = {
pubkeyAcceptedKeyTypes = [ "ssh-ed25519" "ssh-rsa" ]; pubkeyAcceptedKeyTypes = [ "ssh-ed25519" "ssh-rsa" "ecdsa-sha2-nistp256" ];
hostKeyAlgorithms = [ "ssh-ed25519" "ssh-rsa" ]; hostKeyAlgorithms = [ "ssh-ed25519" "ssh-rsa" ];
}; };
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
@ -96,6 +95,9 @@ in
automatic = true; automatic = true;
options = "--delete-older-than 7d"; options = "--delete-older-than 7d";
}; };
extraOptions = ''
experimental-features = nix-command flakes repl-flake
'';
}; };
services.journald.extraConfig = "SystemMaxUse=500M"; services.journald.extraConfig = "SystemMaxUse=500M";
boot.kernel.sysctl = { boot.kernel.sysctl = {

View File

@ -18,13 +18,14 @@ in
domain = builtins.replaceStrings [ "\n" "\"" "\\" "%" ] [ "\\n" "\\\"" "\\\\" "%%" ] cfg.domain; domain = builtins.replaceStrings [ "\n" "\"" "\\" "%" ] [ "\\n" "\\\"" "\\\\" "%%" ] cfg.domain;
in in
[ [
(if cfg.bitwarden.enable then "d /var/lib/bitwarden 0777 vaultwarden vaultwarden -" else "") (if cfg.bitwarden.enable then "d /var/lib/bitwarden 0770 vaultwarden vaultwarden -" else "")
(if cfg.bitwarden.enable then "d /var/lib/bitwarden/backup 0777 vaultwarden vaultwarden -" else "") (if cfg.bitwarden.enable then "d /var/lib/bitwarden/backup 0770 vaultwarden vaultwarden -" else "")
(if cfg.pleroma.enable then "d /var/lib/pleroma 0700 pleroma pleroma - -" else "") (if cfg.pleroma.enable then "d /var/lib/pleroma 0700 pleroma pleroma - -" else "")
"d /var/lib/restic 0600 restic - - -" (if cfg.pleroma.enable then "f /var/lib/pleroma/secrets.exs 0750 pleroma pleroma - -" else "")
(if cfg.pleroma.enable then "f /var/lib/pleroma/secrets.exs 0755 pleroma pleroma - -" else "")
"f+ /var/domain 0444 selfprivacy-api selfprivacy-api - ${domain}" "f+ /var/domain 0444 selfprivacy-api selfprivacy-api - ${domain}"
(if cfg.bitwarden.enable then "f /var/lib/bitwarden/.env 0640 vaultwarden vaultwarden - -" else "") (if cfg.bitwarden.enable then "f /var/lib/bitwarden/.env 0640 vaultwarden vaultwarden - -" else "")
"d /var/sieve 0770 virtualMail virtualMail - -"
"d /var/www/root 0750 nginx nginx - -"
]; ];
system.activationScripts = system.activationScripts =
let let
@ -56,25 +57,6 @@ in
chmod 0440 /var/lib/cloudflare/Credentials.ini chmod 0440 /var/lib/cloudflare/Credentials.ini
chown nginx:acmerecievers /var/lib/cloudflare/Credentials.ini chown nginx:acmerecievers /var/lib/cloudflare/Credentials.ini
''; '';
resticCredentials = ''
mkdir -p /root/.config/rclone
chmod 0400 /root/.config/rclone
chown root:root /root/.config/rclone
echo '[backblaze]' > /root/.config/rclone/rclone.conf
echo 'type = b2' >> /root/.config/rclone/rclone.conf
echo 'account = REPLACEME1' >> /root/.config/rclone/rclone.conf
echo 'key = REPLACEME2' >> /root/.config/rclone/rclone.conf
${sed} -i "s/REPLACEME1/$(cat /etc/nixos/userdata/userdata.json | ${jq} -r '.backup.accountId')/g" /root/.config/rclone/rclone.conf
${sed} -i "s/REPLACEME2/$(cat /etc/nixos/userdata/userdata.json | ${jq} -r '.backup.accountKey')/g" /root/.config/rclone/rclone.conf
chmod 0400 /root/.config/rclone/rclone.conf
chown root:root /root/.config/rclone/rclone.conf
cat /etc/nixos/userdata/userdata.json | ${jq} -r '.resticPassword' > /var/lib/restic/pass
chmod 0400 /var/lib/restic/pass
chown restic /var/lib/restic/pass
'';
pleromaCredentials = pleromaCredentials =
if cfg.pleroma.enable then '' if cfg.pleroma.enable then ''
echo 'import Config' > /var/lib/pleroma/secrets.exs echo 'import Config' > /var/lib/pleroma/secrets.exs

View File

@ -1,6 +1,7 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
let let
cfg = config.services.userdata; cfg = config.services.userdata;
dnsPropagationCheckExceptions = [ "DIGITALOCEAN" ];
in in
{ {
users.groups.acmerecievers = { users.groups.acmerecievers = {
@ -11,17 +12,21 @@ in
defaults = { defaults = {
email = "${cfg.username}@${cfg.domain}"; email = "${cfg.username}@${cfg.domain}";
server = if cfg.dns.useStagingACME then "https://acme-staging-v02.api.letsencrypt.org/directory" else "https://acme-v02.api.letsencrypt.org/directory"; server = if cfg.dns.useStagingACME then "https://acme-staging-v02.api.letsencrypt.org/directory" else "https://acme-v02.api.letsencrypt.org/directory";
dnsPropagationCheck = false; dnsPropagationCheck = if lib.elem cfg.dns.provider dnsPropagationCheckExceptions then false else true;
reloadServices = [ "nginx" ]; reloadServices = [ "nginx" ];
}; };
certs = lib.mkForce { certs = lib.mkForce {
"${cfg.domain}" = { "wildcard-${cfg.domain}" = {
domain = "*.${cfg.domain}"; domain = "*.${cfg.domain}";
extraDomainNames = [ "${cfg.domain}" ];
group = "acmerecievers"; group = "acmerecievers";
dnsProvider = lib.strings.toLower cfg.dns.provider; dnsProvider = lib.strings.toLower cfg.dns.provider;
credentialsFile = "/var/lib/cloudflare/Credentials.ini"; credentialsFile = "/var/lib/cloudflare/Credentials.ini";
}; };
"${cfg.domain}" = {
domain = cfg.domain;
group = "acmerecievers";
webroot = "/var/lib/acme/acme-challenge";
};
}; };
}; };
} }

View File

@ -74,13 +74,6 @@ in
# API options # # API options #
############### ###############
api = { api = {
enableSwagger = mkOption {
default = true;
description = ''
Enable Swagger UI
'';
type = types.bool;
};
skippedMigrations = mkOption { skippedMigrations = mkOption {
default = [ ]; default = [ ];
description = '' description = ''
@ -194,7 +187,7 @@ in
description = '' description = ''
Password authentication for SSH Password authentication for SSH
''; '';
default = true; default = false;
type = types.nullOr types.bool; type = types.nullOr types.bool;
}; };
}; };

View File

@ -16,7 +16,6 @@ in
hashedMasterPassword = lib.attrsets.attrByPath [ "hashedMasterPassword" ] null jsonData; hashedMasterPassword = lib.attrsets.attrByPath [ "hashedMasterPassword" ] null jsonData;
sshKeys = lib.attrsets.attrByPath [ "sshKeys" ] [ ] jsonData; sshKeys = lib.attrsets.attrByPath [ "sshKeys" ] [ ] jsonData;
api = { api = {
enableSwagger = lib.attrsets.attrByPath [ "api" "enableSwagger" ] false jsonData;
skippedMigrations = lib.attrsets.attrByPath [ "api" "skippedMigrations" ] [ ] jsonData; skippedMigrations = lib.attrsets.attrByPath [ "api" "skippedMigrations" ] [ ] jsonData;
}; };
dns = { dns = {

View File

@ -20,8 +20,7 @@ in
virtualHosts = { virtualHosts = {
"${domain}" = { "${domain}" = {
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem"; enableACME = true;
sslCertificateKey = "/var/lib/acme/${domain}/key.pem";
forceSSL = true; forceSSL = true;
extraConfig = '' extraConfig = ''
add_header Strict-Transport-Security $hsts_header; add_header Strict-Transport-Security $hsts_header;
@ -33,10 +32,15 @@ in
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict"; proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
expires 10m; expires 10m;
''; '';
locations = {
"/" = {
root = "/var/www/root";
};
};
}; };
"vpn.${domain}" = { "vpn.${domain}" = {
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem"; sslCertificate = "/var/lib/acme/wildcard-${domain}/fullchain.pem";
sslCertificateKey = "/var/lib/acme/${domain}/key.pem"; sslCertificateKey = "/var/lib/acme/wildcard-${domain}/key.pem";
forceSSL = true; forceSSL = true;
extraConfig = '' extraConfig = ''
add_header Strict-Transport-Security $hsts_header; add_header Strict-Transport-Security $hsts_header;
@ -50,8 +54,8 @@ in
''; '';
}; };
"git.${domain}" = { "git.${domain}" = {
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem"; sslCertificate = "/var/lib/acme/wildcard-${domain}/fullchain.pem";
sslCertificateKey = "/var/lib/acme/${domain}/key.pem"; sslCertificateKey = "/var/lib/acme/wildcard-${domain}/key.pem";
forceSSL = true; forceSSL = true;
extraConfig = '' extraConfig = ''
add_header Strict-Transport-Security $hsts_header; add_header Strict-Transport-Security $hsts_header;
@ -70,8 +74,8 @@ in
}; };
}; };
"cloud.${domain}" = { "cloud.${domain}" = {
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem"; sslCertificate = "/var/lib/acme/wildcard-${domain}/fullchain.pem";
sslCertificateKey = "/var/lib/acme/${domain}/key.pem"; sslCertificateKey = "/var/lib/acme/wildcard-${domain}/key.pem";
forceSSL = true; forceSSL = true;
extraConfig = '' extraConfig = ''
add_header Strict-Transport-Security $hsts_header; add_header Strict-Transport-Security $hsts_header;
@ -90,8 +94,8 @@ in
}; };
}; };
"password.${domain}" = { "password.${domain}" = {
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem"; sslCertificate = "/var/lib/acme/wildcard-${domain}/fullchain.pem";
sslCertificateKey = "/var/lib/acme/${domain}/key.pem"; sslCertificateKey = "/var/lib/acme/wildcard-${domain}/key.pem";
forceSSL = true; forceSSL = true;
extraConfig = '' extraConfig = ''
add_header Strict-Transport-Security $hsts_header; add_header Strict-Transport-Security $hsts_header;
@ -110,8 +114,8 @@ in
}; };
}; };
"api.${domain}" = { "api.${domain}" = {
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem"; sslCertificate = "/var/lib/acme/wildcard-${domain}/fullchain.pem";
sslCertificateKey = "/var/lib/acme/${domain}/key.pem"; sslCertificateKey = "/var/lib/acme/wildcard-${domain}/key.pem";
forceSSL = true; forceSSL = true;
extraConfig = '' extraConfig = ''
add_header Strict-Transport-Security $hsts_header; add_header Strict-Transport-Security $hsts_header;
@ -131,8 +135,8 @@ in
}; };
}; };
"social.${domain}" = { "social.${domain}" = {
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem"; sslCertificate = "/var/lib/acme/wildcard-${domain}/fullchain.pem";
sslCertificateKey = "/var/lib/acme/${domain}/key.pem"; sslCertificateKey = "/var/lib/acme/wildcard-${domain}/key.pem";
root = "/var/www/social.${domain}"; root = "/var/www/social.${domain}";
forceSSL = true; forceSSL = true;
extraConfig = '' extraConfig = ''
@ -152,10 +156,10 @@ in
}; };
}; };
"meet.${domain}" = { "meet.${domain}" = {
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem"; sslCertificate = "/var/lib/acme/wildcard-${domain}/fullchain.pem";
sslCertificateKey = "/var/lib/acme/${domain}/key.pem"; sslCertificateKey = "/var/lib/acme/wildcard-${domain}/key.pem";
forceSSL = true; forceSSL = true;
useACMEHost = domain; useACMEHost = "wildcard-${domain}";
enableACME = false; enableACME = false;
}; };
}; };