Configure host to use SSH certs on the host and client side.

This commit is contained in:
DS 2025-03-31 21:30:46 -07:00
parent a872e6f395
commit 55eb37bb47
10 changed files with 129 additions and 3 deletions

View file

@ -38,6 +38,41 @@ There's already a `.vscode` directory which should direct VSCode to enable the D
# Infrastructure
## Setting up SSH access
You'll need to trust the SSH certificate authority that generates SSH keys for Epesooj's hosts.
The CA's public key is in `./host_config/ssh_certs/host_ca.pub`.
This is the template for the SSH `known_hosts` entry:
```
@cert-authority <dns name or ip address> <CONTENTS OF host_ca.pub>
```
For example:
```
@cert-authority code.akols.com ssh-ed25519 AAAA...
```
## Signing a user's public SSH key to give them host access
Run `just sign_user_key <username> <user_pub_key_path>`.
This will by default give them `root` access.
Check the definition of this `just` command to see how to give them access to different user(s).
Once this is done, give them the signed public key (it'll be a file in the same directory as `<user_pub_key_path>` with the `-cert.pub` suffix) and tell them to add the `CertificateFile` option to their SSH config to make sure it'll also present the signed public key.
For example:
```
Host epesooj
User root
HostName code.akols.com
IdentityFile ~/.ssh/epesooj_personal.pub
CertificateFile ~/.ssh/epesooj_personal-cert.pub
IdentitiesOnly yes
```
## Nixifying a new host
If you have a bunch of SSH keys in your SSH agent and get errors when trying to SSH into a fresh host, you may need to temporarily add the following config to your SSH config (obviously change the details for your case).
@ -50,7 +85,15 @@ Host 188.245.194.78
IdentitiesOnly yes
```
Once you can SSH into the host normally, run `just nixify_host <hostname> "code" "<dns name>,<ip address>"`.
For example: `just nixify_host epesooj-code-0001 code "code.akols.com,188.245.194.78"`.
This command requires you to have the key for the Epesooj Host SSH certificate authority.
If you don't have it, contact someone who does.
## Deploying the webring
You should have a `.env` file with the id and deploy key for each script in the webring, as well as a key to deploy the index page to bunny.
When you have this, run `deno task deploy`.
You'll need the API keys required to deploy these.
If you don't have them, contact someone who does.

View file

@ -21,7 +21,7 @@
systems = [ "x86_64-linux" ];
imports = [
./code_server.nix
./host_config
];
flake =

47
host_config/bootstrap_host.sh Executable file
View file

@ -0,0 +1,47 @@
#!/usr/bin/env bash
set -euxo pipefail
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
host_ca_key="${SCRIPT_DIR}/ssh_certs/host_ca"
user_ca_pub="${SCRIPT_DIR}/ssh_certs/user_ca.pub"
if [ ! -f "${host_ca_key}" ]
then
echo "Host CA key not found."
exit 1
fi
if [ ! -f "${user_ca_pub}" ]
then
echo "Public User CA key not found."
exit 1
fi
temp=$(mktemp -d)
cleanup() {
rm -rf "${temp}"
}
# trap cleanup EXIT
host_type=$1
hostname=$2
extra_names=${3:-}
principal_names="${hostname}"
if [ ! -z "${extra_names}" ]
then
principal_names="${principal_names},${extra_names}"
fi
install -d -m755 "${temp}/persisted/etc/ssh"
ssh-keygen -t ed25519 -f "${temp}/persisted/etc/ssh/ssh_host_ed25519_key" -C '' -N ''
ssh-keygen -s ${host_ca_key} -I ${hostname} -h -n "${principal_names}" -V +52w "${temp}/persisted/etc/ssh/ssh_host_ed25519_key.pub"
cp "${user_ca_pub}" "${temp}/persisted/etc/ssh/user_cas.pub"
echo "${temp}"
#nix run github:nix-community/nixos-anywhere -- --extra-files "${temp}" --flake .#${host_type} --target-host root@${hostname}

View file

@ -96,6 +96,10 @@
settings = {
PasswordAuthentication = false;
};
extraConfig = ''
HostCertificate /persisted/etc/ssh/ssh_host_ed25519_key-cert.pub
TrustedUserCAKeys /persisted/etc/ssh/user_cas.pub
'';
};
users.users.root = {

25
host_config/sign_user_pub.sh Executable file
View file

@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -euxo pipefail
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
user_ca_key="${SCRIPT_DIR}/ssh_certs/user_ca"
if [ ! -f "${user_ca_key}" ]
then
echo "User CA key not found."
exit 1
fi
username=$1
principals=$2
user_pub=$3
if [ ! -f "${user_pub}" ]
then
echo "User public key not found."
exit 1
fi
ssh-keygen -s "${user_ca_key}" -I "${username}" -n "${principals}" -V +52w "${user_pub}"
echo "Done!"

2
host_config/ssh_certs/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
host_ca
user_ca

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJygYxMUdGgApUE3KirRQVgG2X5zWurIBPbwEc10FxDi epesooj host ca

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINdiqYdA3pm9yKgR5hFlL7ZeSV3xeKH9HwyNwaxY6yZZ epesooj user ca

View file

@ -4,5 +4,8 @@ default:
build_nixos_config host_type="code":
nix build .#nixosConfigurations.{{host_type}}.config.system.build.toplevel
nixify_host hostname host_type="code":
nix run github:nix-community/nixos-anywhere -- --flake .#{{host_type}} --target-host root@{{hostname}}
nixify_host hostname host_type="code" extra_names="":
./host_config/bootstrap_host.sh {{host_type}} {{hostname}} {{extra_names}}
sign_user_key username user_pub_key principals="root":
./host_config/sign_user_pub.sh {{username}} {{principals}} {{user_pub_key}}