feat: acme/ddclient/nextcloud container

This commit is contained in:
Patrick Großmann 2023-12-16 22:41:06 +01:00
parent 2ac6562a17
commit 4fda94b984
Signed by: patrick
GPG key ID: 451F95EFB8BECD0F
17 changed files with 169 additions and 21 deletions

View file

@ -122,11 +122,10 @@
inherit inherit
(import ./nix/hosts.nix inputs) (import ./nix/hosts.nix inputs)
hosts hosts
microvmConfigurations
nixosConfigurations nixosConfigurations
minimalConfigurations minimalConfigurations
; ;
nodes = self.nixosConfigurations // self.microvmConfigurations; nodes = self.nixosConfigurations;
inherit inherit
(lib.foldl' lib.recursiveUpdate {} (lib.foldl' lib.recursiveUpdate {}

View file

@ -115,6 +115,7 @@
}; };
fileSystems."/state".neededForBoot = true; fileSystems."/state".neededForBoot = true;
fileSystems."/persist".neededForBoot = true;
fileSystems."/panzer/state".neededForBoot = true; fileSystems."/panzer/state".neededForBoot = true;
fileSystems."/panzer/persist".neededForBoot = true; fileSystems."/panzer/persist".neededForBoot = true;
boot.initrd.luks.devices.enc-rpool.allowDiscards = true; boot.initrd.luks.devices.enc-rpool.allowDiscards = true;

Binary file not shown.

View file

@ -1,18 +1,30 @@
_inputs: _self: super: { inputs: _self: super: {
lib = lib =
super.lib super.lib
// { // {
containers.mkConfig = name: config: containers.mkConfig = name: config:
super.lib.mkMerge [ super.lib.mkMerge [
{ {
config = {
imports = [
../modules/config/impermanence
../modules/config/net.nix
../modules/interface-naming.nix
inputs.impermanence.nixosModules.impermanence
];
};
bindMounts = { bindMounts = {
"state" = { "state" = {
mountPoint = "/state"; mountPoint = "/state";
hostPath = "/state/containers/${name}"; hostPath = "/state/containers/${name}";
isReadOnly = false;
}; };
"persist" = { "persist" = {
mountPoint = "/persist"; mountPoint = "/persist";
hostPath = "/containers/${name}"; hostPath = "/containers/${name}";
isReadOnly = false;
}; };
}; };
zfs.mountpoint = super.lib.mkDefault "/containers/${name}"; zfs.mountpoint = super.lib.mkDefault "/containers/${name}";

9
lib/test.nix Normal file
View file

@ -0,0 +1,9 @@
{
config,
pkgs,
...
}: {
networking.hostName = "lololo";
programs.fuse.userAllowOther = true;
environment.systemPackages = [pkgs.hello];
}

View file

@ -4,6 +4,7 @@
pkgs, pkgs,
... ...
}: { }: {
imports = [./impermanence/users.nix];
home-manager = { home-manager = {
useGlobalPkgs = true; useGlobalPkgs = true;
useUserPackages = true; useUserPackages = true;

View file

@ -3,14 +3,16 @@
lib, lib,
pkgs, pkgs,
... ...
}: { }: let
imports = [./users.nix]; onlyHost =
lib.mkIf (!config.boot.isContainer);
in {
# to allow all users to access hm managed persistent folders # to allow all users to access hm managed persistent folders
programs.fuse.userAllowOther = true; programs.fuse.userAllowOther = true;
environment.persistence."/state" = { environment.persistence."/state" = {
hideMounts = true; hideMounts = true;
files = [ files = onlyHost [
"/etc/machine-id" "/etc/machine-id"
"/etc/ssh/ssh_host_ed25519_key" "/etc/ssh/ssh_host_ed25519_key"
"/etc/ssh/ssh_host_ed25519_key.pub" "/etc/ssh/ssh_host_ed25519_key.pub"
@ -25,13 +27,27 @@
mode = "0777"; mode = "0777";
} }
] ]
++ lib.lists.optionals config.security.acme.acceptTerms [
{
directory = "/var/lib/acme";
user = "acme";
group = "acme";
mode = "0755";
}
]
++ lib.lists.optionals config.hardware.bluetooth.enable [ ++ lib.lists.optionals config.hardware.bluetooth.enable [
"/var/lib/bluetooth" "/var/lib/bluetooth"
]; ];
}; };
environment.persistence."/persist" = {
hideMounts = true;
directories = [];
};
# After importing the rpool, rollback the root system to be empty. # After importing the rpool, rollback the root system to be empty.
boot.initrd.systemd.services.impermanence-root = { boot.initrd.systemd.services.impermanence-root =
onlyHost
{
wantedBy = ["initrd.target"]; wantedBy = ["initrd.target"];
after = ["zfs-import-rpool.service"]; after = ["zfs-import-rpool.service"];
before = ["sysroot.mount"]; before = ["sysroot.mount"];

View file

@ -10,8 +10,10 @@
attrNames attrNames
mkOption mkOption
types types
hasAttr
mkMerge mkMerge
isAttrs isAttrs
mkIf
; ;
in { in {
# Expose a home manager module for each user that allows extending # Expose a home manager module for each user that allows extending

View file

@ -6,11 +6,13 @@
networking = { networking = {
useNetworkd = true; useNetworkd = true;
dhcpcd.enable = false; dhcpcd.enable = false;
firewall.enable = true;
# allow mdns port # allow mdns port
firewall.allowedUDPPorts = [5353]; firewall.allowedUDPPorts = [5353];
renameInterfacesByMac = renameInterfacesByMac = lib.mkIf (!config.boot.isContainer) (
lib.mapAttrs (_: v: v.mac) lib.mapAttrs (_: v: v.mac)
(config.secrets.secrets.local.networking.interfaces or {}); (config.secrets.secrets.local.networking.interfaces or {})
);
}; };
systemd.network = { systemd.network = {
enable = true; enable = true;

View file

@ -18,6 +18,7 @@
avahi = uidGid 209; avahi = uidGid 209;
fwupd-refresh = uidGid 210; fwupd-refresh = uidGid 210;
podman = uidGid 211; podman = uidGid 211;
acme = uidGid 212;
systemd-oom = uidGid 300; systemd-oom = uidGid 300;
systemd-coredump = uidGid 301; systemd-coredump = uidGid 301;
}; };

29
modules/services/acme.nix Normal file
View file

@ -0,0 +1,29 @@
{
config,
lib,
...
}: {
age.secrets.cloudflare_token_acme = {
rekeyFile = ../../secrets/cloudflare/api_token.age;
mode = "440";
group = "acme";
};
security.acme = {
acceptTerms = true;
defaults = {
email = config.secrets.secrets.global.devEmail;
dnsProvider = "cloudflare";
dnsPropagationCheck = true;
reloadServices = ["nginx"];
credentialFiles = {
"CF_DNS_API_TOKEN_FILE" = config.age.secrets.cloudflare_token_acme.path;
"CF_ZONE_API_TOKEN_FILE" = config.age.secrets.cloudflare_token_acme.path;
};
};
};
security.acme.certs = lib.flip lib.mapAttrs config.secrets.secrets.global.domains (_: value: {
domain = value;
extraDomainNames = ["*.${value}"];
});
users.groups.acme.members = ["nginx"];
}

View file

@ -0,0 +1,14 @@
{config, ...}: {
age.secrets.cloudflare_token_dns = {
rekeyFile = ../../secrets/cloudflare/api_token.age;
mode = "440";
};
services.ddclient = {
enable = true;
zone = config.secrets.secrets.global.domains.mail;
protocol = "Cloudflare";
username = "token";
passwordFile = config.age.secrets.cloudflare_token_dns.path;
domains = [config.secrets.secrets.global.domains.mail];
};
}

View file

@ -1,9 +1,27 @@
{ {
lib, lib,
stateVersion, stateVersion,
config,
... ...
}: { }: let
imports = [./containers.nix]; hostName = "nc.${config.secrets.secrets.global.domains.mail}";
in {
imports = [./containers.nix ./nginx.nix ./ddclient.nix ./acme.nix];
services.nginx = {
enable = true;
upstreams.nextcloud = {
servers."192.168.178.33:80" = {};
extraConfig = ''
zone nextcloud 64k ;
keepalive 5 ;
'';
};
virtualHosts.${hostName} = {
forceSSL = true;
useACMEHost = "mail";
locations."/".proxyPass = "http://nextcloud";
};
};
containers.nextcloud = lib.containers.mkConfig "nextcloud" { containers.nextcloud = lib.containers.mkConfig "nextcloud" {
autoStart = true; autoStart = true;
zfs = { zfs = {
@ -18,11 +36,41 @@
pkgs, pkgs,
... ...
}: { }: {
systemd.network.networks = {
"lan01" = {
address = ["192.168.178.33/24"];
gateway = ["192.168.178.1"];
matchConfig.Name = "mv-lan01*";
dns = ["192.168.178.2"];
networkConfig = {
IPv6PrivacyExtensions = "yes";
MulticastDNS = true;
};
};
};
services.nextcloud = { services.nextcloud = {
inherit hostName;
enable = true; enable = true;
package = pkgs.nextcloud27; package = pkgs.nextcloud27;
hostName = "localhost"; configureRedis = true;
config.adminpassFile = "${pkgs.writeText "adminpass" "test123"}"; # DON'T DO THIS IN PRODUCTION - the password file will be world-readable in the Nix Store! config.adminpassFile = "${pkgs.writeText "adminpass" "test123"}"; # DON'T DO THIS IN PRODUCTION - the password file will be world-readable in the Nix Store!
extraApps = with config.services.nextcloud.package.packages.apps; {
inherit contacts calendar tasks;
};
extraAppsEnable = true;
extraOptions.enabledPreviewProviders = [
"OC\\Preview\\BMP"
"OC\\Preview\\GIF"
"OC\\Preview\\JPEG"
"OC\\Preview\\Krita"
"OC\\Preview\\MarkDown"
"OC\\Preview\\MP3"
"OC\\Preview\\OpenDocument"
"OC\\Preview\\PNG"
"OC\\Preview\\TXT"
"OC\\Preview\\XBitmap"
"OC\\Preview\\HEIC"
];
}; };
system.stateVersion = stateVersion; system.stateVersion = stateVersion;

View file

@ -52,6 +52,8 @@ in {
mode = "440"; mode = "440";
group = "nginx"; group = "nginx";
}; };
security.acme.acceptTerms = true;
security.acme.defaults.email = config.secrets.secrets.global.devEmail;
# Sensible defaults for nginx # Sensible defaults for nginx
services.nginx = { services.nginx = {

View file

@ -58,7 +58,6 @@ inputs: let
in { in {
inherit inherit
hosts hosts
microvmConfigurations
nixosConfigurations nixosConfigurations
minimalConfigurations minimalConfigurations
; ;

View file

@ -0,0 +1,13 @@
age-encryption.org/v1
-> X25519 j1vdwUZ+o5coMFAaOCyiS42rLq7FPX6xwuWmoHcN61U
m1QEYj4NW5IdNsFh26Uhwe2Sg1ggkvTYB92S4B2lC8M
-> piv-p256 XTQkUA AhjsxoVBz3h/1Sj+cwnT7gpcE6SDMhNOBMU9nP+gfC5G
a7E3dolF4QaxTVpJBOKA314INK32eTdDykDyRT+/8XQ
-> piv-p256 ZFgiIw Ah49xwjTzvroi4R90URbbE0yY15w+OvUsWZ2cQdYHs/w
4i6XZ8lwOeWinlU1IiCgUBTSWMzxuPyvYKRbz6GqNUk
-> piv-p256 ZFgiIw A49Cv751h0WJYL6qPceFVwjbGVpF668SGKVjHq/lQ4Rs
AAGD0jOCHIOAIBk872SJwe2mCx69xn/1ZjiswebgU0w
-> K("0$@8-grease z`/W }"_xiVH <~Bj._
--- /NUrs98fD72LqCIYVOzrUhFNhxGivAEOZ9pob65I2fI
:(#­¥aô[8@BÊ4èÝ|ÍC7!³>Ù?¬Œ›`5á‰o‡Þr õB´ˆ°y`óAIJ;)÷Å&“)@ÝÎB²¹Ï¡ñ´¾Q

Binary file not shown.