Basic configuration for new servers and start modularizing config

This commit is contained in:
Charlotte Van Petegem 2020-12-01 19:23:28 +01:00
parent 82bb5b401c
commit ca93d09059
No known key found for this signature in database
GPG key ID: 019E764B7184435A
38 changed files with 622 additions and 316 deletions

70
modules/default.nix Normal file
View file

@ -0,0 +1,70 @@
{ config, lib, pkgs, ... }:
{
imports = [
./default/secret.nix
./docker.nix
./git.nix
./nginx.nix
./ovh.nix
./ssh.nix
./sshd.nix
./syncthing-server.nix
./zfs.nix
./zsh.nix
];
options.chvp = {
stateVersion = lib.mkOption {
example = "20.09";
};
dataPrefix = lib.mkOption {
default = "";
example = "/data";
};
cachePrefix = lib.mkOption {
default = "";
example = "/cache";
};
graphical = lib.mkOption {
default = false;
example = true;
};
};
config = {
home-manager.useGlobalPkgs = true;
system.stateVersion = config.chvp.stateVersion;
home-manager.users = {
charlotte = { ... }: {
home.stateVersion = config.chvp.stateVersion;
};
root = { ... }: {
home.stateVersion = config.chvp.stateVersion;
};
};
environment.systemPackages = with pkgs; [
htop
ncdu
ripgrep
];
users = {
mutableUsers = false;
defaultUserShell = pkgs.zsh;
users = {
charlotte = {
isNormalUser = true;
home = "/home/charlotte";
description = "Charlotte Van Petegem";
extraGroups = [ "wheel" "systemd-journal" ];
};
};
};
};
}

BIN
modules/default/secret.nix Normal file

Binary file not shown.

20
modules/docker.nix Normal file
View file

@ -0,0 +1,20 @@
{ config, lib, pkgs, ... }:
{
options.chvp.docker.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.docker.enable {
virtualisation.docker = {
enable = true;
extraOptions = "--data-root ${config.chvp.dataPrefix}/var/lib/docker";
storageDriver = lib.mkIf config.chvp.zfs.enable "zfs";
};
environment.systemPackages = [ pkgs.docker-compose ];
users.users.charlotte.extraGroups = [ "docker" ];
};
}

57
modules/git.nix Normal file
View file

@ -0,0 +1,57 @@
{ config, lib, pkgs, ... }:
{
options.chvp.git = {
enable = lib.mkOption {
default = true;
example = false;
};
email = lib.mkOption {
type = lib.types.str;
default = "charlotte@vanpetegem.me";
example = "charlotte@vanpetegem.me";
description = ''
Default email set in global git config.
'';
};
};
config =
let
base = {
home.packages = with pkgs; [
gitAndTools.gitflow
git-crypt
];
programs.git = {
enable = true;
extraConfig = {
branch = {
autosetuprebase = "always";
};
pull = {
rebase = true;
};
};
ignores = [
".direnv"
".envrc"
"shell.nix"
# Ruby dependencies in source tree
"/vendor/bundle"
"**/*.patch"
];
signing = {
key = "charlotte@vanpetegem.me";
signByDefault = config.chvp.graphical;
};
userEmail = config.chvp.git.email;
userName = "Charlotte Van Petegem";
};
};
in
lib.mkIf config.chvp.git.enable {
home-manager.users.charlotte = { ... }: base;
home-manager.users.root = { ... }: base;
};
}

92
modules/nginx.nix Normal file
View file

@ -0,0 +1,92 @@
{ config, lib, ... }:
{
options.chvp.nginx = {
enable = lib.mkOption {
default = false;
example = true;
};
hosts = lib.mkOption {
default = [ ];
example = [
{
fqdn = "data.vanpetegem.me";
options = {
default = true;
basicAuthFile = "/data/var/secrets/data.vanpetegem.me.htpasswd";
root = "/srv/data";
locations = {
"/".extraConfig = ''
autoindex on;
'';
"/public".extraConfig = ''
autoindex on;
auth_basic off;
'';
};
};
}
];
};
extraPostACMEScripts = lib.mkOption {
default = [ ];
example = [
''
cp fullchain.pem /data/home/charlotte/synapse/slack/cert.crt
cp privkey.pem /data/home/charlotte/synapse/slack/key.pem
pushd /data/home/charlotte/synapse
''${pkgs.docker-compose}/bin/docker-compose restart slack
popd
''
];
};
};
config = lib.mkIf config.chvp.nginx.enable {
networking.firewall.allowedTCPPorts = [ 80 443 ];
security.acme = {
certs."vanpetegem.me" = {
dnsProvider = "cloudflare";
credentialsFile = "/data/var/secrets/vanpetegem.me-cloudflare";
extraDomainNames = [
"*.vanpetegem.me"
"cvpetegem.be"
"*.cvpetegem.be"
"chvp.be"
"*.chvp.be"
];
postRun = lib.concatStrings config.chvp.nginx.extraPostACMEScripts;
};
email = "webmaster@vanpetegem.me";
acceptTerms = true;
preliminarySelfsigned = false;
};
chvp.zfs.systemLinks = [
{ type = "data"; path = "/var/lib/acme"; }
];
services.nginx = {
enable = true;
recommendedTlsSettings = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
virtualHosts = builtins.listToAttrs
(map
(elem: {
name = elem.fqdn;
value = {
forceSSL = true;
useACMEHost = "vanpetegem.me";
locations."/" = lib.mkIf (builtins.hasAttr "basicProxy" elem) {
proxyPass = elem.basicProxy;
extraConfig = ''
proxy_set_header X-Forwarded-Ssl on;
'' + (elem.extraProxySettings or "");
};
} // (elem.options or { });
})
config.chvp.nginx.hosts);
};
users.users.nginx.extraGroups = [ "acme" ];
};
}

62
modules/ovh.nix Normal file
View file

@ -0,0 +1,62 @@
{ config, lib, ... }:
{
options.chvp.ovh = {
enable = lib.mkOption {
default = false;
example = true;
};
publicIPV4 = lib.mkOption {
example = {
ip = "1.2.3.4";
gateway = "1.2.3.254";
};
};
publicIPV6 = lib.mkOption {
example = {
ip = "1:2:3:4::";
gateway = "1:2:3:ff:ff:ff:ff:ff";
};
};
internalIPV4 = lib.mkOption {
example = "192.168.0.1";
};
};
config = lib.mkIf config.chvp.ovh.enable {
networking = with config.chvp.ovh; {
useDHCP = false;
interfaces = {
eno1.useDHCP = false;
eno2.useDHCP = false;
eno3 = {
useDHCP = false;
ipv4.addresses = [{
address = publicIPV4.ip;
prefixLength = 24;
}];
ipv6 = {
addresses = [{
address = publicIPV6.ip;
prefixLength = 64;
}];
routes = [{
address = publicIPV6.gateway;
prefixLength = 128;
}];
};
};
eno4 = {
useDHCP = false;
ipv4.addresses = [{
address = internalIPV4;
prefixLength = 16;
}];
};
};
defaultGateway = publicIPV4.gateway;
defaultGateway6 = publicIPV6.gateway;
nameservers = [ "1.1.1.1" "1.0.0.1" "2606:4700:4700::1111" "2606:4700:4700::1001" ];
};
};
}

43
modules/ssh.nix Normal file
View file

@ -0,0 +1,43 @@
{ config, lib, pkgs, ... }:
let
ssh = pkgs.symlinkJoin {
name = "ssh";
paths = [
(
pkgs.writeShellScriptBin "ssh" ''
export TERM=xterm-256color
${pkgs.openssh}/bin/ssh $@
''
)
pkgs.openssh
];
};
base = home: {
programs.ssh = {
enable = true;
compression = true;
hashKnownHosts = true;
userKnownHostsFile = "${config.chvp.cachePrefix}${home}/.ssh/known_hosts";
serverAliveInterval = 300;
extraOptionOverrides = {
IdentityFile = "${config.chvp.dataPrefix}${home}/.ssh/id_ed25519";
HostKeyAlgorithms = "ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa";
};
matchBlocks = import ./ssh/hosts.secret.nix;
};
home.packages = lib.mkIf config.chvp.graphical [ ssh ];
};
in
{
options.chvp.ssh = {
enable = lib.mkOption {
default = true;
example = false;
};
};
config = lib.mkIf config.chvp.ssh.enable {
home-manager.users.root = { ... }: (base "/root");
home-manager.users.charlotte = { ... }: (base "/home/charlotte");
};
}

Binary file not shown.

24
modules/sshd.nix Normal file
View file

@ -0,0 +1,24 @@
{ config, lib, ... }:
{
imports = [
./sshd/secret.nix
];
options.chvp.sshd.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.sshd.enable {
services.openssh = {
enable = true;
passwordAuthentication = false;
permitRootLogin = "prohibit-password";
hostKeys = [
{ bits = 4096; path = "${config.chvp.dataPrefix}/etc/ssh/ssh_host_rsa_key"; type = "rsa"; }
{ path = "${config.chvp.dataPrefix}/etc/ssh/ssh_host_ed25519_key"; type = "ed25519"; }
];
};
};
}

BIN
modules/sshd/secret.nix Normal file

Binary file not shown.

View file

@ -0,0 +1,28 @@
{ config, lib, ... }:
{
options.chvp.syncthing-server.enable = lib.mkOption {
default = false;
example = true;
};
config = lib.mkIf config.chvp.syncthing-server.enable {
services.syncthing = {
enable = true;
dataDir = "${config.chvp.dataPrefix}/var/lib/synthing";
configDir = "${config.chvp.dataPrefix}/var/lib/synthing/.config";
openDefaultPorts = true;
guiAddress = "127.0.0.1:8384";
};
chvp.nginx.hosts = [
{
fqdn = "syncthing.vanpetegem.me";
basicProxy = "http://localhost:8384";
options = {
basicAuthFile = "${config.chvp.dataPrefix}/var/secrets/syncthing.vanpetegem.me.htpasswd";
};
}
];
};
}

View file

@ -31,27 +31,73 @@ in
{ path = ".cache/nix-index"; type = "cache"; }
];
};
backups = lib.mkOption {
default = [ ];
example = [{
path = "rpool/safe/data";
remotePath = "zdata/recv/<hostname>/safe/data";
fast = false;
location = "lasting-integrity.vanpetegem.me";
}];
};
};
config.boot = lib.mkIf config.chvp.zfs.enable {
supportedFilesystems = [ "zfs" ];
zfs.requestEncryptionCredentials = config.chvp.zfs.encrypted;
initrd.postDeviceCommands = lib.mkAfter ''
zfs rollback -r rpool/local/root@blank
'';
};
config = lib.mkIf config.chvp.zfs.enable {
chvp.dataPrefix = lib.mkDefault "/data";
chvp.cachePrefix = lib.mkDefault "/cache";
config.services.zfs.autoScrub.enable = config.chvp.zfs.enable;
config.services.zfs.trim.enable = config.chvp.zfs.enable;
boot = {
supportedFilesystems = [ "zfs" ];
zfs.requestEncryptionCredentials = config.chvp.zfs.encrypted;
initrd.postDeviceCommands = lib.mkAfter ''
zfs rollback -r rpool/local/root@blank
'';
};
config.systemd.tmpfiles.rules = lib.mkIf config.chvp.zfs.enable (
[ "d /home/charlotte 0700 charlotte users - -" ] ++
(map (location: "L ${location.path} - - - - /${location.type}${location.path}") config.chvp.zfs.systemLinks)
);
services = {
znapzend = {
enable = config.chvp.zfs.backups != [ ];
pure = true;
autoCreation = true;
zetup = builtins.listToAttrs
(map
(elem: {
name = elem.path;
value = {
enable = true;
plan =
if elem.fast then
"1hour=>15min,1day=>1hour,1week=>1day,4week=>1week" else
"1day=>1hour,1week=>1day,4week=>1week,1year=>1month,10year=>6month";
timestampFormat = "%Y-%m-%d--%H%M%SZ";
destinations."${elem.location}" = {
plan =
if elem.fast then
"1day=>1hour,1week=>1day,4week=>1week,1year=>4week,10year=>1year" else
"1day=>1hour,1week=>1day,4week=>1week,1year=>1month,10year=>6month";
host = "${elem.location}";
dataset = elem.remotePath;
};
};
})
config.chvp.zfs.backups);
config.home-manager.users.charlotte = { lib, ... }: {
home.activation = lib.mkIf config.chvp.zfs.enable {
linkCommands = lib.hm.dag.entryAfter [ "writeBoundary" ] (lib.concatStringsSep "\n" linkCommands);
};
zfs = {
autoScrub.enable = true;
trim.enable = true;
};
};
systemd.tmpfiles.rules = (
[ "d /home/charlotte 0700 charlotte users - -" ] ++
(map (location: "L ${location.path} - - - - /${location.type}${location.path}") config.chvp.zfs.systemLinks)
);
home-manager.users.charlotte = { lib, ... }: {
home.activation = {
linkCommands = lib.hm.dag.entryAfter [ "writeBoundary" ] (lib.concatStringsSep "\n" linkCommands);
};
};
};
}

61
modules/zsh.nix Normal file
View file

@ -0,0 +1,61 @@
{ config, lib, pkgs, ... }:
{
options.chvp.zsh.enable = lib.mkOption {
default = true;
example = false;
};
config =
let
base = (home: {
home.packages = [ pkgs.autojump ];
programs.zsh = {
enable = true;
enableAutosuggestions = true;
autocd = true;
dotDir = ".config/zsh";
history = {
expireDuplicatesFirst = true;
path = "${config.chvp.cachePrefix}${home}/.local/share/zsh/history";
};
initExtra = ''
source ${pkgs.nix-index}/etc/profile.d/command-not-found.sh
${pkgs.any-nix-shell}/bin/any-nix-shell zsh --info-right | source /dev/stdin
'';
oh-my-zsh = {
enable = true;
plugins = [
"autojump"
"common-aliases"
"extract"
"history-substring-search"
"git"
"sudo"
"systemd"
"tmux"
];
theme = "agnoster";
};
plugins = [{
name = "zsh-syntax-highlighting";
src = pkgs.fetchFromGitHub {
owner = "zsh-users";
repo = "zsh-syntax-highlighting";
rev = "0.7.1";
sha256 = "03r6hpb5fy4yaakqm3lbf4xcvd408r44jgpv4lnzl9asp4sb9qc0";
};
}];
sessionVariables = { DEFAULT_USER = "charlotte"; };
};
});
in
lib.mkIf config.chvp.zsh.enable {
chvp.zfs.systemLinks = [
{ path = "/home/charlotte/.local/share/autojump"; type = "cache"; }
{ path = "/root/.local/share/autojump"; type = "cache"; }
];
home-manager.users.charlotte = { ... }: (base "/home/charlotte");
home-manager.users.root = { ... }: (base "/root");
};
}