merging in box

This commit is contained in:
Anish Lakhwara 2022-04-24 14:16:17 +10:00
parent cdd7baebb0
commit e950234ee1
27 changed files with 1115 additions and 122 deletions

View file

@ -118,7 +118,8 @@
suites = with profiles; rec { suites = with profiles; rec {
base = [ core users.root users.anish ]; base = [ core users.root users.anish ];
sealight = [ base server ]; # matrix rsshub backup wireguard sealight = [ base server ]; # matrix rsshub backup wireguard
mossnet = [ base server ]; # shaarli wallabag nextcloud taskwarrior headphones mossnet = [ base server ]; # taskd nextcloud networking wireguard shaarli mod-wallabag wallabag headphones dns backup monitoring dev gonic module-gonic cron nfs
cube = [ base site server ]; cube = [ base site server ];
graphical = [ base bluetooth music sync wireguard wifi desktop ]; graphical = [ base bluetooth music sync wireguard wifi desktop ];
curve = [ graphical secrets ]; curve = [ graphical secrets ];

View file

@ -0,0 +1,96 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# Use the GRUB 2 boot loader.
boot.loader.efi.canTouchEfiVariables = false;
boot.loader.efi.efiSysMountPoint = "/boot/efi";
boot.loader.grub = {
enable = true;
device = "nodev";
version = 2;
efiSupport = true;
enableCryptodisk = true;
efiInstallAsRemovable = true;
};
boot.initrd.secrets = {
"/keyfile0.bin" = /etc/secrets/initrd/keyfile0.bin;
"/keyfile1.bin" = /etc/secrets/initrd/keyfile1.bin;
};
boot.initrd.luks.devices = {
"root" = {
#name = "root";
device = "/dev/disk/by-uuid/f37f3222-47d7-42d8-b400-363320a31853"; # UUID for /dev/nvme01np2
preLVM = true;
allowDiscards = true;
keyFile = "/keyfile0.bin";
};
};
# Data mount
fileSystems."/data" = {
device = "/dev/disk/by-uuid/3276a297-9ee4-4998-b262-1ed100366c06"; # UUID for /dev/mapper/crypted-data
encrypted = {
enable = true;
label = "crypted-data";
blkDev = "/dev/disk/by-uuid/8a317bf4-fe13-4334-a6df-5fe5a5048b5e"; # UUID for /dev/sda1
keyFile = "/keyfile1.bin";
};
};
networking.interfaces.enp2s0 = {
ipv4.addresses = [{
address = "192.168.1.240";
prefixLength = 24;
} ];
ipv4.routes = [ { address = "192.168.1.0"; prefixLength = 24; via = "192.168.1.1"; }];
useDHCP = false;
};
#networking.nameservers = [ "172.16.11.240" ];
networking.nameservers = [ "192.168.1.1" ];
networking.defaultGateway = {
address = "192.168.1.1";
interface = "enp2s0";
};
networking.hostName = "box"; # Define your hostname.
networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
# Per-interface useDHCP will be mandatory in the future, so this generated config
# replicates the default behaviour.
networking.useDHCP = false;
networking.interfaces.wlp3s0.useDHCP = true;
networking.interfaces.enp2s0.useDHCP = false;
# Set your time zone.
time.timeZone = "Australia/Brisbane";
# Enable the OpenSSH daemon.
services.openssh.enable = true;
services.openssh.permitRootLogin = "yes";
networking.firewall.allowedTCPPorts = [ 22 ];
sound.enable = false;
programs.gnupg.agent.enable = true;
programs.gnupg.agent.pinentryFlavor = "curses";
programs.gnupg.agent.enableSSHSupport = true;
# This value determines the NixOS release with which your system is to be
# compatible, in order to avoid breaking some software such as database
# servers. You should change this only after NixOS release notes say you
# should.
system.stateVersion = "19.09"; # Did you read the comment?
}

View file

@ -0,0 +1,38 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/ade0752d-84d3-4e39-865b-9027ba2d5c67";
fsType = "ext4";
};
fileSystems."/boot/efi" =
{ device = "/dev/disk/by-uuid/1715-278E";
fsType = "vfat";
};
fileSystems."/data" =
{ device = "/dev/disk/by-uuid/3276a297-9ee4-4998-b262-1ed100366c06";
fsType = "ext4";
};
boot.initrd.luks.devices."crypted-data".device = "/dev/disk/by-uuid/8a317bf4-fe13-4334-a6df-5fe5a5048b5e";
swapDevices =
[ { device = "/dev/disk/by-uuid/b790abb4-ba5f-4476-8f09-b0fc575414aa"; }
];
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
}

109
modules/gonic.nix Normal file
View file

@ -0,0 +1,109 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.gonic;
configFile = "/etc/gonic/config";
dataFolder = "/var/lib/gonic";
in {
options = {
services.gonic = {
enable = mkEnableOption "Gonic music server and streamer";
settings = lib.mkOption {
type = types.str;
default = {};
example = literalExample ''
music-path <path to your music dir>
podcast-path <path to your podcasts dir>
cache-path <path to cache dir>
'';
description = ''
Configuration for Gonic, see <link xlink:href="https://github.com/sentriz/gonic"/> for supported values.
'';
};
user = mkOption {
type = types.str;
default = "gonic";
description = "User account under which gonic runs.";
};
group = mkOption {
type = types.str;
default = "gonic";
description = "Group account under which gonic runs.";
};
};
};
config = mkIf cfg.enable {
environment.etc."gonic/config".text = cfg.settings;
systemd.services.gonic = {
description = "gonic Music Server and Streamer compatible with Subsonic/Airsonic";
after = [ "remote-fs.target" "network.target" ];
wantedBy = [ "multi-user.target" ];
environment = {
#GONIC_MUSIC_PATH
#GONIC_PODCAST_PATH
#GONIC_CACHE_PATH
#GONIC_DB_PATH
GONIC_SCAN_INTERVAL="800";
#...
};
serviceConfig = {
ExecStart = "${pkgs.gonic}/bin/gonic -config-path /etc/gonic/config";
WorkingDirectory = dataFolder;
TimeoutStopSec = "20";
KillMode = "process";
Restart = "on-failure";
RestartSec = "10";
User = cfg.user;
Group = cfg.group;
DevicePolicy = "closed";
NoNewPrivileges= " yes";
PrivateTmp = "yes";
PrivateUsers = "yes";
ProtectControlGroups = "yes";
ProtectKernelModules = "yes";
ProtectKernelTunables = "yes";
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
RestrictNamespaces = "yes";
RestrictRealtime = "yes";
SystemCallFilter = "~@clock @debug @module @mount @obsolete @privileged @reboot @setuid @swap";
ReadWritePaths = dataFolder;
StateDirectory = baseNameOf dataFolder;
};
};
users.users = optionalAttrs (cfg.user == "gonic") ({
gonic = {
description = "gonic service user";
name = cfg.user;
group = cfg.group;
isSystemUser = true;
};
});
users.groups = optionalAttrs (cfg.group == "gonic") ({
gonic = {};
});
services.nginx.virtualHosts."music.mossnet.lan" = {
enableACME = false;
forceSSL = false;
locations."/" = {
extraConfig = ''
proxy_pass http://localhost:4747/;
proxy_set_header X-Forwarded-Host $host;
'';
};
};
};
}

12
modules/grasp.nix Normal file
View file

@ -0,0 +1,12 @@
{ config, lib, pkgs, ...}:
{
systemd.services.grasp = {
description = "grasp server";
wantedBy = [ "default.target" ];
serviceConfig = {
ExecStart = "{$pkgs.grasp}/server/grasp_server.py --path /data/grasp/capture.org";
};
};
}

220
modules/wallabag.nix Normal file
View file

@ -0,0 +1,220 @@
{ config, options, lib, pkgs, ... }:
with lib;
let
cfg = config.services.wallabag;
poolName = "wallabag";
configFile = pkgs.writeTextFile {
name = "wallabag-config";
text = cfg.conf;
destination = "/config/parameters.yml";
};
appDir = pkgs.buildEnv {
name = "wallabag-app-dir";
ignoreCollisions = true;
checkCollisionContents = false;
paths = [ configFile "${cfg.package}/app" ];
};
in {
options = {
services.wallabag = {
enable = mkEnableOption "wallabag";
user = mkOption {
type = types.str;
default = "nginx";
description = ''
User account under which both the update daemon and the web-application run.
'';
};
dataDir = mkOption {
type = types.path;
default = "/var/lib/wallabag";
description = ''
Data directory.
'';
};
package = mkOption {
type = types.package;
default = pkgs.wallabag;
description = ''
Wallabag package to use.
'';
};
hostName = mkOption {
type = types.str;
description = ''
Name of the nginx virtualhost to use and setup.
'';
};
poolConfig = mkOption {
type = types.lines;
default = ''
pm = dynamic
pm.max_children = 75
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 20
pm.max_requests = 500
catch_workers_output = 1
'';
description = ''
Options for wallabag's PHP pool. See the documentation on <literal>php-fpm.conf</literal> for details on configuration directives.
'';
};
conf = mkOption {
type = types.str;
description = ''
Contents of the wallabag configuration file (parameters.yml)
'';
};
};
};
config = mkIf cfg.enable {
services.phpfpm.pools."${poolName}" = {
user = "${cfg.user}";
group = "nginx";
settings = {
"listen.owner" = "nginx";
"listen.group" = "nginx";
"listen.mode" = "0600";
"user" = "${cfg.user}";
"group" = "nginx";
"env[WALLABAG_DATA]" = "${cfg.dataDir}";
"pm" = "dynamic";
"pm.max_children" = "75";
"pm.min_spare_servers" = "5";
"pm.max_spare_servers" = "20";
"pm.max_requests" = "10";
"catch_workers_output" = "1";
"php_admin_value[error_log]" = "/var/log/nginx/${poolName}-phpfpm-error.log";
};
};
services.phpfpm.phpOptions = ''
max_execution_time = 120
'';
services.nginx.enable = mkDefault true;
services.nginx.virtualHosts."${cfg.hostName}" = {
enableACME = false;
forceSSL = false;
root = "${cfg.package}/web";
extraConfig = ''
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
'';
locations."/" = {
extraConfig = ''
try_files $uri /app.php$is_args$args;
'';
};
locations."/assets".root = "${cfg.dataDir}/web";
locations."~ ^/app\\.php(/|$)" = {
extraConfig = ''
fastcgi_pass unix:${config.services.phpfpm.pools."${poolName}".socket};
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME ${cfg.package}/web/$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT ${cfg.package}/web;
fastcgi_read_timeout 120;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
internal;
'';
};
locations."~ /(?!app)\\.php$" = {
extraConfig = ''
return 404;
'';
};
};
systemd.services.wallabag-install = {
description = "Wallabag install service";
wantedBy = [ "multi-user.target" ];
before = [ "phpfpm-wallabag.service" ];
after = [ "mysql.service" "postgresql.service" ];
path = with pkgs; [ coreutils php phpPackages.composer ];
serviceConfig = {
User = cfg.user;
Type = "oneshot";
RemainAfterExit = "yes";
PermissionsStartOnly = true;
};
preStart = ''
mkdir -p "${cfg.dataDir}"
chown ${cfg.user}:nginx "${cfg.dataDir}"
'';
script = ''
echo "Setting up wallabag files in ${cfg.dataDir} ..."
cd "${cfg.dataDir}"
rm -rf var/cache/*
rm -f app
ln -sf ${appDir} app
ln -sf ${cfg.package}/composer.{json,lock} .
export WALLABAG_DATA="${cfg.dataDir}"
if [ ! -f installed ]; then
php ${cfg.package}/bin/console --env=prod doctrine:database:create --if-not-exists --no-interaction
php ${cfg.package}/bin/console --env=prod doctrine:migrations:migrate --no-interaction
# Until https://github.com/wallabag/wallabag/issues/3662 is fixed
# yes no | php ${cfg.package}/bin/console --env=prod wallabag:install
touch installed
else
php ${cfg.package}/bin/console --env=prod doctrine:migrations:migrate --no-interaction
fi
php ${cfg.package}/bin/console --env=prod cache:clear
'';
};
};
meta = with stdenv.lib; {
maintainers = with maintainers; [ nadrieril ];
};
}

22
pkgs/grasp.nix Normal file
View file

@ -0,0 +1,22 @@
{ python3, fetchFromGitHub, lib }:
python3.pkgs.buildPythonApplication rec {
pname = "grasp";
version = "0.6.6";
src = fetchFromGitHub {
owner = "karlicoss";
repo = pname;
rev = "grasp-${version}";
sha256 = "0000000000000000000000000000000000000000000000000000";
};
meta = with lib; {
description = "grasp server";
# License is complicated...
#license = licenses.agpl3;
homepage = "https://github.com/karlicoss/grasp";
platforms = platforms.all;
maintainers = with stdenv.lib.maintainers; [ chickensoupwithrice ];
};
}

9
pkgs/navidrome.nix Normal file
View file

@ -0,0 +1,9 @@
{ config, lib, pkgs, ... }:
{
services.navidrome.enable = true;
services.navidrome.settings = {
MusicFolder = "/data/music";
Port = 4433;
};
networking.firewall.allowedTCPPorts = [ 4433 ];
}

31
pkgs/wallabag.nix Normal file
View file

@ -0,0 +1,31 @@
diff --git a/app/AppKernel.php b/app/AppKernel.php
index 347197e..902b558 100644
--- a/app/AppKernel.php
+++ b/app/AppKernel.php
@@ -69,19 +69,24 @@ class AppKernel extends Kernel
return __DIR__;
}
+ public function getProjectDir()
+ {
+ return getenv('WALLABAG_DATA') ?: dirname(__DIR__);
+ }
+
public function getCacheDir()
{
- return dirname(__DIR__) . '/var/cache/' . $this->getEnvironment();
+ return $this->getProjectDir() . '/var/cache/' . $this->getEnvironment();
}
public function getLogDir()
{
- return dirname(__DIR__) . '/var/logs';
+ return $this->getProjectDir() . '/var/logs';
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
- $loader->load($this->getRootDir() . '/config/config_' . $this->getEnvironment() . '.yml');
+ $loader->load($this->getProjectDir() . '/app/config/config_' . $this->getEnvironment() . '.yml');
$loader->load(function ($container) {

View file

@ -0,0 +1,34 @@
{
# Assumes the remote borg backup server has already been initialized
# borg init --encryption-key=repokey-blake2 -rsh 'ssh -i /run/keys/id_ed25519_borgbase' 20779@hk-s020.rsync.net:<borg-archive>
services.borgbackup.jobs = {
backupTaskwarriorRsync = {
paths = [ "/var/lib/taskserver" ];
doInit = true;
repo = "20779@hk-s020.rsync.net:taskwarrior" ;
encryption = {
mode = "repokey-blake2";
passCommand = "cat /run/keys/rsync";
};
environment = { BORG_RSH = "ssh -i /run/keys/id_ed25519_borgbase"; };
compression = "auto,lzma";
startAt = "weekly";
extraArgs = "--remote-path=borg1";
};
};
services.borgbackup.jobs = {
backupShaarliRsync = {
paths = [ "/var/www/shaarli-config/data/datastore.php" "/var/www/shaarli-config/config" "/var/www/shaarli-config/.json.config" ];
doInit = true;
repo = "20779@hk-s020.rsync.net:shaarli" ;
encryption = {
mode = "repokey-blake2";
passCommand = "cat /run/keys/rsync";
};
environment = { BORG_RSH = "ssh -i /run/keys/id_ed25519_borgbase"; };
compression = "auto,lzma";
startAt = "weekly";
extraArgs = "--remote-path=borg1";
};
};
}

28
profiles/box-zone/box.nix Normal file
View file

@ -0,0 +1,28 @@
{ config, pkgs, ... }:
{
imports = [
./common.nix
./mossnet.nix
];
users.extraUsers."anish".extraGroups = [ "jackaudio" ];
# services.xserver = {
# enable = true;
# displayManager.gdm.enable = true;
# desktopManager.gnome3.enable = true;
# };
# task whisperer broken
#nixpkgs.config.allowBroken = true;
# virtual box
virtualisation.virtualbox.host.enable = true;
# ErgoDox Firmware (doesn't compile)
# environment.systemPackages = with pkgs; [
# qmk_firmware
# ];
}

View file

@ -0,0 +1,120 @@
{ config, pkgs, ... }:
{
imports = [
./nvim.nix
# ./unstable.nix
];
environment.systemPackages = with pkgs; [
tailscale
htop
fzf
iftop
wget
curl
exa
bat
fd
ag
wpa_supplicant
tcpdump
whois
mtr
file
lsof
atool
inotify-tools
strace
zip
unzip
rsync
tmux
pwgen
glow
jq
gitAndTools.gitFull
#neovim defined in ./nvim.nix
# wofi
# firefox
# fractal
# pinentry_gnome
pinentry_curses
pass
gcc
less
# mpv
# zathura
#qmk_firmware
python3
gdb
# vcv-rack
#xdotool
#neofetch
#calibre
#openvpn
#gimp
xxd
# tilix
# kitty
taskwarrior
gnupg
openjdk
glslviewer
#filezilla
# signal-desktop
# wire-desktop
# tdesktop
# feedreader
#newsflash
# syncthing
dijo
#ssb-patchwork
#gnomeExtensions.taskwhisperer
#gnome3.networkmanager-openvpn
#python3Packages.youtube-dl
#appimage-run
home-manager
libreoffice
fontconfig
#hugo
#processing
#nextcloud-client
zsh-powerlevel10k
powerline-fonts
supercollider
haskellPackages.tidal
pandoc
# calibre
];
programs.bash.enableCompletion = true;
programs.gnupg.agent.enable = true;
programs.gnupg.agent.pinentryFlavor = "curses";
programs.gnupg.agent.enableSSHSupport = true;
# needed for vcv-rack
nixpkgs.config.allowUnfree = true;
system.copySystemConfiguration = true;
#services.syncthing = {
# enable = true;
# openDefaultPorts = true;
# systemService = true;
# user = "anish";
# dataDir = "/home/anish/usr/syncthing";
#};
#zsh powerlevel10k
#programs.zsh.enable = true;
#programs.zsh.promptInit = "source ${pkgs.zsh-powerlevel10k}/share/zsh-powerlevel10k/powerlevel10k.zsh-theme";
users.users.anish.shell = pkgs.bash;
#android
programs.adb.enable = true;
users.users.anish.extraGroups = ["adbusers"];
#ssh
services.sshd.enable = true;
}

View file

@ -0,0 +1,28 @@
{config, pkgs, ...}:
{
imports = [
./taskd.nix
./nextcloud.nix
./networking.nix
./wireguard.nix
./shaarli.nix
## ./navidrome.nix
## ./pkg-navidrome.nix
./mod-wallabag.nix
./wallabag.nix
./headphones.nix
./dns.nix
./backup.nix
./monitoring.nix
./dev.nix
./gonic.nix
./module-gonic.nix
# ./rss-bridge.nix
# ./pkg-grasp.nix
# ./mod-grasp.nix
./cron.nix
./ftp.nix
./nfs.nix
];
}

16
profiles/dns/dns.nix Normal file
View file

@ -0,0 +1,16 @@
{ config, pkgs, lib, ... }:
{
services.dnsmasq.enable = true;
services.dnsmasq.extraConfig = ''
domain-needed
no-resolv
local=/lan/
local=/moss/
cache-size=5000
addn-hosts=/ec/adblock.hosts
'';
services.dnsmasq.servers = [ "45.90.30.49" "45.90.28.49" "1.1.1.1" "8.8.8.8" ];
networking.hosts = {"192.168.1.240" = ["mossnet.lan" "links.mossnet.lan" "read.mossnet.lan" "stats.mossnet.lan" "music.moss" "tasks.moss" "headphones.moss" "cloud.moss" "links.moss" "read.moss" "stats.moss" "rss.moss"];};
networking.firewall.allowedTCPPorts = [ 53 ];
networking.firewall.allowedUDPPorts = [ 53 ];
}

20
profiles/ftp/default.nix Normal file
View file

@ -0,0 +1,20 @@
{ pkgs, lib, ... }:
{
networking.firewall.allowedTCPPorts = [ 20 21 ];
networking.firewall.allowedTCPPortRanges = [ { from = 51000; to = 51999; } ];
services.vsftpd = {
enable = true;
writeEnable = true;
anonymousUser = true;
anonymousUserNoPassword = true;
anonymousUploadEnable = true;
anonymousMkdirEnable = true;
anonymousUserHome = "/home/ftp";
extraConfig = ''
pasv_enable=Yes
pasv_min_port=51000
pasv_max_port=51999
'';
};
}

View file

@ -42,18 +42,18 @@
}; };
services.loki = { services.loki = {
enable = true; #enable = true;
configFile = /var/loki-config.yaml; #configFile = /var/loki-config.yaml;
}; };
systemd.services.promtail = { #systemd.services.promtail = {
description = "Promtail service for Loki"; # description = "Promtail service for Loki";
wantedBy = [ "multi-user.target" ]; # wantedBy = [ "multi-user.target" ];
serviceConfig = { # serviceConfig = {
ExecStart = '' # ExecStart = ''
${pkgs.grafana-loki}/bin/promtail --config.file ${/var/promtail.yaml} # ${pkgs.grafana-loki}/bin/promtail --config.file ${/var/promtail.yaml}
''; # '';
}; # };
}; #};
} }

View file

@ -0,0 +1,101 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.navidrome;
configFile = "/etc/navidrome/settings.json";
dataFolder = "/var/lib/navidrome";
in {
options = {
services.navidrome = {
enable = mkEnableOption "Navidrome music server and streamer";
settings = lib.mkOption {
type = with types; attrsOf (oneOf [ int str ]);
default = {};
example = literalExample ''
{
LogLevel = "INFO";
BaseURL = "/music";
ScanInterval = "10s";
TranscodingCacheSize = "15MB";
MusicFolder = "/data/music";
};
'';
description = ''
Configuration for Navidrome, see <link xlink:href="https://www.navidrome.org/docs/usage/configuration-options/"/> for supported values.
'';
};
user = mkOption {
type = types.str;
default = "navidrome";
description = "User account under which Navidrome runs.";
};
group = mkOption {
type = types.str;
default = "navidrome";
description = "Group account under which Navidrome runs.";
};
};
};
config = mkIf cfg.enable {
environment.etc."navidrome/settings.json".text = builtins.toJSON cfg.settings;
services.navidrome.settings = {
DataFolder = dataFolder;
ConfigFile = configFile;
};
systemd.services.navidrome = {
description = "Navidrome Music Server and Streamer compatible with Subsonic/Airsonic";
after = [ "remote-fs.target" "network.target" ];
wantedBy = [ "multi-user.target" ];
environment = {
ND_CONFIGFILE = configFile;
};
serviceConfig = {
ExecStart = "${pkgs.navidrome}/bin/navidrome";
WorkingDirectory = dataFolder;
TimeoutStopSec = "20";
KillMode = "process";
Restart = "on-failure";
User = cfg.user;
Group = cfg.group;
DevicePolicy = "closed";
NoNewPrivileges= " yes";
PrivateTmp = "yes";
PrivateUsers = "yes";
ProtectControlGroups = "yes";
ProtectKernelModules = "yes";
ProtectKernelTunables = "yes";
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
RestrictNamespaces = "yes";
RestrictRealtime = "yes";
SystemCallFilter = "~@clock @debug @module @mount @obsolete @privileged @reboot @setuid @swap";
ReadWritePaths = dataFolder;
StateDirectory = baseNameOf dataFolder;
};
};
users.users = optionalAttrs (cfg.user == "navidrome") ({
navidrome = {
description = "Navidrome service user";
name = cfg.user;
group = cfg.group;
isSystemUser = true;
};
});
users.groups = optionalAttrs (cfg.group == "navidrome") ({
navidrome = {};
});
};
}

View file

@ -1,7 +1,5 @@
{ pkgs, config, ... }: { pkgs, config, ... }:
{ {
age.secrets.nextcloud-db.file = "/etc/nixos/secrets/nextcloud-db.age";
age.secrets.nextcloud-admin.file = "/etc/nixos/secrets/nextcloud-admin.age";
services.nextcloud = { services.nextcloud = {
enable = true; enable = true;
hostName = "mossnet.lan"; hostName = "mossnet.lan";
@ -25,8 +23,9 @@
dbuser = "nextcloud"; dbuser = "nextcloud";
dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
dbname = "nextcloud"; dbname = "nextcloud";
dbpassFile = "/run/secrets/nextcloud-db"; dbpassFile = "/var/nextcloud-db-pass";
adminpassFile = "/run/secrets/nextcloud-admin";
adminpassFile = "/var/nextcloud-admin-pass";
adminuser = "admin"; adminuser = "admin";
}; };
}; };
@ -38,8 +37,7 @@
# Ensure the database, user, and permissions always exist # Ensure the database, user, and permissions always exist
ensureDatabases = [ "nextcloud" ]; ensureDatabases = [ "nextcloud" ];
ensureUsers = [ ensureUsers = [
{ { name = "nextcloud";
name = "nextcloud";
ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES"; ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
} }
]; ];

32
profiles/nfs/default.nix Normal file
View file

@ -0,0 +1,32 @@
{
#fileSystems."/export/" = {
# device = "/mnt/mafuyu";
# options = [ "bind" ];
#};
services.nfs.server = {
enable = true;
# fixed rpc.statd port; for firewall
lockdPort = 4001;
mountdPort = 4002;
statdPort = 4000;
extraNfsdConfig = '''';
exports = ''
/home/ftp 192.168.1.0/24(rw)
'';
};
networking.firewall = {
allowedTCPPorts = [ 111 2049 4000 4001 4002 20048 ];
allowedUDPPorts = [ 111 2049 4000 4001 4002 20048 ];
};
#systemd.services.create-mount-dir = {
# serviceConfig = {
# ExecStart = "mkdir /export";
# };
# wantedBy = [ "multi-user.target" ];
# after = [ "remote-fs.target" ];
# description = "Create a directory we can mount on fs";
#};
}

View file

@ -0,0 +1,8 @@
{pkgs, lib, config, ...}:
{
services.rss-bridge = {
enable = true;
virtualHost = "rss.moss";
whitelist = [ "Facebook" "Bandcamp" "Twitter" "Telegram"];
};
}

View file

@ -0,0 +1,10 @@
{ pkgs, lib, ... }:
{
services.cron = {
enable = true;
systemCronJobs = [
"* */24 * * * * anish ~/get-music.sh"
];
};
}

9
profiles/sync/get-music.sh Executable file
View file

@ -0,0 +1,9 @@
#!/usr/bin/env bash
rsync -r --ignore-existing --log-file=/data/incoming/download-log hypercube@talos.feralhosting.com:private/transmission/data/* /data/incoming
# you need to set defaults for beets
# if already imported -> Skip
# Auto accept changes
# also install it lmao
#beet import /data/incoming

View file

@ -1,9 +1,61 @@
{ config, pkgs, ... }: { config, pkgs, lib, ... }:
{ {
services.taskserver.enable = true; services.tailscale.enable = true;
services.taskserver.fqdn = "task.moss"; networking.firewall.allowedUDPPorts = [ 60990 ];
services.taskserver.listenHost = "172.16.11.240";
services.taskserver.listenPort = 53589; # Enable WireGuard
services.taskserver.organisations.mossnet.users = [ "anish" ]; networking.wireguard.interfaces = {
# "wg0" is the network interface name. You can name the interface arbitrarily.
wg0 = {
# Determines the IP address and subnet of the client's end of the tunnel interface.
ips = [ "10.0.69.4/24" ];
listenPort = 60990; # to match firewall allowedUDPPorts (without this wg uses random port numbers)
# Path to the private key file.
#
# Note: The private key can also be included inline via the privateKey option,
# but this makes the private key world-readable; thus, using privateKeyFile is
# recommended.
privateKeyFile = "/home/anish/wg/privkey";
peers = [
# For a client configuration, one peer entry for the server will suffice.
{
# Public key of the server (not a file path).
publicKey = "c1J4p63rD3IlszugMZiki7UBV3YmDdqa3DU4UejXzAI=";
# Forward all the traffic via VPN.
allowedIPs = [ "10.0.69.0/24" ];
# Or forward only particular subnets
#allowedIPs = [ "10.100.0.1" "91.108.12.0/22" ];
# Set this to the server IP and port.
endpoint = "sealight.xyz:60990"; # ToDo: route to endpoint not automatically configured https://wiki.archlinux.org/index.php/WireGuard#Loop_routing https://discourse.nixos.org/t/solved-minimal-firewall-setup-for-wireguard-client/7577
# Send keepalives every 25 seconds. Important to keep NAT tables alive.
persistentKeepalive = 25;
}
];
};
};
# boot.extraModulePackages = with config.boot.kernelPackages; [ wireguard ];
# environment.systemPackages = [ pkgs.wireguard ];
# networking.wireguard.enable = true;
# networking.wireguard.interfaces = {
# wg0 = {
# ips = [ "10.0.69.4/32" ];
# privateKeyFile = "/home/anish/wg/privkey";
# listenPort = 60990;
#
# peers = [
# { # helix - server
# publicKey = "{c1J4p63rD3IlszugMZiki7UBV3YmDdqa3DU4UejXzAI=}";
# allowedIPs = [ "10.0.69.1/24" ];
# endpoint = "sealight.xyz:60990";
# persistentKeepalive = 25;
# } ];
# };
# };
} }

View file

@ -7,8 +7,7 @@
# Ensure the database, user, and permissions always exist # Ensure the database, user, and permissions always exist
ensureDatabases = [ "wallabag" ]; ensureDatabases = [ "wallabag" ];
ensureUsers = [ ensureUsers = [
{ { name = "wallabag";
name = "wallabag";
ensurePermissions."DATABASE wallabag" = "ALL PRIVILEGES"; ensurePermissions."DATABASE wallabag" = "ALL PRIVILEGES";
} }
]; ];