Compare commits
No commits in common. "main" and "mail-server" have entirely different histories.
main
...
mail-serve
8 changed files with 39 additions and 253 deletions
149
backup.nix
149
backup.nix
|
@ -1,149 +0,0 @@
|
||||||
{ 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,8 +5,6 @@
|
||||||
./heartles-xyz-proxy.nix
|
./heartles-xyz-proxy.nix
|
||||||
./ogdo.nix
|
./ogdo.nix
|
||||||
./postfix.nix
|
./postfix.nix
|
||||||
./nebula.nix
|
|
||||||
./backup.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
nix.settings = {
|
nix.settings = {
|
||||||
|
@ -43,7 +41,6 @@
|
||||||
less
|
less
|
||||||
killall
|
killall
|
||||||
screen
|
screen
|
||||||
inetutils
|
|
||||||
];
|
];
|
||||||
|
|
||||||
users.users.jaina = {
|
users.users.jaina = {
|
||||||
|
@ -57,7 +54,7 @@
|
||||||
matchConfig.Name = "enp1s0";
|
matchConfig.Name = "enp1s0";
|
||||||
networkConfig.DHCP = "ipv4";
|
networkConfig.DHCP = "ipv4";
|
||||||
address = [ "2a01:4ff:1f0:e4bd::/64" ];
|
address = [ "2a01:4ff:1f0:e4bd::/64" ];
|
||||||
routes = [{ Gateway = "fe80::1"; }];
|
routes = [{ routeConfig.Gateway = "fe80::1"; }];
|
||||||
};
|
};
|
||||||
networking.interfaces."enp1s0".useDHCP = true;
|
networking.interfaces."enp1s0".useDHCP = true;
|
||||||
|
|
||||||
|
|
14
flake.lock
generated
14
flake.lock
generated
|
@ -2,16 +2,16 @@
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1741445498,
|
"lastModified": 1719838683,
|
||||||
"narHash": "sha256-F5Em0iv/CxkN5mZ9hRn3vPknpoWdcdCyR0e4WklHwiE=",
|
"narHash": "sha256-Zw9rQjHz1ilNIimEXFeVa1ERNRBF8DoXDhLAZq5B4pE=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "52e3095f6d812b91b22fb7ad0bfc1ab416453634",
|
"rev": "d032c1a6dfad4eedec7e35e91986becc699d7d69",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"ref": "nixos-24.11",
|
"ref": "nixos-24.05",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
@ -24,11 +24,11 @@
|
||||||
},
|
},
|
||||||
"unstable": {
|
"unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1741379970,
|
"lastModified": 1719848872,
|
||||||
"narHash": "sha256-Wh7esNh7G24qYleLvgOSY/7HlDUzWaL/n4qzlBePpiw=",
|
"narHash": "sha256-H3+EC5cYuq+gQW8y0lSrrDZfH71LB4DAf+TDFyvwCNA=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "36fd87baa9083f34f7f5027900b62ee6d09b1f2f",
|
"rev": "00d80d13810dbfea8ab4ed1009b09100cca86ba8",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
|
||||||
unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
|
unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -142,17 +142,11 @@ 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."/" = {
|
||||||
|
@ -198,7 +192,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 pkgs.pnpm pkgs.cypress pkgs.pkg-config pkgs.vips ];
|
[ nodejs nodePackages.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
26
nebula.nix
|
@ -1,26 +0,0 @@
|
||||||
{ 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 = let
|
virtualHosts."xn--xx8a.run" = {
|
||||||
listen = [
|
listen = [
|
||||||
{
|
{
|
||||||
addr = "0.0.0.0";
|
addr = "0.0.0.0";
|
||||||
|
@ -15,21 +15,9 @@
|
||||||
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 = ''
|
||||||
|
@ -48,15 +36,21 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
"ogdo.run" = {
|
virtualHosts."ogdo.run" = {
|
||||||
inherit listen rejectSSL;
|
listen = [
|
||||||
locations."/".return = "301 http://xn--xx8a.run$request_uri";
|
{
|
||||||
};
|
addr = "0.0.0.0";
|
||||||
|
port = 80;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
port = 80;
|
||||||
|
addr = "[::]";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
"ꙮ.run" = {
|
rejectSSL = true;
|
||||||
inherit listen rejectSSL;
|
|
||||||
locations."/".return = "301 http://ogdo.run$request_uri";
|
locations."/".return = "301 http://xn--xx8a.run$request_uri";
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
26
postfix.nix
26
postfix.nix
|
@ -1,30 +1,6 @@
|
||||||
{ pkgs, config, ... }:
|
{ pkgs, config, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
# Prevent outgoing connections to email ports from users other than postfix
|
|
||||||
# unless the destination is localhost
|
|
||||||
networking.firewall.extraCommands = let
|
|
||||||
user = config.services.postfix.user;
|
|
||||||
makeRules = port:
|
|
||||||
let p = builtins.toString port;
|
|
||||||
in ''
|
|
||||||
iptables -A OUTPUT -m owner ! --uid-owner ${user} -m tcp -p tcp --dport ${p} -j REJECT --reject-with icmp-admin-prohibited
|
|
||||||
ip6tables -A OUTPUT -m owner ! --uid-owner ${user} -m tcp -p tcp --dport ${p} -j REJECT --reject-with icmp6-adm-prohibited
|
|
||||||
|
|
||||||
iptables -I OUTPUT -m tcp -p tcp --dport ${p} -d 127.0.0.1 -j ACCEPT
|
|
||||||
ip6tables -I OUTPUT -m tcp -p tcp --dport ${p} -d ::1 -j ACCEPT
|
|
||||||
'';
|
|
||||||
in builtins.concatStringsSep "\n"
|
|
||||||
(builtins.map makeRules [ 25 587 465 2525 ]);
|
|
||||||
# The following is necessary to prevent the above rules from being added at every nixos-rebuild switch.
|
|
||||||
# See link for more info
|
|
||||||
# https://github.com/NixOS/nixpkgs/issues/201614
|
|
||||||
# Flush the firewall rules
|
|
||||||
networking.firewall.extraStopCommands = ''
|
|
||||||
iptables -F
|
|
||||||
ip6tables -F
|
|
||||||
'';
|
|
||||||
|
|
||||||
services.postfix = {
|
services.postfix = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableSubmission = true;
|
enableSubmission = true;
|
||||||
|
@ -42,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},admin.${config.networking.fqdn}";
|
domains = "csl:${config.networking.fqdn}";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue