From 100ab568e3aeb512e86fd1155a73454d22e24895 Mon Sep 17 00:00:00 2001 From: EuAndreh Date: Mon, 10 Aug 2020 12:15:49 -0300 Subject: Migration: Remove Ansible and Docker code, move only to NixOS --- .build.yml | 10 - .envrc | 44 +-- .gitignore | 8 +- TODOs.org | 5 + ansible.cfg | 3 - colors.sh | 119 -------- configuration.nix | 124 -------- default.nix | 15 - derived-configuration.env.nix | 4 - docker-compose.env.yaml | 80 ----- docs/README.css | 335 --------------------- generated/.gitignore | 2 - hosts.env | 2 - logs/.gitignore | 3 - logs/placeholder.txt | 1 - nextcloud-vhost.conf | 1 - nixos-update.sh | 11 + provision.env.yaml | 47 --- scripts/box/bash-profile.sh | 5 - scripts/box/create-backup.env.sh | 14 - scripts/box/restore-backup.env.sh | 21 -- scripts/box/user-data.env.sh | 11 - scripts/ci/deploy.sh | 105 ------- scripts/ci/mail.sh | 51 ---- scripts/ci/setup.sh | 26 -- scripts/local/rotate-ssh-keys.sh | 11 - secrets/nix/private-configuration.nix | Bin 73 -> 0 bytes secrets/secret-envrc.sh | Bin 2683 -> 2713 bytes secrets/ssh/id_rsa | Bin 0 -> 3411 bytes secrets/ssh/id_rsa.pub | Bin 0 -> 769 bytes secrets/ssh/vps-box-client | Bin 3411 -> 0 bytes secrets/ssh/vps-box-client.pub | Bin 769 -> 0 bytes secrets/ssh/vps-box-server | Bin 3411 -> 0 bytes secrets/ssh/vps-box-server.pub | Bin 769 -> 0 bytes .../plan-files/2020-08-10T12:02:19-03:00.tfplan | Bin 0 -> 3977 bytes shutdown.yaml | 17 -- ssh.env.conf | 7 - terraform-update.sh | 13 + vps-configuration.nix | 118 ++++++++ 39 files changed, 149 insertions(+), 1064 deletions(-) mode change 100644 => 120000 .envrc delete mode 100644 ansible.cfg delete mode 100644 colors.sh delete mode 100644 configuration.nix delete mode 100644 derived-configuration.env.nix delete mode 100644 docker-compose.env.yaml delete mode 100644 docs/README.css delete mode 100644 generated/.gitignore delete mode 100644 hosts.env delete mode 100644 logs/.gitignore delete mode 100644 logs/placeholder.txt delete mode 100644 nextcloud-vhost.conf create mode 100755 nixos-update.sh delete mode 100644 provision.env.yaml delete mode 100755 scripts/box/bash-profile.sh delete mode 100755 scripts/box/create-backup.env.sh delete mode 100755 scripts/box/restore-backup.env.sh delete mode 100755 scripts/box/user-data.env.sh delete mode 100755 scripts/ci/deploy.sh delete mode 100755 scripts/ci/mail.sh delete mode 100755 scripts/ci/setup.sh delete mode 100755 scripts/local/rotate-ssh-keys.sh delete mode 100644 secrets/nix/private-configuration.nix create mode 100644 secrets/ssh/id_rsa create mode 100644 secrets/ssh/id_rsa.pub delete mode 100644 secrets/ssh/vps-box-client delete mode 100644 secrets/ssh/vps-box-client.pub delete mode 100644 secrets/ssh/vps-box-server delete mode 100644 secrets/ssh/vps-box-server.pub create mode 100644 secrets/terraform/plan-files/2020-08-10T12:02:19-03:00.tfplan delete mode 100644 shutdown.yaml delete mode 100644 ssh.env.conf create mode 100755 terraform-update.sh create mode 100644 vps-configuration.nix diff --git a/.build.yml b/.build.yml index cb8719f..c8e51f2 100644 --- a/.build.yml +++ b/.build.yml @@ -7,17 +7,7 @@ triggers: to: EuAndreh sources: - https://git.sr.ht/~euandreh/vps - - https://git.sr.ht/~euandreh/vps-state -secrets: - - 814bb9d2-99ac-4070-aceb-d6b11183f574 # GPG keypair - - b715d3df-a0e2-4d5a-a6f3-ece5d0025cad tasks: - - setup: | - cd vps/ - ./scripts/ci/setup.sh - tests: | cd vps/ nix-build -A test - - deploy: | - cd vps/ - ./scripts/ci/deploy.sh diff --git a/.envrc b/.envrc deleted file mode 100644 index 89d8608..0000000 --- a/.envrc +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash -set -Eeuo pipefail - -# -# Operational toggle -# -export DESTROY_VOLUME= - -# -# Variables defined by commands -# -VPS_COMMIT_SHA="$(cat .git/refs/heads/master)" -export VPS_COMMIT_SHA -# Used for keeping bash variables for run-time substituion instead of execution time substitution. -# Taken from: -# https://stackoverflow.com/questions/24963705/is-there-an-escape-character-for-envsubst -export DOLLAR='$' - -# -# docker-compose -# -export VOLUME_HOME="/home/vps/volumes" - -# -# Nix -# -# Use the same $NIX_PATH as in the CI -# See also: -# https://discourse.nixos.org/t/inconsistent-hash-of-buildgomodule/3127/4 -export NIX_PATH=nixpkgs=channel:nixos-unstable - -if [[ "$(file -b ./secrets/secret-envrc.sh 2> /dev/null)" = "data" ]]; -then - echo 'The ./secrets/secret-envrc.sh is encrypted, not sourcing it.' - return -fi - -SSH_SERVER_PRIVATE_KEY="$(cat ./secrets/ssh/vps-box-server)" -export SSH_SERVER_PRIVATE_KEY -SSH_SERVER_PUBLIC_KEY="$(cat ./secrets/ssh/vps-box-server.pub)" -export SSH_SERVER_PUBLIC_KEY - -source ./secrets/secret-envrc.sh diff --git a/.envrc b/.envrc new file mode 120000 index 0000000..9178137 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +secrets/secret-envrc.sh \ No newline at end of file diff --git a/.gitignore b/.gitignore index cf33793..f785cc6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,10 +2,4 @@ /.terraform/ # Nix -/result - -# Logs -/logs.txt - -# envsubst -/provision.yaml \ No newline at end of file +/result \ No newline at end of file diff --git a/TODOs.org b/TODOs.org index 22f762a..bbe8a7e 100644 --- a/TODOs.org +++ b/TODOs.org @@ -1,4 +1,7 @@ * Tasks - v4 +** TODO Run =sudo= as =nixos= user in server +** TODO nginx magic =sslCiphers= value +Why not the default? What do those mean? ** TODO How to handle IP changes in mail server? ** TODO Add borg backup to crontab ** TODO Add 2FA to Vultr @@ -55,6 +58,8 @@ If I move vps-state into vps, I'll have to remove the terraform steps from the p It makes the deploying less automatic, but this removes the IP reputation email issue. This means that the Terraform provisioning should stay out of the CI and be run only locally. +** Run locally instead of on CI +It makes it less automagic, but greatly simplifies the configuration, like removing custom =ssh.env.conf=, =mail.sh=, =vps-box-client.pub=, etc. ** Configuration of =StrictHostKeyChecking= We have 3 cases where I'm pushing things to the server and I'm dealing with it differently: *** 1. Pushing updates to the =vps-state= repository diff --git a/ansible.cfg b/ansible.cfg deleted file mode 100644 index 4b7160e..0000000 --- a/ansible.cfg +++ /dev/null @@ -1,3 +0,0 @@ -[defaults] -inventory = ./generated/hosts -retry_files_enabled = False \ No newline at end of file diff --git a/colors.sh b/colors.sh deleted file mode 100644 index ce21da0..0000000 --- a/colors.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env bash -# shellcheck disable=1117 disable=1004 disable=2034 disable=2154 - -export end="\033[0m" -export black="\033[0;30m" -export blackb="\033[1;30m" -export white="\033[0;37m" -export whiteb="\033[1;37m" -export red="\033[0;31m" -export redb="\033[1;31m" -export green="\033[0;32m" -export greenb="\033[1;32m" -export yellow="\033[0;33m" -export yellowb="\033[1;33m" -export blue="\033[0;34m" -export blueb="\033[1;34m" -export purple="\033[0;35m" -export purpleb="\033[1;35m" -export lightblue="\033[0;36m" -export lightblueb="\033[1;36m" - -function black { - echo -e "${black}${1}${end}" -} -export -f black - -function blackb { - echo -e "${blackb}${1}${end}" -} -export -f blackb - -function white { - echo -e "${white}${1}${end}" -} -export -f white - -function whiteb { - echo -e "${whiteb}${1}${end}" -} -export -f whiteb - -function red { - echo -e "${red}${1}${end}" -} -export -f red - -function redb { - echo -e "${redb}${1}${end}" -} -export -f redb - -function green { - echo -e "${green}${1}${end}" -} -export -f green - -function greenb { - echo -e "${greenb}${1}${end}" -} -export -f greenb - -function yellow { - echo -e "${yellow}${1}${end}" -} -export -f yellow - -function yellowb { - echo -e "${yellowb}${1}${end}" -} -export -f yellowb - -function blue { - echo -e "${blue}${1}${end}" -} -export -f blue - -function blueb { - echo -e "${blueb}${1}${end}" -} -export -f blueb - -function purple { - echo -e "${purple}${1}${end}" -} -export -f purple - -function purpleb { - echo -e "${purpleb}${1}${end}" -} -export -f purpleb - -function lightblue { - echo -e "${lightblue}${1}${end}" -} -export -f lightblue - -function lightblueb { - echo -e "${lightblueb}${1}${end}" -} -export -f lightblueb - -function colors { - black "black" - blackb "blackb" - white "white" - whiteb "whiteb" - red "red" - redb "redb" - green "green" - greenb "greenb" - yellow "yellow" - yellowb "yellowb" - blue "blue" - blueb "blueb" - purple "purple" - purpleb "purpleb" - lightblue "lightblue" - lightblueb "lightblueb" -} diff --git a/configuration.nix b/configuration.nix deleted file mode 100644 index fad5305..0000000 --- a/configuration.nix +++ /dev/null @@ -1,124 +0,0 @@ -{ config, pkgs, ... }: - -let - privateConfiguration = import ./private-configuration.nix; - derivedConfiguration = import ./derived-configuration.nix; -in { - imports = [ ./hardware-configuration.nix]; - - boot.loader.grub = { - enable = true; - version = 2; - device = "/dev/vda"; - }; - - networking = { - useDHCP = false; - interfaces.ens3.useDHCP = true; - }; - - environment.systemPackages = with pkgs; [ - vim - ]; - - networking.firewall.allowedTCPPorts = [ 80 443 22 ]; - - security.acme = { - acceptTerms = true; - email = privateConfiguration.letsencryptEmail; - }; - - services = { - openssh = { - enable = true; - permitRootLogin = "no"; - passwordAuthentication = false; - }; - - nginx = { - enable = true; - recommendedGzipSettings = true; - recommendedOptimisation = true; - recommendedProxySettings = true; - recommendedTlsSettings = true; - sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL"; # FIXME: ????? - virtualHosts = let - customConfigTLDs = {}; - defaultConfigTLDs = [ - derivedConfiguration.nextcloudTLD - derivedConfiguration.gitTLD - ]; - buildDefaultConfiguration = tld: - { - "${tld}" = { - forceSSL = true; - enableACME = true; - }; - }; - in - pkgs.lib.fold - (tldString: acc: acc // buildDefaultConfiguration tldString) - customConfigTLDs - defaultConfigTLDs; - - gitweb = { - enable = true; - location = "/"; - virtualHost = derivedConfiguration.gitTLD; - }; - }; - - nextcloud = { - enable = true; - hostName = derivedConfiguration.nextcloudTLD; - nginx.enable = true; - https = true; - autoUpdateApps.enable = true; - autoUpdateApps.startAt = "05:00:00"; - config = { - overwriteProtocol = "https"; - - dbtype = "pgsql"; - dbuser = "nextcloud"; - dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself - dbname = "nextcloud"; - dbpassFile = "/var/nextcloud-db-pass"; - - adminpassFile = "/var/nextcloud-admin-pass"; - adminuser = "admin"; - }; - }; - - postgresql = { - enable = true; - ensureDatabases = [ "nextcloud" ]; - ensureUsers = [ - { - name = "nextcloud"; - ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES"; - } - ]; - }; - - gitweb = { - gitwebTheme = true; - projectroot = "/srv/git"; - }; - }; - - # FIXME: is this required? - systemd.services."nextcloud-setup" = { - requires = ["postgresql.service"]; - after = ["postgresql.service"]; - }; - - users.users.nixos = { - uid = 1000; - extraGroups = ["wheel"]; - useDefaultShell = true; - # FIXME: password hash file? - openssh.authorizedKeys.keyFiles = [ "/etc/nixos/nixos-user-authorized-key"]; - }; - - system.stateVersion = "19.09"; -} diff --git a/default.nix b/default.nix index 171a3a9..7078a01 100644 --- a/default.nix +++ b/default.nix @@ -18,20 +18,6 @@ in rec { touch $out ''; }); - dockerComposeLint = utils.baseTask.overrideAttrs (baseAttrs: { - name = "${baseAttrs.name}-docker-compose-lint"; - buildInputs = baseAttrs.buildInputs ++ [ pkgs.docker-compose ]; - buildPhase = '' - source .envrc - # =docker-compose config= doesn't accept files with different names - cp docker-compose.env.yaml docker-compose.yaml - docker-compose config &> /dev/null || { - echo "Invalid docker-compose.yml file." - exit 1 - } - touch $out - ''; - }); shellBuildInputs = with pkgs; [ file gitMinimal @@ -48,7 +34,6 @@ in rec { (utils.shellEnvironmentBuild subtasks.shellBuildInputs) utils.formatNix subtasks.formatTerraform - subtasks.dockerComposeLint ]; shell = utils.shellEnvironment subtasks.shellBuildInputs; } diff --git a/derived-configuration.env.nix b/derived-configuration.env.nix deleted file mode 100644 index b2bc8ea..0000000 --- a/derived-configuration.env.nix +++ /dev/null @@ -1,4 +0,0 @@ -{ - nextcloudTLD = "$NEXTCLOUD_TLD"; - gitTLD = "$GIT_TLD"; -} diff --git a/docker-compose.env.yaml b/docker-compose.env.yaml deleted file mode 100644 index 8785b68..0000000 --- a/docker-compose.env.yaml +++ /dev/null @@ -1,80 +0,0 @@ -version: '3' - -networks: - nginx-proxy-network: - -services: - nginx-proxy: - image: jwilder/nginx-proxy - container_name: nginx-proxy - restart: always - ports: - - '80:80' - - '443:443' - volumes: - - /var/run/docker.sock:/tmp/docker.sock:ro - - "${VOLUME_HOME}/vhost-conf:/etc/nginx/vhost.d" - - "${VOLUME_HOME}/docker/nginx-proxy/html:/usr/share/nginx/html" - - "${VOLUME_HOME}/docker/nginx-proxy/certs:/etc/nginx/certs:ro" - - "${VOLUME_HOME}/docker/nginx-proxy/conf:/etc/nginx/conf.d" - - "${VOLUME_HOME}/docker/nginx-proxy/dhparam:/etc/nginx/dhparam" - networks: - - nginx-proxy-network - - letsencrypt: - image: jrcs/letsencrypt-nginx-proxy-companion - container_name: letsencrypt-nginx-proxy-companion - restart: always - volumes: - - "${VOLUME_HOME}/docker/nginx-proxy/certs:/etc/nginx/certs" - - "${VOLUME_HOME}/docker/nginx-proxy/vhost:/etc/nginx/vhost.d" - - "${VOLUME_HOME}/docker/nginx-proxy/html:/usr/share/nginx/html" - - "${VOLUME_HOME}/docker/nginx-proxy/dhparam:/etc/nginx/dhparam:ro" - - /var/run/docker.sock:/var/run/docker.sock:ro - depends_on: - - nginx-proxy - environment: - - NGINX_PROXY_CONTAINER=nginx-proxy - networks: - - nginx-proxy-network - - static: - image: nginx - container_name: static-nginx - restart: always - volumes: - - "${VOLUME_HOME}/static:/usr/share/nginx/html" - ports: - - "${STATIC_PORT}:80" - environment: - - VIRTUAL_HOST=${STATIC_TLD} - - VIRTUAL_PORT=${STATIC_PORT} - - LETSENCRYPT_HOST=${STATIC_TLD} - - LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL} - networks: - - nginx-proxy-network - - nextcloud: - image: nextcloud:latest - container_name: nextcloud - restart: always - volumes: - - "${VOLUME_HOME}/applications/nextcloud/data:/var/www/html" - - "${VOLUME_HOME}/applications/nextcloud/config:/var/www/config" - - "${VOLUME_HOME}/applications/nextcloud/apps:/var/www/apps" - ports: - - "${NEXTCLOUD_PORT}:80" - environment: - - SQLITE_DATABASE=my-nextcloud-database.sqlite - - NEXTCLOUD_UPDATE=1 - - NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER} - - NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD} - - NEXTCLOUD_TABLE_PREFIX=${NEXTCLOUD_TABLE_PREFIX} - - NEXTCLOUD_HOSTNAME=${NEXTCLOUD_TLD} - - NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_TLD} - - VIRTUAL_HOST=${NEXTCLOUD_TLD} - - VIRTUAL_PORT=${NEXTCLOUD_PORT} - - LETSENCRYPT_HOST=${NEXTCLOUD_TLD} - - LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL} - networks: - - nginx-proxy-network diff --git a/docs/README.css b/docs/README.css deleted file mode 100644 index c744528..0000000 --- a/docs/README.css +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Taken from: - * https://gist.github.com/killercup/5917178 - * Inspired by: - * https://github.com/jerieljan/posaune-pandoc-theme - */ - -/* - * I add this to html files generated with pandoc. - */ - -html { - font-size: 100%; - overflow-y: scroll; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} - -body { - color: #444; - font-family: Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman', serif; - font-size: 12px; - line-height: 1.7; - padding: 1em; - margin: auto; - max-width: 42em; - background: #fefefe; -} - -a { - color: #0645ad; - text-decoration: none; -} - -a:visited { - color: #0b0080; -} - -a:hover { - color: #06e; -} - -a:active { - color: #faa700; -} - -a:focus { - outline: thin dotted; -} - -*::-moz-selection { - background: rgba(255, 255, 0, 0.3); - color: #000; -} - -*::selection { - background: rgba(255, 255, 0, 0.3); - color: #000; -} - -a::-moz-selection { - background: rgba(255, 255, 0, 0.3); - color: #0645ad; -} - -a::selection { - background: rgba(255, 255, 0, 0.3); - color: #0645ad; -} - -p { - margin: 1em 0; -} - -img { - max-width: 100%; -} - -h1, h2, h3, h4, h5, h6 { - color: #111; - line-height: 125%; - margin-top: 2em; - font-weight: normal; -} - -h4, h5, h6 { - font-weight: bold; -} - -h1 { - font-size: 2.5em; -} - -h2 { - font-size: 2em; -} - -h3 { - font-size: 1.5em; -} - -h4 { - font-size: 1.2em; -} - -h5 { - font-size: 1em; -} - -h6 { - font-size: 0.9em; -} - -blockquote { - color: #666666; - margin: 0; - padding-left: 3em; - border-left: 0.5em #EEE solid; -} - -hr { - display: block; - height: 2px; - border: 0; - border-top: 1px solid #aaa; - border-bottom: 1px solid #eee; - margin: 1em 0; - padding: 0; -} - -pre, code, kbd, samp { - color: #000; - font-family: monospace, monospace; - _font-family: 'courier new', monospace; - font-size: 0.98em; -} - -pre { - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; -} - -b, strong { - font-weight: bold; -} - -dfn { - font-style: italic; -} - -ins { - background: #ff9; - color: #000; - text-decoration: none; -} - -mark { - background: #ff0; - color: #000; - font-style: italic; - font-weight: bold; -} - -sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -ul, ol { - margin: 1em 0; - padding: 0 0 0 2em; -} - -li p:last-child { - margin-bottom: 0; -} - -ul ul, ol ol { - margin: .3em 0; -} - -dl { - margin-bottom: 1em; -} - -dt { - font-weight: bold; - margin-bottom: .8em; -} - -dd { - margin: 0 0 .8em 2em; -} - -dd:last-child { - margin-bottom: 0; -} - -img { - border: 0; - -ms-interpolation-mode: bicubic; - vertical-align: middle; -} - -figure { - display: block; - text-align: center; - margin: 1em 0; -} - -figure img { - border: none; - margin: 0 auto; -} - -figcaption { - font-size: 0.8em; - font-style: italic; - margin: 0 0 .8em; -} - -table { - margin-bottom: 2em; - border-bottom: 1px solid #ddd; - border-right: 1px solid #ddd; - border-spacing: 0; - border-collapse: collapse; -} - -table th { - padding: .2em 1em; - background-color: #eee; - border-top: 1px solid #ddd; - border-left: 1px solid #ddd; -} - -table td { - padding: .2em 1em; - border-top: 1px solid #ddd; - border-left: 1px solid #ddd; - vertical-align: top; -} - -.author { - font-size: 1.2em; - text-align: center; -} - -@media only screen and (min-width: 480px) { - body { - font-size: 14px; - } -} -@media only screen and (min-width: 768px) { - body { - font-size: 16px; - } -} -@media print { - * { - background: transparent !important; - color: black !important; - filter: none !important; - -ms-filter: none !important; - } - - body { - font-size: 12pt; - max-width: 100%; - } - - a, a:visited { - text-decoration: underline; - } - - hr { - height: 1px; - border: 0; - border-bottom: 1px solid black; - } - - a[href]:after { - content: " (" attr(href) ")"; - } - - abbr[title]:after { - content: " (" attr(title) ")"; - } - - .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { - content: ""; - } - - pre, blockquote { - border: 1px solid #999; - padding-right: 1em; - page-break-inside: avoid; - } - - tr, img { - page-break-inside: avoid; - } - - img { - max-width: 100% !important; - } - - @page :left { - margin: 15mm 20mm 15mm 10mm; -} - - @page :right { - margin: 15mm 10mm 15mm 20mm; -} - - p, h2, h3 { - orphans: 3; - widows: 3; - } - - h2, h3 { - page-break-after: avoid; - } -} diff --git a/generated/.gitignore b/generated/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/generated/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/hosts.env b/hosts.env deleted file mode 100644 index 62fa199..0000000 --- a/hosts.env +++ /dev/null @@ -1,2 +0,0 @@ -[vps] -$TLD diff --git a/logs/.gitignore b/logs/.gitignore deleted file mode 100644 index af144f4..0000000 --- a/logs/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -* -!.gitignore -!placeholder.txt diff --git a/logs/placeholder.txt b/logs/placeholder.txt deleted file mode 100644 index e126580..0000000 --- a/logs/placeholder.txt +++ /dev/null @@ -1 +0,0 @@ -Placeholder log file so =cat logs/*= won't fail after being trapped. diff --git a/nextcloud-vhost.conf b/nextcloud-vhost.conf deleted file mode 100644 index efc1540..0000000 --- a/nextcloud-vhost.conf +++ /dev/null @@ -1 +0,0 @@ -client_max_body_size 4096M; diff --git a/nixos-update.sh b/nixos-update.sh new file mode 100755 index 0000000..7db0bf8 --- /dev/null +++ b/nixos-update.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash +# shellcheck shell=bash +set -Eeuo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")" + +git crypt unlock +direnv allow + +envsubst < vps-configuration.env.nix | ssh "$TLD" 'cat > /etc/nixos/vps-configuration.nix' +ssh "$TLD" sudo nixos-rebuild switch --upgrade diff --git a/provision.env.yaml b/provision.env.yaml deleted file mode 100644 index 8c3e1c8..0000000 --- a/provision.env.yaml +++ /dev/null @@ -1,47 +0,0 @@ ---- -- hosts: all - any_errors_fatal: true - tasks: - - name: Update Ubuntu server - apt: - update_cache: yes - upgrade: dist - - name: Install apt packages - apt: - name: [ 'docker-compose', 'borgbackup' ] - state: latest - - name: Create /home/vps/ base directory - file: - path: /home/vps/ - state: directory - - name: Create symlink to attached volume - file: - src: /mnt/${VPS_VOLUME_NAME} - dest: /home/vps/volumes - state: link - - name: Create required vhost conf directory - file: - path: /home/vps/volumes/vhost-conf - state: directory - mode: '0755' - - name: Copy local interpolated files to remote - copy: src={{ item.src }} dest={{ item.dest }} mode={{ item.mode }} - with_items: - - { src: './generated/restore-backup.sh', dest: '/home/vps/restore-backup.sh', mode: '500' } - - { src: './secrets/borg/borg-remote.pub', dest: '/root/.ssh/id_rsa.pub', mode: '400' } - - { src: './secrets/borg/borg-remote', dest: '/root/.ssh/id_rsa', mode: '400' } - - { src: './secrets/borg/known-hosts.txt', dest: '/root/.ssh/known_hosts', mode: '400' } - - { src: './scripts/box/bash-profile.sh', dest: '/root/.bash_profile', mode: '400' } - - { src: './generated/docker-compose.yaml', dest: '/home/vps/docker-compose.yaml', mode: '400' } - - { src: './nextcloud-vhost.conf', dest: '/home/vps/volumes/vhost-conf/${NEXTCLOUD_TLD}', mode: '400' } - - name: Restore borg backup when we have a fresh volume - shell: /home/vps/restore-backup.sh - when: lookup('env', 'DESTROY_VPS') == "1" - - name: Create the required Docker network - docker_network: - name: nginx-proxy-network - - name: Start docker-compose - docker_compose: - project_src: /home/vps/ - pull: yes - state: present diff --git a/scripts/box/bash-profile.sh b/scripts/box/bash-profile.sh deleted file mode 100755 index c024dbd..0000000 --- a/scripts/box/bash-profile.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# shellcheck disable=SC2164 - -alias l="ls -lahp --color" -cd /home/vps/ diff --git a/scripts/box/create-backup.env.sh b/scripts/box/create-backup.env.sh deleted file mode 100755 index f5cd3b0..0000000 --- a/scripts/box/create-backup.env.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -set -Eeuo pipefail - -export BORG_REMOTE_PATH="${BORG_REMOTE_PATH}" -export BORG_PASSPHRASE="${BORG_PASSPHRASE}" -# The configured $BORG_REPO is already the rsync remote. -# No need to send the files after the backup is done. -borg create \ - --verbose \ - --stats \ - --progress \ - --compression lzma,6 \ - "${BORG_REPO}::{hostname}-{now}-${VPS_COMMIT_SHA}" \ - "${VOLUME_HOME}"/* diff --git a/scripts/box/restore-backup.env.sh b/scripts/box/restore-backup.env.sh deleted file mode 100755 index 151ded5..0000000 --- a/scripts/box/restore-backup.env.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -set -Eeuo pipefail - -export BORG_REMOTE_PATH="${BORG_REMOTE_PATH}" -export BORG_PASSPHRASE="${BORG_PASSPHRASE}" - -pushd "$(mktemp -d)" || exit 1 - -# It is actually being used below using the DOLLAR interpolation -# shellcheck disable=SC2034 -ARCHIVE="$(borg list "${BORG_REPO}" --last 1 --short)" - -echo "Extracting archive ${DOLLAR}{ARCHIVE}" -borg extract \ - --verbose \ - --progress \ - "${BORG_REPO}::${DOLLAR}{ARCHIVE}" -echo "Done." - -mv home/vps/volumes/* /home/vps/volumes/ -popd || exit 1 diff --git a/scripts/box/user-data.env.sh b/scripts/box/user-data.env.sh deleted file mode 100755 index f9da5d7..0000000 --- a/scripts/box/user-data.env.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -# shellcheck disable=SC2016 - -echo '$SSH_SERVER_PRIVATE_KEY' > /etc/ssh/vps-box-server -chmod 400 /etc/ssh/vps-box-server -echo '$SSH_SERVER_PUBLIC_KEY' > /etc/ssh/vps-box-server.pub -echo 'HostKey /etc/ssh/vps-box-server' >> /etc/ssh/sshd_config -echo 'Port $SSH_PORT' >> /etc/ssh/sshd_config -systemctl restart sshd - -# SSH logs on /var/log/auth.log diff --git a/scripts/ci/deploy.sh b/scripts/ci/deploy.sh deleted file mode 100755 index 9be5758..0000000 --- a/scripts/ci/deploy.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env nix-shell -#!nix-shell -i bash ../../shell.nix -# shellcheck shell=bash -set -Eeuo pipefail -cd "$(dirname "${BASH_SOURCE[0]}")" -cd ../../ -PROJECT_ROOT="${PWD}" - -finish-phase() { - local -r exit_code="${?}" - - cd "${PROJECT_ROOT}" - - if [[ "${exit_code}" = 0 ]]; then - echo "Finished successfully." - else - echo "TRAPPED ERROR!" - fi - echo "Running final steps..." - - echo "Sending logs via email..." - ./scripts/ci/mail.sh "${exit_code}" - echo "Done." - - echo "Storing file changes to '.tfstate' files..." - pushd ../vps-state/ - git add . - git commit -m "CI: fallback add all after deploy.sh failure for CI run $VPS_COMMIT_SHA" ||: - git push origin master - popd - echo "Done." - - echo "Locking git-crypt repositories back..." - git crypt lock - pushd ../vps-state/ - git crypt lock - popd - echo "Done." - - echo "Finished cleanup." -} -trap finish-phase EXIT - -create-known-hosts-file() { - echo "${TLD},$(terraform output public_floating_ip) ssh-rsa $(awk '{print $2}' < ./secrets/ssh/vps-box-server.pub)" > ./generated/generated-known-hosts.txt -} - -echo "Interpolating files with envsubst..." -envsubst < ./ssh.env.conf >> ~/.ssh/config -envsubst < ./hosts.env > ./generated/hosts -envsubst < ./docker-compose.env.yaml > ./generated/docker-compose.yaml -envsubst < ./provision.env.yaml > ./generated/provision.yaml -envsubst < ./scripts/box/user-data.env.sh > ./generated/user-data.sh -envsubst < ./scripts/box/create-backup.env.sh > ./generated/create-backup.sh -envsubst < ./scripts/box/restore-backup.env.sh > ./generated/restore-backup.sh -echo "Done." - -echo "Running the Ansible shutdown.yaml playbook..." -create-known-hosts-file -ansible-playbook -v shutdown.yaml > ./logs/ansible-shutdown.txt -echo "Done." - -echo "Initializing Terraform..." -terraform --version -terraform init -echo "Done." - -if [[ "${DESTROY_VPS:-}" != "" ]]; then - echo "Destroying existing infrastructure..." - terraform destroy -input=false -auto-approve > ./logs/terraform-destroy.txt 2>&1 -else - echo 'Refreshing view on existing infrastructure...' - terraform refresh > ./logs/terraform-refresh.txt 2>&1 -fi -echo "Done." - -echo "Running 'terraform plan' and storing the planfile..." -mkdir -p "../vps-state/secrets/plan-files/" -PLAN_FILE_NAME="$(date -Iseconds)-${VPS_COMMIT_SHA}.tfplan" -PLAN_FILE_PATH="../vps-state/secrets/plan-files/${PLAN_FILE_NAME}" -terraform plan -input=false -out="${PLAN_FILE_PATH}" > ./logs/terraform-plan.txt 2>&1 -pushd ../vps-state/ -git add "secrets/plan-files/${PLAN_FILE_NAME}" -git commit -m "CI: add .tfplan plan file for CI run ${VPS_COMMIT_SHA}" -git push origin master -popd -echo "Done." - -echo "Running 'terraform apply'..." -terraform apply -input=false -auto-approve "${PLAN_FILE_PATH}" > ./logs/terraform-apply.txt 2>&1 -echo "Done." - -echo "Storing .tfstate file..." -pushd ../vps-state/ -git add secrets/terraform.tfstate secrets/terraform.tfstate.backup -git commit -m "CI: update Terraform .tfstate files for CI run ${VPS_COMMIT_SHA}" --allow-empty -git push origin master -popd -echo "Done." - -echo "Running the Ansible provision.yaml playbook..." -create-known-hosts-file -cp ./generated/provision.yaml ./provision.yaml -ansible-playbook -v provision.yaml > ./logs/ansible-provision.txt -echo "Done." diff --git a/scripts/ci/mail.sh b/scripts/ci/mail.sh deleted file mode 100755 index 9caebd4..0000000 --- a/scripts/ci/mail.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash -set -Eeuo pipefail -cd "$(dirname "${BASH_SOURCE[0]}")" -cd ../../ - -EXIT_CODE="${1:-}" - -[[ -z "${EXIT_CODE}" ]] && { - # shellcheck disable=SC2016 - echo 'Error: missing $EXIT positional argument.' - exit 2 -} - -if [[ "${EXIT_CODE}" = 0 ]]; then - SUBJECT_SUFFIX=' (successful build)' -else - SUBJECT_SUFFIX=' (FAILED BUILD)' -fi - -SUBJECT="VPS CI run #${JOB_ID} logs${SUBJECT_SUFFIX}" -ATTACHMENT_PATH='logs.txt' -BODY=$(cat < "${ATTACHMENT_PATH}" - -[[ "${USER}" = "build" ]] || { - echo "Not running on CI." - echo "Early exit on sending email logs." - exit -} - -gpg --always-trust \ - -r "${GPG_TO}" \ - -e "${ATTACHMENT_PATH}" - -curl "${MAILGUN_URL}" \ - -s \ - --user "${MAILGUN_USER}" \ - -F from="${MAILGUN_FROM}" \ - -F to="${MAILGUN_TO}" \ - -F subject="${SUBJECT}" \ - -F text="${BODY}" \ - -F attachment="@${ATTACHMENT_PATH}.gpg" diff --git a/scripts/ci/setup.sh b/scripts/ci/setup.sh deleted file mode 100755 index d876df7..0000000 --- a/scripts/ci/setup.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env nix-shell -#!nix-shell -i bash ../../shell.nix -# shellcheck shell=bash -set -Eeuo pipefail -cd "$(dirname "${BASH_SOURCE[0]}")" -cd ../../ - -echo "Unlocking git-crypt repos..." -git crypt unlock -# Assumes vps-state was already cloned -pushd ../vps-state/ -git crypt unlock -git remote set-url origin git@git.sr.ht:~euandreh/vps-state -popd -# git smudge after git-crypt clears file permissions -chmod 400 ./secrets/ssh/vps-box-client -echo "Done." - -echo "cd ./vps/ && source .envrc && cd ../" >> ~/.buildenv - -source .envrc - -git config --global user.email "${GIT_CI_USER}" -git config --global user.name "sr.ht CI" - -curl https://euandre.org/public-key.txt | gpg --import diff --git a/scripts/local/rotate-ssh-keys.sh b/scripts/local/rotate-ssh-keys.sh deleted file mode 100755 index 323d27c..0000000 --- a/scripts/local/rotate-ssh-keys.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -set -Eeuo pipefail -cd "$(dirname "${BASH_SOURCE[0]}")" -cd ../../ - -rm -f ./secrets/ssh/* -ssh-keygen -t rsa -b 4096 -q -N '' -f ./secrets/ssh/vps-box-client -C "${SSH_EMAIL}" -ssh-keygen -t rsa -b 4096 -q -N '' -f ./secrets/ssh/vps-box-server -C "${SSH_EMAIL}" - -git add ./secrets/ssh/ -git commit -m "Script: rotate SSH keys" diff --git a/secrets/nix/private-configuration.nix b/secrets/nix/private-configuration.nix deleted file mode 100644 index 9796247..0000000 Binary files a/secrets/nix/private-configuration.nix and /dev/null differ diff --git a/secrets/secret-envrc.sh b/secrets/secret-envrc.sh index 29469b3..6b8f06c 100644 Binary files a/secrets/secret-envrc.sh and b/secrets/secret-envrc.sh differ diff --git a/secrets/ssh/id_rsa b/secrets/ssh/id_rsa new file mode 100644 index 0000000..439d0fe Binary files /dev/null and b/secrets/ssh/id_rsa differ diff --git a/secrets/ssh/id_rsa.pub b/secrets/ssh/id_rsa.pub new file mode 100644 index 0000000..78fb062 Binary files /dev/null and b/secrets/ssh/id_rsa.pub differ diff --git a/secrets/ssh/vps-box-client b/secrets/ssh/vps-box-client deleted file mode 100644 index 439d0fe..0000000 Binary files a/secrets/ssh/vps-box-client and /dev/null differ diff --git a/secrets/ssh/vps-box-client.pub b/secrets/ssh/vps-box-client.pub deleted file mode 100644 index 78fb062..0000000 Binary files a/secrets/ssh/vps-box-client.pub and /dev/null differ diff --git a/secrets/ssh/vps-box-server b/secrets/ssh/vps-box-server deleted file mode 100644 index df5c34e..0000000 Binary files a/secrets/ssh/vps-box-server and /dev/null differ diff --git a/secrets/ssh/vps-box-server.pub b/secrets/ssh/vps-box-server.pub deleted file mode 100644 index 4cca320..0000000 Binary files a/secrets/ssh/vps-box-server.pub and /dev/null differ diff --git a/secrets/terraform/plan-files/2020-08-10T12:02:19-03:00.tfplan b/secrets/terraform/plan-files/2020-08-10T12:02:19-03:00.tfplan new file mode 100644 index 0000000..5807aee Binary files /dev/null and b/secrets/terraform/plan-files/2020-08-10T12:02:19-03:00.tfplan differ diff --git a/shutdown.yaml b/shutdown.yaml deleted file mode 100644 index a190d1a..0000000 --- a/shutdown.yaml +++ /dev/null @@ -1,17 +0,0 @@ ---- -- hosts: all - any_errors_fatal: true - tasks: - - name: Copy files for performing the backup - copy: src={{ item.src }} dest={{ item.dest }} mode={{ item.mode }} - with_items: - - { src: './generated/create-backup.sh', dest: '/home/vps/create-backup.sh', mode: '500' } - - { src: './secrets/borg/borg-remote.pub', dest: '/root/.ssh/id_rsa.pub', mode: '400' } - - { src: './secrets/borg/borg-remote', dest: '/root/.ssh/id_rsa', mode: '400' } - - { src: './secrets/borg/known-hosts.txt', dest: '/root/.ssh/known_hosts', mode: '400' } - - name: Stop docker-compose - docker_compose: - project_src: /home/vps/ - state: absent - - name: Create a borg backup of the volume - shell: /home/vps/create-backup.sh diff --git a/ssh.env.conf b/ssh.env.conf deleted file mode 100644 index be34b28..0000000 --- a/ssh.env.conf +++ /dev/null @@ -1,7 +0,0 @@ -Host $TLD - User root - IdentityFile $PWD/secrets/ssh/vps-box-client - UserKnownHostsFile $PWD/generated/generated-known-hosts.txt - Port $SSH_PORT -Host git.sr.ht - StrictHostKeyChecking no diff --git a/terraform-update.sh b/terraform-update.sh new file mode 100755 index 0000000..436d7a1 --- /dev/null +++ b/terraform-update.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash +# shellcheck shell=bash +set -Eeuo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")" + +git crypt unlock +direnv allow + +terraform init +PLAN_FILE="./secrets/terraform/plan-files/$(date -Iseconds)" +terraform plan -input=false -out="${PLAN_FILE}" +terraform apply -input=false "${PLAN_FILE}" diff --git a/vps-configuration.nix b/vps-configuration.nix new file mode 100644 index 0000000..8afa57d --- /dev/null +++ b/vps-configuration.nix @@ -0,0 +1,118 @@ +{ config, pkgs, ... }: + +let + envsubstConfiguration = { + nextcloudTLD = "$NEXTCLOUD_TLD"; + gitTLD = "$GIT_TLD"; + letsencryptEmail = "$LETSENCRYPT_EMAIL"; + authorizedKey = "$AUTHORIZED_KEY"; + }; +in { + imports = [ ./hardware-configuration.nix ]; + + boot.loader.grub = { + enable = true; + version = 2; + device = "/dev/vda"; + }; + + networking = { + useDHCP = false; + interfaces.ens3.useDHCP = true; + }; + + environment.systemPackages = with pkgs; [ vim ]; + + networking.firewall.allowedTCPPorts = [ 80 443 22 ]; + + security.acme = { + acceptTerms = true; + email = envsubstConfiguration.letsencryptEmail; + }; + + services = { + openssh = { + enable = true; + permitRootLogin = "no"; + passwordAuthentication = false; + }; + + nginx = { + enable = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL"; + virtualHosts = let + customConfigTLDs = { }; + defaultConfigTLDs = + [ envsubstConfiguration.nextcloudTLD envsubstConfiguration.gitTLD ]; + buildDefaultConfiguration = tld: { + "${tld}" = { + forceSSL = true; + enableACME = true; + }; + }; + in pkgs.lib.fold + (tldString: acc: acc // buildDefaultConfiguration tldString) + customConfigTLDs defaultConfigTLDs; + + gitweb = { + enable = true; + location = "/"; + virtualHost = envsubstConfiguration.gitTLD; + }; + }; + + nextcloud = { + enable = true; + hostName = envsubstConfiguration.nextcloudTLD; + nginx.enable = true; + https = true; + autoUpdateApps.enable = true; + autoUpdateApps.startAt = "05:00:00"; + config = { + overwriteProtocol = "https"; + + dbtype = "pgsql"; + dbuser = "nextcloud"; + dbhost = + "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself + dbname = "nextcloud"; + dbpassFile = "/var/nextcloud-db-pass"; + + adminpassFile = "/var/nextcloud-admin-pass"; + adminuser = "admin"; + }; + }; + + postgresql = { + enable = true; + ensureDatabases = [ "nextcloud" ]; + ensureUsers = [{ + name = "nextcloud"; + ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES"; + }]; + }; + + gitweb = { + gitwebTheme = true; + projectroot = "/srv/git"; + }; + }; + + systemd.services."nextcloud-setup" = { + requires = [ "postgresql.service" ]; + after = [ "postgresql.service" ]; + }; + + users.users.nixos = { + uid = 1000; + extraGroups = [ "wheel" ]; + useDefaultShell = true; + openssh.authorizedKeys.keys = [ envsubstConfiguration.authorizedKey ]; + }; + + system.stateVersion = "19.09"; +} -- cgit v1.2.3