diff --git a/docs/install.md b/docs/install.md new file mode 100644 index 0000000..cd5786a --- /dev/null +++ b/docs/install.md @@ -0,0 +1,157 @@ +# NixOSインストール手順 + +## 事前準備 + +1. [ISOビルド](iso-build.md)を参照してISOを作成 +2. USBに書き込んで対象マシンでブート + +## ネットワーク接続 + +### 有線LAN + +DHCPで自動設定される。 + +### WiFi(有線が使えない場合) + +```bash +nmcli device wifi connect --ask +``` + +## SSH接続 + +コンソールに表示されたIPアドレスに接続: + +```bash +ssh root@ +``` + +## インストール手順 + +### 1. dotfilesのクローン + +```bash +git clone git@github.com:moons-14/dotfiles.git ~/dotfiles +``` + +### 2. SSHホストキーの生成 + +新しいホスト用のSSHホストキーを生成: + +```bash +ssh-keygen -t ed25519 -f /tmp/ssh_host_ed25519_key -N "" +``` + +### 3. age公開鍵の取得 + +SSHホストキーからage公開鍵を取得: + +```bash +ssh-to-age -i /tmp/ssh_host_ed25519_key.pub +``` + +出力されたage公開鍵をコピー。 + +### 4. .sops.yamlの編集 + +```bash +cd ~/dotfiles +vim .sops.yaml +``` + +以下を追加: + +```yaml +keys: + - &host_ + +creation_rules: + - path_regex: ^secrets/hosts//[^/]+\.ya?ml$ + key_groups: + - age: + - *admin_yubikey1 + - *host_ +``` + +### 5. シークレットの再暗号化 + +```bash +sops updatekeys secrets/common/system.yaml +sops updatekeys secrets/hosts//*.yaml +``` + +### 6. disko設定の作成 + +新しいホスト用の`hosts//disko.nix`を作成。 + +#### シンプル構成(暗号化なし) + +```nix +_: +{ + disko.enableConfig = true; + + disko.devices.disk.main = { + type = "disk"; + device = "/dev/sda"; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "512M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; +} +``` + +#### LUKS暗号化 + btrfs + +`hosts/x1g13/disko.nix`を参照。 + +### 7. ディスクのパーティション + +```bash +cd ~/dotfiles +nix run github:nix-community/disko -- --mode disko hosts//disko.nix +``` + +### 8. ホストキーのコピー + +```bash +mkdir -p /mnt/etc/ssh +cp /tmp/ssh_host_ed25519_key* /mnt/etc/ssh/ +chmod 600 /mnt/etc/ssh/ssh_host_ed25519_key +``` + +### 9. NixOSインストール + +```bash +nixos-install --flake ~/dotfiles# +``` + +### 10. 再起動 + +```bash +reboot +``` + +## インストール後の確認 + +- SSHでログインできるか +- sopsシークレットが復号できるか +- diskoでパーティションが正しく設定されているか diff --git a/docs/iso-build.md b/docs/iso-build.md new file mode 100644 index 0000000..d62af15 --- /dev/null +++ b/docs/iso-build.md @@ -0,0 +1,26 @@ +# カスタムISOビルド + +## ビルド + +```bash +nix build .#nixosConfigurations.installer.config.system.build.isoImage +``` + +## ISO書き込み + +```bash +# USBデバイスの確認 +lsblk + +# 書き込み(/dev/sdXは実際のデバイスに置き換える) +sudo dd if=./result/nixos-minimal-*.iso of=/dev/sdX bs=4M status=progress +sync +``` + +## ISOの特徴 + +- SSH鍵認証でrootログイン可能 +- 有線LANはDHCPで自動設定 +- WiFiは`nmcli`で手動設定可能 +- disko/sops/ageなどのツールを内蔵 +- ブート時にIPアドレスとヘルプを表示 diff --git a/hosts/default.nix b/hosts/default.nix index c4f429b..0cbb0c1 100644 --- a/hosts/default.nix +++ b/hosts/default.nix @@ -70,5 +70,15 @@ in "workloads/secure-storage" ]; }; + + installer = nixosSystem { + system = "x86_64-linux"; + modules = [ + ./installer/default.nix + ]; + specialArgs = { + inherit inputs; + }; + }; }; } diff --git a/hosts/installer/default.nix b/hosts/installer/default.nix new file mode 100644 index 0000000..fcbe24f --- /dev/null +++ b/hosts/installer/default.nix @@ -0,0 +1,191 @@ +{ + pkgs, + lib, + modulesPath, + ... +}: +{ + imports = [ + "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix" + ]; + + networking = { + hostName = "nixos-installer"; + + networkmanager = { + enable = true; + wifi.powersave = false; + }; + }; + + services.openssh = { + enable = true; + settings = { + PermitRootLogin = "prohibit-password"; + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + PubkeyAuthentication = "yes"; + }; + }; + + users.users.root.openssh.authorizedKeys.keys = [ + "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIKhxDkucmeCor6CKoXAua7DgDSzuXrZOtpdkyzQxz5+aAAAABHNzaDo= moons@moons14.com" + "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIN6hZJyng/5LgFKPjR6uZAd/00UkO0vN0uQOoIvfSELdAAAABHNzaDo= moons@moons14.com" + ]; + + environment.systemPackages = with pkgs; [ + git # Clone dotfiles repository + disko # Disk partitioning + sops # Secrets management + age # Age encryption + ssh-to-age # Convert SSH keys to age + age-plugin-yubikey # YubiKey support + yubikey-manager # YubiKey management + pcsc-tools # Smart card tools + mkpasswd # Password hash generation + rsync # File synchronization + vim # Text editor + wget # Download files + curl # HTTP client + jq # JSON processor + parted # Partition tools + cryptsetup # LUKS encryption + btrfs-progs # Btrfs filesystem tools + ]; + + services.pcscd.enable = true; + + environment.etc."installer-help.txt".text = '' + + ╔══════════════════════════════════════════════════════════════╗ + ║ NixOS Installer ISO ║ + ╠══════════════════════════════════════════════════════════════╣ + ║ ║ + ║ SSH Access: ║ + ║ ssh root@ ║ + ║ ║ + ║ Network Setup: ║ + ║ Wired: Auto-configured via DHCP ║ + ║ WiFi: nmcli device wifi connect --ask ║ + ║ ║ + ║ Installation Workflow: ║ + ║ ║ + ║ 1. Clone dotfiles: ║ + ║ git clone git@github.com:moons-14/dotfiles.git ~/dotfiles║ + ║ ║ + ║ 2. Generate SSH host key for new host: ║ + ║ ssh-keygen -t ed25519 -f /tmp/ssh_host_ed25519_key -N "" ║ + ║ ║ + ║ 3. Get age public key from SSH host key: ║ + ║ ssh-to-age -i /tmp/ssh_host_ed25519_key.pub ║ + ║ ║ + ║ 4. Add age key to .sops.yaml: ║ + ║ cd ~/dotfiles ║ + ║ # Edit .sops.yaml and add the age key ║ + ║ # Add new host entry to creation_rules ║ + ║ ║ + ║ 5. Re-encrypt secrets: ║ + ║ sops updatekeys secrets/common/system.yaml ║ + ║ sops updatekeys secrets/hosts//*.yaml ║ + ║ ║ + ║ 6. Create disko.nix for new host: ║ + ║ # Check disk devices ║ + ║ lsblk -f ║ + ║ ║ + ║ # Create hosts//disko.nix ║ + ║ # Example: LUKS + btrfs ║ + ║ # See hosts/x1g13/disko.nix for reference ║ + ║ ║ + ║ 7. Partition disk with disko: ║ + ║ nix run github:nix-community/disko -- \ ║ + ║ --mode disko hosts//disko.nix ║ + ║ ║ + ║ 8. Copy host key to installed system: ║ + ║ mkdir -p /mnt/etc/ssh ║ + ║ cp /tmp/ssh_host_ed25519_key* /mnt/etc/ssh/ ║ + ║ chmod 600 /mnt/etc/ssh/ssh_host_ed25519_key ║ + ║ ║ + ║ 9. Install NixOS: ║ + ║ nixos-install --flake ~/dotfiles# ║ + ║ ║ + ║ Disko Configuration Examples: ║ + ║ ║ + ║ Simple (no encryption): ║ + ║ disko.devices.disk.main = { ║ + ║ type = "disk"; ║ + ║ device = "/dev/sda"; ║ + ║ content = { ║ + ║ type = "gpt"; ║ + ║ partitions = { ║ + ║ ESP = { size = "512M"; type = "EF00"; ║ + ║ content = { type = "filesystem"; ║ + ║ format = "vfat"; mountpoint = "/boot"; }; }; ║ + ║ root = { size = "100%"; ║ + ║ content = { type = "filesystem"; ║ + ║ format = "ext4"; mountpoint = "/"; }; }; ║ + ║ }; ║ + ║ }; ║ + ║ }; ║ + ║ ║ + ║ LUKS + btrfs (see hosts/x1g13/disko.nix): ║ + ║ - Use partuuid for device path ║ + ║ - Set askPassword = true for LUKS ║ + ║ - Configure btrfs subvolumes ║ + ║ ║ + ╚══════════════════════════════════════════════════════════════╝ + + ''; + + systemd.services.installer-banner = { + description = "Display installer help on console"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.coreutils}/bin/cat /etc/installer-help.txt"; + StandardOutput = "tty"; + TTYPath = "/dev/tty1"; + }; + }; + + systemd.services.display-ip = { + description = "Display IP address on console"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-online.target" ]; + wants = [ "network-online.target" ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = pkgs.writeShellScript "display-ip" '' + sleep 2 + echo "" + echo "=== Network Interfaces ===" + ${pkgs.iproute2}/bin/ip -4 addr show | ${pkgs.gnugrep}/bin/grep inet + echo "" + echo "=== SSH Access ===" + for ip in $(${pkgs.iproute2}/bin/ip -4 addr show | ${pkgs.gnugrep}/bin/grep -oP 'inet \K[\d.]+' | ${pkgs.gnugrep}/bin/grep -v '127.0.0.1'); do + echo " ssh root@$ip" + done + echo "" + ''; + StandardOutput = "tty"; + TTYPath = "/dev/tty1"; + }; + }; + + nix = { + settings = { + experimental-features = [ + "nix-command" + "flakes" + ]; + trusted-users = [ "root" ]; + }; + + extraOptions = '' + experimental-features = nix-command flakes + ''; + }; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + + system.stateVersion = "26.05"; +}