feat: offline NixOS LiveCD image
Includes inspiration from https://github.com/dhess/nixos-yubikeypull/342/head
parent
5eeae2be7e
commit
fcc77d4159
170
README.md
170
README.md
|
@ -268,24 +268,83 @@ $ sudo yum install -y gnupg2 pinentry-curses pcsc-lite pcsc-lite-libs gnupg2-smi
|
|||
|
||||
## NixOS
|
||||
|
||||
Generate a NixOS LiveCD image with the given config:
|
||||
Generate an air-gapped NixOS LiveCD image with the given config:
|
||||
|
||||
```nix
|
||||
# yubikey-installer.nix
|
||||
{ nixpkgs ? <nixpkgs>, system ? "x86_64-linux" } :
|
||||
|
||||
let
|
||||
config = { pkgs, ... }:
|
||||
with pkgs; {
|
||||
imports = [ <nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-plasma5.nix> ];
|
||||
configuration = { config, lib, pkgs, ... }:
|
||||
with pkgs;
|
||||
let
|
||||
src = fetchGit "https://github.com/drduh/YubiKey-Guide";
|
||||
|
||||
guide = "${src}/README.md";
|
||||
|
||||
contrib = "${src}/contrib";
|
||||
|
||||
drduhConfig = fetchGit "https://github.com/drduh/config";
|
||||
|
||||
gpg-conf = "${drduhConfig}/gpg.conf";
|
||||
|
||||
xserverCfg = config.services.xserver;
|
||||
|
||||
pinentryFlavour = if xserverCfg.desktopManager.lxqt.enable || xserverCfg.desktopManager.plasma5.enable then
|
||||
"qt"
|
||||
else if xserverCfg.desktopManager.xfce.enable then
|
||||
"gtk2"
|
||||
else if xserverCfg.enable || config.programs.sway.enable then
|
||||
"gnome3"
|
||||
else
|
||||
"curses";
|
||||
|
||||
# Instead of hard-coding the pinentry program, chose the appropriate one
|
||||
# based on the environment of the image the user has chosen to build.
|
||||
gpg-agent-conf = runCommand "gpg-agent.conf" {} ''
|
||||
sed '/pinentry-program/d' ${drduhConfig}/gpg-agent.conf > $out
|
||||
echo "pinentry-program ${pinentry.${pinentryFlavour}}/bin/pinentry" >> $out
|
||||
'';
|
||||
|
||||
view-yubikey-guide = writeShellScriptBin "view-yubikey-guide" ''
|
||||
viewer="$(type -P xdg-open || true)"
|
||||
if [ -z "$viewer" ]; then
|
||||
viewer="${glow}/bin/glow -p"
|
||||
fi
|
||||
exec $viewer "${guide}"
|
||||
'';
|
||||
|
||||
shortcut = makeDesktopItem {
|
||||
name = "yubikey-guide";
|
||||
icon = "${yubikey-manager-qt}/share/ykman-gui/icons/ykman.png";
|
||||
desktopName = "drduh's YubiKey Guide";
|
||||
genericName = "Guide to using YubiKey for GPG and SSH";
|
||||
comment = "Open the guide in a reader program";
|
||||
categories = [ "Documentation" ];
|
||||
exec = "${view-yubikey-guide}/bin/view-yubikey-guide";
|
||||
};
|
||||
|
||||
yubikey-guide = symlinkJoin {
|
||||
name = "yubikey-guide";
|
||||
paths = [ view-yubikey-guide shortcut ];
|
||||
};
|
||||
|
||||
in {
|
||||
nixpkgs.config = { allowBroken = true; };
|
||||
|
||||
isoImage.isoBaseName = lib.mkForce "nixos-yubikey";
|
||||
# Uncomment this to disable compression and speed up image creation time
|
||||
#isoImage.squashfsCompression = "gzip -Xcompression-level 1";
|
||||
|
||||
boot.kernelPackages = linuxPackages_latest;
|
||||
# Always copytoram so that, if the image is booted from, e.g., a
|
||||
# USB stick, nothing is mistakenly written to persistent storage.
|
||||
boot.kernelParams = [ "copytoram" ];
|
||||
# Secure defaults
|
||||
boot.cleanTmpDir = true;
|
||||
boot.kernel.sysctl = { "kernel.unprivileged_bpf_disabled" = 1; };
|
||||
|
||||
services.pcscd.enable = true;
|
||||
services.udev.packages = [ yubikey-personalization ];
|
||||
|
||||
environment.systemPackages = [ gnupg pinentry-curses pinentry-qt paperkey wget ];
|
||||
|
||||
programs = {
|
||||
ssh.startAgent = false;
|
||||
gnupg.agent = {
|
||||
|
@ -293,28 +352,108 @@ let
|
|||
enableSSHSupport = true;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
# Tools for backing up keys
|
||||
paperkey
|
||||
pgpdump
|
||||
parted
|
||||
cryptsetup
|
||||
|
||||
# Yubico's official tools
|
||||
yubikey-manager
|
||||
yubikey-manager-qt
|
||||
yubikey-personalization
|
||||
yubikey-personalization-gui
|
||||
yubico-piv-tool
|
||||
yubioath-desktop
|
||||
|
||||
# Testing
|
||||
ent
|
||||
(haskell.lib.justStaticExecutables haskellPackages.hopenpgp-tools)
|
||||
|
||||
# Password generation tools
|
||||
diceware
|
||||
pwgen
|
||||
|
||||
# Miscellaneous tools that might be useful beyond the scope of the guide
|
||||
cfssl
|
||||
pcsctools
|
||||
|
||||
# This guide itself (run `view-yubikey-guide` on the terminal to open it
|
||||
# in a non-graphical environment).
|
||||
yubikey-guide
|
||||
];
|
||||
|
||||
# Disable networking so the system is air-gapped
|
||||
# Comment all of these lines out if you'll need internet access
|
||||
boot.initrd.network.enable = false;
|
||||
networking.dhcpcd.enable = false;
|
||||
networking.dhcpcd.allowInterfaces = [];
|
||||
networking.interfaces = {};
|
||||
networking.firewall.enable = true;
|
||||
networking.useDHCP = false;
|
||||
networking.useNetworkd = false;
|
||||
networking.wireless.enable = false;
|
||||
networking.networkmanager.enable = lib.mkForce false;
|
||||
|
||||
# Unset history so it's never stored
|
||||
# Set GNUPGHOME to an ephemeral location and configure GPG with the
|
||||
# guide's recommended settings.
|
||||
environment.interactiveShellInit = ''
|
||||
unset HISTFILE
|
||||
export GNUPGHOME="/run/user/$(id -u)/gnupg"
|
||||
if [ ! -d "$GNUPGHOME" ]; then
|
||||
echo "Creating \$GNUPGHOME…"
|
||||
install --verbose -m=0700 --directory="$GNUPGHOME"
|
||||
fi
|
||||
[ ! -f "$GNUPGHOME/gpg.conf" ] && cp --verbose ${gpg-conf} "$GNUPGHOME/gpg.conf"
|
||||
[ ! -f "$GNUPGHOME/gpg-agent.conf" ] && cp --verbose ${gpg-agent-conf} "$GNUPGHOME/gpg-agent.conf"
|
||||
echo "\$GNUPGHOME is \"$GNUPGHOME\""
|
||||
'';
|
||||
|
||||
# Copy the contents of contrib to the home directory, add a shortcut to
|
||||
# the guide on the desktop, and link to the whole repo in the documents
|
||||
# folder.
|
||||
system.activationScripts.yubikeyGuide = let
|
||||
homeDir = "/home/nixos/";
|
||||
desktopDir = homeDir + "Desktop/";
|
||||
documentsDir = homeDir + "Documents/";
|
||||
in ''
|
||||
mkdir -p ${desktopDir} ${documentsDir}
|
||||
chown nixos ${homeDir} ${desktopDir} ${documentsDir}
|
||||
|
||||
cp -R ${contrib}/* ${homeDir}
|
||||
ln -sf ${yubikey-guide}/share/applications/yubikey-guide.desktop ${desktopDir}
|
||||
ln -sfT ${src} ${documentsDir}/YubiKey-Guide
|
||||
'';
|
||||
};
|
||||
|
||||
evalNixos = configuration: import <nixpkgs/nixos> {
|
||||
inherit system configuration;
|
||||
nixos = import <nixpkgs/nixos/release.nix> {
|
||||
inherit configuration;
|
||||
supportedSystems = [ "x86_64-linux" ];
|
||||
};
|
||||
|
||||
# Choose the one you like:
|
||||
#nixos-yubikey = nixos.iso_minimal; # No graphical environment
|
||||
#nixos-yubikey = nixos.iso_gnome;
|
||||
nixos-yubikey = nixos.iso_plasma5;
|
||||
|
||||
in {
|
||||
iso = (evalNixos config).config.system.build.isoImage;
|
||||
inherit nixos-yubikey;
|
||||
}
|
||||
```
|
||||
|
||||
Build the installer and copy it to a USB drive.
|
||||
|
||||
```console
|
||||
$ nix build -f yubikey-installer.nix --out-link installer
|
||||
$ nix build -f yubikey-installer.nix -o installer nixos-yubikey
|
||||
|
||||
$ sudo cp -v installer/iso/*.iso /dev/sdb; sync
|
||||
'installer/iso/nixos-20.03.git.c438ce1-x86_64-linux.iso' -> '/dev/sdb'
|
||||
'installer/iso/nixos-yubikey-22.05beta-248980.gfedcba-x86_64-linux.iso' -> '/dev/sdb'
|
||||
```
|
||||
|
||||
On NixOS, ensure that you have `pinentry-program /run/current-system/sw/bin/pinentry-curses` in your `$GNUPGHOME/gpg-agent.conf` before running any `gpg` commands.
|
||||
|
||||
With this image, you won't need to manually create a [temporary working directory](#temporary-working-directory) or [harden the configuration](#harden-configuration), as it was done when creating the image.
|
||||
|
||||
## OpenBSD
|
||||
|
||||
|
@ -2864,3 +3003,4 @@ Before you unmount your backup, ask yourself if you should make another one just
|
|||
* https://mlohr.com/gpg-agent-forwarding/
|
||||
* https://www.ingby.com/?p=293
|
||||
* https://support.yubico.com/support/solutions/articles/15000027139-yubikey-5-2-3-enhancements-to-openpgp-3-4-support
|
||||
* https://github.com/dhess/nixos-yubikey
|
||||
|
|
Loading…
Reference in New Issue