Compare commits
61 commits
mail-serve
...
main
Author | SHA1 | Date | |
---|---|---|---|
3c8b04f71c | |||
67a732d3f8 | |||
410be50be3 | |||
389c766505 | |||
26b20e9c5d | |||
ce6d1fe9f4 | |||
94a140223c | |||
b71910e379 | |||
78290f44cc | |||
386d136d3c | |||
dc250cadbb | |||
af2b0ae655 | |||
d6423db5a5 | |||
587271e42a | |||
a40cc82e7f | |||
99f329f82b | |||
791ae381bb | |||
4031ada385 | |||
ff765d3d2e | |||
2b4b5b9176 | |||
07eecce3f1 | |||
ca6cb3e9da | |||
d486bf3144 | |||
53b87fd40a | |||
0ebd6794d7 | |||
84e4d13ced | |||
c3e53a4c36 | |||
d734274b8a | |||
a112972009 | |||
4fac3bcb0c | |||
975199d535 | |||
87eaff16c4 | |||
374fb3a756 | |||
b814af9ac3 | |||
d5b92c037f | |||
037257b5e2 | |||
aa193bf423 | |||
9606a755d0 | |||
24094cad31 | |||
983f47440f | |||
3aff383a2c | |||
67c1f553fb | |||
652c1b5778 | |||
336b840fcd | |||
72a4be3c5d | |||
aff2d5ab64 | |||
6bb66f3e21 | |||
17aa3246df | |||
da6919a997 | |||
dd41dfb7d9 | |||
a0fb0388c8 | |||
e86c411aca | |||
1cb4864c7c | |||
096d89956e | |||
24b4fa2c8e | |||
13642fbbab | |||
cc26134518 | |||
7d6c9faba2 | |||
a055679544 | |||
dfc43c0ed4 | |||
316bd3e9a2 |
7 changed files with 225 additions and 36 deletions
149
backup.nix
Normal file
149
backup.nix
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
#necessary prep work:
|
||||||
|
# GRANT CONNECT ON DATABASE misskey TO "misskey-backup";
|
||||||
|
# GRANT SELECT ON ALL TABLES IN SCHEMA public TO "misskey-backup";
|
||||||
|
# GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO "misskey-backup";
|
||||||
|
#
|
||||||
|
# TODO: automate this cause it needs to be done whenever db schema changes
|
||||||
|
let
|
||||||
|
user = "misskey-backup";
|
||||||
|
group = user;
|
||||||
|
|
||||||
|
backupConfigFile = "/etc/misskey-backup/conf";
|
||||||
|
s3Cfg = "/etc/misskey-backup/s3cfg";
|
||||||
|
|
||||||
|
tarRedisStdoutCmd = pkgs.writeShellScript "backup-misskey-redis" ''
|
||||||
|
tar -cz -C /var/lib/redis-misskey .
|
||||||
|
'';
|
||||||
|
|
||||||
|
notifyEmailPkg = pkgs.writeShellApplication {
|
||||||
|
name = "notify-email";
|
||||||
|
|
||||||
|
runtimeInputs = [ pkgs.system-sendmail pkgs.coreutils ];
|
||||||
|
|
||||||
|
text = ''
|
||||||
|
from="noreply+$1@admin.egirls.gay"
|
||||||
|
subject="$2"
|
||||||
|
text="$3"
|
||||||
|
|
||||||
|
to="admin@heartles.xyz"
|
||||||
|
|
||||||
|
header="$(cat <<EOEMAIL
|
||||||
|
To: $to
|
||||||
|
From: $from
|
||||||
|
Subject: $subject
|
||||||
|
EOEMAIL
|
||||||
|
)"
|
||||||
|
|
||||||
|
email="$(cat <<EOEMAIL
|
||||||
|
$header
|
||||||
|
|
||||||
|
$text
|
||||||
|
|
||||||
|
EOEMAIL
|
||||||
|
)"
|
||||||
|
|
||||||
|
echo "Sending message:"
|
||||||
|
cat <<< "$header"
|
||||||
|
|
||||||
|
sendmail -f "$from" "$to" <<< "$email"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
users.users."${user}" = {
|
||||||
|
isSystemUser = true;
|
||||||
|
inherit group;
|
||||||
|
extraGroups = [ "misskey" "redis-misskey" "systemd-journal" ];
|
||||||
|
};
|
||||||
|
users.groups."${group}" = { };
|
||||||
|
services.postgresql.ensureUsers = [{ name = user; }];
|
||||||
|
|
||||||
|
systemd.services.misskey-backup = {
|
||||||
|
description = "Misskey backup";
|
||||||
|
|
||||||
|
restartIfChanged = false;
|
||||||
|
unitConfig.X-StopOnRemoval = false;
|
||||||
|
|
||||||
|
serviceConfig.User = user;
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
|
||||||
|
startAt = "weekly";
|
||||||
|
|
||||||
|
path = with pkgs; [
|
||||||
|
gzip
|
||||||
|
config.services.postgresql.package
|
||||||
|
s3cmd
|
||||||
|
coreutils
|
||||||
|
gnutar
|
||||||
|
age
|
||||||
|
];
|
||||||
|
|
||||||
|
script = ''
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
ageRecipient="age17ckyc69njpryytc63ynn545jswyucg28k5xg3043g3j6q38dxqwq0wzhm2"
|
||||||
|
bucket="$(grep 'bucket=' < "${backupConfigFile}" | sed 's/bucket \?= \?//g')"
|
||||||
|
prefix="$(grep 'prefix=' < "${backupConfigFile}" | sed 's/prefix \?= \?//g')"
|
||||||
|
|
||||||
|
s3Dir="s3://$bucket/$prefix""misskey-$(date +'%Y-%m-%dT%H.%M.%S')"
|
||||||
|
echo "Uploading backups to '$s3Dir'"
|
||||||
|
|
||||||
|
function upload () {
|
||||||
|
name="$1"
|
||||||
|
|
||||||
|
age -r "$ageRecipient" | s3cmd put --config "${s3Cfg}" - "$s3Dir/$name.age" --multipart-chunk-size-mb=100
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Uploading config"
|
||||||
|
tar -cz -C /srv/misskey/.config . | upload "config.tar.gz"
|
||||||
|
|
||||||
|
echo "Uploading redis database..."
|
||||||
|
/run/wrappers/bin/sudo ${tarRedisStdoutCmd} | upload "redis.tar.gz"
|
||||||
|
|
||||||
|
echo "Dumping postgres database..."
|
||||||
|
pg_dump misskey | gzip | upload "pg_dump.sql.gz"
|
||||||
|
|
||||||
|
echo "Backup complete to '$s3Dir'"
|
||||||
|
'';
|
||||||
|
|
||||||
|
serviceConfig.ExecStopPost = let
|
||||||
|
script = pkgs.writeShellScript "backup-notify" ''
|
||||||
|
invocationId="$(systemctl show --value -p InvocationID misskey-backup.service)"
|
||||||
|
logs="$(journalctl _SYSTEMD_INVOCATION_ID="$invocationId" -u misskey-backup.service)"
|
||||||
|
|
||||||
|
if [ "$SERVICE_RESULT" = "success" ]; then
|
||||||
|
${notifyEmailPkg}/bin/notify-email "backup" "SUCCESS: Misskey Backup Notification" "$(cat <<EOMSG
|
||||||
|
A backup process has succeeded. Logs to follow:
|
||||||
|
|
||||||
|
$logs
|
||||||
|
|
||||||
|
EOMSG
|
||||||
|
)"
|
||||||
|
else
|
||||||
|
${notifyEmailPkg}/bin/notify-email "backup" "FAILURE: Misskey Backup Notification" "$(cat <<EOMSG
|
||||||
|
A backup process has failed. Logs to follow:
|
||||||
|
|
||||||
|
$logs
|
||||||
|
|
||||||
|
EOMSG
|
||||||
|
)"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
in "${script}";
|
||||||
|
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
requires = [ "postgresql.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.timers.misskey-backup = { timerConfig.Persistent = true; };
|
||||||
|
|
||||||
|
security.sudo.extraRules = [{
|
||||||
|
groups = [ group ];
|
||||||
|
commands = [{
|
||||||
|
command = "${tarRedisStdoutCmd}";
|
||||||
|
options = [ "NOPASSWD" ];
|
||||||
|
}];
|
||||||
|
}];
|
||||||
|
}
|
|
@ -5,6 +5,8 @@
|
||||||
./heartles-xyz-proxy.nix
|
./heartles-xyz-proxy.nix
|
||||||
./ogdo.nix
|
./ogdo.nix
|
||||||
./postfix.nix
|
./postfix.nix
|
||||||
|
./nebula.nix
|
||||||
|
./backup.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
nix.settings = {
|
nix.settings = {
|
||||||
|
|
12
flake.lock
12
flake.lock
|
@ -2,11 +2,11 @@
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1719838683,
|
"lastModified": 1735563628,
|
||||||
"narHash": "sha256-Zw9rQjHz1ilNIimEXFeVa1ERNRBF8DoXDhLAZq5B4pE=",
|
"narHash": "sha256-OnSAY7XDSx7CtDoqNh8jwVwh4xNL/2HaJxGjryLWzX8=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "d032c1a6dfad4eedec7e35e91986becc699d7d69",
|
"rev": "b134951a4c9f3c995fd7be05f3243f8ecd65d798",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -24,11 +24,11 @@
|
||||||
},
|
},
|
||||||
"unstable": {
|
"unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1719848872,
|
"lastModified": 1735471104,
|
||||||
"narHash": "sha256-H3+EC5cYuq+gQW8y0lSrrDZfH71LB4DAf+TDFyvwCNA=",
|
"narHash": "sha256-0q9NGQySwDQc7RhAV2ukfnu7Gxa5/ybJ2ANT8DQrQrs=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "00d80d13810dbfea8ab4ed1009b09100cca86ba8",
|
"rev": "88195a94f390381c6afcdaa933c2f6ff93959cb4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
@ -142,11 +142,17 @@ in {
|
||||||
rewrite .* $path_full break;
|
rewrite .* $path_full break;
|
||||||
proxy_pass https://s3.us-west-1.wasabisys.com;
|
proxy_pass https://s3.us-west-1.wasabisys.com;
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
locations."/localfiles/" = {
|
||||||
|
root = "/srv/www";
|
||||||
|
tryFiles = "$uri =404";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
virtualHosts."egirls.gay" = {
|
virtualHosts."egirls.gay" = {
|
||||||
inherit listen;
|
inherit listen;
|
||||||
|
|
||||||
|
default = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
useACMEHost = "egirls.gay";
|
useACMEHost = "egirls.gay";
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
|
@ -192,7 +198,7 @@ in {
|
||||||
#
|
#
|
||||||
# pnpm2nix does not work due to misskey using workspaces
|
# pnpm2nix does not work due to misskey using workspaces
|
||||||
environment.systemPackages =
|
environment.systemPackages =
|
||||||
[ nodejs nodePackages.pnpm pkgs.cypress pkgs.pkg-config pkgs.vips ];
|
[ nodejs pkgs.pnpm pkgs.cypress pkgs.pkg-config pkgs.vips ];
|
||||||
environment.sessionVariables = {
|
environment.sessionVariables = {
|
||||||
CYPRESS_INSTALL_BINARY = "0";
|
CYPRESS_INSTALL_BINARY = "0";
|
||||||
CYPRESS_RUN_BINARY = "${pkgs.cypress}/bin/Cypress";
|
CYPRESS_RUN_BINARY = "${pkgs.cypress}/bin/Cypress";
|
||||||
|
|
26
nebula.nix
Normal file
26
nebula.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
environment.systemPackages = [ pkgs.nebula ];
|
||||||
|
services.nebula.networks.home = {
|
||||||
|
enable = true;
|
||||||
|
isLighthouse = true;
|
||||||
|
cert = "/var/lib/nebula/node.crt";
|
||||||
|
key = "/var/lib/nebula/node.key";
|
||||||
|
ca = "/var/lib/nebula/ca.crt";
|
||||||
|
|
||||||
|
firewall.inbound = [{
|
||||||
|
host = "any";
|
||||||
|
port = "any";
|
||||||
|
proto = "any";
|
||||||
|
}];
|
||||||
|
firewall.outbound = [{
|
||||||
|
host = "any";
|
||||||
|
port = "any";
|
||||||
|
proto = "any";
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [ 4242 ];
|
||||||
|
networking.firewall.allowedUDPPorts = [ 4242 ];
|
||||||
|
}
|
38
ogdo.nix
38
ogdo.nix
|
@ -4,7 +4,7 @@
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
# ꙮ.run
|
# ꙮ.run
|
||||||
virtualHosts."xn--xx8a.run" = {
|
virtualHosts = let
|
||||||
listen = [
|
listen = [
|
||||||
{
|
{
|
||||||
addr = "0.0.0.0";
|
addr = "0.0.0.0";
|
||||||
|
@ -15,9 +15,21 @@
|
||||||
addr = "[::]";
|
addr = "[::]";
|
||||||
}
|
}
|
||||||
# deliberately avoid listening with https
|
# deliberately avoid listening with https
|
||||||
|
{
|
||||||
|
addr = "0.0.0.0";
|
||||||
|
port = 443;
|
||||||
|
ssl = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
port = 443;
|
||||||
|
ssl = true;
|
||||||
|
addr = "[::]";
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
rejectSSL = true;
|
rejectSSL = true;
|
||||||
|
in {
|
||||||
|
"xn--xx8a.run" = {
|
||||||
|
inherit listen rejectSSL;
|
||||||
root = "/srv/ogdo";
|
root = "/srv/ogdo";
|
||||||
|
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
|
@ -36,21 +48,15 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
virtualHosts."ogdo.run" = {
|
"ogdo.run" = {
|
||||||
listen = [
|
inherit listen rejectSSL;
|
||||||
{
|
|
||||||
addr = "0.0.0.0";
|
|
||||||
port = 80;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
port = 80;
|
|
||||||
addr = "[::]";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
rejectSSL = true;
|
|
||||||
|
|
||||||
locations."/".return = "301 http://xn--xx8a.run$request_uri";
|
locations."/".return = "301 http://xn--xx8a.run$request_uri";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
"ꙮ.run" = {
|
||||||
|
inherit listen rejectSSL;
|
||||||
|
locations."/".return = "301 http://ogdo.run$request_uri";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,6 @@
|
||||||
enable = true;
|
enable = true;
|
||||||
selector = "default";
|
selector = "default";
|
||||||
socket = "inet:8891@127.0.0.1";
|
socket = "inet:8891@127.0.0.1";
|
||||||
domains = "csl:${config.networking.fqdn}";
|
domains = "csl:${config.networking.fqdn},admin.${config.networking.fqdn}";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue