1
0

Compare commits

..

14 Commits

Author SHA1 Message Date
f43eba0036 hosts/clerie-backup: Replicate backups with restic instead of borgbackup 2025-11-16 19:40:33 +01:00
971fb88d97 pkgs/clerie-backup: Support sftp backend for restic 2025-11-16 19:38:50 +01:00
1ab3ae3769 pkgs/clerie-ssh-known-hosts: Pin some more SSH host keys that can net be retrieved automatically 2025-11-16 16:05:57 +01:00
bc8d681956 pkgs/fem-ssh-known-hosts: Pin FeM ssh known hosts globally 2025-11-16 15:32:29 +01:00
fc4bc6ca41 pkgs/well-known-ssh-known-hosts: Pin some regularly used SSH host keys 2025-11-16 15:00:05 +01:00
f17a94c578 profiles/common-ssh: Migrate common SSH config to profile and pin SSH public hosts keys for net.clerie.de 2025-11-16 14:22:50 +01:00
2d9836f793 pkgs/clerie-ssh-known-hosts: Pin SSH host keys to FQDN only 2025-11-16 14:09:24 +01:00
0de7471ac0 profiles/hetzner-storage-box-client: Globally pin Hetzner Storage Box SSH public keys 2025-11-16 14:02:54 +01:00
db9ea1ea5c flake.lock: Update nixpkgs and lix 2025-11-08 12:40:53 +01:00
930be1c50c monitoring/targets.json: Add reichart.uber.space to monitoring 2025-11-06 20:54:52 +01:00
f3629c2653 profiles/ds-lite: Connect to Netcologne with PPP DS-Lite 2025-10-27 21:26:28 +01:00
44afbff445 hosts/carbon: Change DSL uplink to netcologne 2025-10-24 21:36:41 +02:00
92817fdcad hosts/clerie-backup: Export metrics for backup replication to Hetzner 2025-10-24 18:13:24 +02:00
e8cca7b1b6 pkgs/http.server: Add shortcut command for python3 http.server 2025-10-07 19:11:22 +02:00
34 changed files with 598 additions and 113 deletions

View File

@@ -8,7 +8,6 @@
./locale.nix
./networking.nix
./programs.nix
./ssh.nix
./systemd.nix
./user.nix
];

View File

@@ -1,16 +0,0 @@
{ lib, ... }:
{
services.openssh.enable = true;
services.openssh.settings = {
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
PermitRootLogin = lib.mkDefault "no";
};
services.openssh.hostKeys = lib.mkForce [
# Only create ed25519 host keys
{ type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; }
];
}

44
flake.lock generated
View File

@@ -269,11 +269,11 @@
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1751801455,
"narHash": "sha256-hUJqtS88SbNQQSEJAPFyY2vLMh8yA8rQ6jbul50p64M=",
"lastModified": 1759516991,
"narHash": "sha256-esoe/uYPyy4a6hAwZq1QgkSe7dnZ5c0zHHXDq/JG9Yk=",
"ref": "lix-2.93",
"rev": "b940aca430a7ca41f70bdb320659dd62026fe0e9",
"revCount": 4261,
"rev": "b1328322a49e8e153635ea8b3b602db363de727f",
"revCount": 4284,
"type": "git",
"url": "https://git.lix.systems/lix-project/hydra.git"
},
@@ -301,11 +301,11 @@
"pre-commit-hooks": "pre-commit-hooks"
},
"locked": {
"lastModified": 1751235704,
"narHash": "sha256-Jzm3KPZ2gL+0Nl3Mw/2E0B3vqDDi1Xt5+9VCXghUDZ8=",
"lastModified": 1757791921,
"narHash": "sha256-83qbJckLOLrAsKO88UI9N4QRatNEc3gUFtLMiAPwK0g=",
"ref": "release-2.93",
"rev": "f3a7bbe5f8d1a8504ddb6362d50106904523e440",
"revCount": 17874,
"rev": "b7c2f17e9133e8b85d41c58b52f9d4e3254f41da",
"revCount": 17892,
"type": "git",
"url": "https://git.lix.systems/lix-project/lix"
},
@@ -327,11 +327,11 @@
]
},
"locked": {
"lastModified": 1753282722,
"narHash": "sha256-KYMUrTV7H/RR5/HRnjV5R3rRIuBXMemyJzTLi50NFTs=",
"lastModified": 1756125859,
"narHash": "sha256-6a+PWILmqHCs9B5eIBLg6HSZ8jYweZpgOWO8FlyVwYI=",
"ref": "release-2.93",
"rev": "46a9e8fcfe4be72b4c7c8082ee11d2c42da1e873",
"revCount": 149,
"rev": "d3292125035b04df00d01549a26e948631fabe1e",
"revCount": 156,
"type": "git",
"url": "https://git.lix.systems/lix-project/nixos-module.git"
},
@@ -353,11 +353,11 @@
"pre-commit-hooks": "pre-commit-hooks_2"
},
"locked": {
"lastModified": 1753306924,
"narHash": "sha256-jLCEW0FvjFhC+c4RHzH+xbkSOxrnpFHnhjOw6sudhx0=",
"lastModified": 1759940703,
"narHash": "sha256-/dXDCzYnQbkqCsvUDIxgIH4BS/fyxIu73m2v4ftJLXQ=",
"ref": "release-2.93",
"rev": "1a4393d0aac31aba21f5737ede1b171e11336d77",
"revCount": 17884,
"rev": "75c03142049242a5687309e59e4f356fbc92789a",
"revCount": 17894,
"type": "git",
"url": "https://git.lix.systems/lix-project/lix.git"
},
@@ -634,11 +634,11 @@
},
"nixpkgs_3": {
"locked": {
"lastModified": 1751582995,
"narHash": "sha256-u7ubvtxdTnFPpV27AHpgoKn7qHuE7sgWgza/1oj5nzA=",
"lastModified": 1759281824,
"narHash": "sha256-FIBE1qXv9TKvSNwst6FumyHwCRH3BlWDpfsnqRDCll0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "7a732ed41ca0dd64b4b71b563ab9805a80a7d693",
"rev": "5b5be50345d4113d04ba58c444348849f5585b4a",
"type": "github"
},
"original": {
@@ -666,11 +666,11 @@
},
"nixpkgs_5": {
"locked": {
"lastModified": 1753549186,
"narHash": "sha256-Znl7rzuxKg/Mdm6AhimcKynM7V3YeNDIcLjBuoBcmNs=",
"lastModified": 1761114652,
"narHash": "sha256-f/QCJM/YhrV/lavyCVz8iU3rlZun6d+dAiC3H+CDle4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "17f6bd177404d6d43017595c5264756764444ab8",
"rev": "01f116e4df6a15f4ccdffb1bcd41096869fb385c",
"type": "github"
},
"original": {

View File

@@ -6,6 +6,7 @@
./hardware-configuration.nix
./dns.nix
./ds-lite-ncfttb.nix
./mdns.nix
./net-dsl.nix
./net-gastnetz.nix
@@ -16,7 +17,7 @@
./net-printer.nix
./net-voip.nix
./ntp.nix
./ppp.nix
./ppp-ncfttb.nix
./scan-to-gpg.nix
./wg-clerie.nix
];
@@ -39,7 +40,7 @@
networking.nat = {
enableIPv6 = true;
enable = true;
externalInterface = "ppp-dtagdsl";
externalInterface = "ppp-ncfttb";
internalIPv6s = [ "fd00:152:152::/48" "fd00:3214:9453:4920::/64"];
internalIPs = [ "10.152.0.0/16" "192.168.32.0/24" ];
};

View File

@@ -0,0 +1,18 @@
{ ... }:
{
profiles.clerie.ds-lite = {
enable = true;
wanInterfaceName = "ppp-ncfttb";
tunnelInterfaceName = "ds-lite-ncfttb";
lanInterfaces = [
{
name = "net-heimnetz";
sla_id = 201;
prefix_len = 64;
}
];
};
}

View File

@@ -3,17 +3,17 @@
{
## DSL-Uplink
networking.vlans."enp1s0.7" = {
id = 7;
networking.vlans."enp1s0.10" = {
id = 10;
interface = "enp1s0";
};
networking.vlans."enp3s0.7" = {
id = 7;
networking.vlans."enp3s0.10" = {
id = 10;
interface = "enp3s0";
};
networking.bridges."net-dsl".interfaces = [
"enp1s0.7"
"enp3s0.7"
"enp1s0.10"
"enp3s0.10"
];
}

View File

@@ -61,7 +61,7 @@
# net-gastnetz can only access internet
clerie.firewall.extraForwardFilterCommands = ''
ip46tables -A forward-filter -i net-gastnetz -o ppp-dtagdsl -j ACCEPT
ip46tables -A forward-filter -i net-gastnetz -o ppp-ncfttb -j ACCEPT
ip46tables -A forward-filter -i net-gastnetz -j DROP
ip46tables -A forward-filter -o net-gastnetz -j DROP
'';

View File

@@ -4,11 +4,11 @@
services.pppd = {
enable = true;
peers.dtagdsl = {
peers.ncfttb = {
config = ''
plugin pppoe.so net-dsl
user "''${PPPD_DTAGDSL_USERNAME}"
ifname ppp-dtagdsl
user "''${PPPD_NETCOLOGNE_USERNAME}"
ifname ppp-ncfttb
persist
maxfail 0
holdoff 5
@@ -24,9 +24,9 @@
};
};
environment.etc."ppp/peers/dtagdsl".enable = false;
environment.etc."ppp/peers/ncfttb".enable = false;
systemd.services."pppd-dtagdsl".serviceConfig = let
systemd.services."pppd-ncfttb".serviceConfig = let
preStart = ''
mkdir -p /etc/ppp/peers
@@ -34,22 +34,22 @@
umask u=rw,g=,o=
# Copy config and substitute username
rm -f /etc/ppp/peers/dtagdsl
${pkgs.envsubst}/bin/envsubst -i "${config.environment.etc."ppp/peers/dtagdsl".source}" > /etc/ppp/peers/dtagdsl
rm -f /etc/ppp/peers/ncfttb
${pkgs.envsubst}/bin/envsubst -i "${config.environment.etc."ppp/peers/ncfttb".source}" > /etc/ppp/peers/ncfttb
# Copy login secrets
rm -f /etc/ppp/pap-secrets
cat ${config.sops.secrets.pppd-dtagdsl-secrets.path} > /etc/ppp/pap-secrets
cat ${config.sops.secrets.pppd-ncfttb-secrets.path} > /etc/ppp/pap-secrets
rm -f /etc/ppp/chap-secrets
cat ${config.sops.secrets.pppd-dtagdsl-secrets.path} > /etc/ppp/chap-secrets
cat ${config.sops.secrets.pppd-ncfttb-secrets.path} > /etc/ppp/chap-secrets
'';
preStartFile = pkgs.writeShellApplication {
name = "pppd-dtagdsl-pre-start";
name = "pppd-ncfttb-pre-start";
text = preStart;
};
in {
EnvironmentFile = config.sops.secrets.pppd-dtagdsl-username.path;
EnvironmentFile = config.sops.secrets.pppd-ncfttb-username.path;
ExecStartPre = [
# "+" marks script to be executed without priviledge restrictions
"+${lib.getExe preStartFile}"

View File

@@ -1,21 +1,17 @@
{
"wg-monitoring": "ENC[AES256_GCM,data:+k5MgBrj/psMCE1T2jDtCCJI9Q7L+wJ3j83inNkeGp3LSUjoAPtBp4YoyL4=,iv:C19g/Lqi+cWAyiJBMNDtgLc3SDNI9bMBrBPWn+26mVY=,tag:9zIoawuGeGCMbOX1HKR/sQ==,type:str]",
"pppd-dtagdsl-username": "ENC[AES256_GCM,data:JC7EyyMoN0p5YwnS9W5I0G5Omhk5usw28UiJrCfifGr+2FUgMrtFYAHQdrtWAELvYNBQDPgrHMmQjGQLhpqqK0hH,iv:/q+Fm63GVBApGInyS8i39V/lo6iv+I2omVh47deq+o8=,tag:LkR+1zTDNWuYkhH2iWT7SA==,type:str]",
"pppd-dtagdsl-secrets": "ENC[AES256_GCM,data:c5pOb8It1py/9NXNTgLvt9zmsBVbSLHJt4iXWiNA+Osvomw3r7pgoO/JJh9ujomPMnOlDwN7g+pJ,iv:W36gA8E1mWchN6+8hdMdt2epv/RdS91T5ANB/JTcHCE=,tag:7eZ3fZkjERCVJCXYrABnlQ==,type:str]",
"pppd-ncfttb-username": "ENC[AES256_GCM,data:vyOCNm23xsD3Kj+R7zqnBjH4jEIfYpx/YUUGPcVzqMs9pnFEembahtFTl2sNzOFXLfYCYg==,iv:gMfi/6jldkXCnfdvhu5X1VKj58sVsPR8IX8iEECPfgk=,tag:PJGyIASP6RPAdVULEnn+Gg==,type:str]",
"pppd-ncfttb-secrets": "ENC[AES256_GCM,data:IEAguET78vdzRo47UvxbDdz+kKgYWVxYakPPu5rNAZ4BCui7DUG3qm2X9bBdHSMA,iv:Q8D58HXkCoVbqwFoYk+dizXNcEP1J63uMaDSNEzfg2g=,tag:R/xG3owmbVDOLM79sfBQjA==,type:str]",
"wg-clerie": "ENC[AES256_GCM,data:OEZg8ZoLAdVhKkvB0ai13ID3gPnVUU/xkOjZ4KiJ9MnRbcFu5HBd7Nw6iNwh,iv:edPuaehya2ZvYKkiBqNUbXVDAxAT6yNgETnWtd6it94=,tag:cX12szdQfAcC6cij6zk6Dw==,type:str]",
"sops": {
"kms": null,
"gcp_kms": null,
"azure_kv": null,
"hc_vault": null,
"age": [
{
"recipient": "age16mln27e2p58gu6dpxfclttmuzfnq39mv62kthjpps33g3nl3scfq449857",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3Rkd5WFE3aE5EQzY5ZXV4\nbXVGYmxTdVg1ekRpVjlRUnozY2tMTGloL21RCktjZW95OU9ZZ2owTCtMR1NxaXJn\na2VYS2ttb3VhSjNXOG84UUJtYU04QjAKLS0tIGd3aHM0RldFYnVFdDRVS0Vhc3BF\nckJhYmN6a1FJUC9ibks1cGlRaU1zbFkKE4ClunQ3XGAILwluC6iYFs+rlR02PdhK\njOmPbOlS0aNG0hoC7Z6aetgpj689AkJgl68QVcyvm+ecHH7TOT7l1A==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2024-08-13T14:06:43Z",
"mac": "ENC[AES256_GCM,data:yGKY0fi3KQWGHBeyNtQ8EJ6561dKRZ5aAjO9zq3odDtX75i2RSjORIlNjBsVvegBzeo8AkwwnzxNPt2sHl6MKDZfEsysWAi8Wolh4UvHk087AnR/uKvtG6t4uUaNIWej2DEzxUtTQ8QP1afsdqGCf0vZVruNcJ4u2xiQbN2vJPc=,iv:CDXJ5/P+h0Enq/0EL1su1Mw55FVYLy4XPSoUCkRkt+U=,tag:AvRfEDYMBunyIQIVCPbXag==,type:str]",
"lastmodified": "2025-10-24T19:16:49Z",
"mac": "ENC[AES256_GCM,data:ADhCQ7JxrEq+5ssevuuQVf3uyHcrcNVSzdT8bkFfDFVEE1hKv8q9QsGxhIaKtv4N2gt079fy0YA+WFKH6H8zWb5ONepH4H/mAek2SYgAtmVsxwdWY13zswsJUPi2CfbaCWOqppb9IiDb8+RCbzY2u/8Qqwk8gx/0uw2hr3IJrhM=,iv:c1/TS+W4pQgh2oPT77LX+dUL929YppRYdZCmMl2yN+M=,tag:fTk1sxdeT9xFjDMhqiHZAg==,type:str]",
"pgp": [
{
"created_at": "2024-05-10T13:05:56Z",
@@ -24,6 +20,6 @@
}
],
"unencrypted_suffix": "_unencrypted",
"version": "3.8.1"
"version": "3.10.2"
}
}

View File

@@ -5,6 +5,7 @@
[
./hardware-configuration.nix
./replication.nix
./restic-server.nix
];
@@ -36,25 +37,6 @@
};
};
# fix borgbackup primary grouping
users.users.borg.group = "borg";
services.borgbackup.jobs = {
backup-replication-hetzner = {
paths = [
"/mnt/clerie-backup"
];
doInit = true;
repo = "u275370-sub2@u275370.your-storagebox.de:./clerie-backup/" ;
encryption = {
mode = "none";
};
environment = { BORG_RSH = "ssh -p 23 -i /var/src/secrets/ssh/borg-backup-replication-hetzner"; };
compression = "auto,lzma";
startAt = "*-*-* 04:07:00";
};
};
clerie.monitoring = {
enable = true;
id = "204";

View File

@@ -0,0 +1,23 @@
{ lib, ... }:
with lib;
{
clerie.backup = {
enable = true;
targets = mkForce {
hetzner-storage-box = {
serverUrl = "sftp://u275370-sub2@u275370.your-storagebox.de:23";
sshKeyFile = "/var/src/secrets/ssh/borg-backup-replication-hetzner";
};
};
jobs.replication = {
paths = [
"/mnt/clerie-backup/cyan"
];
exclude = [
"/mnt/clerie-backup/cyan/.htpasswd"
];
};
};
}

View File

@@ -1,19 +1,16 @@
{
"clerie-backup-job-replication": "ENC[AES256_GCM,data:J9zWkW1xGUiK73M=,iv:0PCJW1qrOMlX0Twy2HXGmqFzyXknE4dVdpJnnEbW36U=,tag:yxIdsqMHZgHLUIN+JCcZ6A==,type:str]",
"restic-server-cyan-htpasswd": "ENC[AES256_GCM,data:Fe6lcXXy0Hu27Y2LtwQRbk+78+unSGkII144jtstOgK0pyjlJqG2mo8ZG7L+3mmthuu+leZ6XXadEcRGpby3eCwyVEYd3lDr930pPC8hChWYMC5mGkkRUAobYED63iVxcsc36PVFQYMCDbYvtcPk8uQTXfQmhs9kSzCrONrL1Id0L9D+sGoU0snpE+eCNXyiLwuyc1qocchhuHIwkGi4dyVJWgMsKGummF5Pf9zK4KzHmT6RuPouEUAfwHkdPwtOSJ8OqZof/C/CuPYmJQyfOFAqtw8xD9OXUpvyxjC1Kta89sL5cRAE0R15oPvNUmYGaXputm9iMycPjMacpouycx1TXMTEDB0caryX9uEFAyTfPm7keHT86qA1UfImWqEE9QqJ3uCeiwW698SbTZVeKLDBqDCPP+nP/L+N412d+HHyGugPOnTj1gXY50xeOay8Wryw87iDZ9rnJxcn0u5D4+JjOIbjWvydqBXacMD/o0NG2CcQu6LVRAHRiDKoSQWEwx25tzVwn2dsgFV8c3oQ0xQI7050R11Z3M9QWOvPmOZCvYV5VSoxu7r1jMu5asrcPbbhXKatbrabEHCAbDGsBpDkqts3BVUfUaHwboXVR0DxqOC6CHVE34J99SVTGI0kIHXyNqpeUJ36tCXFg7eNPNsu8cra9whjyUUHtw==,iv:Gfg3t3YPw2hz0LJ5hovPftMYOADN2Xjc93VmT2fFVQI=,tag:k6KH4qDPrFYIU2PGgW3F9Q==,type:str]",
"wg-monitoring": "ENC[AES256_GCM,data:rOpBlDt9K//zlgWo1Bw9IX5jmpLbnit5zi60Ulz8f6tHwqVsKJv5NkxYc9A=,iv:Jlo0QZP6R1CEE20iLa7M/LV/ZX2/33oMv/FzBBo6nvY=,tag:Ttqo7BKd6RuUiMksW6rZnw==,type:str]",
"sops": {
"kms": null,
"gcp_kms": null,
"azure_kv": null,
"hc_vault": null,
"age": [
{
"recipient": "age1px682xeu0xfkr49qdqe95er040p2vv3ugekk04e36jj2wqs7tyfs8mhclh",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0UCtUZ3NZQWxOK1FUNDhL\nbWhaanN2OEJIVmpMOURzWU1vcGhuODdtcDJnCm9Nb01NaVVpWDJ6Q3JCbXRkRUJP\nUVdFaGVScUdxRnlpSnRNOG1RalNRaFUKLS0tICs0cW1WR0JMUmdaVWVzdTh2bjFm\nenBzaERpb1hCS1E3TUo3cmxpZFUxWmcKcLL5/YTGyZEVLwHSpbEI5XfWGklkI7h+\n0uhCww8Wh23EpUYFslZ0Nnbf5HX5/Z34qBwf20cvN8eLToTAQvTdeg==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-02-16T18:13:34Z",
"mac": "ENC[AES256_GCM,data:io2WVxTxHSlxrk7JaN6/fUI7YotvPfgbXTD1lEf1tN7QhuGRH/iZrji/VQlhJ8tk2dAS1Pe0rsTuxCMXcXcxRIh4EYbQky5IZj5jpfPcslQOquTcXzmPYdijPUWSqu6leGc0GG/7KccjSFD8TfwAgeuVrc2Br57yfqKoPf+M0fY=,iv:iYp73PrFnLZoI9014mbqQQERhFtfhb5YmzV6HiUi+YM=,tag:2AZEzhVVdEos5FLkg8cr5w==,type:str]",
"lastmodified": "2025-11-16T16:13:47Z",
"mac": "ENC[AES256_GCM,data:ksW2wq/EWTi9dKppGhEheVQ74G6riy1asiDmdsC78bfeAJHTbXqlni5u11DIbo67sdpZE+xXJiB1woLEcG0B4wS92r5MIWhQrul+ot95UnwVFceYLkO4KLxgOjlJzgHKuWq/ccOoKnucd/vmagQ5E/4ubBXMOHvHVLL4dNYOsDo=,iv:unLO6F/b1mAIefWfvD0PW840pTWUULgwJSl6mh637q4=,tag:0dlOFTAmLZc7oXJ25SeH1A==,type:str]",
"pgp": [
{
"created_at": "2024-05-05T12:12:27Z",
@@ -22,6 +19,6 @@
}
],
"unencrypted_suffix": "_unencrypted",
"version": "3.8.1"
"version": "3.11.0"
}
}

View File

@@ -25,6 +25,7 @@
wireshark
tcpdump
nmap
pkgs."http.server"
kdePackages.okular
chromium-incognito

View File

@@ -60,16 +60,19 @@ let
config.sops.secrets."clerie-backup-job-${jobName}".path;
repoPath = if jobOptions.repoPath == null then "/${config.networking.hostName}/${jobName}" else jobOptions.repoPath;
targetPasswordFile = if targetOptions.passwordFile != null then targetOptions.passwordFile else
config.sops.secrets."clerie-backup-target-${targetName}".path;
config.sops.secrets."clerie-backup-target-${targetName}".path or null;
targetUsername = if targetOptions.username == null then config.networking.hostName else targetOptions.username;
in {
"clerie-backup/${jobName}-${targetName}/repo_password".source = jobPasswordFile;
"clerie-backup/${jobName}-${targetName}/repo_url".text = "${targetOptions.serverUrl}${repoPath}";
"clerie-backup/${jobName}-${targetName}/auth_username".text = targetUsername;
"clerie-backup/${jobName}-${targetName}/auth_password".source = targetPasswordFile;
"clerie-backup/${jobName}-${targetName}/files".text = concatStringsSep "\n" jobOptions.paths;
"clerie-backup/${jobName}-${targetName}/excludes".text = concatStringsSep "\n" jobOptions.exclude;
}
} // (if targetPasswordFile == null then {} else {
"clerie-backup/${jobName}-${targetName}/auth_password".source = targetPasswordFile;
}) // (if targetOptions.sshKeyFile == null then {} else {
"clerie-backup/${jobName}-${targetName}/ssh_key".source = targetOptions.sshKeyFile;
})
) jobTargetPairs);
targetOptions = { ... }: {
@@ -85,6 +88,10 @@ let
serverUrl = mkOption {
type = types.str;
};
sshKeyFile = mkOption {
type = with types; nullOr str;
default = null;
};
};
};

View File

@@ -48,5 +48,8 @@
},
"cleriewi.uber.space": {
"clerie-uberspace": { "enable": true }
},
"reichart.uber.space": {
"clerie-uberspace": { "enable": true }
}
}

View File

@@ -45,30 +45,39 @@ if [[ ! -f "${CONFIG_DIR}/auth_username" ]]; then
echo "File ${CONFIG_DIR}/auth_username not found"
ISSUE_EXIST=1
fi
if [[ ! -f "${CONFIG_DIR}/auth_password" ]]; then
echo "File ${CONFIG_DIR}/auth_password not found"
ISSUE_EXIST=1
fi
if [[ -n "${ISSUE_EXIST}" ]]; then
exit 1
fi
RESTIC_PASSWORD_FILE="${CONFIG_DIR}/repo_password"
export RESTIC_PASSWORD_FILE
RESTIC_REPOSITORY="rest:$(cat "${CONFIG_DIR}/repo_url")"
REPO_URL="$(cat "${CONFIG_DIR}/repo_url")"
if [[ "${REPO_URL}" == http* ]]; then
RESTIC_REPOSITORY="rest:${REPO_URL}"
else
RESTIC_REPOSITORY="${REPO_URL}"
fi
export RESTIC_REPOSITORY
RESTIC_REST_USERNAME="$(cat "${CONFIG_DIR}/auth_username")"
export RESTIC_REST_USERNAME
RESTIC_REST_PASSWORD="$(cat "${CONFIG_DIR}/auth_password")"
export RESTIC_REST_PASSWORD
if [[ -e "${CONFIG_DIR}/auth_password" ]]; then
RESTIC_REST_PASSWORD="$(cat "${CONFIG_DIR}/auth_password")"
export RESTIC_REST_PASSWORD
fi
RESTIC_PROGRESS_FPS="0.1"
export RESTIC_PROGRESS_FPS
RESTIC_CACHE_DIR="/var/cache/restic"
export RESTIC_CACHE_DIR
EXTRA_OPTIONS=()
if [[ -e "${CONFIG_DIR}/ssh_key" ]]; then
EXTRA_OPTIONS+=("-o" "sftp.args='-o IdentityFile=${CONFIG_DIR}/ssh_key'")
fi
case "${ACTION}" in
restic)
restic "$@"
restic "${EXTRA_OPTIONS[@]}" "$@"
;;
backup)
ISSUE_EXIST=
@@ -84,9 +93,9 @@ backup)
exit 1
fi
restic snapshots --latest 1 || restic init
restic "${EXTRA_OPTIONS[@]}" snapshots --latest 1 || restic "${EXTRA_OPTIONS[@]}" init
restic backup --exclude-file "${CONFIG_DIR}/excludes" --files-from "${CONFIG_DIR}/files"
restic "${EXTRA_OPTIONS[@]}" backup --exclude-file "${CONFIG_DIR}/excludes" --files-from "${CONFIG_DIR}/files"
;;
*)
echo "Unsupported ACTION: ${ACTION}"

View File

@@ -0,0 +1,10 @@
backup.clerie.de ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBsTlqDyK726hwhX8lbs9EhMrkf3LsKIm5Ya3k39C7VZ
git.clerie.de ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHQDwfRlw6L+pkLjXDgW2BUWlY1zNEDtVhNEsClgqaL
mercury.net.clerie.de ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH4HbnxUyBAxidh88rIvG9tf61/VWjndMLOSvx9LZY+u
clerie.uber.space ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINT6gukzAjyu8ST6ndP5TgXWEfdksxyqmMz4ngQkyVLr
cleriewi.uber.space ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3k7sMhABfQr9CufavOY6BCXJPpDH5OFkRpz/vJ2gSF
ceea.uber.space ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJg2Vr3/SucAM13pZGR36W/LPFcTI9nCQAIIATIZGL9A
reichart.uber.space ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINhafJF7TZPAhX1hj4saom21RqkOMVFF7bLVKaEC+vcB

View File

@@ -10,7 +10,6 @@ let
sshPubkey = stripR (builtins.readFile (../../hosts + "/${hostname}/ssh.pub"));
}) hostsWithSshPubkey;
knownHosts = builtins.concatStringsSep "" (builtins.map ({name, sshPubkey}: ''
${name} ${sshPubkey}
${name}.net.clerie.de ${sshPubkey}
'') sshkeyList);
in writeTextFile {
@@ -18,5 +17,9 @@ in writeTextFile {
destination = "/known_hosts";
allowSubstitutes = true;
preferLocalBuild = false;
text = knownHosts;
text = ''
${knownHosts}
${builtins.readFile ./additional-ssh-known-hosts}
'';
}

View File

@@ -0,0 +1,12 @@
{ pkgs, ... }:
pkgs.writeShellApplication {
name = "ds-lite-dhcpcd-hook";
text = builtins.readFile ./ds-lite-dhcpcd-hook.sh;
runtimeInputs = with pkgs; [
iproute2
jq
dig
gawk
];
}

View File

@@ -0,0 +1,102 @@
#!/usr/bin/env bash
set -euo pipefail
# Setting up required environment variables
# shellcheck disable=SC2154
WAN_INTERFACE_NAME="${DS_LITE_WAN_INTERFACE_NAME}"
# shellcheck disable=SC2154
TUNNEL_INTERFACE_NAME="${DS_LITE_TUNNEL_INTERFACE_NAME}"
log_dhcp () {
echo "<ds-lite-dhcpcd-hook> ${WAN_INTERFACE_NAME}: $1"
}
log_tunnel () {
echo "<ds-lite-dhcpcd-hook> ${WAN_INTERFACE_NAME} (${TUNNEL_INTERFACE_NAME}): $1"
}
# Check if the event calling this hook is for the wan interface
# exit immediately if not
# shellcheck disable=SC2154
if [[ "$interface" != "$WAN_INTERFACE_NAME" ]]; then
exit
fi
# Make sure the event calling this hook carries the environment variable
# in question. The environment variable is not provided with every call
# and we just want to exit if it is not provided
# shellcheck disable=SC2154
if [[ ! -v new_dhcp6_aftr_name ]]; then
# Variable is not set
exit
fi
# shellcheck disable=SC2154
if [[ -z "${new_dhcp6_aftr_name}" ]]; then
# Variable is empty, can't do anything
exit
fi
# shellcheck disable=SC2154
AFTR_NAME="$new_dhcp6_aftr_name"
log_dhcp "Received new AFTR_NAME ${AFTR_NAME}"
# Make sure we have a nameserver to resolve aftr name against
# shellcheck disable=SC2154
if [[ ! -v new_dhcp6_name_servers ]]; then
# Variable is not set
exit
fi
# shellcheck disable=SC2154
if [[ -z "${new_dhcp6_name_servers}" ]]; then
# Variable is empty, can't do anything
exit
fi
# shellcheck disable=SC2154
NAME_SERVERS="$new_dhcp6_name_servers"
log_dhcp "Received new NAME_SERVERS ${NAME_SERVERS}"
# Select first nameserver
NAME_SERVER="$(echo "${NAME_SERVERS}" | awk '{print $1;}')"
log_dhcp "Selected NAME_SERVER ${NAME_SERVER}"
# Figure out a usable IPv6 address on the wan interface, to origin our DNS requests and tunnel
WAN_INTERFACE_ADDRESS="$(ip --json address show "${WAN_INTERFACE_NAME}" | jq -r '.[0].addr_info[] | select(.family == "inet6" and .scope == "global" and .mngtmpaddr == true) | .local')"
log_dhcp "Using WAN_INTERFACE_ADDRESS ${WAN_INTERFACE_ADDRESS}"
AFTR_ADDRESS="$(dig "@${NAME_SERVER}" -b "${WAN_INTERFACE_ADDRESS}" AAAA "${AFTR_NAME}" +short | head -1)"
log_dhcp "Resolved AFTR_NAME ${AFTR_NAME} to ${AFTR_ADDRESS}"
# Check if there is already a tunnel interface
if TUNNEL_INTERFACE_CONFIG="$(ip --json link show "${TUNNEL_INTERFACE_NAME}")"; then
TUNNEL_INTERFACE_OPERSTATE="$(echo "${TUNNEL_INTERFACE_CONFIG}" | jq -r '.[0].operstate')"
TUNNEL_INTERFACE_ORIGIN_ADDRESS="$(echo "${TUNNEL_INTERFACE_CONFIG}" | jq -r '.[0].address')"
TUNNEL_INTERFACE_REMOTE_ADDRESS="$(echo "${TUNNEL_INTERFACE_CONFIG}" | jq -r '.[0].broadcast')"
# Reconfigure tunnel interface, if not already in state we want
if [[ "${TUNNEL_INTERFACE_ORIGIN_ADDRESS}" != "${WAN_INTERFACE_ADDRESS}" || "${TUNNEL_INTERFACE_REMOTE_ADDRESS}" != "${AFTR_ADDRESS}" || "${TUNNEL_INTERFACE_OPERSTATE}" != "UNKNOWN" ]]; then
log_tunnel "Bad configuration, fixing tunnel parameter"
ip tunnel change "${TUNNEL_INTERFACE_NAME}" mode ipip6 local "${WAN_INTERFACE_ADDRESS}" remote "${AFTR_ADDRESS}"
ip link set "$TUNNEL_INTERFACE_NAME" up
else
log_tunnel "Tunnel already configured"
fi
else
log_tunnel "Setting up DS-Lite tunnel"
ip tunnel add "${TUNNEL_INTERFACE_NAME}" mode ipip6 local "${WAN_INTERFACE_ADDRESS}" remote "${AFTR_ADDRESS}"
ip link set "$TUNNEL_INTERFACE_NAME" up
fi
log_tunnel "Setting default route"
ip route replace default dev "${TUNNEL_INTERFACE_NAME}"
log_tunnel "Tunnel setup finished"

View File

@@ -0,0 +1,6 @@
{ runCommand, ... }:
runCommand "fem-ssh-known-hosts" {} ''
mkdir -p $out
cp ${./fem-ssh-known-hosts} $out/known_hosts
''

View File

@@ -0,0 +1,47 @@
# FeM FeM SSH Known Hosts
# Gitlab
gitlab.fem-net.de ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH7jb0VQpEJD+Xf9Odb0ROK9BWvm1bI0JW92zVOewnSO
# Jumphost Mgmt-VLAN
grumpy.fem.tu-ilmenau.de ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCQ/8cqTuuAY2YaC0nLX9RexBeMbXEhvczpTSmzYqob3ke4NAUnVFRU/vnCQQDHG3sNtpEErKlE2/MyyGrqSssI=
# Webhosting
web-1.fem.tu-ilmenau.de ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBO1ErxOUxu501CDKZokoLzky4e0LGm+wsrOhWfG1iq1vRkHf+nANMzR0XwTdUOZBJ2NnU2ReorGVzdBzEP3YDOo=
web-1.fem.tu-ilmenau.de ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICH2vZqsv/5w2PKFccBZUmkBQDHNJmkwGTu0kIC1t146
# FeM Office
officevm.fem.tu-ilmenau.de ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBhquVgaKqQC3OaYW6kXpPOhkoLptTTeuWf5P43XaWszzCt6Wyu4gXcp/+6vLUE/QubiMoqBzBBsibsLjRQWxrk=
# Xen Virt oberer Campus
[chrom.net.fem.tu-ilmenau.de]:1022 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMAM+QrJTssQZJ3hJUHtjxUd0jBRMyWzPr/dCJ/X9Nyx+xfklyIw301aDKnbdLp3kKDJB5/oj1Zc2f9HsP9yO1w=
[chrom.net.fem.tu-ilmenau.de]:1022 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC8SGRtJw7crcNS2+gmD3Qel/oKkaY/ZFa+72mHe7TDveUBfgi6dWM0BW4Se3uIqxEStlbYoE/GxVA8SnmTUJx2xyqC43gGT8uYdKZBF3rZ2d6U39jTH7aKkuO96DDMj+0oKnMK22MRWLCdIwyrrY3sWXsedc0aC0nTsO8D3LIiQHYQ1C4eCyYt7qntc7jU+5T5/HkWwCouyMajHZyDMpyzWD35mt0pSdOaqtbKnplYTLSEQ3xQ2CFFplaPe3ZafR8J0sdxpHogrXnKcIkpsm2qNInzF/gX7vUFWNCdmvBmwbz5ThFaE8Rlw6W8jO741Zgxp6RLdTpBk9KxsbG9oKWlBaZ5rqkrWvHLjLDOINFhlqeTJrjmqBmaDGBzc/JDAG96wUtkWzbRluyFD+j9MKcCb5T2VB3AMDAQ4WA6ykPWvekmiAADjg0sxiNZ8q/JkxbW0H9zMNNLpxfoVxS5DLIQk7Ee8tuJNJ9h4DSHl3pb0zwugblvI0wPCDtTUnrB5d0=
[chrom.net.fem.tu-ilmenau.de]:1022 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOePZRlNv7ZeOhX6kwNjT1dIm3n91Vn19pUtERupHPvQ
[flavino.net.fem.tu-ilmenau.de]:1022 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAOhhOUnBBoozLULy/Q2VAoXD1/dlruEYFKlCJLPBZ87
[flavino.net.fem.tu-ilmenau.de]:1022 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDnhmna9iIWp74LfvkdesvaGidMC2Uadz0w3hYGdu88tpQrc7CE21Vp+/8koSSubE6nGYV5JuZAL5mHW8xjq87POSkX2El6V0AyCWOofarmIciWDdlxszMxmk/rJnW8s/noZpUQWP2s9AGy7NqCHnzcxrNLCeQkAMdJw5KwKJ6dPNc8H3/FwdYgYipOb/WOZQrTn3MZEA9h6vPm/MN+zfzl4hKBSzmt9qSL546PiREgVkk/cIrAq6xDilSGHjGT+EiIC8p+0QsiLdhvD4bnn4fHisVzypY9BXAeF9DE0RivUEkP9HwuH61dwQKT90UPiifg0LFSPegd+vM/WwuZghPz
[flavino.net.fem.tu-ilmenau.de]:1022 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJFZGrjTt9YiErgspJsEgA8uYse7OyD9EeTa8FvGNZJyALbQIVp5LW4XLsUmFcl3utx4wJD4VaCf62T9ocq1odY=
[flavino.fem.tu-ilmenau.de]:1022 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAOhhOUnBBoozLULy/Q2VAoXD1/dlruEYFKlCJLPBZ87
# pgsql-2 database cluster
pgsql-2-node-1.net.fem.tu-ilmenau.de ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICd/uXtoDNL4YIh1hF8z95dJ9p9at6dilrSkuuiL8Mz+
pgsql-2-node-1.net.fem.tu-ilmenau.de ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCyYxSGd+/eO5gzQDvzJQzt66Lw12XuTrnZwQxfoK4ziiy20uVj+3Jv+6vX9HmqVpFPmdj0HZX9b8K6SzAF32e6AvZo8cShG9K1S8nefJHAeRXf7st/tGf5BUd5J2tfGOs7187dabofcsEGlqy7qxPQz/DXoR9jjZeiVfVhTXURWSEDOwkuS19yYkMd6HDng3ptk3eIM0XBZBXiMty+kt/elLf5tbLOgaEkP73qefHCGjE2qnErRg5yfYSKD+tjSZoVHM2wjpyy+jW1zvo0GGwhmA58GN5/J4EiHTEi7FIF/IwopjvCQ3YU6i/XqmgbYPLJRXDRLJNgfJITueTovHHHgwcm6Vg8bOnO0p/+syrZFw015CeucY0rhbjw0tmEMLgxgdLuztlWwop0RmwIjzbUs2w7Dg7T8J/bshOQgpzGHE6eLcp1ptu5lIz0xH0ltiiLCV5Lx1MKZakZKhLCvnHkfF9fMMH1F2U2NOnBej0RnappWmbYv2W4fY6EhK5cu1Wreh1XCrhbOXp9CVfcaqt238lTNx2qtJrL6X7dNLloIeEDQ/zzCI0bea8okelOO7R0/LBVnqGN5zUAdJL+5B0a25UZF+fudnwuqwwjA8TCqTFDvPTm4/jWrCMbpHaICT/+w/53rKn8UOHfSF2u+4HEPAbL5X0HC97d2SwLZs001w==
pgsql-2-node-2.net.fem.tu-ilmenau.de ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPmr+R1DBuIDrV4WfUsBQJ7KmkLY5DLFJyDJjfWBU2Vx
pgsql-2-node-2.net.fem.tu-ilmenau.de ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDNg8/SXPdAKkYaqc0N+MoJcikAi3u3hxPiDNHOKGvvf7NtnoWg36y89KQAm3Qv7jZ++WOgUZzGeG8uQDibRQKZheAPbVC6lSnlV5gXLxfm6KpEyJKqGHzj8PW+gldPVB/EuLJSMncfmSPnD660COdyaNztvI8LSyWoWnL5bPb8rcCJaFydfO/yf8jvGrJHf7rKBTb21w8jsqhIGev55PrIqZZCR2UuyoLyqEAVD0oSGAvVFwrWp2il2ufZvy4Qq809KGDjbNoDQMIcAOek0PWVjrSF0k9/qHB3XJoaqwki4kwNKLL8vwgr/3RM2EiWtSObh+1xdLWFbt4QA8Cjq5UAquCwG36vx43rR2TY77ldJ2VAY+SAwxn3JGBzCPOASp7LaRtHL6VVqHxA7Zi6yOGIH39dXeSPK/UzXMF6dOcQqx7hFB8Zgl8En9mNNjVAoneJ4Hr45CO0e3/Adv6zBEsXtkmbb/1TyUoOdli/ZQM9++AzB+T9hO7D2/CzUL8IU6Qid+Dqo90IqvhC8S3HDUQvGXkVSh6cLd0wSI7LtSUVs/ypd8gGiOGtlyDo/d85gl7fZA4bIaQ0ohJtDAtGbwVowk0ZQfUfHSJIZqZdNEPWy5ooGWJRlVVCenBXvAu1Bx3QPccY/O/NoB2Hyr4aooh/YEpkFFPyqo5G/KoMdJ5qEQ==
pgsql-2-node-3.net.fem.tu-ilmenau.de ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICsJOfaJut0w+Aey4HSjlFDWRp5z2rBRYh0yhwZG8ORK
pgsql-2-node-3.net.fem.tu-ilmenau.de ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCswxmPwXiboy03LltFgoGW2/AMm+wM37nwLI/2dtdkCaICn95krMo3JTKNdq810UiaB0UUp5/FB090Lye1GmSWTHy8/vbEhW9bmf0+V9olvum3k4BT/mKRhvfpkTRlslDlRYgFMOhYuFpBZOn3h0iUJg2MwWWY8Ce6KymzUwwfOsSTDDiPY6Tcdt0OML6fRvUxCe9EOD82FO+PuAO44uoEC84YT3qNufzt4/O/Xy71lIiTFyEv2isJJ3MWFTyLnAg+KT18ztzYvCBAa9AXXsZpE/M/hh0tcKdUqNw2gscgLkELA0olQbi4rGYAkKEcn/QIRPRrKTx3I43vDBiZZkQXeTLnvtJjcK38W6rcqJ9B5tFyAWzpBh767Yr0BbgfkgOJ4EcZhFuH5Y2uCZnFB6HlwehhQq0vGgE04zzGsW3ODIdiE15aoHBl9vrDXKr84hmZ8+/FU8+ds3IOSoQgK8ZXMB/Bat9MmNLcdzwpxRgeZIHl0w1Z6OPOm5qAPSAR5PtqLo69nhb3cc/VoK9S41e5zeBx7o8eYcPkKUeWNI+wV5aw3fbzk5RQQX4YImFaYVqYJw+NxkKQns3Wcr1+TbpX/mYY2uobZHvMzdqbhheBMyKS6vIhxcZEUc0+1qgjqrgp7TkXU/kXN9huULeZ3OQNJkuEPm7OWTcZElJohokflQ==
# Video Storage
[video-storage.fem.tu-ilmenau.de]:1022 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ6J6Mn14zjBoAJyiaLg+76x6eedM/NUrKcpMltP6DwY
[video-storage.fem.tu-ilmenau.de]:1022 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMvUAbPLQrDJYgL2wCvNrxdgZU65J0dU9vCwIwGYVXRvKv9S9RyDuDZvWLTZl26KIrVy94pnlySK0Zi2wJ6oOtg=
# NixOS build server
fuedra.fem.tu-ilmenau.de ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILvofCx3KMN+A0G58akpp1BMsmY6731YrYBWntEC9LQ1
fuedra.fem.tu-ilmenau.de ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC9eiienHWTqncnsI0Ttnkb68rCwnublqU8rki/JmCZ8Yl2+QP8bOYvqRIf3Pq+4WTYCxmzOCaaHJRzYCB1wiohdxsmxj0qNgMfyzmY6rf38Cjby0QpBEq31sHc+4oeKKGqFiM5mdBq/69DKs0aY8hob0Iy1dqwjMfDNcRXz08Uzq7S08YNXB0nkuMFaS7WYj+m0aX8SPanu0G7+OKzjzXfRWJlWUrAoj1flV723SyCGTRXdugsBjxpuudwoo17UNDZw7J7w63WqiUW4LfktB8mu+UaLbUzR2YK3IQLrEq42k9IB1LBknS8gKKd0FX56nJKCN0HrgbjSQZlw1x1S5wxfxbaSfOpZUblk+4PNSmpv/ca4S/Hdq7UlNrq2lJnoXj1nd+qrKGZ96or0dxYIHP1qH3WkExO8ywEkoazOG7khFqxddLzPMdhrhp93EHN9QEKgpSpm2YbP416I64Pu77+DtCCXS8ywnl9rf4JO8Kr1v4JdiG34yL14mvq4saI1f4X+bCWuotf45cRezqlB5WVz/2FywYQKHj6wFMM4ew+6beSgFx/0TUdkDQYZPKp6xmb7A5wxdhZ9nZfYa3p0neJTDe1gTpin3xs9Byexoe/jEtiWBwZ+3SvZ9z1DK4QnHaa7FiGa8KxQwEiUUfs45GjxnpT9J0b3wgaJTlbDZNTMQ==
# fem.social
mastodon.fem.tu-ilmenau.de ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMzI1QoVPrwaJnbwA5PmmtGsiKBhV4ZO/q8Vb07r8I1w
mastodon.fem.tu-ilmenau.de ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDXMGscT9g55wT/rzkNzO8ScOh9Kw049Fu9ocAWvkDauiVJPtLE+7C16JQyzHKeMcuXCRpgv6g4BJQhPYoD1C4Gq7zjiYvIyiAFLcqvdK4ROhiJw5vxYvcEUNLTmydcsaS/GWOIRzLeZo1DOsDG/jiMcmVq2hRUc32QJroMci5fSvNC+6lNjxomZE/gnwATdjV0TTgIaQy0EkgSn7vyD3qpNSax0StPCLIFxPSy1fP3IQmYIsObiaSlcvdVH4bE0DUPe1gzIufTGEINVdlUl5847cIr+ZGOSaS0SP8fP7qXYqrwFt83ROspTr9UnyhmJayqIODu2RMpvrhHITlm5Lo5wazw2GLormWxVmhtDIqypKOUG93hdZ8a55x1Z7nnfS6cnPoZA5QwY02zjKaAvDkw1NN7Ud/LCfv/Vpu+EwsNJSoxSK6yx7k6X2qd99KTVzDm9AkXlzzOYZhAOQSskp5mOfb82mCFk/YImoDQ7tVcy9PLnxhcQ2b/OY/akobjYhitlmPENAY/KhrqE26lwmzA5V0jEi5SqJXYNQcTktNPUDBCc0maS8azroDmom5dlozPTLcR/9+/BgzR1cEtiyqajJFkuKUSkwA3x9D07wJSquu5CDO+Wf5U15k60cBRICxlh5n0w19sybZn9jffPg5v7IPBa6hhKdFynHyec1/M3w==
# FeM XMPP
xmpp-2.fem.tu-ilmenau.de ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPMfNNj/nEYDeF8I7ds/yyQ+fJ+2AGZkGFNh3y3ZUReW
xmpp-2.fem-net.de ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPMfNNj/nEYDeF8I7ds/yyQ+fJ+2AGZkGFNh3y3ZUReW

View File

@@ -0,0 +1,14 @@
{
python3,
writeShellApplication,
}:
writeShellApplication {
name = "http.server";
text = ''
python3 -m http.server "$@"
'';
runtimeInputs = [
python3
];
}

View File

@@ -14,14 +14,17 @@ final: prev: {
chromium-incognito = final.callPackage ./chromium-incognito {};
convert-flac-dir-to-mp3 = final.callPackage ./convert-flac-dir-to-mp3 {};
curl-timings = final.callPackage ./curl-timings {};
ds-lite-dhcpcd-hook = final.callPackage ./ds-lite-dhcpcd-hook {};
factorio-launcher = final.callPackage ./factorio-launcher {};
feeds-dir = final.callPackage ./feeds-dir {};
fem-ssh-known-hosts = final.callPackage ./fem-ssh-known-hosts {};
generate-blocked-prefixes = final.callPackage ./generate-blocked-prefixes {};
git-checkout-github-pr = final.callPackage ./git-checkout-github-pr {};
git-diff-word = final.callPackage ./git-diff-word {};
git-pp = final.callPackage ./git-pp {};
git-show-link = final.callPackage ./git-show-link {};
grow-last-partition-and-filesystem = final.callPackage ./grow-last-partition-and-filesystem {};
"http.server" = final.callPackage ./http.server {};
nix-remove-result-links = final.callPackage ./nix-remove-result-links {};
nixfiles-auto-install = final.callPackage ./nixfiles/nixfiles-auto-install.nix {};
nixfiles-generate-config = final.callPackage ./nixfiles/nixfiles-generate-config.nix {};
@@ -33,4 +36,5 @@ final: prev: {
ssh-gpg = final.callPackage ./ssh-gpg {};
update-from-hydra = final.callPackage ./update-from-hydra {};
uptimestatus = final.python3.pkgs.callPackage ./uptimestatus {};
well-known-ssh-known-hosts = final.callPackage ./well-known-ssh-known-hosts {};
}

View File

@@ -0,0 +1,20 @@
final: prev:
prev.dhcpcd.overrideAttrs (finalAttrs: prevAttrs: {
configureFlags = [
"--sysconfdir=/etc/ds-lite-dhcpcd"
"--localstatedir=/var"
"--disable-fork"
"--disable-privsep"
"--dbdir=/var/lib/ds-lite-dhcpcd"
"--rundir=/var/run/ds-lite-dhcpcd"
"--with-default-hostname=ds-lite"
"--disable-ipv4"
"--disable-arp"
"--disable-arpping"
"--disable-ipv4ll"
"--disable-ntp"
];
})

View File

@@ -1,4 +1,5 @@
final: prev: {
dino = import ./dino.nix final prev;
ds-lite-dhcpcd = import ./ds-lite-dhcpcd.nix final prev;
xmppc = import ./xmppc.nix final prev;
}

View File

@@ -0,0 +1,6 @@
{ runCommand, ... }:
runCommand "well-known-ssh-known-hosts" {} ''
mkdir -p $out
cp ${./well-known-ssh-known-hosts} $out/known_hosts
''

View File

@@ -0,0 +1,30 @@
# List of SSH Public Keys that should be pinned everywhere
# Check fingerprints with:
# ssh-keygen -l -f ./well-known-ssh-known-hosts
# Github
# From: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
# SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
# SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM
github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
# SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s
github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
# GitLab.com
# From: https://docs.gitlab.com/user/gitlab_com/#ssh-host-keys-fingerprints
# SHA256:eUXGGm1YGsMAS7vkcx6JOJdOGHPem5gQp4taiCfCLB8
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
# SHA256:ROQFvPThGrW4RuWLoL9tq9I9zJ42fK4XywyRtbOz/EQ
gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9
# SHA256:HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
# Codeberg
# From: https://docs.codeberg.org/security/ssh-fingerprint/
# SHA256:T9FYDEHELhVkulEKKwge5aVhVTbqCW0MIRwAfpARs/E
codeberg.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBL2pDxWr18SoiDJCGZ5LmxPygTlPu+cCKSkpqkvCyQzl5xmIMeKNdfdBpfbCGDPoZQghePzFZkKJNR/v9Win3Sc=
# SHA256:6QQmYi4ppFS4/+zSZ5S4IU+4sa6rwvQ4PbhCtPEBekQ
codeberg.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8hZi7K1/2E2uBX8gwPRJAHvRAob+3Sn+y2hxiEhN0buv1igjYFTgFO2qQD8vLfU/HT/P/rqvEeTvaDfY1y/vcvQ8+YuUYyTwE2UaVU5aJv89y6PEZBYycaJCPdGIfZlLMmjilh/Sk8IWSEK6dQr+g686lu5cSWrFW60ixWpHpEVB26eRWin3lKYWSQGMwwKv4LwmW3ouqqs4Z4vsqRFqXJ/eCi3yhpT+nOjljXvZKiYTpYajqUC48IHAxTWugrKe1vXWOPxVXXMQEPsaIRc2hpK+v1LmfB7GnEGvF1UAKnEZbUuiD9PBEeD5a1MZQIzcoPWCrTxipEpuXQ5Tni4mN
# SHA256:mIlxA9k46MmM6qdJOdMnAQpzGxF4WIVVL+fj+wZbw0g
codeberg.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIVIC02vnjFyL+I4RHfvIGNtOgJMe769VTF1VR4EB3ZB

View File

@@ -0,0 +1,31 @@
{ config, lib, pkgs, ... }:
with lib;
{
options.profiles.clerie.common-ssh = {
enable = mkEnableOption "Common ssh config";
};
config = mkIf config.profiles.clerie.common-ssh.enable {
services.openssh.enable = true;
services.openssh.settings = {
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
PermitRootLogin = lib.mkDefault "no";
};
services.openssh.hostKeys = lib.mkForce [
# Only create ed25519 host keys
{ type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; }
];
programs.ssh.knownHostsFiles = [
(pkgs.clerie-ssh-known-hosts + "/known_hosts")
(pkgs.fem-ssh-known-hosts + "/known_hosts")
(pkgs.well-known-ssh-known-hosts + "/known_hosts")
];
};
}

View File

@@ -11,11 +11,11 @@ with lib;
config = mkIf config.profiles.clerie.common.enable {
profiles.clerie.common-dns.enable = mkDefault true;
profiles.clerie.common-networking.enable = mkDefault true;
profiles.clerie.common-nix.enable = mkDefault true;
profiles.clerie.common-ssh.enable = mkDefault true;
profiles.clerie.common-webserver.enable = mkDefault true;
profiles.clerie.hetzner-storage-box-client.enable = mkDefault true;
};
}

View File

@@ -7,14 +7,17 @@
./common-dns
./common-networking
./common-nix
./common-ssh
./common-webserver
./cybercluster-vm
./desktop
./dn42-router
./ds-lite
./fem-net
./firefox
./gpg-ssh
./hetzner-cloud
./hetzner-storage-box-client
./hydra-build-machine
./mercury-vm
./monitoring-server

View File

@@ -0,0 +1,150 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.profiles.clerie.ds-lite;
dsLiteDhcpcdConfig = ''
allowinterfaces ${cfg.wanInterfaceName} ${concatMapStringsSep " " (interface: interface.name) cfg.lanInterfaces}
option dhcp6_name_servers
option dhcp6_aftr_name
waitip 6
ipv6only
ipv6ra_noautoconf
noipv6rs
interface ${cfg.wanInterfaceName}
ipv6ra_autoconf
ipv6rs
ia_pd 1/::/48 ${concatMapStringsSep " " (interface: "${interface.name}/${toString interface.sla_id}/${toString interface.prefix_len}") cfg.lanInterfaces}
${concatMapStrings (interface: ''
interface ${interface.name}
nolink
'') cfg.lanInterfaces}
'';
dsLiteDhcpcdConfigFile = pkgs.writeTextFile {
name = "dhcpcd.conf";
text = dsLiteDhcpcdConfig;
};
dsLiteDhcpcdHookWrapperFile = pkgs.writeShellScript "ds-lite-dhcpcd-hook-wrapper" ''
DS_LITE_WAN_INTERFACE_NAME=${lib.escapeShellArg cfg.wanInterfaceName};
export DS_LITE_WAN_INTERFACE_NAME
DS_LITE_TUNNEL_INTERFACE_NAME=${lib.escapeShellArg cfg.tunnelInterfaceName};
export DS_LITE_TUNNEL_INTERFACE_NAME
exec ${lib.getExe pkgs.ds-lite-dhcpcd-hook}
'';
in {
options.profiles.clerie.ds-lite = {
enable = mkEnableOption "DS-Lite setup";
wanInterfaceName = mkOption {
type = types.str;
description = "Interface with IPv6 connectivity to provider";
};
tunnelInterfaceName = mkOption {
type = types.str;
description = "Interface with IPv4 connectivity to provider";
};
lanInterfaces = mkOption {
type = with types; listOf (submodule ({ ... }: {
options = {
name = mkOption {
type = types.str;
};
sla_id = mkOption {
type = types.ints.unsigned;
};
prefix_len = mkOption {
type = types.ints.between 48 128;
};
};
}));
default = [];
description = "Interfaces to provisn with an IPv6 prefix";
};
};
config = mkIf cfg.enable {
systemd.services.ds-lite-dhcpcd = {
description = "DS-Lite dhcpcd";
wantedBy = [ "multi-user.target" ];
environment = {
};
serviceConfig = {
Type = "simple";
User = "ds-lite";
Group = "ds-lite";
StateDirectory = "ds-lite-dhcpcd";
RuntimeDirectory = "ds-lite-dhcpcd";
ExecStart = "${pkgs.ds-lite-dhcpcd}/bin/dhcpcd --ipv6only --nobackground --config ${dsLiteDhcpcdConfigFile} --script ${dsLiteDhcpcdHookWrapperFile}";
Restart = "always";
AmbientCapabilities = [
"CAP_NET_ADMIN"
"CAP_NET_RAW"
"CAP_NET_BIND_SERVICE"
];
ReadWritePaths = [
"/proc/sys/net/ipv6"
];
DeviceAllow = "";
LockPersonality = true;
MemoryDenyWriteExecute = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateTmp = true;
PrivateUsers = false;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = "tmpfs"; # allow exceptions to be added to ReadOnlyPaths, etc.
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
RemoveIPC = true;
RestrictAddressFamilies = [
"AF_UNIX"
"AF_INET"
"AF_INET6"
"AF_NETLINK"
"AF_PACKET"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallFilter = [
"@system-service"
"~@keyring"
"~@memlock"
"~@mount"
];
SystemCallArchitectures = "native";
UMask = "0027";
};
};
users.users.ds-lite = {
isSystemUser = true;
group = "ds-lite";
};
users.groups.ds-lite = { };
};
}

View File

@@ -0,0 +1,19 @@
{ config, lib, ... }:
with lib;
{
options.profiles.clerie.hetzner-storage-box-client = {
enable = mkEnableOption "Profile for Hetzner Storage Box Clients";
};
config = mkIf config.profiles.clerie.hetzner-storage-box-client.enable {
programs.ssh.knownHostsFiles = [
./hetzner-storage-box-ssh_known_hosts
];
};
}

View File

@@ -0,0 +1,7 @@
# SSH public keys of Hetzner Storage Box servers
# Fingerprints from: https://docs.hetzner.com/de/storage/storage-box/general#ssh-host-keys
# Verify with: ssh-keygen -l -f hetzner-storage-box-ssh_known_hosts
# SHA256:XqONwb1S0zuj5A1CDxpOSuD2hnAArV1A3wKY7Z3sdgM MD5:12:cd:bd:c7:de:76:91:34:1c:24:31:24:55:40:ab:87
*.your-storagebox.de,[*.your-storagebox.de]:23 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICf9svRenC/PLKIL9nk6K/pxQgoiFC41wTNvoIncOxs
# SHA256:EMlfI8GsRIfpVkoW1H2u0zYVpFGKkIMKHFZIRkf2ioI MD5:3d:7b:6f:99:5f:68:53:21:73:15:f9:2e:6b:3a:9f:e3
*.your-storagebox.de,[*.your-storagebox.de]:23 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA5EB5p/5Hp3hGW1oHok+PIOH9Pbn7cnUiGmUEBrCVjnAw+HrKyN8bYVV0dIGllswYXwkG/+bgiBlE6IVIBAq+JwVWu1Sss3KarHY3OvFJUXZoZyRRg/Gc/+LRCE7lyKpwWQ70dbelGRyyJFH36eNv6ySXoUYtGkwlU5IVaHPApOxe4LHPZa/qhSRbPo2hwoh0orCtgejRebNtW5nlx00DNFgsvn8Svz2cIYLxsPVzKgUxs8Zxsxgn+Q/UvR7uq4AbAhyBMLxv7DjJ1pc7PJocuTno2Rw9uMZi1gkjbnmiOh6TTXIEWbnroyIhwc8555uto9melEUmWNQ+C+PwAK+MPw==