diff options
28 files changed, 310 insertions, 117 deletions
@@ -1 +1,26 @@ -secrets/secret-envrc.sh
\ No newline at end of file +#!/usr/bin/env bash +set -Eeuo pipefail + +# +# envsubst variables for: +# - envsubst-configuration.nix +# - nixos-update.sh +# +export TLD='euandreh.xyz' +export DATA_ROOT='/data' +export FAVICONS_ROOT="${DATA_ROOT}/favicons" +export STATIC_ROOT="${DATA_ROOT}/static" +export CI_LOGS_ROOT="${STATIC_ROOT}/ci-logs" +export GIT_ROOT="${DATA_ROOT}/git" +export SYSTEM_STATE_VERSION='20.03' +export USER_NAME='andreh' +export SECRETS_ROOT='/secrets' +export NEXTCLOUD_DATABASE_USER='nextcloud' +export PROSODY_ENABLE='false' + +# +# Terraform +# +export TF_VAR_tld="${TLD}" +export TF_VAR_hostname="sovereignty-nixos" +export TF_VAR_storage_name="sovereignty-nixos-storage" @@ -47,7 +47,7 @@ The basic `configuration.nix` file in the current snapshots looks just like this uid = 1000; isNormalUser = true; extraGroups = [ "wheel" ]; - password = "...password..."; + password = "...tmp password..."; openssh.authorizedKeys.keys = [ "...ssh public key..." ]; @@ -1,6 +1,15 @@ * Tasks - v4 -** TODO cgit: show README in about section -** TODO Update matterbridge version +** TODO "Migration": use =euandreh_nextcloud_= prefix to database table +** DONE cgit: show README in about section +CLOSED: [2020-09-06 dim. 08:59] +- State "DONE" from [2020-09-06 dim. 08:59] +** CANCELLED Update matterbridge version +CLOSED: [2020-09-06 dim. 08:59] +- State "CANCELLED" from [2020-09-06 dim. 08:59] \\ +I found matterbridge to be too simplistic for what it was proposing to do. The +puppeting bridges from Matrix are a much more robust solution, and I'll try that +instead later. + https://github.com/42wim/matterbridge/issues/1061 ** DONE Add Prosody DNS record to allow me to use eu@euandreh.xyz as an XMPP address CLOSED: [2020-08-23 dim. 18:40] @@ -17,7 +26,9 @@ Or even better: switch to SQLite. *** TODO [#A] [[https://docs.nextcloud.com/server/stable/admin_manual/installation/harden_server.html][Nextcloud: Hardening and security guidance]] *** TODO [#A] [[https://ownyourbits.com/2017/03/25/nextcloud-a-security-analysis/][NextCloud, a security analysis]] *** TODO [#B] [[https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/HTTP_Strict_Transport_Security_Cheat_Sheet.md][Check for HSTS header configuration]] -*** TODO Move secrets outside the Nix store +*** DONE Move secrets outside the Nix store +CLOSED: [2020-09-06 dim. 11:35] +- State "DONE" from [2020-09-06 dim. 11:35] *** TODO Properly configure PostgreSQL *** TODO Separate lighttpd user ownership from =$GIT_ROOT=? ** TODO Add volume @@ -113,6 +124,15 @@ Instead, explicitly call =ansible-playbook= after =terraform apply= finished run This way we test the DNS A record -> Floating IP -> Droplet IP path. We can't do that inside Terraform declaration because the =local-exec= provisioning command runs before the =digitalocean_floating_ip_assignment= is created, and we can't create a cyclic dependency between the two resources. We could use the raw Droplet IP instead of the DNS A record, but I prefer calling it later in order to always test the full DNS resolution. +** On public SSH key leakage +As described in "[[https://rushter.com/blog/public-ssh-keys/][Public SSH keys can leak your private infrastructure]]", public +SSH keys can expose undesired infrastructure, specially for targeted attacks. + +I'm not considering this a threat, since the link between the server and me is +already public. It may be much more effective to just change the SSH port away +from the default: it doesn't accomplish the same thing, but it prevents simple +detections. It is still possible to find this out via a script, but is orders of +magnitute harder for the attacker. * Questions ** How to best handle IP changes when the server changes? How does this affect the email sending IP reputation? ** Enable 2FA for Nextcloud? diff --git a/secrets/nix/5d05f383bcf61-snapshot-configuration.nix b/base-image/5d05f383bcf61-snapshot-configuration.nix index c59f37b..c59f37b 120000 --- a/secrets/nix/5d05f383bcf61-snapshot-configuration.nix +++ b/base-image/5d05f383bcf61-snapshot-configuration.nix diff --git a/secrets/nix/c565f318e4aea-snapshot-configuration.nix b/base-image/c565f318e4aea-snapshot-configuration.nix index c59f37b..c59f37b 120000 --- a/secrets/nix/c565f318e4aea-snapshot-configuration.nix +++ b/base-image/c565f318e4aea-snapshot-configuration.nix diff --git a/base-image/e1d5f317b0f7a-snapshot-configuration.nix b/base-image/e1d5f317b0f7a-snapshot-configuration.nix new file mode 100644 index 0000000..b80eab0 --- /dev/null +++ b/base-image/e1d5f317b0f7a-snapshot-configuration.nix @@ -0,0 +1,107 @@ +# 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.grub.enable = true; + boot.loader.grub.version = 2; + # boot.loader.grub.efiSupport = true; + # boot.loader.grub.efiInstallAsRemovable = true; + # boot.loader.efi.efiSysMountPoint = "/boot/efi"; + # Define on which hard drive you want to install Grub. + boot.loader.grub.device = "/dev/vda"; # or "nodev" for efi only + + # networking.hostName = "nixos"; # 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.ens3.useDHCP = true; + + # Configure network proxy if necessary + # networking.proxy.default = "http://user:password@proxy:port/"; + # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; + + # Select internationalisation properties. + # i18n = { + # consoleFont = "Lat2-Terminus16"; + # consoleKeyMap = "us"; + # defaultLocale = "en_US.UTF-8"; + # }; + + # Set your time zone. + # time.timeZone = "Europe/Amsterdam"; + + # List packages installed in system profile. To search, run: + # $ nix search wget + environment.systemPackages = with pkgs; [ vim ]; + + # Some programs need SUID wrappers, can be configured further or are + # started in user sessions. + # programs.mtr.enable = true; + # programs.gnupg.agent = { enable = true; enableSSHSupport = true; }; + + # List services that you want to enable: + + # Enable the OpenSSH daemon. + services.openssh.enable = true; + services.openssh.permitRootLogin = "no"; + + # Open ports in the firewall. + # networking.firewall.allowedTCPPorts = [ ... ]; + # networking.firewall.allowedUDPPorts = [ ... ]; + # Or disable the firewall altogether. + # networking.firewall.enable = false; + + # Enable CUPS to print documents. + # services.printing.enable = true; + + # Enable sound. + # sound.enable = true; + # hardware.pulseaudio.enable = true; + + # Enable the X11 windowing system. + # services.xserver.enable = true; + # services.xserver.layout = "us"; + # services.xserver.xkbOptions = "eurosign:e"; + + # Enable touchpad support. + # services.xserver.libinput.enable = true; + + # Enable the KDE Desktop Environment. + # services.xserver.displayManager.sddm.enable = true; + # services.xserver.desktopManager.plasma5.enable = true; + + # Define a user account. Don't forget to set a password with ‘passwd’. + # users.users.jane = { + # isNormalUser = true; + # extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. + # }; + + users.extraUsers.andreh = { + uid = 1000; + isNormalUser = true; + extraGroups = [ "wheel" ]; + password = + "...tmp password..."; # stored in secrets/base-image-old-password.txt + openssh.authorizedKeys.keys = [ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDF+uy407LKZAFnfFkJPRiOBzwV98qIEcKhITnLYhqfITfrJvcFVOY0/YDCrs6WHXyLdM29AoywVWsQ1qXiB7xQCwknPV8YZoCnJQcn0gvH8jbCk+C8Po0Rx846wbhL49qYolnmlhe+Uoy30j7XIJSDtPVO9d/hZqt2GPwGVJ98HLyY2ak+j4i1YkHr+mPFgnCaqCAzA374d1Bop18+YENYtMMU0k8hCsomwZny/7qNo4V8mjLxQAS8FvTuljxlthEpOM4Jsjl07yDLgE69kLvU7mmFi8EeC26e50N18Ouse82dZigtVhAMeLBhbJnQbDff4WfUBzSjpKjZPGcxoRaej3qSRbIkcMMqCOSlww6GcjRi+COvlpA4c1i4hKI15wHceoiKghDLA6jbaHfOqEMldflYl5gCVUIYzJ5XehZppH6L7PzO+L4suNs+aFjWPDZ0jqEtcyTmgTMea40p7wwz086ExnBDorbG79oDiJrWc+swJjXuVakS+fQjb3mPsCC/FgUhsxEtqiVfvLo2mphp47pOYvs64aUp3RV9muqQNuS4tEuP9V1urGTLtgPL26LEjF0oLu1ag0H+VZY5O/T9KRYvWre8IWbj/KkZYo1tJaGJyEVr0plmyzLBEy8b3Hu/6Wtq7yB0Eii60fxqFWC24nEkvs1V0cxDa+o6I2iA9w== eu@euandre.org" + ]; + }; + + # 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? + +} diff --git a/envsubst-configuration.nix b/envsubst-configuration.nix new file mode 100644 index 0000000..e0fa592 --- /dev/null +++ b/envsubst-configuration.nix @@ -0,0 +1,13 @@ +{ }: { + TLD = "$TLD"; + dataRoot = "$DATA_ROOT"; + faviconsRoot = "$FAVICONS_ROOT"; + staticRoot = "$STATIC_ROOT"; + ciLogsRoot = "$CI_LOGS_ROOT"; + gitRoot = "$GIT_ROOT"; + systemStateVersion = "$SYSTEM_STATE_VERSION"; + userName = "$USER_NAME"; + nextcloudDatabaseUser = "$NEXTCLOUD_DATABASE_USER"; + secretsRoot = "$SECRETS_ROOT"; + prosodyEnable = "$PROSODY_ENABLE"; +} diff --git a/gen-hash.sh b/gen-hash.sh new file mode 100755 index 0000000..774f9f9 --- /dev/null +++ b/gen-hash.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -Eeuo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")" + +mkpasswd -m sha-512 \ + "$(cat ./secrets/user-password.txt)" \ + "$(cat ./secrets/user-salt.txt)" \ + | tr -d '\n' \ + > ./secrets/passwords/user-hash.txt diff --git a/nixos-switch.sh b/nixos-switch.sh index dc7797d..e704437 100755 --- a/nixos-switch.sh +++ b/nixos-switch.sh @@ -4,13 +4,33 @@ set -Eeuo pipefail cd "$(dirname "${BASH_SOURCE[0]}")" -envsubst < vps-configuration.env.nix | ssh "$TLD" 'cat > /etc/nixos/configuration.nix' +if [[ "${1:-}" = '--bootstrap' ]]; then + USER_PASSWORD="$(cat ./secrets/base-image-old-password.txt)" +else + USER_PASSWORD="$(cat ./secrets/user-password.txt)" +fi + +# Copy secrets +echo "${USER_PASSWORD}" | ssh "$TLD" sudo -S "\ +sudo mkdir -p ${SECRETS_ROOT}; \ +sudo chown -R ${USER_NAME}:users ${SECRETS_ROOT}/; \ +sudo chmod 700 ${SECRETS_ROOT}/; \ +sudo touch /etc/nixos/envsubst-configuration.nix; \ +sudo chown -R ${USER_NAME}:users /etc/nixos/envsubst-configuration.nix;" +rsync -avzP secrets/passwords/ "${TLD}:${SECRETS_ROOT}/" +envsubst < envsubst-configuration.nix | ssh "$TLD" 'cat > /etc/nixos/envsubst-configuration.nix' +echo "${USER_PASSWORD}" | ssh "$TLD" sudo -S "\ +sudo chown nextcloud:users ${SECRETS_ROOT}/nextcloud-admin.txt; \ +sudo chown nextcloud:users ${SECRETS_ROOT}/nextcloud-database.txt;" + +# Run nixos-rebuild +scp vps-configuration.nix "${TLD}:/etc/nixos/configuration.nix" echo "${USER_PASSWORD}" | ssh "$TLD" sudo -S nix-channel --add "https://nixos.org/channels/nixos-${SYSTEM_STATE_VERSION}" nixos echo "${USER_PASSWORD}" | ssh "$TLD" sudo -S -i nixos-rebuild switch --upgrade -ssh "${TLD}" rm -rf "${DATA_ROOT}/favicons/" -rsync -avzP favicons/ "${TLD}:${DATA_ROOT}/favicons/" - +# Copy support files +ssh "${TLD}" rm -rf "${FAVICONS_ROOT}/" +rsync -avzP favicons/ "${TLD}:${FAVICONS_ROOT}/" scp cgit-about.html "${TLD}:${GIT_ROOT}/about.html" scp ci-gen-index.sh "${TLD}:${CI_LOGS_ROOT}/ci-gen-index.sh" scp bash-profile.sh "${TLD}:.bash_profile" diff --git a/secrets/base-image-old-password.txt b/secrets/base-image-old-password.txt Binary files differnew file mode 100644 index 0000000..e8c8f00 --- /dev/null +++ b/secrets/base-image-old-password.txt diff --git a/secrets/nix/e1d5f317b0f7a-snapshot-configuration.nix b/secrets/nix/e1d5f317b0f7a-snapshot-configuration.nix Binary files differdeleted file mode 100644 index 8dcfe98..0000000 --- a/secrets/nix/e1d5f317b0f7a-snapshot-configuration.nix +++ /dev/null diff --git a/secrets/passwords/matrix-registration.txt b/secrets/passwords/matrix-registration.txt Binary files differnew file mode 100644 index 0000000..86c632e --- /dev/null +++ b/secrets/passwords/matrix-registration.txt diff --git a/secrets/passwords/nextcloud-admin.txt b/secrets/passwords/nextcloud-admin.txt Binary files differnew file mode 100644 index 0000000..0fd239d --- /dev/null +++ b/secrets/passwords/nextcloud-admin.txt diff --git a/secrets/passwords/nextcloud-database.txt b/secrets/passwords/nextcloud-database.txt Binary files differnew file mode 100644 index 0000000..084e356 --- /dev/null +++ b/secrets/passwords/nextcloud-database.txt diff --git a/secrets/passwords/user-hash.txt b/secrets/passwords/user-hash.txt Binary files differnew file mode 100644 index 0000000..e315081 --- /dev/null +++ b/secrets/passwords/user-hash.txt diff --git a/secrets/secret-envrc.sh b/secrets/secret-envrc.sh Binary files differdeleted file mode 100644 index 87656dc..0000000 --- a/secrets/secret-envrc.sh +++ /dev/null diff --git a/secrets/terraform/plan-files/2020-09-06T11:35:40-03:00.tfplan b/secrets/terraform/plan-files/2020-09-06T11:35:40-03:00.tfplan Binary files differnew file mode 100644 index 0000000..7b45ac1 --- /dev/null +++ b/secrets/terraform/plan-files/2020-09-06T11:35:40-03:00.tfplan diff --git a/secrets/terraform/plan-files/2020-09-06T12:18:46-03:00.tfplan b/secrets/terraform/plan-files/2020-09-06T12:18:46-03:00.tfplan Binary files differnew file mode 100644 index 0000000..eeb2f97 --- /dev/null +++ b/secrets/terraform/plan-files/2020-09-06T12:18:46-03:00.tfplan diff --git a/secrets/terraform/plan-files/2020-09-06T12:21:46-03:00.tfplan b/secrets/terraform/plan-files/2020-09-06T12:21:46-03:00.tfplan Binary files differnew file mode 100644 index 0000000..a75b3ca --- /dev/null +++ b/secrets/terraform/plan-files/2020-09-06T12:21:46-03:00.tfplan diff --git a/secrets/terraform/plan-files/2020-09-06T14:41:36-03:00.tfplan b/secrets/terraform/plan-files/2020-09-06T14:41:36-03:00.tfplan Binary files differnew file mode 100644 index 0000000..2b56aea --- /dev/null +++ b/secrets/terraform/plan-files/2020-09-06T14:41:36-03:00.tfplan diff --git a/secrets/terraform/plan-files/2020-09-06T15:37:03-03:00.tfplan b/secrets/terraform/plan-files/2020-09-06T15:37:03-03:00.tfplan Binary files differnew file mode 100644 index 0000000..3a5f186 --- /dev/null +++ b/secrets/terraform/plan-files/2020-09-06T15:37:03-03:00.tfplan diff --git a/secrets/terraform/terraform.tfstate b/secrets/terraform/terraform.tfstate Binary files differindex d7179d0..cea16aa 100644 --- a/secrets/terraform/terraform.tfstate +++ b/secrets/terraform/terraform.tfstate diff --git a/secrets/terraform/terraform.tfstate.backup b/secrets/terraform/terraform.tfstate.backup Binary files differindex 306bed7..58a911b 100644 --- a/secrets/terraform/terraform.tfstate.backup +++ b/secrets/terraform/terraform.tfstate.backup diff --git a/secrets/terraform/vultr-api-key.txt b/secrets/terraform/vultr-api-key.txt Binary files differnew file mode 100644 index 0000000..557429a --- /dev/null +++ b/secrets/terraform/vultr-api-key.txt diff --git a/secrets/user-password.txt b/secrets/user-password.txt Binary files differnew file mode 100644 index 0000000..63555f9 --- /dev/null +++ b/secrets/user-password.txt diff --git a/secrets/user-salt.txt b/secrets/user-salt.txt Binary files differnew file mode 100644 index 0000000..60fb774 --- /dev/null +++ b/secrets/user-salt.txt diff --git a/terraform-apply.sh b/terraform-apply.sh index 8179b96..588e1bb 100755 --- a/terraform-apply.sh +++ b/terraform-apply.sh @@ -4,6 +4,9 @@ set -Eeuo pipefail cd "$(dirname "${BASH_SOURCE[0]}")" +TF_VAR_vultr_api_key="$(cat ./secrets/terraform/vultr-api-key.txt)" +export TF_VAR_vultr_api_key + rm -rf .terraform/ terraform init PLAN_FILE="./secrets/terraform/plan-files/$(date -Iseconds).tfplan" diff --git a/vps-configuration.env.nix b/vps-configuration.nix index d5a7f54..06d0e29 100644 --- a/vps-configuration.env.nix +++ b/vps-configuration.nix @@ -1,54 +1,49 @@ { config, pkgs, ... }: let - envsubstConfiguration = { - TLD = "$TLD"; - nextcloudTLD = "$NEXTCLOUD_TLD"; - gitTLD = "$GIT_TLD"; - prosodyTLD = "$PROSODY_TLD"; - bonecoTLD = "$BONECO_TLD"; - pdfsTLD = "$PDFS_TLD"; - ciLogsTLD = "$CI_LOGS_TLD"; - songbooksDocumentationTLD = "$SONGBOOKS_DOCUMENTATION_TLD"; - piresDocumentationTLD = "$PIRES_DOCUMENTATION_TLD"; - mediatorDocumentationTLD = "$MEDIATOR_DOCUMENTATION_TLD"; - cementDocumentationTLD = "$CEMENT_DOCUMENTATION_TLD"; - piresProdTLD = "$PIRES_PROD_TLD"; - piresProdPort = "$PIRES_PROD_PORT"; - piresProdDir = "$PIRES_PROD_DIR"; - letsencryptEmail = "$LETSENCRYPT_EMAIL"; - authorizedKey = "$AUTHORIZED_KEY"; - userPassword = "$USER_PASSWORD"; - userName = "$USER_NAME"; - dataRoot = "$DATA_ROOT"; - staticRoot = "$STATIC_ROOT"; - ciLogsRoot = "$CI_LOGS_ROOT"; - faviconsRoot = "$FAVICONS_ROOT"; - nextcloudDatabaseUser = "$NEXTCLOUD_DATABASE_USER"; - nextcloudDatabasePassword = "$NEXTCLOUD_DATABASE_PASSWORD"; - nextcloudAdminUser = "$NEXTCLOUD_ADMIN_USER"; - nextcloudAdminPassword = "$NEXTCLOUD_ADMIN_PASSWORD"; - nextcloudTablePrefix = "$NEXTCLOUD_TABLE_PREFIX"; - gitPort = "$GIT_PORT"; - gitRoot = "$GIT_ROOT"; - systemStateVersion = "$SYSTEM_STATE_VERSION"; - prosodyConverseTLD = "$PROSODY_CONVERSE_TLD"; - prosodyAdminUser = "$PROSODY_ADMIN_USER"; - prosodyMUCTLD = "$PROSODY_MUC_TLD"; - prosodyPort = "$PROSODY_PORT"; - prosodyHTTPPort = "$PROSODY_HTTP_PORT"; - prosodyEnable = $PROSODY_ENABLE; + envsubstConfiguration = + pkgs.callPackage /etc/nixos/envsubst-configuration.nix { }; + config = rec { + letsencryptEmail = + "eu@euandre.org"; # this should change when adding email to the box + authorizedKey = + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDF+uy407LKZAFnfFkJPRiOBzwV98qIEcKhITnLYhqfITfrJvcFVOY0/YDCrs6WHXyLdM29AoywVWsQ1qXiB7xQCwknPV8YZoCnJQcn0gvH8jbCk+C8Po0Rx846wbhL49qYolnmlhe+Uoy30j7XIJSDtPVO9d/hZqt2GPwGVJ98HLyY2ak+j4i1YkHr+mPFgnCaqCAzA374d1Bop18+YENYtMMU0k8hCsomwZny/7qNo4V8mjLxQAS8FvTuljxlthEpOM4Jsjl07yDLgE69kLvU7mmFi8EeC26e50N18Ouse82dZigtVhAMeLBhbJnQbDff4WfUBzSjpKjZPGcxoRaej3qSRbIkcMMqCOSlww6GcjRi+COvlpA4c1i4hKI15wHceoiKghDLA6jbaHfOqEMldflYl5gCVUIYzJ5XehZppH6L7PzO+L4suNs+aFjWPDZ0jqEtcyTmgTMea40p7wwz086ExnBDorbG79oDiJrWc+swJjXuVakS+fQjb3mPsCC/FgUhsxEtqiVfvLo2mphp47pOYvs64aUp3RV9muqQNuS4tEuP9V1urGTLtgPL26LEjF0oLu1ag0H+VZY5O/T9KRYvWre8IWbj/KkZYo1tJaGJyEVr0plmyzLBEy8b3Hu/6Wtq7yB0Eii60fxqFWC24nEkvs1V0cxDa+o6I2iA9w== eu@euandre.org"; + TLD = envsubstConfiguration.TLD; + nextcloudDomain = "cloud.${TLD}"; + gitDomain = "git.${TLD}"; + prosodyDomain = "${TLD}"; + bonecoDomain = "boneco.${TLD}"; + pdfsDomain = "pdfs-da-d-maria.${TLD}"; + ciLogsDomain = "ci.${TLD}"; + songbooksDocumentationDomain = "songbooks.${TLD}"; + piresDocumentationDomain = "pires.${TLD}"; + mediatorDocumentationDomain = "mediator.${TLD}"; + cementDocumentationDomain = "cement.${TLD}"; + piresProdDomain = "pires-prod.${TLD}"; + piresProdPort = "1234"; + piresProdDir = "/home/andreh/pires-git/"; + nextcloudDatabaseUser = "nextcloud"; + nextcloudAdminUser = envsubstConfiguration.userName; + nextcloudTablePrefix = "euandreh_"; + gitPort = "81"; + prosodyConverseDomain = "chat.${TLD}"; + prosodyAdminUser = "eu@${TLD}"; + prosodyMUCDomain = "conference.${TLD}"; + prosodyPort = "5222"; + prosodyHTTPPort = "5280"; + prosodyEnable = envsubstConfiguration.prosodyEnable == "true"; + openSSHPort = 23841; }; staticSiteFromRepo = repoName: pkgs.stdenv.mkDerivation { name = repoName; src = fetchTarball - "https://git.sr.ht/~euandreh/${DOLLAR}{repoName}/archive/master.tar.gz"; + "https://git.sr.ht/~euandreh/${repoName}/archive/master.tar.gz"; phases = "unpackPhase buildPhase"; buildPhase = '' - mkdir ${DOLLAR}out - cp index.html ${DOLLAR}out - cp favicon.ico ${DOLLAR}out + mkdir $out + cp index.html $out + cp favicon.ico $out ''; }; pkgsUnstable = import (builtins.fetchTarball { @@ -58,14 +53,14 @@ let export FLASK_CONFIG=production export PIRES_PROD_DIR="$" - if [[ ! -d ${envsubstConfiguration.piresProdDir} ]]; then - ${pkgs.git}/bin/git clone https://gitlab.com/EuAndreh/pires.git ${envsubstConfiguration.piresProdDir} + if [[ ! -d ${config.piresProdDir} ]]; then + ${pkgs.git}/bin/git clone https://gitlab.com/EuAndreh/pires.git ${config.piresProdDir} fi - pushd ${envsubstConfiguration.piresProdDir} + pushd ${config.piresProdDir} ${pkgs.git}/bin/git pull ${pkgsUnstable.poetry}/bin/poetry install --no-dev --extras "waitress" ${pkgsUnstable.poetry}/bin/poetry run flask inicializar-banco - ${pkgsUnstable.poetry}/bin/poetry run waitress-serve --host localhost --port ${envsubstConfiguration.piresProdPort} --call pires:create_app + ${pkgsUnstable.poetry}/bin/poetry run waitress-serve --host localhost --port ${config.piresProdPort} --call pires:create_app ''; in { nix = { @@ -95,28 +90,27 @@ in { ]; networking.firewall.allowedTCPPorts = [ - # SSH: OpenSSH - 22 + config.openSSHPort # HTTP and HTPPS: NGINX 80 443 - ] ++ (if prosodyEnable then - [ - # XMPP: Prosody - # https://prosody.im/doc/ports - 5000 - 5222 - 5269 - 5280 - 5281 - 5347 - 5582 - ] else []); + ] ++ (if config.prosodyEnable then [ + # XMPP: Prosody + # https://prosody.im/doc/ports + 5000 + 5222 + 5269 + 5280 + 5281 + 5347 + 5582 + ] else + [ ]); security.acme = { acceptTerms = true; - email = envsubstConfiguration.letsencryptEmail; + email = config.letsencryptEmail; }; services = { @@ -124,6 +118,7 @@ in { enable = true; permitRootLogin = "no"; passwordAuthentication = false; + ports = [ config.openSSHPort ]; }; nginx = { @@ -133,11 +128,11 @@ in { recommendedProxySettings = true; recommendedTlsSettings = true; virtualHosts = { - "${envsubstConfiguration.nextcloudTLD}" = { + "${config.nextcloudDomain}" = { forceSSL = true; enableACME = true; }; - "${envsubstConfiguration.gitTLD}" = { + "${config.gitDomain}" = { forceSSL = true; enableACME = true; extraConfig = '' @@ -145,26 +140,26 @@ in { alias ${envsubstConfiguration.dataRoot}/favicons/git.ico; } location / { - proxy_pass http://localhost:${envsubstConfiguration.gitPort}; + proxy_pass http://localhost:${config.gitPort}; } ''; }; - "${envsubstConfiguration.bonecoTLD}" = { + "${config.bonecoDomain}" = { forceSSL = true; enableACME = true; root = staticSiteFromRepo "boneco"; }; - "${envsubstConfiguration.pdfsTLD}" = { + "${config.pdfsDomain}" = { forceSSL = true; enableACME = true; root = staticSiteFromRepo "pdfs-da-d-maria"; }; - "${envsubstConfiguration.ciLogsTLD}" = { + "${config.ciLogsDomain}" = { forceSSL = true; enableACME = true; root = "${envsubstConfiguration.ciLogsRoot}"; }; - "${envsubstConfiguration.mediatorDocumentationTLD}" = { + "${config.mediatorDocumentationDomain}" = { forceSSL = true; enableACME = true; extraConfig = '' @@ -174,7 +169,7 @@ in { root ${envsubstConfiguration.staticRoot}/mediator/; ''; }; - "${envsubstConfiguration.cementDocumentationTLD}" = { + "${config.cementDocumentationDomain}" = { forceSSL = true; enableACME = true; extraConfig = '' @@ -184,7 +179,7 @@ in { root ${envsubstConfiguration.staticRoot}/cement/; ''; }; - "${envsubstConfiguration.songbooksDocumentationTLD}" = { + "${config.songbooksDocumentationDomain}" = { forceSSL = true; enableACME = true; extraConfig = '' @@ -194,28 +189,25 @@ in { root ${envsubstConfiguration.staticRoot}/songbooks/; ''; }; - "${envsubstConfiguration.piresDocumentationTLD}" = { + "${config.piresDocumentationDomain}" = { forceSSL = true; enableACME = true; root = "${envsubstConfiguration.staticRoot}/pires/"; }; - "${envsubstConfiguration.piresProdTLD}" = { + "${config.piresProdDomain}" = { forceSSL = true; enableACME = true; locations = { - "/" = { - proxyPass = - "http://localhost:${envsubstConfiguration.piresProdPort}/"; - }; + "/" = { proxyPass = "http://localhost:${config.piresProdPort}/"; }; }; }; # Generate and maintain TLS certificate with NGINX # to be used by Prosody - "${envsubstConfiguration.prosodyTLD}" = { + "${config.prosodyDomain}" = { forceSSL = true; enableACME = true; }; - "${envsubstConfiguration.prosodyConverseTLD}" = { + "${config.prosodyConverseDomain}" = { forceSSL = true; enableACME = true; extraConfig = '' @@ -226,7 +218,7 @@ in { return 301 conversejs; } location / { - proxy_pass http://localhost:${envsubstConfiguration.prosodyHTTPPort}/; + proxy_pass http://localhost:${config.prosodyHTTPPort}/; } ''; }; @@ -247,7 +239,7 @@ in { enable = true; package = pkgs.nextcloud19; nginx.enable = true; - hostName = envsubstConfiguration.nextcloudTLD; + hostName = config.nextcloudDomain; https = true; maxUploadSize = "4G"; autoUpdateApps.enable = true; @@ -256,28 +248,28 @@ in { dbtype = "pgsql"; dbhost = "/run/postgresql"; dbuser = envsubstConfiguration.nextcloudDatabaseUser; - dbpass = envsubstConfiguration.nextcloudDatabasePassword; - dbtableprefix = envsubstConfiguration.nextcloudTablePrefix; - adminuser = envsubstConfiguration.nextcloudAdminUser; - adminpass = envsubstConfiguration.nextcloudAdminPassword; + dbpassFile = + "${envsubstConfiguration.secretsRoot}/nextcloud-database.txt"; + dbtableprefix = config.nextcloudTablePrefix; + adminuser = config.nextcloudAdminUser; + adminpassFile = + "${envsubstConfiguration.secretsRoot}/nextcloud-admin.txt"; }; }; prosody = let XMPP = { - fullchainPEM = - "/var/lib/acme/${envsubstConfiguration.prosodyTLD}/fullchain.pem"; - keyPEM = "/var/lib/acme/${envsubstConfiguration.prosodyTLD}/key.pem"; + fullchainPEM = "/var/lib/acme/${config.prosodyDomain}/fullchain.pem"; + keyPEM = "/var/lib/acme/${config.prosodyDomain}/key.pem"; }; ConverseJS = { fullchainPEM = - "/var/lib/acme/${envsubstConfiguration.prosodyConverseTLD}/fullchain.pem"; - keyPEM = - "/var/lib/acme/${envsubstConfiguration.prosodyConverseTLD}/key.pem"; + "/var/lib/acme/${config.prosodyConverseDomain}/fullchain.pem"; + keyPEM = "/var/lib/acme/${config.prosodyConverseDomain}/key.pem"; }; in { - enable = prosodyEnable; - admins = [ envsubstConfiguration.prosodyAdminUser ]; + enable = config.prosodyEnable; + admins = [ config.prosodyAdminUser ]; allowRegistration = false; modules = { websocket = true; }; package = pkgs.prosody.override { @@ -285,17 +277,17 @@ in { }; extraModules = [ "http_upload" "conversejs" "bookmarks" ]; virtualHosts = { - "${envsubstConfiguration.prosodyTLD}" = { + "${config.prosodyDomain}" = { enabled = true; - domain = "${envsubstConfiguration.prosodyTLD}"; + domain = "${config.prosodyDomain}"; ssl = { cert = XMPP.fullchainPEM; key = XMPP.keyPEM; }; }; - "${envsubstConfiguration.prosodyConverseTLD}" = { + "${config.prosodyConverseDomain}" = { enabled = true; - domain = "${envsubstConfiguration.prosodyConverseTLD}"; + domain = "${config.prosodyConverseDomain}"; ssl = { cert = ConverseJS.fullchainPEM; key = ConverseJS.keyPEM; @@ -306,7 +298,7 @@ in { lighttpd = { enable = true; - port = pkgs.lib.toInt envsubstConfiguration.gitPort; + port = pkgs.lib.toInt config.gitPort; cgit = { enable = true; subdir = ""; @@ -340,10 +332,10 @@ in { # extraConfig = '' # compress - # ${envsubstConfiguration.ciLogsRoot}/*/*.log { + # ${config.ciLogsRoot}/*/*.log { # rotate 5 # daily - # olddir ${envsubstConfiguration.staticRoot}/logrorate/ + # olddir ${config.staticRoot}/logrorate/ # createolddir 744 andreh users # su andreh users # } @@ -362,9 +354,9 @@ in { wantedBy = [ "multi-user.target" ]; script = pkgs.lib.fold (p: acc: acc + '' - mkdir -p ${DOLLAR}{p} - chown -R andreh:users ${DOLLAR}{p} - chmod -R 755 ${DOLLAR}{p} + mkdir -p ${p} + chown -R andreh:users ${p} + chmod -R 755 ${p} '') "" (with envsubstConfiguration; [ staticRoot gitRoot @@ -394,7 +386,7 @@ in { # Service serviceConfig = { User = "${envsubstConfiguration.userName}"; - ExecStart = "${DOLLAR}{piresProd}/bin/run-pires.sh"; + ExecStart = "${piresProd}/bin/run-pires.sh"; Restart = "always"; }; # Install @@ -402,12 +394,16 @@ in { }; }; - users.extraUsers."${envsubstConfiguration.userName}" = { - uid = 1000; - isNormalUser = true; - extraGroups = [ "wheel" ]; - password = envsubstConfiguration.userPassword; - openssh.authorizedKeys.keys = [ envsubstConfiguration.authorizedKey ]; + users = { + mutableUsers = false; + extraUsers."${envsubstConfiguration.userName}" = { + uid = 1000; + isNormalUser = true; + extraGroups = [ "wheel" ]; + hashedPassword = + builtins.readFile "${envsubstConfiguration.secretsRoot}/user-hash.txt"; + openssh.authorizedKeys.keys = [ config.authorizedKey ]; + }; }; system.stateVersion = envsubstConfiguration.systemStateVersion; |