mirror of
https://github.com/ryan4yin/nix-config.git
synced 2026-04-25 02:08:29 +02:00
feat(ai): add webdav mount (#253)
feat(aquamarine): add group for filesharing, protect /data on subvolume mount failures
This commit is contained in:
6
flake.lock
generated
6
flake.lock
generated
@@ -583,10 +583,10 @@
|
|||||||
"mysecrets": {
|
"mysecrets": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1773850740,
|
"lastModified": 1773927262,
|
||||||
"narHash": "sha256-izDf+wgii0KGAfNZ3/RFt2HJgUY/s+u8qKyKvNi0uGc=",
|
"narHash": "sha256-nxx7jAiHGTYU6hXdjHYjdR1SJNgFcVPokiFlR8MZwTc=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "86de5313787257806723f03dccabd52bb7501ff3",
|
"rev": "c388ca33beb5c099bf4603e6ab25a2e94af00b80",
|
||||||
"shallow": true,
|
"shallow": true,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "ssh://git@github.com/ryan4yin/nix-secrets.git"
|
"url": "ssh://git@github.com/ryan4yin/nix-secrets.git"
|
||||||
|
|||||||
@@ -1,38 +1,25 @@
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
myvars,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
# supported file systems, so we can mount any removable disks with these filesystems
|
# enable davfs2 driver for webdav
|
||||||
boot.supportedFilesystems = [
|
services.davfs2.enable = true;
|
||||||
# "cifs"
|
|
||||||
"davfs"
|
|
||||||
];
|
|
||||||
|
|
||||||
# mount a smb/cifs share
|
|
||||||
# fileSystems."/home/${myvars.username}/SMB-Downloads" = {
|
|
||||||
# device = "//windows-server-nas/Downloads";
|
|
||||||
# fsType = "cifs";
|
|
||||||
# options = [
|
|
||||||
# # https://www.freedesktop.org/software/systemd/man/latest/systemd.mount.html
|
|
||||||
# "nofail,_netdev"
|
|
||||||
# "uid=1000,gid=100,dir_mode=0755,file_mode=0755"
|
|
||||||
# "vers=3.0,credentials=${config.age.secrets.smb-credentials.path}"
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
|
|
||||||
# mount a webdav share
|
# mount a webdav share
|
||||||
# https://wiki.archlinux.org/title/Davfs2
|
# https://wiki.archlinux.org/title/Davfs2
|
||||||
# fileSystems."/home/${myvars.username}/webdav-downloads" = {
|
fileSystems."/mnt/fileshare" = {
|
||||||
# device = "https://webdav.writefor.fun/Downloads";
|
device = "https://webdav.writefor.fun/";
|
||||||
# fsType = "davfs";
|
fsType = "davfs";
|
||||||
# options = [
|
options = [
|
||||||
# # https://www.freedesktop.org/software/systemd/man/latest/systemd.mount.html
|
# https://www.freedesktop.org/software/systemd/man/latest/systemd.mount.html
|
||||||
# "nofail,_netdev"
|
"nofail,_netdev"
|
||||||
# "uid=1000,gid=100,dir_mode=0755,file_mode=0755"
|
"uid=1000,gid=100,dir_mode=0750,file_mode=0750"
|
||||||
# ];
|
];
|
||||||
# };
|
};
|
||||||
# davfs2 reads its credentials from /etc/davfs2/secrets
|
# davfs2 reads its credentials from /etc/davfs2/secrets
|
||||||
# environment.etc."davfs2/secrets".source = config.age.secrets."davfs-secrets".path;
|
environment.etc."davfs2/secrets" = {
|
||||||
|
source = config.age.secrets."davfs-secrets".path;
|
||||||
|
mode = "0600";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,30 @@ let
|
|||||||
unlockDisk = "data-encrypted";
|
unlockDisk = "data-encrypted";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
# Bind-mount a dedicated backing directory (/data-ro) onto /data as read-only.
|
||||||
|
# Using a separate source instead of a self-bind avoids the duplicate mount
|
||||||
|
# entries that a self-bind (device == mountpoint) would produce in lsblk.
|
||||||
|
# Disk subvolumes (/data/apps, /data/fileshare, …) are mounted on top by
|
||||||
|
# systemd automatically (path-hierarchy ordering). If any subvolume fails
|
||||||
|
# (nofail), its subdirectory falls back to this read-only layer and ALL
|
||||||
|
# writes — including root — are rejected with EROFS.
|
||||||
|
fileSystems."/data" = {
|
||||||
|
device = "/data-ro";
|
||||||
|
fsType = "none";
|
||||||
|
options = [
|
||||||
|
"bind"
|
||||||
|
"ro"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Pre-create the backing directory and subvolume mountpoints on the root
|
||||||
|
# filesystem. activation runs before sysinit.target (before all mount
|
||||||
|
# units), and writes to /data-ro (not the ro-mounted /data), so this is
|
||||||
|
# safe to re-run on nixos-rebuild switch.
|
||||||
|
system.activationScripts.data-ro-backing.text = ''
|
||||||
|
mkdir -p /data-ro/fileshare /data-ro/apps /data-ro/backups /data-ro/apps-snapshots
|
||||||
|
'';
|
||||||
|
|
||||||
fileSystems."/data/fileshare/public".depends = [ "/data/fileshare" ];
|
fileSystems."/data/fileshare/public".depends = [ "/data/fileshare" ];
|
||||||
|
|
||||||
# By adding this crypttab entry, the disk will be unlocked by systemd-cryptsetup@xxx.service at boot time.
|
# By adding this crypttab entry, the disk will be unlocked by systemd-cryptsetup@xxx.service at boot time.
|
||||||
|
|||||||
@@ -5,12 +5,21 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
# Read SFTPGO_DEFAULT_ADMIN_USERNAME and SFTPGO_DEFAULT_ADMIN_PASSWORD from a file
|
# Read SFTPGO_DEFAULT_ADMIN_USERNAME and SFTPGO_DEFAULT_ADMIN_PASSWORD from a file
|
||||||
systemd.services.sftpgo.serviceConfig.EnvironmentFile = config.age.secrets."sftpgo.env".path;
|
systemd.services.sftpgo.serviceConfig = {
|
||||||
|
EnvironmentFile = config.age.secrets."sftpgo.env".path;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Join the shared fileshare group (defined globally in user-group.nix) so
|
||||||
|
# sftpgo can read/write files created by transmission, and vice versa.
|
||||||
|
users.users.${user}.extraGroups = [ "fileshare" ];
|
||||||
|
|
||||||
# Create Directories
|
# Create Directories
|
||||||
# https://www.freedesktop.org/software/systemd/man/latest/tmpfiles.d.html#Type
|
# https://www.freedesktop.org/software/systemd/man/latest/tmpfiles.d.html#Type
|
||||||
|
# Mode 2775: setgid ensures new files/dirs inherit the 'fileshare' group
|
||||||
|
# regardless of the creating process's primary group.
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d ${dataDir} 0755 ${user} ${user}"
|
"d ${dataDir} 0755 ${user} ${user} -"
|
||||||
|
"d /data/fileshare/public 2775 root fileshare -"
|
||||||
];
|
];
|
||||||
|
|
||||||
services.sftpgo = {
|
services.sftpgo = {
|
||||||
|
|||||||
@@ -9,6 +9,17 @@ let
|
|||||||
name = "transmission";
|
name = "transmission";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
# Join the shared fileshare group so transmission can read/write files
|
||||||
|
# created by sftpgo, and vice versa (via setgid directories).
|
||||||
|
users.users.${name}.extraGroups = [ "fileshare" ];
|
||||||
|
|
||||||
|
# Set up transmission's home dir with setgid + fileshare group ownership.
|
||||||
|
# The setgid bit (2) causes all files created here to inherit the group
|
||||||
|
# 'fileshare', regardless of which service creates them.
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d ${dataDir} 2775 ${name} fileshare -"
|
||||||
|
];
|
||||||
|
|
||||||
# the headless Transmission BitTorrent daemon
|
# the headless Transmission BitTorrent daemon
|
||||||
# https://github.com/NixOS/nixpkgs/blob/nixos-25.11/nixos/modules/services/torrent/transmission.nix
|
# https://github.com/NixOS/nixpkgs/blob/nixos-25.11/nixos/modules/services/torrent/transmission.nix
|
||||||
# https://wiki.archlinux.org/title/transmission
|
# https://wiki.archlinux.org/title/transmission
|
||||||
@@ -18,7 +29,8 @@ in
|
|||||||
user = name;
|
user = name;
|
||||||
group = name;
|
group = name;
|
||||||
home = dataDir;
|
home = dataDir;
|
||||||
downloadDirPermissions = "0770";
|
# 2770: setgid preserves fileshare group on download/incomplete dirs.
|
||||||
|
downloadDirPermissions = "2770";
|
||||||
|
|
||||||
# Whether to enable tweaking of kernel parameters to open many more connections at the same time.
|
# Whether to enable tweaking of kernel parameters to open many more connections at the same time.
|
||||||
# Note that you may also want to increase peer-limit-global.
|
# Note that you may also want to increase peer-limit-global.
|
||||||
|
|||||||
@@ -19,6 +19,9 @@
|
|||||||
plugdev = { };
|
plugdev = { };
|
||||||
# misc
|
# misc
|
||||||
uinput = { };
|
uinput = { };
|
||||||
|
# shared group for services that read/write the same data directory
|
||||||
|
# (e.g. sftpgo + transmission on aquamarine)
|
||||||
|
fileshare = { };
|
||||||
};
|
};
|
||||||
|
|
||||||
users.users."${myvars.username}" = {
|
users.users."${myvars.username}" = {
|
||||||
@@ -36,6 +39,7 @@
|
|||||||
"wireshark"
|
"wireshark"
|
||||||
"adbusers" # android debugging
|
"adbusers" # android debugging
|
||||||
"libvirtd" # virt-viewer / qemu
|
"libvirtd" # virt-viewer / qemu
|
||||||
|
"fileshare"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -99,19 +99,11 @@ in
|
|||||||
}
|
}
|
||||||
// noaccess;
|
// noaccess;
|
||||||
|
|
||||||
# ---------------------------------------------
|
|
||||||
# only root can read this file.
|
|
||||||
# ---------------------------------------------
|
|
||||||
|
|
||||||
"wg-business.conf" = {
|
|
||||||
file = "${mysecrets}/wg-business.conf.age";
|
|
||||||
}
|
|
||||||
// high_security;
|
|
||||||
|
|
||||||
# Used only by NixOS Modules
|
# Used only by NixOS Modules
|
||||||
# smb-credentials is referenced in /etc/fstab, by ../hosts/ai/cifs-mount.nix
|
|
||||||
"smb-credentials" = {
|
# referenced in /etc/fstab to mount davfs volume
|
||||||
file = "${mysecrets}/smb-credentials.age";
|
"davfs-secrets" = {
|
||||||
|
file = "${mysecrets}/davfs-secrets.age";
|
||||||
}
|
}
|
||||||
// high_security;
|
// high_security;
|
||||||
|
|
||||||
@@ -138,11 +130,6 @@ in
|
|||||||
|
|
||||||
# place secrets in /etc/
|
# place secrets in /etc/
|
||||||
environment.etc = {
|
environment.etc = {
|
||||||
# wireguard config used with `wg-quick up wg-business`
|
|
||||||
"wireguard/wg-business.conf" = {
|
|
||||||
source = config.age.secrets."wg-business.conf".path;
|
|
||||||
};
|
|
||||||
|
|
||||||
"agenix/rclone.conf" = {
|
"agenix/rclone.conf" = {
|
||||||
source = config.age.secrets."rclone.conf".path;
|
source = config.age.secrets."rclone.conf".path;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user