Merge remote-tracking branch 'prism/master'

This commit is contained in:
tv 2023-01-06 12:17:36 +01:00
commit 2cd5ed1699
18 changed files with 353 additions and 110 deletions

View File

@ -66,7 +66,6 @@ rec {
"cgit.prism.r"
"bota.r"
"flix.r"
"jelly.r"
"paste.r"
"c.r"
"p.r"

39
kartei/lass/radio.nix Normal file
View File

@ -0,0 +1,39 @@
{ r6, w6, ... }:
{
nets = {
retiolum = {
ip4.addr = "10.243.0.11";
ip6.addr = r6 "4d10";
aliases = [
"radio.r"
];
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEAx08urv4sl22+pLchD6W6kprJ1JZBiG9/MVA50PqYAJmvTpYyDUCR
Dwgt7pR8n/zbbof98QS5D67J5rZPcrLI6PY2bBzlXFFKHZEj2AVwUjUbyvEvQqtf
yJM+AxFy1/CaXmDvYM9UF/Wh6rb/ZeUxFtbaIVfMPox0Zln0THEsOmCWvNzxMvjZ
rjouZGzrH+er3yxJVovxD/JT32COmK0R20DLDoofBdtBkFlB/VkrbxYfX/cWXX1K
WQVJuQ/H1xP9m4c4S8g/nM63rLUBOIkn06TcXyI/mEgRecEUDgC02PNXc5BDgB4A
seXx+BiLC/f6+64KOWODHEEm/iHjCyrOSZtdA2EbPCATfOHrj0EG5Y4V6d1Iw4WP
kiOIQByHMbOzRwm91yd/gM1DTxdy3j5nqaMhCzrM/QeOhSf5FXkWpARawUsChwh+
eCuSZDg218u/NkzCrTvCPTdY1q+MZ5d5qgID4VQrenjBJq4AZxsw74Zd2G2uRWlF
paZ2pSCyAey19A/or2iG10tqNpXJzZy0HNhh7q/gKhQKKTh+ggzgOrRe2ZaxlbEy
P45JQKcR9/WJAohnYQ8uZJ6oin5EsEdVkapdYu60aReRGeyTmq3RLnu3Zn5MR5RH
1r+W03KQcQzmmpE5YrxKSZL6OriXQYEPTa9/mSZT6TEUIvRT8W5jGQ0CAwEAAQ==
-----END RSA PUBLIC KEY-----
'';
tinc.pubkey_ed25519 = "DmiyfmRsWd8Qg6M/ZsAd5lFM+vnkwRTfnMH/jCFwWFF";
};
wiregrill = {
ip6.addr = w6 "4d10";
aliases = [
"radio.w"
];
wireguard.pubkey = ''
iCe1O9qeziw18AlGuFt5tIxm6SIBtNpwO/6OZm9Bn30=
'';
};
};
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHsvyWrMN2lupBmjI8nW+NUSJIDPkr8c90Z4BcuZ7Myi";
syncthing.id = "KMDPLE5-7FBYYXH-PF5LEET-G2AWR33-7XAPZJU-5S3VOB7-ZX5Q74V-PZKI6QN";
}

View File

@ -6,6 +6,7 @@
ip6.addr = r6 "3110";
aliases = [
"yellow.r"
"jelly.r"
];
tinc = {
pubkey = ''

View File

@ -53,6 +53,7 @@ with import <stockholm/lib>;
config.krebs.users.lass-mors.pubkey
config.krebs.users.makefu.pubkey
config.krebs.users.tv.pubkey
config.krebs.users.kmein.pubkey
];
# The NixOS release to be compatible with for stateful data such as databases.

View File

@ -16,7 +16,7 @@
<stockholm/lass/2configs/steam.nix>
<stockholm/lass/2configs/wine.nix>
<stockholm/lass/2configs/fetchWallpaper.nix>
<stockholm/lass/2configs/prism-mounts/samba.nix>
<stockholm/lass/2configs/yellow-mounts/samba.nix>
<stockholm/lass/2configs/pass.nix>
<stockholm/lass/2configs/mail.nix>
<stockholm/lass/2configs/bitcoin.nix>

View File

@ -4,21 +4,9 @@
imports = [
<stockholm/lass>
<stockholm/lass/2configs/retiolum.nix>
<stockholm/lass/2configs/libvirt.nix>
{ # TODO make new hfos.nix out of this vv
users.users.riot = {
uid = pkgs.stockholm.lib.genid_uint31 "riot";
isNormalUser = true;
extraGroups = [ "libvirtd" ];
openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6o6sdTu/CX1LW2Ff5bNDqGEAGwAsjf0iIe5DCdC7YikCct+7x4LTXxY+nDlPMeGcOF88X9/qFwdyh+9E4g0nUAZaeL14Uc14QDqDt/aiKjIXXTepxE/i4JD9YbTqStAnA/HYAExU15yqgUdj2dnHu7OZcGxk0ZR1OY18yclXq7Rq0Fd3pN3lPP1T4QHM9w66r83yJdFV9szvu5ral3/QuxQnCNohTkR6LoJ4Ny2RbMPTRtb+jPbTQYTWUWwV69mB8ot5nRTP4MRM9pu7vnoPF4I2S5DvSnx4C5zdKzsb7zmIvD4AmptZLrXj4UXUf00Xf7Js5W100Ne2yhYyhq+35 riot@lagrange"
];
};
# krebs.iptables.tables.filter.FORWARD.rules = [
# { v6 = false; predicate = "--destination 95.216.1.130"; target = "ACCEPT"; }
# { v6 = false; predicate = "--source 95.216.1.130"; target = "ACCEPT"; }
# ];
}
<stockholm/lass/2configs/consul.nix>
<stockholm/lass/2configs/yellow-host.nix>
<stockholm/lass/2configs/riot.nix>
];
krebs.build.host = config.krebs.hosts.neoprism;

View File

@ -0,0 +1,24 @@
with import <stockholm/lib>;
{ config, lib, pkgs, ... }:
{
imports = [
<stockholm/lass>
<stockholm/lass/2configs>
<stockholm/lass/2configs/retiolum.nix>
<stockholm/lass/2configs/syncthing.nix>
<stockholm/lass/2configs/radio>
];
krebs.build.host = config.krebs.hosts.radio;
security.acme = {
acceptTerms = true;
defaults.email = "acme@lassul.us";
};
lass.sync-containers3.inContainer = {
enable = true;
pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOvPKdbVwMEFCDMyNAzR8NdVjTbQL2G+03Xomxn6KKFt";
};
}

View File

@ -0,0 +1,7 @@
{
imports = [
./config.nix
];
boot.isContainer = true;
networking.useDHCP = true;
}

View File

@ -16,7 +16,7 @@
<stockholm/lass/2configs/blue-host.nix>
<stockholm/lass/2configs/green-host.nix>
<stockholm/krebs/2configs/news-host.nix>
<stockholm/lass/2configs/prism-mounts/samba.nix>
<stockholm/lass/2configs/yellow-mounts/samba.nix>
<stockholm/lass/2configs/fetchWallpaper.nix>
<stockholm/lass/2configs/consul.nix>
<stockholm/lass/2configs/red-host.nix>

View File

@ -9,20 +9,23 @@ in {
krebs.build.host = config.krebs.hosts.yellow;
lass.sync-containers3.inContainer = {
enable = true;
pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN737BAP36KiZO97mPKTIUGJUcr97ps8zjfFag6cUiYL";
};
users.groups.download.members = [ "transmission" ];
networking.useHostResolvConf = false;
networking.useNetworkd = true;
systemd.services.transmission.bindsTo = [ "openvpn-nordvpn.service" ];
systemd.services.transmission.after = [ "openvpn-nordvpn.service" ];
services.transmission = {
enable = true;
home = "/var/state/transmission";
group = "download";
downloadDirPermissions = "775";
settings = {
download-dir = "/var/download/finished";
incomplete-dir = "/var/download/incoming";
incomplete-dir-enable = true;
download-dir = "/var/download/transmission";
incomplete-dir-enabled = false;
rpc-bind-address = "::";
message-level = 1;
umask = 18;
@ -40,11 +43,8 @@ in {
};
virtualHosts.default = {
default = true;
locations."/dl".extraConfig = ''
return 301 /;
'';
locations."/" = {
root = "/var/download/finished";
root = "/var/download";
extraConfig = ''
fancyindex on;
fancyindex_footer "/fancy.html";
@ -136,6 +136,58 @@ in {
''};
'';
};
virtualHosts."jelly.r" = {
locations."/".extraConfig = ''
proxy_pass http://localhost:8096/;
proxy_set_header Accept-Encoding "";
'';
};
};
services.samba = {
enable = true;
enableNmbd = false;
extraConfig = ''
workgroup = WORKGROUP
server string = ${config.networking.hostName}
# only allow retiolum addresses
hosts allow = 42::/16 10.243.0.0/16 10.244.0.0/16
# Use sendfile() for performance gain
use sendfile = true
# No NetBIOS is needed
disable netbios = true
# Only mangle non-valid NTFS names, don't care about DOS support
mangled names = illegal
# Performance optimizations
socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536
# Disable all printing
load printers = false
disable spoolss = true
printcap name = /dev/null
map to guest = Bad User
max log size = 50
dns proxy = no
security = user
[global]
syslog only = yes
'';
shares.public = {
comment = "Warez";
path = "/var/download";
public = "yes";
"only guest" = "yes";
"create mask" = "0644";
"directory mask" = "2777";
writable = "no";
printable = "no";
};
};
systemd.services.bruellwuerfel =
@ -164,14 +216,33 @@ in {
tables.filter.INPUT.rules = [
{ predicate = "-p tcp --dport 80"; target = "ACCEPT"; } # nginx web dir
{ predicate = "-p tcp --dport 9091"; target = "ACCEPT"; } # transmission-web
{ predicate = "-p tcp --dport 9092"; target = "ACCEPT"; } # magnetico webinterface
{ predicate = "-p tcp --dport 51413"; target = "ACCEPT"; } # transmission-traffic
{ predicate = "-p udp --dport 51413"; target = "ACCEPT"; } # transmission-traffic
{ predicate = "-p tcp --dport 8096"; target = "ACCEPT"; } # jellyfin
{ predicate = "-p tcp --dport 9696"; target = "ACCEPT"; } # prowlarr
{ predicate = "-p tcp --dport 8989"; target = "ACCEPT"; } # sonarr
{ predicate = "-p tcp --dport 7878"; target = "ACCEPT"; } # radarr
# smbd
{ predicate = "-i retiolum -p tcp --dport 445"; target = "ACCEPT"; }
{ predicate = "-i retiolum -p tcp --dport 111"; target = "ACCEPT"; }
{ predicate = "-i retiolum -p udp --dport 111"; target = "ACCEPT"; }
{ predicate = "-i retiolum -p tcp --dport 2049"; target = "ACCEPT"; }
{ predicate = "-i retiolum -p udp --dport 2049"; target = "ACCEPT"; }
{ predicate = "-i retiolum -p tcp --dport 4000:4002"; target = "ACCEPT"; }
{ predicate = "-i retiolum -p udp --dport 4000:4002"; target = "ACCEPT"; }
{ predicate = "-i wiregrill -p tcp --dport 445"; target = "ACCEPT"; }
{ predicate = "-i wiregrill -p tcp --dport 111"; target = "ACCEPT"; }
{ predicate = "-i wiregrill -p udp --dport 111"; target = "ACCEPT"; }
{ predicate = "-i wiregrill -p tcp --dport 2049"; target = "ACCEPT"; }
{ predicate = "-i wiregrill -p udp --dport 2049"; target = "ACCEPT"; }
{ predicate = "-i wiregrill -p tcp --dport 4000:4002"; target = "ACCEPT"; }
{ predicate = "-i wiregrill -p udp --dport 4000:4002"; target = "ACCEPT"; }
];
tables.filter.OUTPUT = {
policy = "DROP";
rules = [
{ predicate = "-o lo"; target = "ACCEPT"; }
{ v6 = false; predicate = "-d ${vpnIp}/32"; target = "ACCEPT"; }
{ predicate = "-o tun0"; target = "ACCEPT"; }
{ predicate = "-o retiolum"; target = "ACCEPT"; }
@ -279,7 +350,7 @@ in {
ExecStart = pkgs.writers.writeDash "flix-index" ''
set -efu
DIR=/var/download/finished
DIR=/var/download
cd "$DIR"
while inotifywait -rq -e create -e move -e delete "$DIR"; do
find . -type f > "$DIR"/index.tmp
@ -294,9 +365,15 @@ in {
group = "download";
};
services.magnetico = {
services.radarr = {
enable = true;
};
services.sonarr = {
enable = true;
};
services.prowlarr = {
enable = true;
web.address = "0.0.0.0";
web.port = 9092;
};
}

View File

@ -3,7 +3,7 @@
let
name = "radio";
music_dir = "/home/radio/music";
music_dir = "/var/music";
skip_track = pkgs.writers.writeBashBin "skip_track" ''
set -eu
@ -303,10 +303,10 @@ in {
'';
};
services.syncthing.declarative.folders."the_playlist" = {
path = "/home/radio/music/the_playlist";
path = "/var/music/the_playlist";
devices = [ "mors" "phone" "prism" "omo" ];
};
krebs.acl."/home/radio/music/the_playlist"."u:syncthing:X".parents = true;
krebs.acl."/home/radio/music/the_playlist"."u:syncthing:rwX" = {};
krebs.acl."/home/radio/music/the_playlist"."u:radio:rwX" = {};
krebs.acl."/var/music/the_playlist"."u:syncthing:X".parents = true;
krebs.acl."/var/music/the_playlist"."u:syncthing:rwX" = {};
krebs.acl."/var/music/the_playlist"."u:radio:rwX" = {};
}

View File

@ -10,7 +10,7 @@ def stringify_attrs(attrs) =
out
end
def filter_graveyard(req) =
def filter_music(req) =
filename = request.filename(req)
if string.match(pattern = '.*/\\.graveyard/.*', filename) then
false
@ -27,7 +27,7 @@ end
env = environment()
port = string.to_int(env["RADIO_PORT"], default = 8000)
all_music = playlist(env["MUSIC"], check_next = filter_graveyard)
all_music = playlist(env["MUSIC"], check_next = filter_music)
wishlist = request.queue()
tracks = fallback(track_sensitive = true, [wishlist, all_music])
tracks = blank.eat(tracks)
@ -36,7 +36,7 @@ last_metadata = ref([])
def on_metadata(m) =
last_metadata := m
print("changing tracks")
out = process.read(env["HOOK_TRACK_CHANGE"], env = m)
out = process.read(env["HOOK_TRACK_CHANGE"], env = m, timeout = 5.0)
print(out)
end
tracks.on_metadata(on_metadata)

View File

@ -18,11 +18,14 @@ let
MAXMIND_GEOIP_DB="/tmp/GeoLite2-City.mmdb"; export MAXMIND_GEOIP_DB
OPENWEATHER_API_KEY=$(cat "$CREDENTIALS_DIRECTORY/openweather_api"); export OPENWEATHER_API_KEY
ss -no 'sport = :8000' |
jc --ss | jq -r '.[] |
select(
.local_address != "[::ffff:127.0.0.1]"
and .local_address != "[::1]"
) | .peer_address | gsub("[\\[\\]]"; "")
jc --ss | jq -r '
[
.[] |
select(
.local_address != "[::ffff:127.0.0.1]"
and .local_address != "[::1]"
) | .peer_address | gsub("[\\[\\]]"; "")
] | unique[]
' |
${weather_for_ips}/bin/weather_for_ips
'';

View File

@ -3,32 +3,43 @@ import fileinput
import json
import requests
import os
import random
geoip = geoip2.database.Reader(os.environ['MAXMIND_GEOIP_DB'])
seen = {}
output = []
for ip in fileinput.input():
location = geoip.city(ip.strip())
if location.city.geoname_id not in seen:
seen[location.city.geoname_id] = True
weather_api_key = os.environ['OPENWEATHER_API_KEY']
url = (
f'https://api.openweathermap.org/data/2.5/onecall'
f'?lat={location.location.latitude}'
f'&lon={location.location.longitude}'
f'&appid={weather_api_key}'
f'&units=metric'
)
resp = requests.get(url)
weather = json.loads(resp.text)
if "80.147.140.51" in ip:
output.append(
f'Weather report for {location.city.name}, {location.country.name}. '
f'It is {weather["current"]["weather"][0]["description"]} outside '
f'with a temperature of {weather["current"]["temp"]:.1f} degrees, '
f'a wind speed of {weather["current"]["wind_speed"]:.1f} meters per second '
f'and a humidity of {weather["current"]["humidity"]} percent. '
f'The probability of precipitation is {weather["hourly"][0]["pop"] * 100:.0f} percent. '
'Weather report for c-base, space.'
'It is empty space outside '
'with a temperature of -270 degrees, '
'a lightspeed of 299792 kilometers per second '
'and a humidity of Not a Number percent. '
f'The probability of reincarnation is {random.randrange(0, 100)} percent.'
)
else:
location = geoip.city(ip.strip())
if location.city.geoname_id not in seen:
seen[location.city.geoname_id] = True
weather_api_key = os.environ['OPENWEATHER_API_KEY']
url = (
f'https://api.openweathermap.org/data/2.5/onecall'
f'?lat={location.location.latitude}'
f'&lon={location.location.longitude}'
f'&appid={weather_api_key}'
f'&units=metric'
)
resp = requests.get(url)
weather = json.loads(resp.text)
output.append(
f'Weather report for {location.city.name}, {location.country.name}. '
f'It is {weather["current"]["weather"][0]["description"]} outside '
f'with a temperature of {weather["current"]["temp"]:.1f} degrees, '
f'a wind speed of {weather["current"]["wind_speed"]:.1f} meters per second '
f'and a humidity of {weather["current"]["humidity"]} percent. '
f'The probability of precipitation is {weather["hourly"][0]["pop"] * 100:.0f} percent. '
)
print('\n'.join(output))

59
lass/2configs/riot.nix Normal file
View File

@ -0,0 +1,59 @@
{ config, lib, pkgs, ... }:
{
containers.riot = {
config = {
environment.systemPackages = [
pkgs.dhcpcd
pkgs.git
pkgs.jq
];
services.openssh.enable = true;
users.users.root.openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6o6sdTu/CX1LW2Ff5bNDqGEAGwAsjf0iIe5DCdC7YikCct+7x4LTXxY+nDlPMeGcOF88X9/qFwdyh+9E4g0nUAZaeL14Uc14QDqDt/aiKjIXXTepxE/i4JD9YbTqStAnA/HYAExU15yqgUdj2dnHu7OZcGxk0ZR1OY18yclXq7Rq0Fd3pN3lPP1T4QHM9w66r83yJdFV9szvu5ral3/QuxQnCNohTkR6LoJ4Ny2RbMPTRtb+jPbTQYTWUWwV69mB8ot5nRTP4MRM9pu7vnoPF4I2S5DvSnx4C5zdKzsb7zmIvD4AmptZLrXj4UXUf00Xf7Js5W100Ne2yhYyhq+35 riot@lagrange"
];
networking.defaultGateway = "10.233.1.1";
systemd.services.autoswitch = {
environment = {
NIX_REMOTE = "daemon";
};
wantedBy = [ "multi-user.target" ];
serviceConfig.ExecStart = pkgs.writers.writeDash "autoswitch" ''
set -efu
if test -e /var/src/nixos-config; then
/run/current-system/sw/bin/nixos-rebuild -I /var/src switch || :
fi
'';
unitConfig.X-StopOnRemoval = false;
};
};
autoStart = true;
enableTun = true;
privateNetwork = true;
hostAddress = "10.233.1.1";
localAddress = "10.233.1.2";
forwardPorts = [
{ hostPort = 45622; containerPort = 22; }
];
};
systemd.network.networks."50-ve-riot" = {
matchConfig.Name = "ve-riot";
networkConfig = {
IPForward = "yes";
# weirdly we have to use POSTROUTING MASQUERADE here
# IPMasquerade = "both";
LinkLocalAddressing = "no";
KeepConfiguration = "static";
};
};
# networking.nat can be used instead of this
krebs.iptables.tables.nat.POSTROUTING.rules = [
{ v6 = false; predicate = "-s ${config.containers.riot.localAddress}"; target = "MASQUERADE"; }
];
krebs.iptables.tables.filter.FORWARD.rules = [
{ predicate = "-i ve-riot"; target = "ACCEPT"; }
{ predicate = "-o ve-riot"; target = "ACCEPT"; }
];
}

View File

@ -0,0 +1,14 @@
{ config, pkgs, ... }:
{
lass.sync-containers3.containers.yellow = {
sshKey = "${toString <secrets>}/yellow.sync.key";
};
containers.yellow.bindMounts."/var/lib" = {
hostPath = "/var/lib/sync-containers3/yellow/state";
isReadOnly = false;
};
containers.yellow.bindMounts."/var/download" = {
hostPath = "/var/download";
isReadOnly = false;
};
}

View File

@ -1,6 +1,6 @@
{
fileSystems."/mnt/prism" = {
device = "//prism.r/public";
fileSystems."/mnt/yellow" = {
device = "//yellow.r/public";
fsType = "cifs";
options = [
"guest"

View File

@ -28,6 +28,10 @@ in {
type = lib.types.bool;
default = false;
};
runContainer = lib.mkOption {
type = lib.types.bool;
default = true;
};
};
}));
};
@ -50,7 +54,8 @@ in {
wantedBy = [ "multi-user.target" ];
serviceConfig.ExecStart = pkgs.writers.writeDash "autoswitch" ''
set -efu
ln -frs /var/state/var_src /var/src
mkdir -p /var/state/var_src
ln -Tfrs /var/state/var_src /var/src
if test -e /var/src/nixos-config; then
/run/current-system/sw/bin/nixos-rebuild -I /var/src switch || :
fi
@ -64,7 +69,6 @@ in {
privateNetwork = true;
hostBridge = "ctr0";
bindMounts = {
"/etc/resolv.conf".hostPath = "/etc/resolv.conf";
"/var/lib/self/disk" = {
hostPath = "/var/lib/sync-containers3/${ctr.name}/disk";
isReadOnly = false;
@ -74,7 +78,7 @@ in {
isReadOnly = false;
};
};
}) cfg.containers;
}) (lib.filterAttrs (_: ctr: ctr.runContainer) cfg.containers);
systemd.services = lib.foldr lib.recursiveUpdate {} (lib.flatten (map (ctr: [
{ "${ctr.name}_syncer" = {
@ -101,14 +105,14 @@ in {
set -efux
if /run/wrappers/bin/ping -c 1 ${ctr.name}.r; then
touch "$HOME"/incomplete
rsync -a -e "ssh -i $CREDENTIALS_DIRECTORY/ssh_key" --inplace container_sync@${ctr.name}.r:disk "$HOME"/disk
rsync -a -e "ssh -i $CREDENTIALS_DIRECTORY/ssh_key" --timeout=30 --inplace container_sync@${ctr.name}.r:disk "$HOME"/disk
rm "$HOME"/incomplete
fi
''}
'';
};
}; }
{ "${ctr.name}_watcher" = {
{ "${ctr.name}_watcher" = lib.mkIf ctr.runContainer {
path = with pkgs; [
coreutils
consul
@ -136,7 +140,8 @@ in {
;;
200)
# echo 'got 200 from kv, will check payload'
export payload=$(consul kv get containers/${ctr.name})
payload=$(consul kv get containers/${ctr.name}) || continue
export payload
if [ "$(jq -rn 'env.payload | fromjson.host')" = '${config.networking.hostName}' ]; then
# echo 'we are the host, trying to reach container'
if $(retry -t 10 -d 10 -- /run/wrappers/bin/ping -q -c 1 ${ctr.name}.r > /dev/null); then
@ -163,7 +168,7 @@ in {
'';
};
}; }
{ "${ctr.name}_scheduler" = {
{ "${ctr.name}_scheduler" = lib.mkIf ctr.runContainer {
wantedBy = [ "multi-user.target" ];
path = with pkgs; [
coreutils
@ -246,7 +251,7 @@ in {
users.groups = lib.mapAttrs' (_: ctr: lib.nameValuePair "${ctr.name}_container" {
}) cfg.containers;
users.users = lib.mapAttrs' (_: ctr: lib.nameValuePair "${ctr.name}_container" ({
group = "container_${ctr.name}";
group = "${ctr.name}_container";
isNormalUser = true;
uid = slib.genid_uint31 "container_${ctr.name}";
home = "/var/lib/sync-containers3/${ctr.name}";
@ -254,47 +259,51 @@ in {
homeMode = "705";
})) cfg.containers;
environment.systemPackages = lib.mapAttrsToList (_: ctr: (pkgs.writers.writeDashBin "${ctr.name}_init" ''
set -efux
export PATH=${lib.makeBinPath [
pkgs.coreutils
pkgs.cryptsetup
pkgs.libxfs.bin
]}:$PATH
truncate -s 5G /var/lib/sync-containers3/${ctr.name}/disk
cryptsetup luksFormat /var/lib/sync-containers3/${ctr.name}/disk ${ctr.luksKey}
cryptsetup luksOpen --key-file ${ctr.luksKey} /var/lib/sync-containers3/${ctr.name}/disk ${ctr.name}
mkfs.xfs /dev/mapper/${ctr.name}
mkdir -p /var/lib/sync-containers3/${ctr.name}/state
mountpoint /var/lib/sync-containers3/${ctr.name}/state || mount /dev/mapper/${ctr.name} /var/lib/sync-containers3/${ctr.name}/state
/run/current-system/sw/bin/nixos-container start ${ctr.name}
/run/current-system/sw/bin/nixos-container run ${ctr.name} -- ${pkgs.writeDash "init" ''
mkdir -p /var/state
''}
'')) cfg.containers;
})
(lib.mkIf (cfg.containers != {}) {
# networking
networking.networkmanager.unmanaged = [ "ctr0" ];
networking.interfaces.dummy0.virtual = true;
networking.bridges.ctr0.interfaces = [ "dummy0" ];
networking.interfaces.ctr0.ipv4.addresses = [{
address = "10.233.0.1";
prefixLength = 24;
}];
systemd.services."dhcpd-ctr0" = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
Type = "forking";
Restart = "always";
DynamicUser = true;
StateDirectory = "dhcpd-ctr0";
User = "dhcpd-ctr0";
Group = "dhcpd-ctr0";
AmbientCapabilities = [
"CAP_NET_RAW" # to send ICMP messages
"CAP_NET_BIND_SERVICE" # to bind on DHCP port (67)
];
ExecStartPre = "${pkgs.coreutils}/bin/touch /var/lib/dhcpd-ctr0/dhcpd.leases";
ExecStart = "${pkgs.dhcp}/bin/dhcpd -4 -lf /var/lib/dhcpd-ctr0/dhcpd.leases -cf ${pkgs.writeText "dhpd.conf" ''
default-lease-time 600;
max-lease-time 7200;
authoritative;
ddns-update-style interim;
log-facility local1; # see dhcpd.nix
option subnet-mask 255.255.255.0;
option routers 10.233.0.1;
# option domain-name-servers 8.8.8.8; # TODO configure dns server
subnet 10.233.0.0 netmask 255.255.255.0 {
range 10.233.0.10 10.233.0.250;
}
''} ctr0";
systemd.network.networks.ctr0 = {
name = "ctr0";
address = [
"10.233.0.1/24"
];
networkConfig = {
IPForward = "yes";
IPMasquerade = "both";
ConfigureWithoutCarrier = true;
DHCPServer = "yes";
};
};
systemd.network.netdevs.ctr0.netdevConfig = {
Kind = "bridge";
Name = "ctr0";
};
networking.networkmanager.unmanaged = [ "ctr0" ];
krebs.iptables.tables.filter.INPUT.rules = [
{ predicate = "-i ctr0"; target = "ACCEPT"; }
];
krebs.iptables.tables.filter.FORWARD.rules = [
{ predicate = "-i ctr0"; target = "ACCEPT"; }
{ predicate = "-o ctr0"; target = "ACCEPT"; }
];
})
(lib.mkIf cfg.inContainer.enable {
users.groups.container_sync = {};
@ -308,6 +317,17 @@ in {
cfg.inContainer.pubkey
];
};
networking.useHostResolvConf = false;
networking.useNetworkd = true;
systemd.network = {
enable = true;
networks.eth0 = {
matchConfig.Name = "eth0";
DHCP = "yes";
dhcpV4Config.UseDNS = true;
};
};
})
];
}