Compare commits

..

No commits in common. "e8054965889e634163caebea41c507f640d4c268" and "673ead7863bec924ffc3ba7c971423c9b5d02e27" have entirely different histories.

177 changed files with 532 additions and 851 deletions

View file

@ -4,9 +4,9 @@ type: exec
name: NixOS config check
steps:
- name: nix flake check
- name: format check
commands:
- nix flake check
- nix develop -c nixpkgs-fmt .
- name: notifiy
commands:

4
.git-crypt/.gitattributes vendored Normal file
View file

@ -0,0 +1,4 @@
# Do not edit this file. To specify the files to encrypt, create your own
# .gitattributes file in the directory where your files are.
* !filter !diff
*.gpg binary

View file

@ -58,8 +58,6 @@ get_ssh() {
get_doc "SysAdmin/SSH" "shared-key-public" "$HOME/.ssh/shared_rsa.pub" 644
get_doc "SysAdmin/SSH" "shared-key-private" "$HOME/.ssh/shared_rsa" 600
get_doc "SysAdmin/SSH" "agenix-public" "$HOME/.ssh/id_ed25519.pub" 644
get_doc "SysAdmin/SSH" "agenix-private" "$HOME/.ssh/id_ed25519" 600
}
get_pgp() {

View file

@ -1,26 +1,5 @@
{
"nodes": {
"agenix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1631896269,
"narHash": "sha256-DAyCxJ8JacayOzGgGSfzrn7ghtsfL/EsCyk1NEUaAR8=",
"owner": "ryantm",
"repo": "agenix",
"rev": "daf1d773989ac5d949aeef03fce0fe27e583dbca",
"type": "github"
},
"original": {
"owner": "ryantm",
"ref": "master",
"repo": "agenix",
"type": "github"
}
},
"futils": {
"locked": {
"lastModified": 1629481132,
@ -116,7 +95,6 @@
},
"root": {
"inputs": {
"agenix": "agenix",
"futils": "futils",
"home-manager": "home-manager",
"nixpkgs": "nixpkgs",

View file

@ -1,16 +1,6 @@
{
description = "NixOS configuration with flakes";
inputs = {
agenix = {
type = "github";
owner = "ryantm";
repo = "agenix";
ref = "master";
inputs = {
nixpkgs.follows = "nixpkgs";
};
};
futils = {
type = "github";
owner = "numtide";
@ -57,7 +47,6 @@
outputs =
inputs @
{ self
, agenix
, futils
, home-manager
, nixpkgs
@ -85,6 +74,8 @@
./modules
# Include bundles of settings
./profiles
# Include my secrets
./secrets
];
buildHost = name: system: lib.nixosSystem {
@ -128,6 +119,7 @@
name = "NixOS-config";
nativeBuildInputs = with pkgs; [
git-crypt
gitAndTools.pre-commit
gnupg
nixpkgs-fmt

View file

@ -1,37 +1,38 @@
{ ... }:
{
imports = [
./bat
./bluetooth
./comma
./direnv
./documentation
./feh
./bat.nix
./bluetooth.nix
./comma.nix
./direnv.nix
./documentation.nix
./feh.nix
./firefox
./flameshot
./gammastep
./flameshot.nix
./gammastep.nix
./gdb
./git
./gpg
./gtk
./htop
./jq
./gpg.nix
./gtk.nix
./htop.nix
./jq.nix
./mail
./mpv
./nix-index
./nm-applet
./packages
./pager
./power-alert
./ssh
./mpv.nix
./nix-index.nix
./nm-applet.nix
./packages.nix
./pager.nix
./power-alert.nix
./secrets # Home-manager specific secrets
./ssh.nix
./terminal
./tmux
./udiskie
./tmux.nix
./udiskie.nix
./vim
./wm
./x
./xdg
./zathura
./xdg.nix
./zathura.nix
./zsh
];

View file

@ -23,7 +23,7 @@
};
imports = [
./firefox
./tridactyl
./firefox.nix
./tridactyl.nix
];
}

View file

@ -6,9 +6,9 @@ let
in
{
imports = [
./accounts
./himalaya
./msmtp
./accounts.nix
./himalaya.nix
./msmtp.nix
];
options.my.home.mail = with lib; {

3
home/secrets/.gitattributes vendored Normal file
View file

@ -0,0 +1,3 @@
* filter=git-crypt diff=git-crypt
.gitattributes !filter !diff
/default.nix !filter !diff

BIN
home/secrets/canary Normal file

Binary file not shown.

31
home/secrets/default.nix Normal file
View file

@ -0,0 +1,31 @@
{ lib, ... }:
with lib;
let
throwOnCanary =
let
canaryHash = builtins.hashFile "sha256" ./canary;
expectedHash =
"9df8c065663197b5a1095122d48e140d3677d860343256abd5ab6e4fb4c696ab";
in
if canaryHash != expectedHash
then throw "Secrets are not readable. Have you run `git-crypt unlock`?"
else id;
in
throwOnCanary {
options.my.secrets = mkOption {
type =
let
valueType = with types; oneOf [
int
str
(attrsOf valueType)
];
in
valueType;
};
config.my.secrets = {
# Home-manager secrets go here
};
}

View file

@ -10,7 +10,7 @@ let
in
{
imports = [
./termite
./termite.nix
];
options.my.home = with lib; {

View file

@ -10,11 +10,11 @@ let
in
{
imports = [
./dunst
./i3
./i3bar
./rofi
./screen-lock
./dunst.nix
./i3.nix
./i3bar.nix
./rofi.nix
./screen-lock.nix
];
options.my.home.wm = with lib; {

View file

@ -4,8 +4,8 @@ let
in
{
imports = [
./cursor
./keyboard
./cursor.nix
./keyboard.nix
];
options.my.home.x = with lib; {

View file

@ -1,7 +1,7 @@
# Deployed services
{ config, ... }:
let
secrets = config.age.secrets;
my = config.my;
in
{
# List services that you want to enable:
@ -19,8 +19,11 @@ in
OnActiveSec = "6h";
OnUnitActiveSec = "6h";
};
passwordFile = secrets."backup/password".path;
credentialsFile = secrets."backup/credentials".path;
# Insecure, I don't care.
passwordFile =
builtins.toFile "password.txt" my.secrets.backup.password;
credentialsFile =
builtins.toFile "creds.env" my.secrets.backup.credentials;
};
# My blog and related hosts
blog.enable = true;
@ -31,8 +34,11 @@ in
drone = {
enable = true;
runners = [ "docker" "exec" ];
secretFile = secrets."drone/gitea".path;
sharedSecretFile = secrets."drone/secret".path;
# Insecure, I don't care.
secretFile =
builtins.toFile "gitea.env" my.secrets.drone.gitea;
sharedSecretFile =
builtins.toFile "rpc.env" my.secrets.drone.secret;
};
# Flood UI for transmission
flood = {
@ -50,24 +56,28 @@ in
# Gitea mirrorig service
lohr = {
enable = true;
sharedSecretFile = secrets."lohr/secret".path;
sharedSecretFile =
let
content = "LOHR_SECRET=${my.secrets.lohr.secret}";
in
builtins.toFile "lohr-secret.env" content;
};
# Matrix backend and Element chat front-end
matrix = {
enable = true;
mailConfigFile = secrets."matrix/mail".path;
# Only necessary when doing the initial registration
# secret = "change-me";
mail = my.secrets.matrix.mail;
secret = my.secrets.matrix.secret;
};
miniflux = {
enable = true;
credentialsFiles = secrets."miniflux/credentials".path;
password = my.secrets.miniflux.password;
};
# Various monitoring dashboards
monitoring = {
enable = true;
grafana = {
passwordFile = secrets."monitoring/password".path;
passwordFile =
builtins.toFile "grafana.txt" my.secrets.monitoring.password; # Insecure, I don't care
};
};
# FLOSS music streaming server
@ -78,38 +88,29 @@ in
# Nextcloud self-hosted cloud
nextcloud = {
enable = true;
passwordFile = secrets."nextcloud/password".path;
password = my.secrets.nextcloud.password;
};
nginx = {
enable = true;
acme = {
credentialsFile = secrets."acme/dns-key".path;
};
sso = {
authKeyFile = secrets."sso/auth-key".path;
users = {
ambroisie = {
passwordHashFile = secrets."sso/ambroisie/password-hash".path;
totpSecretFile = secrets."sso/ambroisie/totp-secret".path;
};
};
groups = {
root = [ "ambroisie" ];
};
};
};
paperless = {
enable = true;
documentPath = "/data/media/paperless";
passwordFile = secrets."paperless/password".path;
secretKeyFile = secrets."paperless/secret-key".path;
# Insecure, I don't care
passwordFile =
builtins.toFile "paperless.env" my.secrets.paperless.password;
secretKey = my.secrets.paperless.secretKey;
};
# The whole *arr software suite
pirate.enable = true;
# Podcast automatic downloader
podgrab = {
enable = true;
passwordFile = secrets."podgrab/password".path;
passwordFile =
let
contents = "PASSWORD=${my.secrets.podgrab.password}";
in
builtins.toFile "podgrab.env" contents;
port = 9598;
};
# Regular backups
@ -125,7 +126,8 @@ in
# Torrent client and webui
transmission = {
enable = true;
credentialsFile = secrets."transmission/credentials".path;
username = "Ambroisie";
password = my.secrets.transmission.password;
};
# Simple, in-kernel VPN
wireguard = {

View file

@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDWVUvOT1/triPcj7wiLAmiVkPZ71crySbReetHaGxMYYdKNFurJQsP6BqsdCAwrGbduLUDJovLtjOM7SxghjkGqh2RZucj/zqpja8YoFqYTcLutlqa1NwUqQTq21azKBDSdvkBPWWyZhOKssnag+0bZRN3vVajoDrwAU6zJLhHh9eNESTEytAnZnllXsHB1dKF1p7FWVwYTGAc1PdHHSQNMkjg9aCM+VBzTHhp8nF+GOtGzt0A0XnoZGdhn6KqhKyH7KxwPMmeD3RNeCEmQY/TXjthOx/mBkgTEa8LWOBxdy/Rs6edUenvPcQ5tK5nX0GSxxqtbORlhT+tGiqq1UHeIUhXirBUaS7pnDo+Edc0m8ruLcwHwyQ5yVn2ts3daKxb87+PyjYiRxxeQXvbF84ef7ZOkLTEn0tnftFHLqszBfOjoV1DmMNSWPDULD3krObzNbr1I0xHE7bDRXw2t8L1cwHOLHTL9KwsTCw1d25JSxINp2wAZxlGVZLXoXVMKTjfx1xSGbUuRzA1Q6+1IH9WDvSSixDzvc2Dqnj91/xardivApK+T+OxTBurwWsxzEezIAbTCpoKW9ulzu06xWGWhxATkzUmVh/qhFUHAVlmhEvn0KqlYbWteEcUxgKS1uSAoA6+pZh5NMG1u1hLEktBQbDnS0VdyKYBUHZidLuR4w== ambroisie@porthos

View file

@ -10,6 +10,6 @@ in
group = "nginx";
createHome = false; # Messes with permissions
home = "/var/www/";
openssh.authorizedKeys.keyFiles = [ ./ssh/drone.pub ];
openssh.authorizedKeys.keys = [ my.secrets.drone.ssh.publicKey ];
};
}

View file

@ -4,9 +4,8 @@
{
imports = [
./hardware
./home
./home.nix
./programs
./secrets
./services
./system
];

View file

@ -3,11 +3,11 @@
{
imports = [
./bluetooth
./ergodox
./mx-ergo
./networking
./sound
./upower
./bluetooth.nix
./ergodox.nix
./mx-ergo.nix
./networking.nix
./sound.nix
./upower.nix
];
}

View file

@ -14,7 +14,7 @@ in
config = lib.mkIf cfg.enable {
home-manager = {
# Not a fan of out-of-directory imports, but this is a good exception
users.${config.my.user.name} = import ../../home;
users.${config.my.user.name} = import ../home;
# Nix Flakes compatibility
useGlobalPkgs = true;

View file

@ -3,6 +3,6 @@
{
imports = [
./steam
./steam.nix
];
}

View file

@ -1,10 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg 0bz3W8QcGaulxy+kDmM717jTthQpFOCwV9HkenFJEyo
NKeh1/JkX4WAWbOjUeKLMbsyCevnDf3a70FfYUav26c
-> ssh-ed25519 jPowng Q59ybJMMteOSB6hZ5m6UPP0N2p8jrDSu5vBYwPgGcRw
j420on2jSsfMsv4MDtiOTMIFjaXV7sIsrS+g4iab+68
-> z}.q-grease s2W<qM_Z t
n1Yfs/gmNsl/n9HtuKBIIT8iwIjYca2yxlh7Q1XAT1B+RZ8oGjW8yCPj1unbDGZL
e5BfLO3zgkEZnQ
--- FSgNKEdDeeTjCx9jN9UtOFl58mC/Lbu1PAYRGK0CZW4
U€¿+æ©jïÝ{gø`GŽ›ÆàˆQk]šóïdÐ6å˜úy5T²$Äñs~Ùh‰Ä£òÔ<C3B2>Fº¢ç%°vöÌm<C38C>

View file

@ -1,9 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg YlDuj9wwBKSHHvQOhfti1ah95vxDV3bLE+GElBkyTB0
KsMyd3L4GaQa0eDQps+bJXj+cpy0zUNvFXU8NAmtThI
-> ssh-ed25519 jPowng JB4UtNyZab4ab4Pep3acyMjwCbluuEPuI6YOQ/045Fo
P9qnrPDGpHJL1TyNqYdNfqkd21Yjn/5mlovorWy60j4
-> _6l|s-grease M ]2qMsa'w P] j0EE
W3CToUTg
--- 8aWYUi33mEIKFcFbphlDZumnBu9Xbj+j18dQbElx1v8
3$m(ø<>äÂTK±î·”eAZâ>dn:-­Òí‚¥ˆÅh.(<28>¶U²!rìx D3ô‡4Ø93~È»f{üƒšL¸Î þÆ£ÃØ>Þß^vl—¡Î-=„í¯ä£<C3A4>ÉU'â»(#;¤ªHñÆ@M%|ʦ

View file

@ -1,8 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg dgS4bezgtDi44R1A8am+J6zh80kUVYTo1heaxJCtzX4
F3w/62xwtqYa40NU7OvF9pnZzYz/5hACAGJfMA4e2zw
-> ssh-ed25519 jPowng lx81CK3yeNp9RjHCUFJeKYZlRzxBmXuADVBvRc13zCI
P7e75t8xU+ZkYmeQ8mmMfyZZsRdG1J8yrvSUkiWzkFQ
-> *z4/`-grease S/)a{e sFd";=
--- 15FVhqRTkoPFEeETRRyFQhsv4Fn19Ozlax0u8Zy9mNA
õ#+¥àÎvøSÈ4èá}<7D>§Rì%ίF4fnDœ˜J¹¤Z¸A¥Û™,_

View file

@ -1,29 +0,0 @@
{ config, inputs, lib, options, ... }:
{
imports = [
inputs.agenix.nixosModules.age
];
config.age = {
secrets =
let
toName = lib.removeSuffix ".age";
userExists = u: builtins.hasAttr u config.users.users;
# Only set the user if it exists, to avoid warnings
userIfExists = u: if userExists u then u else "root";
toSecret = name: { owner ? "root", ... }: {
file = ./. + "/${name}";
owner = lib.mkDefault (userIfExists owner);
};
convertSecrets = n: v: lib.nameValuePair (toName n) (toSecret n v);
secrets = import ./secrets.nix;
in
lib.mapAttrs' convertSecrets secrets;
sshKeyPaths = options.age.sshKeyPaths.default ++ [
# FIXME: hard-coded path, could be inexistent
"/home/ambroisie/.ssh/id_ed25519"
];
};
}

View file

@ -1,10 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg vLLu1kbzyGxr5sU/Dl4xf0uGO+gVsvODiqEJU21lwyI
LbJO4Go+8G7/UtFWjv+x7Nqhn7n+kge/oHP8dGCBnM8
-> ssh-ed25519 jPowng obxX4ojPwp/DaerFzVbK5hUnshebh/chriT3a7uqYEw
x9jpbBefJZHz8o1lEkr48XhT7sVAM5tq3tZ8M91CDDo
-> eZ.G`B3W-grease 6k|.\v
D0u3P4oCpPNnueqZAAYn71xEUGWlavwLTrEXJ+2tdYOX6BwwFReOlMZWIA+FikmZ
8Pg7dHnbYPWc33jMjv3UnNsxCGUsDw9C9NkI5vfZSLvUxQ
--- Cea09ivsGZeoWif7xbdrvfoGsoiD+tRh7HQsOL75cqE
tFa˜|GÐ, ìoå6Öù$ë×ý…U«"âwiß¹ªÈS½Ó¿î×ghµ6^Ð*=¬¦©[¬g1%çVuäápû©-™ï{`ÑPÅ(?&¼QV#îKeåX•4dß÷KÞ:šxt‰0LsbÆ6Þœßü Ð[¡ #E[¬í•¹ì>Ë)|cwÅëÑqŸÊö+cÄõ¶þÕw1$ÓÌý×Ò^I(wGÕ¡ç9>jIâ(yÌ!@O«ƉkE¼z]áí«Pk

View file

@ -1,9 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg 1+cLlzctgcM0FnVDwMPOAqBkvMcDBRg8SvCw4djI93Y
oV2XI4f1AvM9P591kZZ6NgJXa+SDtqGzCSgc4psOmxM
-> ssh-ed25519 jPowng Ufjfh1p350XxRPg95+/DHdmnl4lC0bbzUUlaxd1Bmxc
/RHwFDSn2ov+60r1uHUigrsn99+GmmKmlk4h4T2gbA0
-> *Lc$@-grease
pzVJAHy1qRq3jUrnFV0DDO7/hwV1US4Ogf0RsrVfX0xzbr73uJ003YjieVB25LqN
--- ME7/iVevyiguyhXugbkVFGzJV0yDccyKNlWbEZa/FmY
YžŠXjb2uþnd;i0íýX]…§é0þL„PÔT~óú ƒÙ^kc”$D×ÚÛr¹úu³¶fr€e¸¸þ<C2B8>+p•¨<E280A2><C2A8>&ãw®öϨ

View file

@ -1,9 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg HCVbkI26JjkBgm1L2cpunVui0PfHLNfnx6VczErF3A4
3jEHfT6wUqNNFZFaVeiNBUhSKZmuKclPmubDMsda5O8
-> ssh-ed25519 jPowng SyClv9kGtjRKSXdig27tiqp66wD1T8QsHeOD2JQl4QA
8zdtfSJEh5/bfu5tb6M8Jgy5CZPiWD8TLQDpzp6cTr0
-> 3r2-grease
Lg/G911eZjeZTw5xhqje26vDfJkcSro+gKQ5SUboxLMnaibNi1qTeRLR
--- Q5/fikhVPoK+NFujTso5V7cty4k/dQlzFlz5z9DkzYk
øt/ŒWAMuˆ"Þêð´<>ó-!@ ¨E1¯”<C2AF> äR[eŽhÖû3 ëŒÉÐScoÝBt1TýØb¨äÀ3möP×Tc¤feP

View file

@ -1,9 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg lmu3MinmydRHD0A/YVRRtopermfoBC8M8cTHfVanY1s
ygrtpZZJ7aeQTblNazpoP7DdifmDxHsE3DFJsIrWX5M
-> ssh-ed25519 jPowng X0cihOc+fBtmtrkEivIHQngdYIobezXEF1x+pHqNzAw
/+sw9x1NWY0anZhDMpAywBPrR0F4XCHaF9e8j/Yo/kI
-> 32;%1s-grease
JafjuSZty6a4NSO/y4y5wHWL8Mw
--- dwCl66vdpsL0MR5NWWvg3JUnQ2QZQBeW0Dj0l5tvOKY
oi,`ÓÜ#uÄwW%PoubÚ­cy8<79>ó ƒÃÉ><¿F‰Ååq…ÂKÃÇk0Çk/<2F>hÀ¥Ÿ5势ÝF+ýu‡ •e<06>¾Ÿ²óôbãè>1QŠ2®ñwn˜WbÖB˜âî<C3A2>iŸ^xurâ†- /llùÒÀÀ-ã=°7;jã0»I×%Fi¼<69>í€ø™A;Y†ìUd]KÅI0(½ ”øAg£Ðóž^†uG:äpkJŸ:q<>¢šWSaLw¯¿Ô!ïM³4ã L/ùZŇ®¢D¶-XéUb»vÊbPó0ÇÅfÂ9êú<08> †âJ`ÃX°ôÐOÅ!s{ÙÄQAšc€c;ÏÃÑ4öMíچݹ lxH&ïéöé{é}ÁäÛzZ¦œ9ûÊXžÜ“g‰]Vϱ•0gt¡¿…žw·

View file

@ -1,9 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg ociW6AZww4nfW0Dw0DB0WNgQbJ3MNkHPPZlA0z+o/mI
THAz89pjyrkxJB9tPQGgEwZrZX9OudWMnyzr0JiwzTA
-> ssh-ed25519 jPowng 1werbtuWK0DUFxq9mAWp/QzMHC1B8UfadutvK6+j9XE
YmAwYo3X00gMB9AyQfOsR82CUPAtxfuzCzP4OyYFxjc
-> 8g-grease N9DR4 .U<
--- Cwh2hPrM2RzRroJRw3XrP1khcpL0leTXfJ+T7WG57To
¡Â±jÏ°LæDFºðÔ xux<75>ý1
U/âàoÚGgoãË)Çê÷*Þï/Ç”dÈ"L#RõÄhW Íû«

View file

@ -1,10 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg OdLtFHbHbc28rUn47vgsVvXxFNg9nF+9y9R6XOK390Y
yQQYUPQGjN2+xrSqqBYa7/zS618KrVjX5Amw2MFuSLg
-> ssh-ed25519 jPowng NwUjiLtiXVi6XFmht5l1CxEs3gm0oN4vHYwDZyda7Q4
di6znVjNRO6QdqteVNkeot5Ko2NwWLe6v+zVR3f+o10
-> 4Vx%\(-grease ^^Z>EC91 R 2BJ d48Wip*s
yPiBgChRF31XgxccQFLO3MzRL7+5s29sfRoF3W1yUX6Bu59MpxD4D+n/jhLcxSH/
CxW7KaiOctNmPm5tWh6qjmgQ+V4bcAji5vo4FKs40l56cfyueEJj+Q
--- WUGF28zqK9E1AlOeeCtSHxFg6ikRy85gOoLtBd4m0y0
.|…rr>©†ðìì1ÅÆ2SÉž.×hw<12>w qºš%i˜øé *U^­)Öè'qžµO2ÓœümòQÝ7˜¯m`

View file

@ -1,10 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg zhpo89xef68JoeOFWzhdFshrj2BXXUCFPMLVJzv6EyE
fmJxJi5rmyai9qGwDo7iHg4BrObGre96KCpl+g91O6I
-> ssh-ed25519 jPowng INA6EZdy4J1p3QY5mfVOQXiLdOjIDaZR+CZMP+GfkXM
8Nf5soaxY5SEzeJca5kaJkx7ByOvc4NkJVetB7wpEmo
-> xjK'w-grease
f5v0cvlt4JbHlAwDOob86qOInWdlN/oohTg
--- NTGv4rr+MhJ/YeZhVHOjoS1V+zCHFf2itJYfK36R+wE
š×—®JÚ dő oŞę'YFUź@
r7”ă“_N$‰˙Ź–č‡>‚ˇę]hq»-¨FŰ°qX˙?Î| Ę

View file

@ -1,10 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg tZwn2usN6K62oS4vBa6boh9zEp/+cS4chP8boXG6SH4
Fr3kV8gUDoiDqMxPYWsHyww8umYhQEKhqbVBiVw5NeI
-> ssh-ed25519 jPowng wRbJl4G85obH/GluQBBsXE7MOvooEui65eqHfurvuQs
KqVZMBSyHhkayEdwI6ocmA4qhHY9zYJvg1CEKM1SOa0
-> 2E"/OFW-grease o Qp3HFe^
bGhCNicPqt7txqxUiEWXCFs1OuQLqOqHmjHSqYQv919dqYep/xBXzi/aRf3dsdvh
TCJCTvZG31Qxvikp
--- xKJGbdVp+Z5h0vCBleSF2zYYYd2S5i0y4szNqjRwrDY
Tª /N¯<4E>¨¹i7m4#³MhiñP¹šÒÞ›Á¥-ÏgI÷ñ±%@E†(iÿ7·ý©ýYg¦k±´"+㸠Àª(þ]o¨¸ý†ð<E280A0>@báÊÞ§+Ï[Y"ÿÌBóóCR[ >-Ë.4d…¤b9v

View file

@ -1,9 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg 8rcBI7fYHuA3jO6EzJNFaAj2niIApKDt1HQEv61AKTs
ANxkIX/CeI7t7Zqp6wmjt/D194Z+xpeiidb+qvYzoQU
-> ssh-ed25519 jPowng oruewwTM9X/HjjcmOPcQVdp02rQBlgJPdzvlAffs3T0
MrO0kaNhjgOkNHuz3NrIMWXNrXOHH9dT/Fk6hoQNKyY
-> COK%H7-grease
6yfI90QurOKlM+kgpW8KZ/iBzDYD9yhNmjG1LQ
--- uArz8eHg8sLO0sdlkM6cELFh+FHiI5BrM0+iXJxxiDo
¿vývû´ÊNÊbæ@Ÿ¡Â<C2A1>FÛMMíYËÆíÌ&‰’/%¤¹Ñm¨®ØtÁÖ“ªd†h„­|¡ðŒß©8¼Ž Ú½¨9®<11>Cã¯/Å

View file

@ -1,59 +0,0 @@
let
# FIXME: read them from directories
ambroisie = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMIVd6Oh08iUNb1vTULbxGpevnh++wxsWW9wqhaDryIq ambroisie@agenix";
users = [ ambroisie ];
porthos = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICGzznQ3LSmBYHx6fXthgMDiTcU5i/Nvj020SbmhzAFb root@porthos";
machines = [ porthos ];
all = users ++ machines;
in
{
"acme/dns-key.age".publicKeys = all;
"backup/password.age".publicKeys = all;
"backup/credentials.age".publicKeys = all;
"drone/gitea.age".publicKeys = all;
"drone/secret.age".publicKeys = all;
"drone/ssh/private-key.age".publicKeys = all;
"lohr/secret.age".publicKeys = all;
"matrix/mail.age" = {
owner = "matrix-synapse";
publicKeys = all;
};
"matrix/secret.age".publicKeys = all;
"miniflux/credentials.age".publicKeys = all;
"monitoring/password.age" = {
owner = "grafana";
publicKeys = all;
};
"nextcloud/password.age" = {
# Must be readable by the service
owner = "nextcloud";
publicKeys = all;
};
"paperless/password.age".publicKeys = all;
"paperless/secret-key.age".publicKeys = all;
"podgrab/password.age".publicKeys = all;
"sso/auth-key.age".publicKeys = all;
"sso/ambroisie/password-hash.age".publicKeys = all;
"sso/ambroisie/totp-secret.age".publicKeys = all;
"transmission/credentials.age".publicKeys = all;
"users/ambroisie/hashed-password.age".publicKeys = all;
"users/root/hashed-password.age".publicKeys = all;
"wireguard/aramis/private-key.age".publicKeys = all;
"wireguard/porthos/private-key.age".publicKeys = all;
"wireguard/richelieu/private-key.age".publicKeys = all;
}

Binary file not shown.

View file

@ -1,10 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg mP2H3PWJN6Pv3q6C2wci3KnXjtFAIiuGy0YH0sGIy2g
f43QqyUQfTYznszub47kgc2Mz95zVScTDkwnG3INi9U
-> ssh-ed25519 jPowng fENbu7+FZ1mnQQHQCLm1spLHmsQGlRoJResUJtGzYkY
hX+AqCkLCca6m/aKtGCThi7/mCCz/TZQNJNOlOmlqyA
-> J<-grease
n7+CPRr4oazWnE7yzpJN2ZAI4QrGsAerloP4wNeebjQDx8+IxJq1JE0g3Yi0RxzN
chDccuSPLYk45Ov+SD/qqqFZlQ
--- p81HYw3LFj+qz2kiZsDcevM4ZBfvN743P9Jdi7J9XkM
¢ìÛ±S·7 <EFBFBD>ý£÷ÜãV»»Bðßâø±³ˆ¶ïO‰lEt˜Á…šqý</Ç—Ø©9²ã(ØP†$Wƒ0h;÷‰±àJy¯feø >·_D,PºVFp\æ"AM}èg?<3F>ÿ<EFBFBD>Ý/\²Ä;ùy ¬Óš(<28>ÑSñKË

View file

@ -1,9 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg vOaL2ZKsFEjX9mzQvw8Je7x2Dq8cMhrZEyBTXpH4QnE
HXO4fbWdJsbsRmGq0IYzq8/szObxzpsGfQNNTJ4vNzg
-> ssh-ed25519 jPowng WPxg0pP6O3ZS4dPc1WcDvzig22Fylk3mR/W9STaWbW4
GuhFwt7M5Lc38q2LC/0eul0yP60UxmWwi9I8ToHv7bE
-> :;V8\-grease ZC#7~eR# P<'e?vI3 9R
lZlb44QiAaIxd0SYiRNT/QRnxxUt7npbksg
--- 9xv4lt8IcGR8jP0UcKYYnTuh1Ix/pqXgDmevkTH9j1A
Ï]ºcÓ3óxí wÿ'ã ` <0B>ùhçÒ=X¨í·¢Çg3ÆÆÄ]~ËôÞqÙ.XnÄa*€±W:<3A>¸±,â©z®vyzñI¦æ }ÂDO=`êw“ñõ¹ˆ7:™ù“ÐRx•5$¨Ö6:ö¨´"õ,HM„<4D>"_ëÞòMÛMƒœˆBJe‰ùFá

View file

@ -1,10 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg +WwRpd2MzycutQFXyLsr2+GzSgF67Z6UuvyqYZaLd3w
sppt8HzaZP3yxnvnhzjl18Trnz8g3VyXJ6CaVBWd7jA
-> ssh-ed25519 jPowng wanoqGB7T8bim/WZ4IAYViFQoGzaIZSgeoTr3YKpeTY
ihDAdGa1XVW/qQz40V1v7a7iK7tu0EHMa7ayIogpcRw
-> l-grease |PIcZ NIr >0;*
4o8o0bevQZ6uDSx1WxxlDCURbFCM+yK1XPdrb9aztCSvG2a+ne78E42l5rBcoH7I
m51A8uWS4nSj36N/76v6K4kelxKzWUg
--- O6cGbTAVbDcdmPHf7UzfZiyiRtu1yfL4sBI+CkJA1qw
ýqýŐ$ň`żw'čS“X¸]Ąá÷ř®úî…?¤6Đ/ĆN(Bžň N«a” HŽ7żí•I<E280A2>ú÷Ŕoz‡/4:sK",7J

View file

@ -1,10 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 cKojmg rYhrpoTaFjLBGtbCXxEK7jZa+KnriEV/kWViIEjmuQs
jHMSjxKIIqjUnpAcEo3JgsieI1iiA5/gKEx8+QFhDgY
-> ssh-ed25519 jPowng 6sQQFvSbWdjgDYSKmJ/CBG+BTzxFghX4SaJ4GyACKWc
OABJuh+Ta8q+G0onF/9bz3xxv4zTlHYlF4AjC5P6Y6I
-> xwW|#D`-grease $xYH C m8lBk9
OBqgvLNIurE0qNaSB7dO2/6dQkVXeLgf/3l9gGlRJ6ynhqwmbXOUa0vyj+OBz27O
uI97+0y1TFAs3HN0Y8nj8LrwsafbDENu99JuVow2OuLKeSqc7sxOQQ
--- 9filSHStPTJJGDLY7AWzIXu/6tK4X0okT522sc4OJTc
M{イ顗仭$ケ:Nル災[ンカャ2xy8&腴_{RワLX<4C>W√€<E2889A>サxム*Pr`セUイp<EFBDB2>Jノ枇鵲#藝ヤ<E8979D><EFBFBD> s

View file

@ -2,33 +2,33 @@
{
imports = [
./adblock
./backup
./blog
./calibre-web
./drone
./flood
./gitea
./indexers
./jellyfin
./lohr
./matrix
./miniflux
./monitoring
./navidrome
./nextcloud
./nginx
./paperless
./pirate
./podgrab
./postgresql-backup
./postgresql
./quassel
./rss-bridge
./sabnzbd
./ssh-server
./tlp
./transmission
./wireguard
./adblock.nix
./backup.nix
./blog.nix
./calibre-web.nix
./drone.nix
./flood.nix
./gitea.nix
./indexers.nix
./jellyfin.nix
./lohr.nix
./matrix.nix
./miniflux.nix
./monitoring.nix
./navidrome.nix
./nextcloud.nix
./nginx.nix
./paperless.nix
./pirate.nix
./podgrab.nix
./postgresql-backup.nix
./postgresql.nix
./quassel.nix
./rss-bridge.nix
./sabnzbd.nix
./ssh-server.nix
./tlp.nix
./transmission.nix
./wireguard.nix
];
}

194
modules/services/drone.nix Normal file
View file

@ -0,0 +1,194 @@
# A docker-based CI/CD system
#
# Inspired by [1]
# [1]: https://github.com/Mic92/dotfiles/blob/master/nixos/eve/modules/drone.nix
{ config, lib, pkgs, ... }:
let
cfg = config.my.services.drone;
hasRunner = (name: builtins.elem name cfg.runners);
execPkg = pkgs.drone-runner-exec;
dockerPkg = pkgs.drone-runner-docker;
in
{
options.my.services.drone = with lib; {
enable = mkEnableOption "Drone CI";
runners = mkOption {
type = with types; listOf (enum [ "exec" "docker" ]);
default = [ ];
example = [ "exec" "docker" ];
description = "Types of runners to enable";
};
admin = mkOption {
type = types.str;
default = "ambroisie";
example = "admin";
description = "Name of the admin user";
};
port = mkOption {
type = types.port;
default = 3030;
example = 8080;
description = "Internal port of the Drone UI";
};
secretFile = mkOption {
type = types.str;
example = "/run/secrets/drone-gitea.env";
description = "Secrets to inject into Drone server";
};
sharedSecretFile = mkOption {
type = types.str;
example = "/run/secrets/drone-rpc.env";
description = "Shared RPC secret to inject into server and runners";
};
};
config = lib.mkIf cfg.enable {
systemd.services.drone-server = {
wantedBy = [ "multi-user.target" ];
after = [ "postgresql.service" ];
serviceConfig = {
EnvironmentFile = [
cfg.secretFile
cfg.sharedSecretFile
];
Environment = [
"DRONE_DATABASE_DATASOURCE=postgres:///drone?host=/run/postgresql"
"DRONE_SERVER_HOST=drone.${config.networking.domain}"
"DRONE_SERVER_PROTO=https"
"DRONE_DATABASE_DRIVER=postgres"
"DRONE_SERVER_PORT=:${toString cfg.port}"
"DRONE_USER_CREATE=username:${cfg.admin},admin:true"
"DRONE_JSONNET_ENABLED=true"
"DRONE_STARLARK_ENABLED=true"
];
ExecStart = "${pkgs.drone}/bin/drone-server";
User = "drone";
Group = "drone";
};
};
users.users.drone = {
isSystemUser = true;
createHome = true;
group = "drone";
};
users.groups.drone = { };
services.postgresql = {
enable = true;
ensureDatabases = [ "drone" ];
ensureUsers = [{
name = "drone";
ensurePermissions = {
"DATABASE drone" = "ALL PRIVILEGES";
};
}];
};
my.services.nginx.virtualHosts = [
{
subdomain = "drone";
inherit (cfg) port;
}
];
# Docker runner
systemd.services.drone-runner-docker = lib.mkIf (hasRunner "docker") {
wantedBy = [ "multi-user.target" ];
after = [ "docker.socket" ]; # Needs the socket to be available
# might break deployment
restartIfChanged = false;
confinement.enable = true;
serviceConfig = {
Environment = [
"DRONE_SERVER_HOST=drone.${config.networking.domain}"
"DRONE_SERVER_PROTO=https"
"DRONE_RUNNER_CAPACITY=10"
"CLIENT_DRONE_RPC_HOST=127.0.0.1:${toString cfg.port}"
];
BindPaths = [
"/var/run/docker.sock"
];
EnvironmentFile = [
cfg.sharedSecretFile
];
ExecStart = "${dockerPkg}/bin/drone-runner-docker";
User = "drone-runner-docker";
Group = "drone-runner-docker";
};
};
# Make sure it is activated in that case
virtualisation.docker.enable = lib.mkIf (hasRunner "docker") true;
users.users.drone-runner-docker = lib.mkIf (hasRunner "docker") {
isSystemUser = true;
group = "drone-runner-docker";
extraGroups = [ "docker" ]; # Give access to the daemon
};
users.groups.drone-runner-docker = lib.mkIf (hasRunner "docker") { };
# Exec runner
systemd.services.drone-runner-exec = lib.mkIf (hasRunner "exec") {
wantedBy = [ "multi-user.target" ];
# might break deployment
restartIfChanged = false;
confinement.enable = true;
confinement.packages = with pkgs; [
git
gnutar
bash
nixUnstable
gzip
];
path = with pkgs; [
git
gnutar
bash
nixUnstable
gzip
];
serviceConfig = {
Environment = [
"DRONE_SERVER_HOST=drone.${config.networking.domain}"
"DRONE_SERVER_PROTO=https"
"DRONE_RUNNER_CAPACITY=10"
"CLIENT_DRONE_RPC_HOST=127.0.0.1:${toString cfg.port}"
"NIX_REMOTE=daemon"
"PAGER=cat"
];
BindPaths = [
"/nix/var/nix/daemon-socket/socket"
"/run/nscd/socket"
];
BindReadOnlyPaths = [
"/etc/resolv.conf:/etc/resolv.conf"
"/etc/resolvconf.conf:/etc/resolvconf.conf"
"/etc/passwd:/etc/passwd"
"/etc/group:/etc/group"
"/nix/var/nix/profiles/system/etc/nix:/etc/nix"
"${config.environment.etc."ssl/certs/ca-certificates.crt".source}:/etc/ssl/certs/ca-certificates.crt"
"${config.environment.etc."ssh/ssh_known_hosts".source}:/etc/ssh/ssh_known_hosts"
"/etc/machine-id"
# channels are dynamic paths in the nix store, therefore we need to bind mount the whole thing
"/nix/"
];
EnvironmentFile = [
cfg.sharedSecretFile
];
ExecStart = "${execPkg}/bin/drone-runner-exec";
User = "drone-runner-exec";
Group = "drone-runner-exec";
};
};
users.users.drone-runner-exec = lib.mkIf (hasRunner "exec") {
isSystemUser = true;
group = "drone-runner-exec";
};
users.groups.drone-runner-exec = lib.mkIf (hasRunner "exec") { };
};
}

View file

@ -1,44 +0,0 @@
# A docker-based CI/CD system
#
# Inspired by [1]
# [1]: https://github.com/Mic92/dotfiles/blob/master/nixos/eve/modules/drone.nix
{ config, lib, pkgs, ... }:
{
imports = [
./runner-docker
./runner-exec
./server
];
options.my.services.drone = with lib; {
enable = mkEnableOption "Drone CI";
runners = mkOption {
type = with types; listOf (enum [ "exec" "docker" ]);
default = [ ];
example = [ "exec" "docker" ];
description = "Types of runners to enable";
};
admin = mkOption {
type = types.str;
default = "ambroisie";
example = "admin";
description = "Name of the admin user";
};
port = mkOption {
type = types.port;
default = 3030;
example = 8080;
description = "Internal port of the Drone UI";
};
secretFile = mkOption {
type = types.str;
example = "/run/secrets/drone-gitea.env";
description = "Secrets to inject into Drone server";
};
sharedSecretFile = mkOption {
type = types.str;
example = "/run/secrets/drone-rpc.env";
description = "Shared RPC secret to inject into server and runners";
};
};
}

View file

@ -1,44 +0,0 @@
{ config, lib, pkgs, ... }:
let
cfg = config.my.services.drone;
hasRunner = (name: builtins.elem name cfg.runners);
dockerPkg = pkgs.drone-runner-docker;
in
{
config = lib.mkIf (cfg.enable && hasRunner "docker") {
systemd.services.drone-runner-docker = {
wantedBy = [ "multi-user.target" ];
after = [ "docker.socket" ]; # Needs the socket to be available
# might break deployment
restartIfChanged = false;
confinement.enable = true;
serviceConfig = {
Environment = [
"DRONE_SERVER_HOST=drone.${config.networking.domain}"
"DRONE_SERVER_PROTO=https"
"DRONE_RUNNER_CAPACITY=10"
"CLIENT_DRONE_RPC_HOST=127.0.0.1:${toString cfg.port}"
];
BindPaths = [
"/var/run/docker.sock"
];
EnvironmentFile = [
cfg.sharedSecretFile
];
ExecStart = "${dockerPkg}/bin/drone-runner-docker";
User = "drone-runner-docker";
Group = "drone-runner-docker";
};
};
# Make sure it is activated in that case
virtualisation.docker.enable = true;
users.users.drone-runner-docker = {
isSystemUser = true;
group = "drone-runner-docker";
extraGroups = [ "docker" ]; # Give access to the daemon
};
users.groups.drone-runner-docker = { };
};
}

Some files were not shown because too many files have changed in this diff Show more