Compare commits

..

2 Commits

Author SHA1 Message Date
marc
042e246b1b Agenix + Consul 2024-02-11 16:06:03 +01:00
marc
fa12502c6e Structured documentation 2024-02-10 20:26:01 +01:00
21 changed files with 696 additions and 231 deletions

View File

@@ -1,175 +1,13 @@
* Installing
** Fresh system (nixos USB drive)
1. Open a nix-shell with git (if not installed):
#+BEGIN_SRC bash
nix-shell -p git
#+END_SRC
2. Clone the flake
#+BEGIN_SRC bash
git clone https://git.samfelag.xyz/marc/samfelag.git
#+END_SRC
3. Partition the disk
We'll partition the disk in the follwing way:
* 512MB at the beginning for the boot partition
* 8GB at the end for swap
* The rest (at the middle) for the filesystem (/)
1. Locate the disk
#+BEGIN_SRC bash
lsblk
#+END_SRC
2. Create a GPT partition table
#+BEGIN_SRC bash
sudo parted /dev/nvme0n1 -- mklabel gpt
#+END_SRC
3. Create the root partition
#+BEGIN_SRC bash
sudo parted /dev/nvme0n1 -- mkpart primary 512MB -8GB
#+END_SRC
4. Create the swap partition
#+BEGIN_SRC bash
sudo parted /dev/nvme0n1 -- mkpart primary linux-swap -8GB 100%
#+END_SRC
5. Create the boot partition
#+BEGIN_SRC bash
sudo parted /dev/nvme0n1 -- mkpart ESP fat32 1MB 512MB
sudo parted /dev/nvme0n1 -- set 3 esp on
#+END_SRC
4. Format the partitions
1. Root partition
#+BEGIN_SRC bash
sudo mkfs.ext4 -L nixos /dev/nvme0n1p1
#+END_SRC
2. Swap partition
#+BEGIN_SRC bash
sudo mkswap -L swap /dev/nvme0n1p2
#+END_SRC
3. Boot partition
#+BEGIN_SRC bash
sudo mkfs.fat -F 32 -n BOOT /dev/nvme0n1p3
#+END_SRC
5. Mount the filesystems
1. Root partition
#+BEGIN_SRC bash
sudo mount /dev/disk/by-label/nixos /mnt
#+END_SRC
2. Boot partition
#+BEGIN_SRC bash
sudo mkdir -p /mnt/boot
sudo mount /dev/disk/by-label/BOOT /mnt/boot
#+END_SRC
3. Swap partition (if needed)
#+BEGIN_SRC bash
sudo swapon /dev/disk/by-label/swap
#+END_SRC
6. Create the host nix configuration
If the host is not present under system/hosts, create a new folder for the host.
Generate the hardware configuration file, you can use nixos-generate-config as a base:
#+BEGIN_SRC bash
nixos-generate-config --dir <<host directory>> --no-filesystems
#+END_SRC
7. Install nixos!
#+BEGIN_SRC bash
sudo nixos-install --impure --root /mnt --flake '.#reykjavik'
#+END_SRC
8. Set up the user
You'll set the root password during the installation. You can then reboot and use the installed OS. First thing you'll have to do is log in as root and set the password for your user:
#+BEGIN_SRC bash
passwd marc
#+END_SRC
** Fresh system (vultr)
1. [Optional] Set the root password via the Vultr Console, so you can ssh to the instance
2. Open a nix-shell with git (if not installed):
#+BEGIN_SRC bash
nix-shell -p git
#+END_SRC
3. Clone the flake
#+BEGIN_SRC bash
git clone https://git.samfelag.xyz/marc/samfelag.git
#+END_SRC
4. Partition the disk
We'll partition the disk in the follwing way:
* 512MB at the beginning for the boot partition
* 8GB at the end for swap
* The rest (at the middle) for the filesystem (/)
* Locate the disk
#+BEGIN_SRC bash
lsblk
#+END_SRC
* Create a MBR partition table
#+BEGIN_SRC bash
sudo parted /dev/vda -- mklabel msdos
#+END_SRC
* Create the root partition
#+BEGIN_SRC bash
sudo parted /dev/vda -- mkpart primary 1MiB -8GiB
#+END_SRC
* Create the swap partition
#+BEGIN_SRC bash
sudo parted /dev/vda -- mkpart primary linux-swap -8GiB 100%
#+END_SRC
* Create the boot partition
#+BEGIN_SRC bash
sudo parted /dev/vda -- mkpart ESP fat32 1MB 512MB
sudo parted /dev/vda -- set 3 esp on
#+END_SRC
5. Format the partitions
1. Root partition
#+BEGIN_SRC bash
sudo mkfs.ext4 -L nixos /dev/vda1
#+END_SRC
2. Swap partition
#+BEGIN_SRC bash
sudo mkswap -L swap /dev/vda2
#+END_SRC
6. Mount the filesystems
1. Root partition
#+BEGIN_SRC bash
sudo mount /dev/disk/by-label/nixos /mnt
#+END_SRC
2. Swap partition (if needed)
#+BEGIN_SRC bash
sudo swapon /dev/disk/by-label/swap
#+END_SRC
7. Create the host nix configuration
If the host is not present under system/hosts, create a new folder for the host.
Generate the hardware configuration file, you can use nixos-generate-config as a base:
#+BEGIN_SRC bash
nixos-generate-config --dir <<host directory>> --no-filesystems
#+END_SRC
8. Install nixos!
#+BEGIN_SRC bash
sudo nixos-install --impure --root /mnt --flake '.#vultr-test'
#+END_SRC
9. Set up the user
You'll set the root password during the installation. You can then reboot and use the installed OS. First thing you'll have to do is log in as root and set the password for your user:
#+BEGIN_SRC bash
passwd marc
#+END_SRC
* Rebuilding
#+BEGIN_SRC bash
sudo nixos-rebuild switch --impure --flake '.#reykjavik'
#+END_SRC
* Modules
** Desktop environment
*** Themeing
* NixOS
** [[file:docs/install.org][Installing]]
** Rebuilding
#+BEGIN_SRC bash
sudo nixos-rebuild switch --impure --flake '.#reykjavik'
#+END_SRC
** Modules
*** Desktop environment
**** Themeing
We use [[https://github.com/Misterio77/nix-colors][nix-colors]] to (try to) keep a consistent theme across all applications. This uses [[https://github.com/chriskempson/base16][base-16 themes]] (here is a [[https://github.com/chriskempson/base16/blob/main/styling.md][styiling guide]] for it).
* Samfelag Mesh
** [[file:docs/hosts.org][Hosts]]
** [[file:docs/consul.org][Consul]]

View File

@@ -0,0 +1,41 @@
{
"datacenter": "samfelag",
"data_dir": "/opt/consul",
"tls": {
"defaults": {
"verify_incoming": false,
"verify_outgoing": true,
"ca_file": "/etc/consul.d/certs/consul-agent-ca.pem"
},
"internal_rpc": {
"verify_server_hostname": true
}
},
"auto_encrypt": {
"tls": true
},
"bind_addr": "{{ GetInterfaceIP \"tailscale0\" }}",
"advertise_addr": "{{ GetInterfaceIP \"tailscale0\" }}",
"client_addr": "0.0.0.0",
"retry_join": ["100.80.195.56", "100.107.148.47"],
"ports": {
"grpc_tls": 8502
},
"acl": {
"enabled": true,
"default_policy": "allow",
"enable_token_persistence": true
},
"connect": {
"enabled": true
},
"performance": {
"raft_multiplier": 1
}
}

View File

@@ -1,9 +1,5 @@
;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-
;; Place your private configuration here! Remember, you do not need to run 'doom
;; sync' after modifying this file!
;; Some functionality uses this to identify you, e.g. GPG configuration, email
;; clients, file templates and snippets.
(setq user-full-name "Marc Sastre Rienitz"
@@ -74,6 +70,7 @@
(use-package parinfer
:defer t)
;; -----------------------------------------------------------------------------
;; LSP
;; -----------------------------------------------------------------------------
@@ -86,6 +83,7 @@
(lsp-mode . lsp-enable-which-key-integration))
:commands (lsp lsp-deferred))
;; -----------------------------------------------------------------------------
;; Python
;; -----------------------------------------------------------------------------
@@ -116,42 +114,17 @@
;; -----------------------------------------------------------------------------
;; Org
;; -----------------------------------------------------------------------------
(setq org-directory "~/org")
(setq org-agenda-files (directory-files-recursively "~/org/agenda" "\\.org$"))
(setq org-directory "~/org/")
; (use-package org-roam
; :ensure t
; :init
; (setq org-roam-v2-ack t)
; :custom
; (org-roam-directory "~/org-roam")
; (org-roam-capture-templates
; '(("d" "default" plain "%?"
; :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
; :unnarrowed t)
; ("m" "màquina" plain (file "~/org-roam/templates/maquina.org")
; :target (file "%<%Y%m%d%H%M%S>-${slug}.org")
; :unnarrowed t)
; ("s" "software" plain (file "~/org-roam/templates/software.org")
; :target (file "%<%Y%m%d%H%M%S>-${slug}.org")
; :unnarrowed t)))
; :config
; (org-roam-setup))
;
; (use-package! websocket
; :after org-roam)
;
; (use-package! org-roam-ui
; :after org-roam ;; or :after org
; ;; normally we'd recommend hooking orui after org-roam, but since org-roam does not have
; ;; a hookable mode anymore, you're advised to pick something yourself
; ;; if you don't care about startup time, use
; ;; :hook (after-init . org-roam-ui-mode)
; :config
; (setq org-roam-ui-sync-theme t
; org-roam-ui-follow t
; org-roam-ui-update-on-save t
; org-roam-ui-open-on-start nil))
;; -----------------------------------------------------------------------------
;; Agenix
;; -----------------------------------------------------------------------------
(load! "modules/agenix.el")
(setq agenix-age-program "age")
(setq agenix-agenix-program "agenix")
;; -----------------------------------------------------------------------------
;; Appearance - Prettify
@@ -159,8 +132,8 @@
(load! "modules/prettify-utils.el")
(pretty-hook python-mode
;; ("def" "󰊕")
;; ("class" "𝙘")
("def" " 󰊕 ")
("class" "𝙘")
("None" "")
("lambda" "λ")
("not in" "")

View File

@@ -0,0 +1,231 @@
;;; agenix.el --- Decrypt and encrypt agenix secrets -*- lexical-binding: t -*-
;; Copyright (C) 2022-2023 Tomasz Maciosowski (t4ccer)
;; Author: Tomasz Maciosowski <t4ccer@gmail.com>
;; Maintainer: Tomasz Maciosowski <t4ccer@gmail.com>
;; Package-Requires: ((emacs "27.1"))
;; URL: https://github.com/t4ccer/agenix.el
;; Version: 1.0
;;
;; Modified version by Marc Sastre that allows subdirectories in the secrets folder.
;; This file is NOT part of GNU Emacs.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Fully transparent editing of agenix secrets. Open a file, edit it, save it and it will be
;; encrypted automatically.
;;; Code:
(defcustom agenix-age-program "age"
"The age program."
:group 'agenix
:type 'string)
(defcustom agenix-key-files '("~/.ssh/id_ed25519" "~/.ssh/id_rsa")
"List of age key files."
:group 'agenix
:type '(repeat string))
(defcustom agenix-pre-mode-hook nil
"Hook to run before entering `agenix-mode'.
Can be used to set up age binary path."
:group 'agenix
:type 'hook)
(defvar-local agenix--encrypted-fp nil)
(defvar-local agenix--keys nil)
(defvar-local agenix--undo-list nil)
(defvar-local agenix--point nil)
(define-derived-mode agenix-mode text-mode "agenix"
"Major mode for agenix files.
Don't use directly, use `agenix-mode-if-with-secrets-nix' to ensure that
secrets.nix exists."
(read-only-mode 1)
(run-hooks 'agenix-pre-mode-hook)
(agenix-decrypt-buffer)
(goto-char (point-min))
(setq buffer-undo-list nil)
(setq require-final-newline nil)
(setq buffer-auto-save-file-name nil)
(setq write-contents-functions '(agenix-save-decrypted))
;; Reverting loads encrypted file back to the buffer, so we need to decrypt it
(add-hook 'after-revert-hook
(lambda () (when (eq major-mode 'agenix-mode) (agenix-decrypt-buffer)))))
(defun agenix--file-search-upward (directory file)
"Search DIRECTORY for FILE and return its full path if found, or NIL if not.
If FILE is not found in DIRECTORY, the parent of DIRECTORY will be searched."
(let ((parent-dir (file-truename (concat (file-name-directory directory) "../")))
(current-path (if (not (string= (substring directory (- (length directory) 1)) "/"))
(concat directory "/" file)
(concat directory file))))
(if (file-exists-p current-path)
current-path
(when (and (not (string= (file-truename directory) parent-dir))
(< (length parent-dir) (length (file-truename directory))))
(agenix--file-search-upward parent-dir file)))))
(defun agenix--secrets-nix-path ()
"Search for secrets.nix file in the current directory or any parent directory.
Return it if found"
(agenix--file-search-upward "./" "secrets.nix"))
(defun agenix--relative-buffer-path ()
"Return the filename of the current buffer relative to the secrets.nix path."
(file-relative-name
(buffer-file-name)
(file-name-directory (agenix--secrets-nix-path))))
(defun agenix--buffer-string* (buffer)
"Like `buffer-string' but read from BUFFER parameter."
(with-current-buffer buffer
(buffer-substring-no-properties (point-min) (point-max))))
(defun agenix--with-temp-buffer (func)
"Like `with-temp-buffer' but doesn't actually switch the buffer.
FUNC takes a temporary buffer that will be disposed after the call."
(let* ((age-buf (generate-new-buffer "*age-buf*"))
(res (funcall func age-buf)))
(kill-buffer age-buf)
res))
(defun agenix--process-exit-code-and-output (program &rest args)
"Run PROGRAM with ARGS and return the exit code and output in a list."
(agenix--with-temp-buffer
(lambda (buf) (list (apply #'call-process program nil buf nil args)
(agenix--buffer-string* buf)))))
;;;###autoload
(defun agenix-decrypt-buffer (&optional encrypted-buffer)
"Decrypt ENCRYPTED-BUFFER in place.
If ENCRYPTED-BUFFER is unset or nil, decrypt the current buffer."
(interactive
(when current-prefix-arg
(list (read-buffer "Encrypted buffer: " (current-buffer) t))))
(with-current-buffer (or encrypted-buffer (current-buffer))
(let* ((nix-res (apply #'agenix--process-exit-code-and-output "nix-instantiate"
(list "--strict" "--json" "--eval" "--expr"
(format
"(import %s).\"%s\".publicKeys"
(agenix--secrets-nix-path)
(agenix--relative-buffer-path)))))
(nix-exit-code (car nix-res))
(nix-output (car (cdr nix-res))))
(if (/= nix-exit-code 0)
(warn "Nix evaluation error.
Probably file %s is not declared as a secret in 'secrets.nix' file.
Error: %s" (buffer-file-name) nix-output)
(let* ((keys (json-parse-string nix-output :array-type 'list))
(age-flags (list "--decrypt")))
;; Add all user's keys to the age command
(dolist (key-path agenix-key-files)
(when (file-exists-p (expand-file-name key-path))
(setq age-flags
(nconc age-flags (list "--identity" (expand-file-name key-path))))))
;; Add file-path to decrypt to the age command
(setq age-flags (nconc age-flags (list (buffer-file-name))))
(setq agenix--encrypted-fp (buffer-file-name))
(setq agenix--keys keys)
;; Check if file already exists
(if (not (file-exists-p (buffer-file-name)))
(progn
(message "Not decrypting. File %s does not exist and will be created when you \
will save this buffer." (buffer-file-name))
(read-only-mode -1))
(let*
((age-res
(apply #'agenix--process-exit-code-and-output agenix-age-program age-flags))
(age-exit-code (car age-res))
(age-output (car (cdr age-res))))
(if (= 0 age-exit-code)
(progn
;; Replace buffer with decrypted content
(read-only-mode -1)
(erase-buffer)
(insert age-output)
;; Mark buffer as not modified
(set-buffer-modified-p nil)
(setq buffer-undo-list agenix--undo-list))
(error age-output))))
(when agenix--point
(goto-char agenix--point)))))))
;;;###autoload
(defun agenix-save-decrypted (&optional unencrypted-buffer)
"Encrypt UNENCRYPTED-BUFFER back to the original .age file.
If UNENCRYPTED-BUFFER is unset or nil, use the current buffer."
(interactive
(when current-prefix-arg
(list (read-buffer "Unencrypted buffer: " (current-buffer) t))))
(with-current-buffer (or unencrypted-buffer (current-buffer))
(let* ((age-flags (list "--encrypt")))
(progn
(dolist (k agenix--keys)
(setq age-flags (nconc age-flags (list "--recipient" k))))
(setq age-flags (nconc age-flags (list "-o" agenix--encrypted-fp)))
(let* ((decrypted-text (buffer-string))
(age-res
(agenix--with-temp-buffer
(lambda (buf)
(list
(apply #'call-process-region
decrypted-text nil
agenix-age-program
nil
buf
t
age-flags)
(agenix--buffer-string* buf))))))
(when (/= 0 (car age-res))
(error (car (cdr age-res))))
(setq agenix--point (point))
(setq agenix--undo-list buffer-undo-list)
(revert-buffer :ignore-auto :noconfirm :preserve-modes)
(set-buffer-modified-p nil)
t)))))
;;;###autoload
(defun agenix-mode-if-with-secrets-nix ()
"Enable `agenix-mode' if the current buffer is in a directory with secrets.nix."
(interactive)
(when (agenix--secrets-nix-path)
(agenix-mode)))
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.age\\'" . agenix-mode-if-with-secrets-nix))
(provide 'agenix)
;;; agenix.el ends here

View File

@@ -73,3 +73,10 @@
(package! doom-nano-modeline
:recipe (:host github
:repo "ronisbr/doom-nano-modeline"))
;; Agenix
;; (package! agenix
;; :recipe (:host github
;; :repo "t4ccer/agenix.el"
;; :branch "main"
;; :files ("*.el")))

68
docs/consul.org Normal file
View File

@@ -0,0 +1,68 @@
#+title: Consul
* ACLs
** Policies
*** Node Policy
Policy for agent tokens
#+begin_src hcl
agent_prefix "" {
policy = "write"
}
node_prefix "" {
policy = "write"
}
service_prefix "" {
policy = "read"
}
session_prefix "" {
policy = "read"
}
#+end_src
*** Nomad client
Policy for nomad clients (to be added in the consul.token field in the nomad config)
#+begin_src hcl
agent_prefix "" {
policy = "read"
}
node_prefix "" {
policy = "read"
}
service_prefix "" {
policy = "write"
}
#+end_src
*** Nomad server
Policy for nomad servers (to be added in the consul.token field in the nomad config)
#+begin_src hcl
agent_prefix "" {
policy = "read"
}
node_prefix "" {
policy = "read"
}
service_prefix "" {
policy = "write"
}
acl = "write"
#+end_src
** Node Agent Token
Create a token at http://hvannadal:8500/ui/samfelag/acls/tokens with the node policy.
Create the consul config file and encrypt it via agenix:
#+begin_src bash
agenix -e consul.d/agent-token-<host>.json.age
#+end_src
JSON config:
#+begin_src json
{
"acl": {
"tokens": {
"default": "<AGENT_TOKEN>",
"agent": "<AGENT_TOKEN>"
}
}
}
#+end_src

39
docs/hosts.org Normal file
View File

@@ -0,0 +1,39 @@
#+title: Hosts
* [[file:../hosts/reykjavik/README.org][Reykjavik]]
* [[file:../hosts/kopavogur/README.org][Kopavogur]]
* <<new_host>> Setting up a new host
** Generate a host ssh key pair
Generate the key pair (we'll use the name `id_<host>`)
#+BEGIN_SRC bash
ssh-keygen -f id_<host>
#+END_SRC
Encrypt the private key if you want to put it in the repo:
#+begin_src bash
gpg -r marc@sastre.cat -e id_<host>
#+end_src
You can decrypt it later with:
#+begin_src bash
gpg -d id_<host>.gpg > id_<host>
#+end_src
** Add the public key to secrets.nix
In the [[file:../secrets/secrets.nix][agenix secrets file]] add the public key, and give access to the necessary secrets.
Remember to rekey the secrets afterwards:
#+begin_src bash
agenix --rekey
#+end_src
** SSH public key authentication
Setting up authentication from localhost (client) to remotehost (server). On localhost run:
#+BEGIN_SRC bash
ssh-keygen -f ~/.ssh/remotehost
ssh-copy-id -i ~/.ssh/remotehost remotehost-or-ip
#+END_SRC
We may want to edit the ssh config file to use this ssh key when connection to remotehost:
#+BEGIN_SRC
Host remotehost
# HostName 192.168.1.105
# Port 22
# User user
IdentitiesOnly yes
IdentityFile ~/.ssh/remotehost
#+END_SRC

114
docs/install.org Normal file
View File

@@ -0,0 +1,114 @@
#+title: Installing
* Set up
** If new host, follow [[new_host][Setting up a new host]]
** Open a nix-shell with dependencies
#+BEGIN_SRC bash
nix shell nixpkgs#git
#+END_SRC
** Obtain the flake
+ Via git clone
#+BEGIN_SRC bash
git clone https://git.samfelag.xyz/marc/samfelag.git
#+END_SRC
+ Via scp (in this case, from local to remote)
#+BEGIN_SRC bash
scp samfelag marc@remotehost:samfelag
#+END_SRC
** Copy the host ssh key
Obtain the host ssh *private* key. You can decrypt it using gpg:
#+begin_src bash
gpg -d secrets/ssh-keys/id_<host>.gpg > /etc/ssh/id_<host>
#+end_src
Copy the ssh keys to `/etc/ssh`
* Partition the disk
We'll partition the disk in the follwing way:
+ 512MB at the beginning for the boot partition
+ 8GB at the end for swap
+ The rest (at the middle) for the filesystem (/)
** Locate the disk
#+BEGIN_SRC bash
lsblk
#+END_SRC
** UEFI Boot
1. Create a GPT partition table
#+BEGIN_SRC bash
sudo parted /dev/nvme0n1 -- mklabel gpt
#+END_SRC
2. Create the root partition
#+BEGIN_SRC bash
sudo parted /dev/nvme0n1 -- mkpart primary 512MB -8GB
#+END_SRC
3. Create the swap partition
#+BEGIN_SRC bash
sudo parted /dev/nvme0n1 -- mkpart primary linux-swap -8GB 100%
#+END_SRC
4. Create the boot partition
#+BEGIN_SRC bash
sudo parted /dev/nvme0n1 -- mkpart ESP fat32 1MB 512MB
sudo parted /dev/nvme0n1 -- set 3 esp on
#+END_SRC
** MBR boot
1. Create a MBR partition table
#+BEGIN_SRC bash
sudo parted /dev/vda -- mklabel msdos
#+END_SRC
2. Create the root partition
#+BEGIN_SRC bash
sudo parted /dev/vda -- mkpart primary 1MiB -8GiB
#+END_SRC
3. Create the swap partition
#+BEGIN_SRC bash
sudo parted /dev/vda -- mkpart primary linux-swap -8GiB 100%
#+END_SRC
4. Create the boot partition
#+BEGIN_SRC bash
sudo parted /dev/vda -- mkpart ESP fat32 1MB 512MB
sudo parted /dev/vda -- set 3 esp on
#+END_SRC
* Format the partitions
1. Root partition
#+BEGIN_SRC bash
sudo mkfs.ext4 -L nixos /dev/nvme0n1p1
#+END_SRC
2. Swap partition
#+BEGIN_SRC bash
sudo mkswap -L swap /dev/nvme0n1p2
#+END_SRC
3. Boot partition (if UEFI boot)
#+BEGIN_SRC bash
sudo mkfs.fat -F 32 -n BOOT /dev/nvme0n1p3
#+END_SRC
* Mount the filesystems
1. Root partition
#+BEGIN_SRC bash
sudo mount /dev/disk/by-label/nixos /mnt
#+END_SRC
2. Boot partition (if UEFI boot)
#+BEGIN_SRC bash
sudo mkdir -p /mnt/boot
sudo mount /dev/disk/by-label/BOOT /mnt/boot
#+END_SRC
3. Swap partition (if needed)
#+BEGIN_SRC bash
sudo swapon /dev/disk/by-label/swap
#+END_SRC
* Create the host nix configuration
If the host is not present under system/hosts, create a new folder for the host.
Check [[Setting up a new host]] for further documentation.
Generate the hardware configuration file, you can use nixos-generate-config as a base:
#+BEGIN_SRC bash
nixos-generate-config --dir <<host directory>> --no-filesystems
#+END_SRC
* Install nixos!
#+BEGIN_SRC bash
sudo nixos-install --impure --root /mnt --flake '.#reykjavik'
#+END_SRC
* Copy the ssh deploy key (again)
#+begin_src bash
cp /etc/ssh/samfelag_agenix* /mnt/etc/ssh
#+end_src
* Set up the user
You'll set the root password during the installation. You can then reboot and use the installed OS. First thing you'll have to do is log in as root and set the password for your user:
#+BEGIN_SRC bash
passwd marc
#+END_SRC

61
flake.lock generated
View File

@@ -1,5 +1,28 @@
{
"nodes": {
"agenix": {
"inputs": {
"darwin": [],
"home-manager": "home-manager",
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
},
"locked": {
"lastModified": 1703433843,
"narHash": "sha256-nmtA4KqFboWxxoOAA6Y1okHbZh+HsXaMPFkYHsoDRDw=",
"owner": "ryantm",
"repo": "agenix",
"rev": "417caa847f9383e111d1397039c9d4337d024bf0",
"type": "github"
},
"original": {
"owner": "ryantm",
"repo": "agenix",
"type": "github"
}
},
"base16-schemes": {
"flake": false,
"locked": {
@@ -50,27 +73,28 @@
"type": "github"
}
},
"grub2-themes": {
"home-manager": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1668213765,
"narHash": "sha256-mTx1jAy6AOY4moWRGvCHYnUNX4qBL/ba47ZcIkhczJM=",
"owner": "vinceliuice",
"repo": "grub2-themes",
"rev": "c106dfb9b5b18ad092ff0f952f2b734933e8283e",
"lastModified": 1703113217,
"narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1",
"type": "github"
},
"original": {
"owner": "vinceliuice",
"repo": "grub2-themes",
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"home-manager": {
"home-manager_2": {
"inputs": {
"nixpkgs": [
"nixpkgs"
@@ -172,13 +196,28 @@
},
"root": {
"inputs": {
"agenix": "agenix",
"emacs-overlay": "emacs-overlay",
"grub2-themes": "grub2-themes",
"home-manager": "home-manager",
"home-manager": "home-manager_2",
"nix-colors": "nix-colors",
"nixpkgs": "nixpkgs_2",
"nur": "nur"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",

View File

@@ -6,10 +6,16 @@
# - Nixpkgs ----------------------------------
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
# - Home-Manager -----------------------------
# - Home Manager -----------------------------
home-manager.url = "github:nix-community/home-manager/release-23.11";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
# - Agenix -----------------------------------
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixpkgs";
# optionally choose not to download darwin deps (saves some resources on Linux)
agenix.inputs.darwin.follows = "";
# - NUR --------------------------------------
nur.url = "github:nix-community/NUR";
@@ -17,11 +23,7 @@
emacs-overlay.url = "github:nix-community/emacs-overlay";
# - Themeing ---------------------------------
grub2-themes.url = "github:vinceliuice/grub2-themes";
grub2-themes.inputs.nixpkgs.follows = "nixpkgs";
nix-colors.url = "github:misterio77/nix-colors";
};
outputs = inputs @ { self, nixpkgs, home-manager, ... }:
@@ -48,7 +50,14 @@
[
inputs.home-manager.nixosModules.home-manager
inputs.nix-colors.homeManagerModule
inputs.grub2-themes.nixosModule
# Agenix
inputs.agenix.nixosModules.default
{
environment.systemPackages = [
inputs.agenix.packages.${system}.default
pkgs.age
];
}
]
# All my personal modules
++ (lib.my.mapModulesRec' (toString ./modules) import);

View File

@@ -39,6 +39,10 @@ in
kind = "dark";
};
age.identityPaths = [
"/home/marc/.ssh/id_ed25519"
];
# - Modules ------------------------------------
samfelag.modules = {
@@ -57,6 +61,12 @@ in
system.pass.enable = true;
system.sshfs.enable = true;
# - Server ----------------------------------
server.consul = {
enable = true;
agent-token = config.age.secrets."consul.d/agent-token-reykjavik.json".path;
};
# - Desktop ----------------------------------
desktop = {
inherit wallpaper;

26
modules/secrets.nix Normal file
View File

@@ -0,0 +1,26 @@
{ config, pkgs, lib, ... }:
{
config = {
age.secrets = {
# Consul -------------------------------
"consul.d/gossip.json" = {
file = ../secrets/consul.d/gossip.json.age;
owner = "consul";
group = "consul";
mode = "644";
};
"consul.d/consul-agent-ca.pem" = {
file = ../secrets/consul.d/consul-agent-ca.pem.age;
owner = "consul";
group = "consul";
mode = "644";
};
"consul.d/agent-token-reykjavik.json" = {
file = ../secrets/consul.d/agent-token-reykjavik.json.age;
owner = "consul";
group = "consul";
mode = "644";
};
};
};
}

47
modules/server/consul.nix Normal file
View File

@@ -0,0 +1,47 @@
{ config, lib, pkgs, self, ... }:
let
cfg = config.samfelag.modules.server.consul;
in
{
options.samfelag.modules.server.consul = {
enable = lib.mkEnableOption "consul";
agent-token = lib.mkOption {
type = lib.types.str;
description = "Agent token config file (should be secret)";
};
};
config = lib.mkIf cfg.enable {
services.consul = {
enable = true;
webUi = true;
};
environment.etc = {
agent-ca = {
# Consul agent CA
target = "consul.d/certs/consul-agent-ca.pem";
source = config.age.secrets."consul.d/consul-agent-ca.pem".path;
};
gossip = {
# Gossip encryption key
target = "consul.d/gossip.json";
source = config.age.secrets."consul.d/gossip.json".path;
};
client = {
# Client config
target = "consul.d/client.json";
source = ../../config/consul.d/client.json;
};
agent-token = {
# Agent token
target = "consul.d/agent-token.json";
source = cfg.agent-token;
};
};
# networking.firewall.allowedTCPPorts = [ 22 ];
};
}

View File

@@ -0,0 +1,5 @@
age-encryption.org/v1
-> ssh-ed25519 GWuf0Q WZXSz/V10nOYp7jSK2WapD0IIoV5odZnAQX4bfVG6Hk
K6ESj+ABGvRh6U6/e0NT/5rObkGfRBAQU8ujOEemM3g
--- PHbxtNcEtz+cVZPIbYdu3jjsoVBf2fbFIqB0gSZ2DDk
“á}i4ìßùÅjR¨µÕÿH_y=2'TœJ~Ø1zL0  ñš‰(N

Binary file not shown.

View File

@@ -0,0 +1,5 @@
age-encryption.org/v1
-> ssh-ed25519 GWuf0Q PZ9afqz3THF8vuV1bBzKU2QQ5j0cA7TriznFu1/eF1Q
sk8JAVRjCyhjjkebWtqJaxoacxiYSdir7w9Ep9ch0/4
--- lBViOk0i5qkicV2kqyGSI/fiEjtyrGqKAoUIzz3V9lQ
Ã8"ŸVô

11
secrets/secrets.nix Normal file
View File

@@ -0,0 +1,11 @@
let
id-reykjavik = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFwwpKfxNmUyBoPZqz1jYc6arCdHPvJrEsBN49m/P3By";
id-hvannadal = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICy1ocZywBvFHpIj+FvaC7QspRWuLXjy6fwakq9t+0Ev";
in
{
# -- Consul -------------------------------
"consul.d/gossip.json.age".publicKeys = [id-reykjavik];
"consul.d/consul-agent-ca.pem.age".publicKeys = [id-reykjavik];
# Agent tokens
"consul.d/agent-token-reykjavik.json.age".publicKeys = [id-reykjavik];
}

Binary file not shown.

View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICy1ocZywBvFHpIj+FvaC7QspRWuLXjy6fwakq9t+0Ev marc@reykjavik

Binary file not shown.

View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFwwpKfxNmUyBoPZqz1jYc6arCdHPvJrEsBN49m/P3By marc@sastre.cat