Skip to content

Instantly share code, notes, and snippets.

@ixmatus
Forked from techhazard/Readme.md
Created July 30, 2017 18:10
Show Gist options
  • Save ixmatus/7dcd56c8e878e8d98ee6d266f7949d11 to your computer and use it in GitHub Desktop.
Save ixmatus/7dcd56c8e878e8d98ee6d266f7949d11 to your computer and use it in GitHub Desktop.

Revisions

  1. @techhazard techhazard revised this gist Apr 21, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion formatzfs.sh
    Original file line number Diff line number Diff line change
    @@ -66,6 +66,6 @@ zpool set bootfs=rpool/root/nixos rpool
    # - 7 daily snapshots
    # - 4 weekly snapshots
    # - 12 monthly snapshots
    zfs set com.sun:auto-snapshot rpool/home
    zfs set com.sun:auto-snapshot=true rpool/home

    exit 0
  2. @techhazard techhazard revised this gist Apr 21, 2017. 1 changed file with 9 additions and 0 deletions.
    9 changes: 9 additions & 0 deletions formatzfs.sh
    Original file line number Diff line number Diff line change
    @@ -59,4 +59,13 @@ mount /dev/disk/by-partlabel/efiboot /mnt/boot
    # set boot filesystem
    zpool set bootfs=rpool/root/nixos rpool

    # enable auto snapshots for home dataset
    # defaults to keeping:
    # - 4 frequent snapshots (1 per 15m)
    # - 24 hourly snapshots
    # - 7 daily snapshots
    # - 4 weekly snapshots
    # - 12 monthly snapshots
    zfs set com.sun:auto-snapshot rpool/home

    exit 0
  3. @techhazard techhazard revised this gist Apr 21, 2017. No changes.
  4. @techhazard techhazard revised this gist Apr 21, 2017. 1 changed file with 9 additions and 11 deletions.
    20 changes: 9 additions & 11 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -4,16 +4,14 @@ After some effort (and asking for help on the nix-dev mailing list) I
    installed ZFS on an encrypted partition. The relevant configuration is
    below.

    - [NixOS with ZFS on LUKS](#nixos-with-zfs-on-luks)
    - [Installing](#installing)
    - [Use keyfile](#use-keyfile)
    - [Configure passphrase](#configure-passphrase)
    - [Configure without passphrase](#configure-without-passphrase)
    - [Misc commands](#misc-commands)
    - [To Do](#to-do)
    - [Resources](#resources)
    - [Installing with old script](#installing-with-old-script)

    - [Installing](#installing)
    - [Use keyfile](#use-keyfile)
    - [Configure passphrase](#configure-passphrase)
    - [Configure without passphrase](#configure-without-passphrase)
    - [Misc commands](#misc-commands)
    - [To Do](#to-do)
    - [Resources I used](#resources-i-used)
    - [Installing with old script](#installing-with-old-script)

    ## Installing
    *I do not have a custom iso yet, so you'll need two USBs. One for the NixOS iso, and one for these files. You'll have to mount the second stick manually.*
    @@ -65,7 +63,7 @@ loadkeys dvorak-programmer
    - [ ] customise the iso with ZFS support and these files
    - [ ] find the location of `automated_install.sh` in the built iso.

    ## Resources
    ## Resources I used
    I used the following resources:
    - https://nixos.org/wiki/ZFS_on_NixOS#How_to_install_NixOS_on_a_ZFS_root_filesystem
    - https://nixos.org/wiki/Encrypted_Root_on_NixOS
  5. @techhazard techhazard revised this gist Apr 21, 2017. 1 changed file with 15 additions and 4 deletions.
    19 changes: 15 additions & 4 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -4,6 +4,17 @@ After some effort (and asking for help on the nix-dev mailing list) I
    installed ZFS on an encrypted partition. The relevant configuration is
    below.

    - [NixOS with ZFS on LUKS](#nixos-with-zfs-on-luks)
    - [Installing](#installing)
    - [Use keyfile](#use-keyfile)
    - [Configure passphrase](#configure-passphrase)
    - [Configure without passphrase](#configure-without-passphrase)
    - [Misc commands](#misc-commands)
    - [To Do](#to-do)
    - [Resources](#resources)
    - [Installing with old script](#installing-with-old-script)


    ## Installing
    *I do not have a custom iso yet, so you'll need two USBs. One for the NixOS iso, and one for these files. You'll have to mount the second stick manually.*

    @@ -49,20 +60,20 @@ I always run these command right after booting the install usb.
    loadkeys dvorak-programmer
    ```

    ### To Do
    ## To Do
    - [ ] use nixos-rebuild to make an iso containing the files
    - [ ] customise the iso with ZFS support and these files
    - [ ] find the location of `automated_install.sh` in the built iso.

    ### Resources
    ## Resources
    I used the following resources:
    - https://nixos.org/wiki/ZFS_on_NixOS#How_to_install_NixOS_on_a_ZFS_root_filesystem
    - https://nixos.org/wiki/Encrypted_Root_on_NixOS
    - http://www.pavelkogan.com/2014/05/23/luks-full-disk-encryption/
    - https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF
    - https://github.com/zfsonlinux/zfs/wiki/Ubuntu-16.10-Root-on-ZFS

    ### Installing with old version (tested, working)
    ## Installing with old script
    use this version of the files: [old version](https://gist.github.com/awesomefireduck/c763e168a62a0ef559a1fb9473261459/a92e653ae949972d12738a1f7e042eceb832dadf). All text below is about those versions, not the ones you see here.

    The commands in `init.sh` I run manually, (so no sed :-P)
    @@ -71,4 +82,4 @@ The `zfscreate.sh` is used to set up a single-disk ZFS root filesystem inside of

    The two `*.nix` files have the minimum config needed for this (compare them with the generated ones in `/mnt/etc/nixos/`); The UUIDs should be filled-in by `nixos-generate-config`;
    the `"usb_storage"` addition is not needed for everyone, just like the `keyfile` options; the other important changes
    are the `hostId`, which is required by ZFS; and the `boot.supportedFilesystems` which I'm not even sure of if that's necessary
    are the `hostId`, which is required by ZFS; and the `boot.supportedFilesystems` which I'm not even sure of if that's necessary
  6. @techhazard techhazard revised this gist Apr 21, 2017. 3 changed files with 24 additions and 42 deletions.
    8 changes: 4 additions & 4 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -21,23 +21,22 @@ bash /path/to/automated_install.sh
    ### Use keyfile
    It is possible to use a keyfile (e.g. on a usb stick). If you want a keyfile and not have a passphrase for backup, see [Configure without passphrase](#configure-without-passphrase) below.
    ```sh
    # step 2
    # part of step 3
    export keyfile="/dev/disk/by-id/usb-Some-Usb-Stick"
    # optional, default is 4096
    export keysize="8192"
    # step 4
    ```
    ### Configure passphrase
    It is possible to pass the passphrase in an environment variable to make the install fully automated. This is generally unwise, but since we are in a temporary live enviorment I consider it safe enough. You can also put it as `passphrase="your passphrase here"` in `automated_install.sh` on line `16` instead.
    If you add a keyfile as well, both are added.
    ```sh
    # step 2
    # part of step 3
    export passphrase="your passphrase here"
    # step 4
    ```
    ### Configure without passphrase
    If you only want to add a keyfile and not set a passphrase, set `use_passphrase` to `no`. This is not recommended.
    ```sh
    # part of step 3
    export use_passphrase="no"
    # see Use keyfile above
    export keyfile="/path/to/keyfile"
    @@ -52,6 +51,7 @@ loadkeys dvorak-programmer

    ### To Do
    - [ ] use nixos-rebuild to make an iso containing the files
    - [ ] customise the iso with ZFS support and these files
    - [ ] find the location of `automated_install.sh` in the built iso.

    ### Resources
    6 changes: 3 additions & 3 deletions automated_install.sh
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,5 @@
    # you only need to set this to the disk to want to install to
    # IT WILL BE WIPED
    # but a backup of the partition table (not the contents) will be made
    rootdisk="${rootdisk:-NONE}";

    # use keyfile (optional)
    @@ -21,7 +20,9 @@ passphrase="${passphrase:-NONE}"
    # exit on error
    set -e
    # abort if no root disk is set
    if [[ "${rootdisk}" != "NONE" ]]; echo "please set rootdisk with: \`rootdisk=/dev/disk/by-id/disk_id_for_root_device $0\`; exit 1; fi
    if [[ "${rootdisk}" != "NONE" ]]; echo "please set rootdisk with: \`rootdisk=/dev/disk/by-id/disk_id_for_root_device $0\`"; exit 1; fi

    if [[ "${use_passphrase}" == "no" ]] && [[ "${keyfile}" == "NONE" ]]; echo "please use at least one of the following: keyfile, password."; exit 2; fi

    if [[ "${use_passphrase}" == "no" ]]; echo "using a passprase is highly recommended, since keyfiles can get corrupt or lost."; fi

    @@ -52,7 +53,6 @@ then
    # replace placeholder keysize with actual keysize
    sed -i '' -e "s!keyfile_size_here!${keysize}!" /mnt/etc/nixos/lukskeyfile.nix;

    # add ./lukskeyfile.nix to the imports of configuration.nix
    sed -i '' -e "s!\(./hardware-configuration.nix\)!\1\n ./lukskeyfile.nix!" /mnt/etc/nixos/configuration.nix
    fi
    52 changes: 17 additions & 35 deletions partition.sh
    Original file line number Diff line number Diff line change
    @@ -1,33 +1,10 @@
    #!/bin/bash
    set -e

    # filename of partition backup
    gptbackup="gpt-backup_$(basename ${rootdisk})_$(date +%s)"

    # location to save the partition backup to
    backuplocation="/var/tmp/${gptbackup}"

    # First we make a backup of the current table
    # at /tmp/gpt-backup_{id_of_device}_{current_timestamp}
    # Note that this only backs-up the partition layout, not the data in it
    #
    # b: create backup
    # $backloc: location to write to
    # q: quit without saving
    gdisk ${rootdisk} >/dev/null <<EOF
    b
    ${backuplocation}
    q
    EOF
    # copy the backup next to this script (partition.sh)
    cp "${backuplocation}" "${scriptlocation}"

    # This partitions the given rootdisk into two partitions: one for EFI (300MB) and the rest for LUKS (which will contain ZFS)
    # This then formats the resulting EFI partition with FAT32

    ####################
    ### Partitioning ###
    ####################
    # Now we have a backup, we can create
    # a new GPT table
    set -e
    ## The actual command is below the comment block.
    # we will create a new GPT table
    #
    # o: create new GPT table
    # y: confirm creation
    @@ -59,8 +36,10 @@ cp "${backuplocation}" "${scriptlocation}"
    # 2: partition to label
    # cryptroot: name of the partition
    #
    # w: write changes and quit
    # y: confirm write

    gdisk ${rootdisk} >/dev/null <<EOF
    gdisk ${rootdisk} >/dev/null <<end_of_commands
    o
    y
    n
    @@ -79,23 +58,26 @@ efiboot
    c
    2
    cryptroot
    p
    w
    y
    EOF
    end_of_commands


    # check for the newly created partitions
    # this *might* give unrelated errors;
    # if so, change it to `partprobe || true`
    partprobe "${rootdisk}" >/dev/null
    # this sometimes gives unrelated errors
    # so we change it to `partprobe || true`
    partprobe "${rootdisk}" >/dev/null || true

    # wait for label to show up
    while [[ ! -e /dev/disk/by-partlabel/efiboot ]];
    do
    sleep 2;
    done

    # wait for label to show up
    while [[ ! -e /dev/disk/by-partlabel/cryptroot ]];
    do
    sleep 2;
    done
    # check if both labels exist
    ls /dev/disk/by-partlabel/efiboot >/dev/null
    ls /dev/disk/by-partlabel/cryptroot >/dev/null
  7. @techhazard techhazard revised this gist Apr 21, 2017. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -13,13 +13,13 @@ below.
    # whole disk please, no partition
    export rootdisk="/dev/disk/by-id/ata-Some-Storage-Device"
    ```
    3. use keyfile and/or configure passphrase usage (see sections below)
    3. [use keyfile](#use-keyfile) and/or [configure passphrase](#configure-passphrase) usage (see sections below)
    4. run it:
    ```sh
    bash /path/to/automated_install.sh
    ```
    ### Use keyfile
    It is possible to use a keyfile (e.g. on a usb stick). If you want a keyfile and not have a passphrase for backup, see [Configure without passphrase](#Configure-without-passphrase) below.
    It is possible to use a keyfile (e.g. on a usb stick). If you want a keyfile and not have a passphrase for backup, see [Configure without passphrase](#configure-without-passphrase) below.
    ```sh
    # step 2
    export keyfile="/dev/disk/by-id/usb-Some-Usb-Stick"
    @@ -63,7 +63,7 @@ I used the following resources:
    - https://github.com/zfsonlinux/zfs/wiki/Ubuntu-16.10-Root-on-ZFS

    ### Installing with old version (tested, working)
    use this version of the files: [old version](https://gist.github.com/awesomefireduck/c763e168a62a0ef559a1fb9473261459/a92e653ae949972d12738a1f7e042eceb832dadf)
    use this version of the files: [old version](https://gist.github.com/awesomefireduck/c763e168a62a0ef559a1fb9473261459/a92e653ae949972d12738a1f7e042eceb832dadf). All text below is about those versions, not the ones you see here.

    The commands in `init.sh` I run manually, (so no sed :-P)

  8. @techhazard techhazard revised this gist Apr 21, 2017. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -8,7 +8,7 @@ below.
    *I do not have a custom iso yet, so you'll need two USBs. One for the NixOS iso, and one for these files. You'll have to mount the second stick manually.*

    1. Boot into the nixos environment and find the uuid or id of the disk you want to install to. Do not use `/dev/sda` but `/dev/disk/by-...`, use `lsblk` and `blkid`.
    2. export it to the environment as `rootdisk` and run it:
    2. export it to the environment as `rootdisk`:
    ```sh
    # whole disk please, no partition
    export rootdisk="/dev/disk/by-id/ata-Some-Storage-Device"
    @@ -19,7 +19,7 @@ export rootdisk="/dev/disk/by-id/ata-Some-Storage-Device"
    bash /path/to/automated_install.sh
    ```
    ### Use keyfile
    It is possible to use a keyfile (e.g. on a usb stick)
    It is possible to use a keyfile (e.g. on a usb stick). If you want a keyfile and not have a passphrase for backup, see [Configure without passphrase](#Configure-without-passphrase) below.
    ```sh
    # step 2
    export keyfile="/dev/disk/by-id/usb-Some-Usb-Stick"
    @@ -28,7 +28,7 @@ export keysize="8192"
    # step 4
    ```
    ### Configure passphrase
    It is possible to pass the passphrase in an environment variable. This is generally unwise, but since we are in a temporary live enviorment I consider it safe enough. You can also put it as `passphrase="your passphrase here"` in `automated_install.sh` instead.
    It is possible to pass the passphrase in an environment variable to make the install fully automated. This is generally unwise, but since we are in a temporary live enviorment I consider it safe enough. You can also put it as `passphrase="your passphrase here"` in `automated_install.sh` on line `16` instead.
    If you add a keyfile as well, both are added.
    ```sh
    # step 2
  9. @techhazard techhazard revised this gist Apr 21, 2017. 1 changed file with 8 additions and 17 deletions.
    25 changes: 8 additions & 17 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -18,38 +18,29 @@ export rootdisk="/dev/disk/by-id/ata-Some-Storage-Device"
    ```sh
    bash /path/to/automated_install.sh
    ```
    ### Install with keyfile
    ### Use keyfile
    It is possible to use a keyfile (e.g. on a usb stick)
    ```sh
    export rootdisk="/dev/disk/by-id/ata-Some-Storage-Device"

    # step 2
    export keyfile="/dev/disk/by-id/usb-Some-Usb-Stick"
    # optional, default is 4096
    export keysize="8192"

    bash /path/to/automated_install.sh
    # step 4
    ```

    ### Automated install with passphrase
    ### Configure passphrase
    It is possible to pass the passphrase in an environment variable. This is generally unwise, but since we are in a temporary live enviorment I consider it safe enough. You can also put it as `passphrase="your passphrase here"` in `automated_install.sh` instead.
    If you add a keyfile as well, both are added.
    ```sh
    export rootdisk="/dev/disk/by-id/ata-Some-Storage-Device"

    # step 2
    export passphrase="your passphrase here"

    bash /path/to/automated_install.sh
    # step 4
    ```
    ### Automated install without passphrase
    ### Configure without passphrase
    If you only want to add a keyfile and not set a passphrase, set `use_passphrase` to `no`. This is not recommended.
    ```sh
    export rootdisk="/dev/disk/by-id/ata-Some-Storage-Device"

    export use_passphrase="no"

    # see Use keyfile above
    export keyfile="/path/to/keyfile"

    bash /path/to/automated_install.sh
    ```

    ## Misc commands
  10. @techhazard techhazard revised this gist Apr 21, 2017. 1 changed file with 9 additions and 5 deletions.
    14 changes: 9 additions & 5 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -4,14 +4,18 @@ After some effort (and asking for help on the nix-dev mailing list) I
    installed ZFS on an encrypted partition. The relevant configuration is
    below.

    ## Installing (new version, tested & working, no iso yet; you'll need two USBs)
    Boot into the nixos environment and find the uuid or id of the disk you want to install to. (use `blkid` and `lsblk`)
    (so no `/dev/sda` but `/dev/disk/by-id/...` or `/dev/disk/by-uuid/...`)
    export it to the environment as `rootdisk` and run it:
    ## Installing
    *I do not have a custom iso yet, so you'll need two USBs. One for the NixOS iso, and one for these files. You'll have to mount the second stick manually.*

    1. Boot into the nixos environment and find the uuid or id of the disk you want to install to. Do not use `/dev/sda` but `/dev/disk/by-...`, use `lsblk` and `blkid`.
    2. export it to the environment as `rootdisk` and run it:
    ```sh
    # whole disk please, no partition
    export rootdisk="/dev/disk/by-id/ata-Some-Storage-Device"
    # run it
    ```
    3. use keyfile and/or configure passphrase usage (see sections below)
    4. run it:
    ```sh
    bash /path/to/automated_install.sh
    ```
    ### Install with keyfile
  11. @techhazard techhazard revised this gist Apr 21, 2017. 2 changed files with 54 additions and 19 deletions.
    71 changes: 53 additions & 18 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -4,41 +4,76 @@ After some effort (and asking for help on the nix-dev mailing list) I
    installed ZFS on an encrypted partition. The relevant configuration is
    below.

    ## Installing (old version, tested, I currently run it)
    use this version of the files: [newest tested version](https://gist.github.com/awesomefireduck/c763e168a62a0ef559a1fb9473261459/a92e653ae949972d12738a1f7e042eceb832dadf)
    ## Installing (new version, tested & working, no iso yet; you'll need two USBs)
    Boot into the nixos environment and find the uuid or id of the disk you want to install to. (use `blkid` and `lsblk`)
    (so no `/dev/sda` but `/dev/disk/by-id/...` or `/dev/disk/by-uuid/...`)
    export it to the environment as `rootdisk` and run it:
    ```sh
    # whole disk please, no partition
    export rootdisk="/dev/disk/by-id/ata-Some-Storage-Device"
    # run it
    bash /path/to/automated_install.sh
    ```
    ### Install with keyfile
    It is possible to use a keyfile (e.g. on a usb stick)
    ```sh
    export rootdisk="/dev/disk/by-id/ata-Some-Storage-Device"

    The commands in `init.sh` I run manually, (so no sed :-P)
    export keyfile="/dev/disk/by-id/usb-Some-Usb-Stick"
    # optional, default is 4096
    export keysize="8192"

    The `zfscreate.sh` is used to set up a single-disk ZFS root filesystem inside of an encrypted LUKS container.
    bash /path/to/automated_install.sh
    ```

    The two `*.nix` files have the minimum config needed for this (compare them with the generated ones in `/mnt/etc/nixos/`); The UUIDs should be filled-in by `nixos-generate-config`;
    the `"usb_storage"` addition is not needed for everyone, just like the `keyfile` options; the other important changes
    are the `hostId`, which is required by ZFS; and the `boot.supportedFilesystems` which I'm not even sure of if that's necessary
    ### Automated install with passphrase
    It is possible to pass the passphrase in an environment variable. This is generally unwise, but since we are in a temporary live enviorment I consider it safe enough. You can also put it as `passphrase="your passphrase here"` in `automated_install.sh` instead.
    If you add a keyfile as well, both are added.
    ```sh
    export rootdisk="/dev/disk/by-id/ata-Some-Storage-Device"

    ## Installing (new version, tested & working, files need small modifications)
    ~Dowload the zip and put its contents on the small FAT partition of your NixOS install stick~. TODO: use nixos-rebuild to make an iso containing the files
    export passphrase="your passphrase here"

    Boot into the nixos environment and find the uuid or id of the disk you want to install to. (use `blkid` and `lsblk`)
    (so no `/dev/sda` but `/dev/disk/by-id/...` or `/dev/disk/by-uuid/...`)
    TODO: Find the location of `automated_install.sh`
    Add that path to `automated_install.sh` (as `rootdisk`) and add an optional keyfile.
    run it:
    ```
    bash /path/to/automated_install.sh
    ```
    ### Automated install without passphrase
    If you only want to add a keyfile and not set a passphrase, set `use_passphrase` to `no`. This is not recommended.
    ```sh
    export rootdisk="/dev/disk/by-id/ata-Some-Storage-Device"

    ### Misc commands
    export use_passphrase="no"

    export keyfile="/path/to/keyfile"

    bash /path/to/automated_install.sh
    ```
    ## I always run these command right after booting the install usb

    ## Misc commands
    I always run these command right after booting the install usb.
    ```sh
    # I use programmer dvorak instead of qwerty
    loadkeys dvorak-programmer
    ```

    ### To Do
    - [ ] use nixos-rebuild to make an iso containing the files
    - [ ] find the location of `automated_install.sh` in the built iso.

    ### Resources
    I used the following resources:
    - https://nixos.org/wiki/ZFS_on_NixOS#How_to_install_NixOS_on_a_ZFS_root_filesystem
    - https://nixos.org/wiki/Encrypted_Root_on_NixOS
    - http://www.pavelkogan.com/2014/05/23/luks-full-disk-encryption/
    - https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF
    - https://github.com/zfsonlinux/zfs/wiki/Ubuntu-16.10-Root-on-ZFS
    - https://github.com/zfsonlinux/zfs/wiki/Ubuntu-16.10-Root-on-ZFS

    ### Installing with old version (tested, working)
    use this version of the files: [old version](https://gist.github.com/awesomefireduck/c763e168a62a0ef559a1fb9473261459/a92e653ae949972d12738a1f7e042eceb832dadf)

    The commands in `init.sh` I run manually, (so no sed :-P)

    The `zfscreate.sh` is used to set up a single-disk ZFS root filesystem inside of an encrypted LUKS container.

    The two `*.nix` files have the minimum config needed for this (compare them with the generated ones in `/mnt/etc/nixos/`); The UUIDs should be filled-in by `nixos-generate-config`;
    the `"usb_storage"` addition is not needed for everyone, just like the `keyfile` options; the other important changes
    are the `hostId`, which is required by ZFS; and the `boot.supportedFilesystems` which I'm not even sure of if that's necessary
    2 changes: 1 addition & 1 deletion automated_install.sh
    Original file line number Diff line number Diff line change
    @@ -35,7 +35,7 @@ bash formatzfs.sh
    nixos-generate-config --root /mnt
    if [[ k"$keyfile" != "NONE" ]];
    if [[ "$keyfile" != "NONE" ]];
    then
    # add lukskeyfile.nix
    cp "${scriptlocation}/lukskeyfile.nix" /mnt/etc/nixos/
  12. @techhazard techhazard revised this gist Apr 21, 2017. 4 changed files with 34 additions and 11 deletions.
    23 changes: 18 additions & 5 deletions automated_install.sh
    Original file line number Diff line number Diff line change
    @@ -10,8 +10,12 @@ keysize="${keysize:-4096}";
    # set to "no" to not set a passphrase
    # I highly recommed setting a passphrase and storing it in a safe location
    use_passphrase="${use_passphrase:-yes}";
    # You can set the passphrase here (so you can view it in plaintext,
    # but do not forget to remove it.
    # TODO: check if this file is on a tempfs just like /etc/nixos/configuration.nix
    passphrase="${passphrase:-NONE}"

    # Probably no need to change anything
    # Probably no need to change anything below or
    # in the other scripts, there be dragons

    # exit on error
    @@ -35,6 +39,12 @@ if [[ k"$keyfile" != "NONE" ]];
    then
    # add lukskeyfile.nix
    cp "${scriptlocation}/lukskeyfile.nix" /mnt/etc/nixos/
    # replace `/path/to/device` with actual keyfile
    echo "path to device"
    blkdevice="$(basename "$(ls -l /dev/disk/by-partlabel/cryptroot | awk '{print $11}')")";
    device="$(ls -l /dev/disk/by-partuuid/ | grep "$blkdevice" | awk '{print $9}')"
    sed -i'' -e "s!/path/to/device!${device}!" /mnt/etc/nixos/lukskeyfile.nix;
    # replace `/path/to/keyfile` with actual keyfile
    sed -i '' -e "s!/path/to/keyfile!${keyfile}!" /mnt/etc/nixos/lukskeyfile.nix;
    @@ -45,15 +55,18 @@ then
    # add ./lukskeyfile.nix to the imports of configuration.nix
    sed -i '' -e "s!\(./hardware-configuration.nix\)!\1\n ./lukskeyfile.nix!" /mnt/etc/nixos/configuration.nix
    done
    fi
    # add the zfs.nix
    # add the zfs.nix
    cp "${scriptlocation}/zfs.nix" /mnt/etc/nixos/
    # generate and insert a unique hostid
    hostid="$(head -c4 /dev/urandom | od -A none -t x4)"
    sed -i '' -e "s!cafebabe!${hostid}!" /mnt/etc/nixos/configuration.nix
    sed -i '' -e "s!cafebabe!${hostid}!" /mnt/etc/nixos/zfs.nix
    # add ./zfs.nix to the imports of configuration.nix
    sed -i '' -e "s!\(./hardware-configuration.nix\)!\1\n ./zfs.nix!" /mnt/etc/nixos/configuration.nix
    echo "Done!"
    echo "Please check if if everything looks allright in all the files in /mnt/etc/nixos/"
    echo "Please check if if everything looks allright in all the files in /mnt/etc/nixos/"
    exit 0
    15 changes: 12 additions & 3 deletions formatluks.sh
    Original file line number Diff line number Diff line change
    @@ -8,17 +8,25 @@ dd if=/dev/urandom of=/tmp/keyfile bs=1k count=8
    # pick a strong passphrase

    echo "Creating the encrypted partition, follow the instructions and use a strong password!"
    cryptsetup luksFormat /dev/disk/by-partlabel/cryptroot --key-size 512 --hash sha512 --key-file /tmp/keyfile
    # formats the partition with luks and adds the temporary keyfile.
    echo "YES" | cryptsetup luksFormat /dev/disk/by-partlabel/cryptroot --key-size 512 --hash sha512 --key-file /tmp/keyfile

    if [[ $use_passphrase != "no" ]];
    then
    cryptsetup luksAddKey /dev/disk/by-partlabel/cryptroot --key-file /tmp/keyfile
    # sets the given passphrase or asks for one
    if [[ "${passphrase}" != "NONE" ]];
    then
    echo "$passphrase" | cryptsetup luksAddKey /dev/disk/by-partlabel/cryptroot --key-file /tmp/keyfile
    else
    cryptsetup luksAddKey /dev/disk/by-partlabel/cryptroot --key-file /tmp/keyfile
    fi
    echo "added passphrase"
    fi


    if [[ "${keyfile}" != "NONE" ]];
    then
    cryptsetup luksAddKey /dev/disk/by-partlabel/cryptroot -d /tmp/keyfile --new-keyfile-size="${keylength}" "${keyfile}"
    cryptsetup luksAddKey /dev/disk/by-partlabel/cryptroot -d /tmp/keyfile --new-keyfile-size="${keysize}" "${keyfile}"
    echo "added keyfile"
    fi

    @@ -28,5 +36,6 @@ cryptsetup luksOpen /dev/disk/by-partlabel/cryptroot nixroot -d /tmp/keyfile

    # remove the temporary keyfile
    cryptsetup luksRemoveKey /dev/disk/by-partlabel/cryptroot /tmp/keyfile
    rm -f /tmp/keyfile

    exit 0
    1 change: 1 addition & 0 deletions formatzfs.sh
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,7 @@
    set -e

    # Install zfs in the live environment
    # TODO: do this in the custom bootable iso
    sed -i '' -e 's/^}/ boot.supportedFilesystems = ["zfs"];\n}/' /etc/nixos/configuration.nix;
    nixos-rebuild switch

    6 changes: 3 additions & 3 deletions partition.sh
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@ set -e
    gptbackup="gpt-backup_$(basename ${rootdisk})_$(date +%s)"

    # location to save the partition backup to
    backuplocation="/tmp/${gptbackup}"
    backuplocation="/var/tmp/${gptbackup}"

    # First we make a backup of the current table
    # at /tmp/gpt-backup_{id_of_device}_{current_timestamp}
    @@ -88,12 +88,12 @@ EOF
    # check for the newly created partitions
    # this *might* give unrelated errors;
    # if so, change it to `partprobe || true`
    partprobe >/dev/null
    partprobe "${rootdisk}" >/dev/null

    # wait for label to show up
    while [[ ! -e /dev/disk/by-partlabel/efiboot ]];
    do
    sleep 0.3;
    sleep 2;
    done

    # check if both labels exist
  13. @techhazard techhazard revised this gist Apr 21, 2017. 4 changed files with 15 additions and 10 deletions.
    1 change: 1 addition & 0 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -17,6 +17,7 @@ are the `hostId`, which is required by ZFS; and the `boot.supportedFilesystems`

    ## Installing (new version, tested & working, files need small modifications)
    ~Dowload the zip and put its contents on the small FAT partition of your NixOS install stick~. TODO: use nixos-rebuild to make an iso containing the files

    Boot into the nixos environment and find the uuid or id of the disk you want to install to. (use `blkid` and `lsblk`)
    (so no `/dev/sda` but `/dev/disk/by-id/...` or `/dev/disk/by-uuid/...`)
    TODO: Find the location of `automated_install.sh`
    18 changes: 11 additions & 7 deletions automated_install.sh
    Original file line number Diff line number Diff line change
    @@ -1,21 +1,25 @@
    # you only need to set this to the disk to want to install to
    # IT WILL BE WIPED
    # but a backup of the partition table (not the contents) will be made
    rootdisk="/dev/disk/by-id/some_device_id";
    rootdisk="${rootdisk:-NONE}";

    # use keyfile (optional)
    #keyfile=;
    #keysize="4096";
    keyfile="${keyfile:-NONE}";
    keysize="${keysize:-4096}";

    # set to "no" to not set a passphrase
    # I highly recommed setting a passphrase and storing it in a safe location
    use_passphrase="yes";
    use_passphrase="${use_passphrase:-yes}";

    # Probably no need to change anything
    # in the other scripts, there be dragons

    # exit on error
    set -e
    # abort if no root disk is set
    if [[ "${rootdisk}" != "NONE" ]]; echo "please set rootdisk with: \`rootdisk=/dev/disk/by-id/disk_id_for_root_device $0\`; exit 1; fi
    if [[ "${use_passphrase}" == "no" ]]; echo "using a passprase is highly recommended, since keyfiles can get corrupt or lost."; fi
    export rootdisk keyfile keysize use_passphrase;
    # absolute location for this script (directory the files are in)
    @@ -27,7 +31,7 @@ bash formatzfs.sh
    nixos-generate-config --root /mnt
    if [[ ! -z "$keyfile" ]];
    if [[ k"$keyfile" != "NONE" ]];
    then
    # add lukskeyfile.nix
    cp "${scriptlocation}/lukskeyfile.nix" /mnt/etc/nixos/
    @@ -36,7 +40,7 @@ then
    sed -i '' -e "s!/path/to/keyfile!${keyfile}!" /mnt/etc/nixos/lukskeyfile.nix;
    # replace placeholder keysize with actual keysize
    sed -i '' -e "s!4096!${keysize}!" /mnt/etc/nixos/lukskeyfile.nix;
    sed -i '' -e "s!keyfile_size_here!${keysize}!" /mnt/etc/nixos/lukskeyfile.nix;
    # add ./lukskeyfile.nix to the imports of configuration.nix
    @@ -48,7 +52,7 @@ cp "${scriptlocation}/zfs.nix" /mnt/etc/nixos/
    # generate and insert a unique hostid
    hostid="$(head -c4 /dev/urandom | od -A none -t x4)"
    sed -i '' -e "s#cafebabe#${hostid}#" /mnt/etc/nixos/configuration.nix
    sed -i '' -e "s!cafebabe!${hostid}!" /mnt/etc/nixos/configuration.nix
    sed -i '' -e "s!\(./hardware-configuration.nix\)!\1\n ./zfs.nix!" /mnt/etc/nixos/configuration.nix
    echo "Done!"
    4 changes: 2 additions & 2 deletions formatluks.sh
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    #!/bin/bash
    set -e

    # temporary keyfile, will be removed
    # temporary keyfile, will be removed (8k, ridiculously large)
    dd if=/dev/urandom of=/tmp/keyfile bs=1k count=8

    ## now we encrypt the second partition
    @@ -16,7 +16,7 @@ then
    fi


    if [[ ! -z "${keyfile}" ]];
    if [[ "${keyfile}" != "NONE" ]];
    then
    cryptsetup luksAddKey /dev/disk/by-partlabel/cryptroot -d /tmp/keyfile --new-keyfile-size="${keylength}" "${keyfile}"
    echo "added keyfile"
    2 changes: 1 addition & 1 deletion lukskeyfile.nix
    Original file line number Diff line number Diff line change
    @@ -9,6 +9,6 @@

    boot.initrd.luks.devices."nixroot" = {
    keyFile = "/path/to/keyfile";
    keyFileSize = 4096; # or some other length
    keyFileSize = keyfile_size_here;
    };
    }
  14. @techhazard techhazard revised this gist Apr 21, 2017. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -15,8 +15,8 @@ The two `*.nix` files have the minimum config needed for this (compare them with
    the `"usb_storage"` addition is not needed for everyone, just like the `keyfile` options; the other important changes
    are the `hostId`, which is required by ZFS; and the `boot.supportedFilesystems` which I'm not even sure of if that's necessary

    ## Installing (new version, not yet tested)
    Dowload the zip and put its contents on the small FAT partition of your NixOS install stick. (TODO: check if this is possible)
    ## Installing (new version, tested & working, files need small modifications)
    ~Dowload the zip and put its contents on the small FAT partition of your NixOS install stick~. TODO: use nixos-rebuild to make an iso containing the files
    Boot into the nixos environment and find the uuid or id of the disk you want to install to. (use `blkid` and `lsblk`)
    (so no `/dev/sda` but `/dev/disk/by-id/...` or `/dev/disk/by-uuid/...`)
    TODO: Find the location of `automated_install.sh`
  15. @techhazard techhazard revised this gist Apr 7, 2017. 1 changed file with 14 additions and 20 deletions.
    34 changes: 14 additions & 20 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -1,32 +1,18 @@
    # My attempt at ZFS on LUKS
    I used the following resources:
    - https://nixos.org/wiki/ZFS_on_NixOS#How_to_install_NixOS_on_a_ZFS_root_filesystem
    - https://nixos.org/wiki/Encrypted_Root_on_NixOS
    - http://www.pavelkogan.com/2014/05/23/luks-full-disk-encryption/
    - https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF
    - https://github.com/zfsonlinux/zfs/wiki/Ubuntu-16.10-Root-on-ZFS

    I succesfully did the following:
    - Installed nixos on an unencrypted ZFS root filesystem;
    I only booted it and logged in as root to shut it down.
    - Installed nixos on an encrypted ext4 root filesystem using a keyfile;
    Logged in as root to shut it down; after deleting the keyfile,
    system did not prompt for passphrase and was unable to boot.

    ## Victory!!!
    # NixOS with ZFS on LUKS

    After some effort (and asking for help on the nix-dev mailing list) I
    installed ZFS on an encrypted partition. The relevant configuration is
    below.

    ## Installing (old version)
    ## Installing (old version, tested, I currently run it)
    use this version of the files: [newest tested version](https://gist.github.com/awesomefireduck/c763e168a62a0ef559a1fb9473261459/a92e653ae949972d12738a1f7e042eceb832dadf)

    The commands in `init.sh` I run manually, (so no sed :-P)

    The `zfscreate.sh` is used to set up a single-disk ZFS root filesystem inside of an encrypted LUKS container.

    The two `*.nix` files have the minimum config needed for this; The UUIDs should be filled-in by `nixos-generate-config`;
    the `"usb_storage"` addition is not needed for everyone, just like the `keyfile` options; and the other important changes
    The two `*.nix` files have the minimum config needed for this (compare them with the generated ones in `/mnt/etc/nixos/`); The UUIDs should be filled-in by `nixos-generate-config`;
    the `"usb_storage"` addition is not needed for everyone, just like the `keyfile` options; the other important changes
    are the `hostId`, which is required by ZFS; and the `boot.supportedFilesystems` which I'm not even sure of if that's necessary

    ## Installing (new version, not yet tested)
    @@ -46,4 +32,12 @@ bash /path/to/automated_install.sh
    # I use programmer dvorak instead of qwerty
    loadkeys dvorak-programmer
    ```
    ```

    ### Resources
    I used the following resources:
    - https://nixos.org/wiki/ZFS_on_NixOS#How_to_install_NixOS_on_a_ZFS_root_filesystem
    - https://nixos.org/wiki/Encrypted_Root_on_NixOS
    - http://www.pavelkogan.com/2014/05/23/luks-full-disk-encryption/
    - https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF
    - https://github.com/zfsonlinux/zfs/wiki/Ubuntu-16.10-Root-on-ZFS
  16. @techhazard techhazard revised this gist Apr 7, 2017. 6 changed files with 39 additions and 33 deletions.
    22 changes: 15 additions & 7 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -19,7 +19,8 @@ installed ZFS on an encrypted partition. The relevant configuration is
    below.

    ## Installing (old version)
    use this version of the files: https://gist.github.com/awesomefireduck/c763e168a62a0ef559a1fb9473261459/a92e653ae949972d12738a1f7e042eceb832dadf
    use this version of the files: [newest tested version](https://gist.github.com/awesomefireduck/c763e168a62a0ef559a1fb9473261459/a92e653ae949972d12738a1f7e042eceb832dadf)

    The commands in `init.sh` I run manually, (so no sed :-P)

    The `zfscreate.sh` is used to set up a single-disk ZFS root filesystem inside of an encrypted LUKS container.
    @@ -28,14 +29,21 @@ The two `*.nix` files have the minimum config needed for this; The UUIDs should
    the `"usb_storage"` addition is not needed for everyone, just like the `keyfile` options; and the other important changes
    are the `hostId`, which is required by ZFS; and the `boot.supportedFilesystems` which I'm not even sure of if that's necessary

    ## Warning
    I am currently changing the script without testing. [This revision](https://gist.github.com/awesomefireduck/c763e168a62a0ef559a1fb9473261459/a92e653ae949972d12738a1f7e042eceb832dadf) is tested and should work without problems.

    ## Installing (new version, not yet tested)
    Dowload the zip and put it on the small FAT partition of your NixOS install stick.
    Boot into the nixos environment and find the uuid or id of the disk you want to install to.
    Dowload the zip and put its contents on the small FAT partition of your NixOS install stick. (TODO: check if this is possible)
    Boot into the nixos environment and find the uuid or id of the disk you want to install to. (use `blkid` and `lsblk`)
    (so no `/dev/sda` but `/dev/disk/by-id/...` or `/dev/disk/by-uuid/...`)
    Add that path to `automated_install.sh` add an optional keyfile and run it:
    TODO: Find the location of `automated_install.sh`
    Add that path to `automated_install.sh` (as `rootdisk`) and add an optional keyfile.
    run it:
    ```
    bash /path/to/automated_install.sh
    ```

    ### Misc commands
    ```
    ## I always run these command right after booting the install usb
    # I use programmer dvorak instead of qwerty
    loadkeys dvorak-programmer
    ```
    22 changes: 16 additions & 6 deletions automated_install.sh
    Original file line number Diff line number Diff line change
    @@ -29,17 +29,27 @@ nixos-generate-config --root /mnt

    if [[ ! -z "$keyfile" ]];
    then
    cp "${scriptlocation}/lukskeyfile.nix" /mnt/etc/nixos/
    # replace `/path/to/keyfile` with actual keyfile
    # replace placeholder keysize with actual keysize
    sed -i '' -e "s#/path/to/keyfile#${keyfile}#"; -e "s#4096#${keysize}#" /mnt/etc/nixos/lukskeyfile.nix
    # add lukskeyfile.nix
    cp "${scriptlocation}/lukskeyfile.nix" /mnt/etc/nixos/

    # replace `/path/to/keyfile` with actual keyfile
    sed -i '' -e "s!/path/to/keyfile!${keyfile}!" /mnt/etc/nixos/lukskeyfile.nix;

    # replace placeholder keysize with actual keysize
    sed -i '' -e "s!4096!${keysize}!" /mnt/etc/nixos/lukskeyfile.nix;


    # add ./lukskeyfile.nix to the imports of configuration.nix
    sed -i '' -e "s#\(./hardware-configuration.nix\)#\1\n ./lukskeyfile.nix#" /mnt/etc/nixos/configuration.nix
    sed -i '' -e "s!\(./hardware-configuration.nix\)!\1\n ./lukskeyfile.nix!" /mnt/etc/nixos/configuration.nix
    done

    # add the zfs.nix
    cp "${scriptlocation}/zfs.nix" /mnt/etc/nixos/

    # generate and insert a unique hostid
    hostid="$(head -c4 /dev/urandom | od -A none -t x4)"
    sed -i '' -e "s#cafebabe#${hostid}#" /mnt/etc/nixos/configuration.nix
    sed -i '' -e "s#cafebabe#${hostid}#" /mnt/etc/nixos/configuration.nix
    sed -i '' -e "s!\(./hardware-configuration.nix\)!\1\n ./zfs.nix!" /mnt/etc/nixos/configuration.nix

    echo "Done!"
    echo "Please check if if everything looks allright in all the files in /mnt/etc/nixos/"
    2 changes: 1 addition & 1 deletion formatluks.sh
    Original file line number Diff line number Diff line change
    @@ -27,6 +27,6 @@ fi
    cryptsetup luksOpen /dev/disk/by-partlabel/cryptroot nixroot -d /tmp/keyfile

    # remove the temporary keyfile
    cryptsetup luksRemoveKey /dev/disk/by-partlabel/cryptroot /tmp/keyfile:
    cryptsetup luksRemoveKey /dev/disk/by-partlabel/cryptroot /tmp/keyfile

    exit 0
    5 changes: 5 additions & 0 deletions formatzfs.sh
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,11 @@
    #!/bin/bash
    set -e

    # Install zfs in the live environment
    sed -i '' -e 's/^}/ boot.supportedFilesystems = ["zfs"];\n}/' /etc/nixos/configuration.nix;
    nixos-rebuild switch


    ## the actual zpool create is below
    #
    # zpool create \
    17 changes: 0 additions & 17 deletions init.sh
    Original file line number Diff line number Diff line change
    @@ -1,17 +0,0 @@
    ## I always run these command right after booting the install usb

    # I use programmer dvorak instead of qwerty
    loadkeys dvorak-programmer

    # I add `boot.supportedFilesystems = ["zfs" "exfat"];` to /etc/nixos/configuration.nix
    # zfs would be obvious, The usb that has e.g. zfscreate.sh runs on exfat
    sed -i '' -e 's/^}/ boot.supportedFilesystems = ["zfs" "exfat"];\n}/' /etc/nixos/configuration.nix;

    # use the new config
    nixos-rebuild switch

    mkdir ~/mount
    # mount the stick containing the scripts
    mount /dev/disk/by-id/[some id] ~/mount

    # this would be the point at which I run ~/mount/automated_install.sh, or do other stuff
    4 changes: 2 additions & 2 deletions lukskeyfile.nix
    Original file line number Diff line number Diff line change
    @@ -3,8 +3,8 @@
    # You can skip this file if you use a passphrase
    { config, lib, pkgs, ... }:
    {
    # uncomment if you use an usb-stick with a keyfile
    #boot.kernelModules = [ "usb_storage" ];
    # remove if you do not use an usb-stick with a keyfile
    boot.kernelModules = [ "usb_storage" ];
    boot.extraModulePackages = [ ];

    boot.initrd.luks.devices."nixroot" = {
  17. @techhazard techhazard revised this gist Apr 7, 2017. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -13,7 +13,6 @@ I succesfully did the following:
    Logged in as root to shut it down; after deleting the keyfile,
    system did not prompt for passphrase and was unable to boot.


    ## Victory!!!
    After some effort (and asking for help on the nix-dev mailing list) I
    installed ZFS on an encrypted partition. The relevant configuration is
    @@ -34,7 +33,7 @@ I am currently changing the script without testing. [This revision](https://gist

    ## Installing (new version, not yet tested)
    Dowload the zip and put it on the small FAT partition of your NixOS install stick.
    Boot into the nixos environment and find the uuid or id of the disk you want to install to.
    Boot into the nixos environment and find the uuid or id of the disk you want to install to.
    (so no `/dev/sda` but `/dev/disk/by-id/...` or `/dev/disk/by-uuid/...`)
    Add that path to `automated_install.sh` add an optional keyfile and run it:
    ```
  18. @techhazard techhazard revised this gist Apr 7, 2017. 1 changed file with 9 additions and 2 deletions.
    11 changes: 9 additions & 2 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -19,7 +19,7 @@ After some effort (and asking for help on the nix-dev mailing list) I
    installed ZFS on an encrypted partition. The relevant configuration is
    below.

    # Installing (old version)
    ## Installing (old version)
    use this version of the files: https://gist.github.com/awesomefireduck/c763e168a62a0ef559a1fb9473261459/a92e653ae949972d12738a1f7e042eceb832dadf
    The commands in `init.sh` I run manually, (so no sed :-P)

    @@ -32,4 +32,11 @@ are the `hostId`, which is required by ZFS; and the `boot.supportedFilesystems`
    ## Warning
    I am currently changing the script without testing. [This revision](https://gist.github.com/awesomefireduck/c763e168a62a0ef559a1fb9473261459/a92e653ae949972d12738a1f7e042eceb832dadf) is tested and should work without problems.

    ## Installing (with the new version
    ## Installing (new version, not yet tested)
    Dowload the zip and put it on the small FAT partition of your NixOS install stick.
    Boot into the nixos environment and find the uuid or id of the disk you want to install to.
    (so no `/dev/sda` but `/dev/disk/by-id/...` or `/dev/disk/by-uuid/...`)
    Add that path to `automated_install.sh` add an optional keyfile and run it:
    ```
    bash /path/to/automated_install.sh
    ```
  19. @techhazard techhazard revised this gist Apr 7, 2017. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion Readme.md
    Original file line number Diff line number Diff line change
    @@ -19,6 +19,8 @@ After some effort (and asking for help on the nix-dev mailing list) I
    installed ZFS on an encrypted partition. The relevant configuration is
    below.

    # Installing (old version)
    use this version of the files: https://gist.github.com/awesomefireduck/c763e168a62a0ef559a1fb9473261459/a92e653ae949972d12738a1f7e042eceb832dadf
    The commands in `init.sh` I run manually, (so no sed :-P)

    The `zfscreate.sh` is used to set up a single-disk ZFS root filesystem inside of an encrypted LUKS container.
    @@ -28,4 +30,6 @@ the `"usb_storage"` addition is not needed for everyone, just like the `keyfile`
    are the `hostId`, which is required by ZFS; and the `boot.supportedFilesystems` which I'm not even sure of if that's necessary

    ## Warning
    I am currently changing the script without testing, revision #N should work without problems
    I am currently changing the script without testing. [This revision](https://gist.github.com/awesomefireduck/c763e168a62a0ef559a1fb9473261459/a92e653ae949972d12738a1f7e042eceb832dadf) is tested and should work without problems.

    ## Installing (with the new version
  20. @techhazard techhazard revised this gist Apr 7, 2017. 1 changed file with 0 additions and 35 deletions.
    35 changes: 0 additions & 35 deletions hardware-configuration.nix
    Original file line number Diff line number Diff line change
    @@ -1,35 +0,0 @@
    # Do not modify this file! It was generated by ‘nixos-generate-config’
    # and may be overwritten by future invocations. Please make changes
    # to /etc/nixos/configuration.nix instead.
    { config, lib, pkgs, ... }:

    {
    imports =
    [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
    ];

    boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
    boot.kernelModules = [ "kvm-intel" ];
    boot.extraModulePackages = [ ];

    fileSystems."/" =
    { device = "rpool/root/nixos";
    fsType = "zfs";
    };

    fileSystems."/home" =
    { device = "rpool/home";
    fsType = "zfs";
    };

    fileSystems."/boot" =
    { device = "/dev/disk/by-uuid/[uuid of efiboot]";
    fsType = "vfat";
    };

    swapDevices =
    [ { device = "/dev/zd0"; }
    ];

    nix.maxJobs = lib.mkDefault 4;
    }
  21. @techhazard techhazard revised this gist Apr 7, 2017. 8 changed files with 36 additions and 35 deletions.
    3 changes: 3 additions & 0 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -26,3 +26,6 @@ The `zfscreate.sh` is used to set up a single-disk ZFS root filesystem inside of
    The two `*.nix` files have the minimum config needed for this; The UUIDs should be filled-in by `nixos-generate-config`;
    the `"usb_storage"` addition is not needed for everyone, just like the `keyfile` options; and the other important changes
    are the `hostId`, which is required by ZFS; and the `boot.supportedFilesystems` which I'm not even sure of if that's necessary

    ## Warning
    I am currently changing the script without testing, revision #N should work without problems
    33 changes: 27 additions & 6 deletions automated_install.sh
    Original file line number Diff line number Diff line change
    @@ -4,21 +4,42 @@
    rootdisk="/dev/disk/by-id/some_device_id";

    # use keyfile (optional)
    keyfile=;
    keylength="4096";
    #keyfile=;
    #keysize="4096";

    # set to "no" to not set a passphrase
    passphrase="yes";
    # I highly recommed setting a passphrase and storing it in a safe location
    use_passphrase="yes";

    # Probably no need to change anything
    # in the other scripts, there be dragons

    # No need to change anything below,
    # there be dragons
    # exit on error
    set -e

    export rootdisk keyfile keysize use_passphrase;
    # absolute location for this script (directory the files are in)
    export scriptlocation=$(dirname $(readlink -f $0))

    bash partition.sh
    bash formatluks.sh
    bash formatzfs.sh

    nixos-generate-config --root /mnt

    echo "done!"
    if [[ ! -z "$keyfile" ]];
    then
    cp "${scriptlocation}/lukskeyfile.nix" /mnt/etc/nixos/
    # replace `/path/to/keyfile` with actual keyfile
    # replace placeholder keysize with actual keysize
    sed -i '' -e "s#/path/to/keyfile#${keyfile}#"; -e "s#4096#${keysize}#" /mnt/etc/nixos/lukskeyfile.nix
    # add ./lukskeyfile.nix to the imports of configuration.nix
    sed -i '' -e "s#\(./hardware-configuration.nix\)#\1\n ./lukskeyfile.nix#" /mnt/etc/nixos/configuration.nix
    done

    cp "${scriptlocation}/zfs.nix" /mnt/etc/nixos/
    hostid="$(head -c4 /dev/urandom | od -A none -t x4)"
    sed -i '' -e "s#cafebabe#${hostid}#" /mnt/etc/nixos/configuration.nix

    echo "Done!"
    echo "Please check if if everything looks allright in all the files in /mnt/etc/nixos/"
    19 changes: 0 additions & 19 deletions configuration.nix
    Original file line number Diff line number Diff line change
    @@ -1,19 +0,0 @@
    # Edit this configuration file to define what should be installed on
    # your system. Help is available in the configuration.nix(5) man page
    # and in the NixOS manual (accessible by running ‘nixos-help’).

    { config, pkgs, ... }:

    {
    # add zfs for zfs settings
    # add lukskey if using a keyfile for luks
    imports =
    [ # Include the results of the hardware scan.
    ./hardware-configuration.nix
    ./lukskey.nix
    ./zfs.nix
    ];

    #[rest of the file below]
    #...
    }
    4 changes: 2 additions & 2 deletions formatluks.sh
    Original file line number Diff line number Diff line change
    @@ -10,7 +10,7 @@ dd if=/dev/urandom of=/tmp/keyfile bs=1k count=8
    echo "Creating the encrypted partition, follow the instructions and use a strong password!"
    cryptsetup luksFormat /dev/disk/by-partlabel/cryptroot --key-size 512 --hash sha512 --key-file /tmp/keyfile

    if [[ $passphrase != "no" ]];
    if [[ $use_passphrase != "no" ]];
    then
    cryptsetup luksAddKey /dev/disk/by-partlabel/cryptroot --key-file /tmp/keyfile
    fi
    @@ -27,6 +27,6 @@ fi
    cryptsetup luksOpen /dev/disk/by-partlabel/cryptroot nixroot -d /tmp/keyfile

    # remove the temporary keyfile
    cryptsetup luksRemoveKey /dev/disk/by-partlabel/cryptroot /tmp/keyfile
    cryptsetup luksRemoveKey /dev/disk/by-partlabel/cryptroot /tmp/keyfile:

    exit 0
    4 changes: 2 additions & 2 deletions init.sh
    Original file line number Diff line number Diff line change
    @@ -11,7 +11,7 @@ sed -i '' -e 's/^}/ boot.supportedFilesystems = ["zfs" "exfat"];\n}/' /etc/nixo
    nixos-rebuild switch

    mkdir ~/mount
    # mount the stick containing zfscreate.sh
    # mount the stick containing the scripts
    mount /dev/disk/by-id/[some id] ~/mount

    # this would be the point at which I run ~/mount/zfscreate.sh, or do other stuff
    # this would be the point at which I run ~/mount/automated_install.sh, or do other stuff
    3 changes: 1 addition & 2 deletions lukskeyfile.nix
    Original file line number Diff line number Diff line change
    @@ -9,7 +9,6 @@

    boot.initrd.luks.devices."nixroot" = {
    keyFile = "/path/to/keyfile";
    keyFileSize = 4096;
    keyFileSize = 4096; # or some other length
    };

    }
    3 changes: 0 additions & 3 deletions partition.sh
    Original file line number Diff line number Diff line change
    @@ -7,9 +7,6 @@ gptbackup="gpt-backup_$(basename ${rootdisk})_$(date +%s)"
    # location to save the partition backup to
    backuplocation="/tmp/${gptbackup}"

    # absolute location for this script
    scriptlocation=$(dirname $(readlink -f $0))

    # First we make a backup of the current table
    # at /tmp/gpt-backup_{id_of_device}_{current_timestamp}
    # Note that this only backs-up the partition layout, not the data in it
    2 changes: 1 addition & 1 deletion zfs.nix
    Original file line number Diff line number Diff line change
    @@ -14,7 +14,7 @@

    # required by ZFS
    # see https://nixos.org/nixos/options.html#networking.hostid
    networking.hostId = "dd03c40c";
    networking.hostId = "cafebabe";

    # this enables the zfs-auto-snapshot
    services.zfs.autoSnapshot = {
  22. @techhazard techhazard revised this gist Apr 7, 2017. 5 changed files with 221 additions and 224 deletions.
    24 changes: 24 additions & 0 deletions automated_install.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    # you only need to set this to the disk to want to install to
    # IT WILL BE WIPED
    # but a backup of the partition table (not the contents) will be made
    rootdisk="/dev/disk/by-id/some_device_id";

    # use keyfile (optional)
    keyfile=;
    keylength="4096";

    # set to "no" to not set a passphrase
    passphrase="yes";

    # No need to change anything below,
    # there be dragons
    # exit on error
    set -e

    bash partition.sh
    bash formatluks.sh
    bash formatzfs.sh

    nixos-generate-config --root /mnt

    echo "done!"
    32 changes: 32 additions & 0 deletions formatluks.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,32 @@
    #!/bin/bash
    set -e

    # temporary keyfile, will be removed
    dd if=/dev/urandom of=/tmp/keyfile bs=1k count=8

    ## now we encrypt the second partition
    # pick a strong passphrase

    echo "Creating the encrypted partition, follow the instructions and use a strong password!"
    cryptsetup luksFormat /dev/disk/by-partlabel/cryptroot --key-size 512 --hash sha512 --key-file /tmp/keyfile

    if [[ $passphrase != "no" ]];
    then
    cryptsetup luksAddKey /dev/disk/by-partlabel/cryptroot --key-file /tmp/keyfile
    fi


    if [[ ! -z "${keyfile}" ]];
    then
    cryptsetup luksAddKey /dev/disk/by-partlabel/cryptroot -d /tmp/keyfile --new-keyfile-size="${keylength}" "${keyfile}"
    echo "added keyfile"
    fi


    # mount the cryptdisk at /dev/mapper/nixroot
    cryptsetup luksOpen /dev/disk/by-partlabel/cryptroot nixroot -d /tmp/keyfile

    # remove the temporary keyfile
    cryptsetup luksRemoveKey /dev/disk/by-partlabel/cryptroot /tmp/keyfile

    exit 0
    56 changes: 56 additions & 0 deletions formatzfs.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,56 @@
    #!/bin/bash
    set -e

    ## the actual zpool create is below
    #
    # zpool create \
    # -O atime=on \ #
    # -O relatime=on \ # only write access time (requires atime, see man zfs)
    # -O compression=lz4 \ # compress all the things! (man zfs)
    # -O snapdir=visible \ # ever so sligthly easier snap management (man zfs)
    # -O xattr=sa \ # selinux file permissions (man zfs)
    # -o ashift=12 \ # 4k blocks (man zpool)
    # -o altroot=/mnt \ # temp mount during install (man zpool)
    # rpool \ # new name of the pool
    # /dev/mapper/nixroot # devices used in the pool (in my case one, so no mirror or raid)

    zpool create \
    -O atime=on \
    -O relatime=on \
    -O compression=lz4 \
    -O snapdir=visible \
    -O xattr=sa \
    -o ashift=12 \
    -o altroot=/mnt \
    rpool \
    /dev/mapper/nixroot \


    # dataset for / (root)
    zfs create -o mountpoint=none rpool/root
    echo created root dataset
    zfs create -o mountpoint=legacy rpool/root/nixos

    # dataset for home, make copies of all files against corruption
    zfs create -o copies=2 -o mountpoint=legacy rpool/home

    # dataset for swap
    zfs create -o compression=off -V 8G rpool/swap
    mkswap -L SWAP /dev/zvol/rpool/swap
    swapon /dev/zvol/rpool/swap

    # mount the root dataset at /mnt
    mount -t zfs rpool/root/nixos /mnt

    # mount the home datset at future /home
    mkdir -p /mnt/home
    mount -t zfs rpool/home /mnt/home

    # mount EFI partition at future /boot
    mkdir -p /mnt/boot
    mount /dev/disk/by-partlabel/efiboot /mnt/boot

    # set boot filesystem
    zpool set bootfs=rpool/root/nixos rpool

    exit 0
    109 changes: 109 additions & 0 deletions partition.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,109 @@
    #!/bin/bash
    set -e

    # filename of partition backup
    gptbackup="gpt-backup_$(basename ${rootdisk})_$(date +%s)"

    # location to save the partition backup to
    backuplocation="/tmp/${gptbackup}"

    # absolute location for this script
    scriptlocation=$(dirname $(readlink -f $0))

    # First we make a backup of the current table
    # at /tmp/gpt-backup_{id_of_device}_{current_timestamp}
    # Note that this only backs-up the partition layout, not the data in it
    #
    # b: create backup
    # $backloc: location to write to
    # q: quit without saving
    gdisk ${rootdisk} >/dev/null <<EOF
    b
    ${backuplocation}
    q
    EOF
    # copy the backup next to this script (partition.sh)
    cp "${backuplocation}" "${scriptlocation}"


    ####################
    ### Partitioning ###
    ####################
    # Now we have a backup, we can create
    # a new GPT table
    #
    # o: create new GPT table
    # y: confirm creation
    #
    # with the new partition table,
    # we now create the EFI partition
    #
    # n: create new partion
    # 1: partition number
    # 2048: start position
    # +300M: make it 300MB big
    # ef00: set an EFI partition type
    #
    # With the EFI partition, we
    # use the rest of the disk for LUKS
    #
    # n: create new partition
    # 2: partition number
    # <empty>: start partition right after first
    # <empty>: use all remaining space
    # 8300: set generic linux partition type
    #
    # We only need to set the partition labels
    #
    # c: change partition label
    # 1: partition to label
    # efiboot: name of the partition
    # c: change partition label
    # 2: partition to label
    # cryptroot: name of the partition
    #

    gdisk ${rootdisk} >/dev/null <<EOF
    o
    y
    n
    1
    2048
    +300M
    ef00
    n
    2
    8300
    c
    1
    efiboot
    c
    2
    cryptroot
    p
    w
    y
    EOF


    # check for the newly created partitions
    # this *might* give unrelated errors;
    # if so, change it to `partprobe || true`
    partprobe >/dev/null

    # wait for label to show up
    while [[ ! -e /dev/disk/by-partlabel/efiboot ]];
    do
    sleep 0.3;
    done

    # check if both labels exist
    ls /dev/disk/by-partlabel/efiboot >/dev/null
    ls /dev/disk/by-partlabel/cryptroot >/dev/null

    ## format the EFI partition
    mkfs.vfat /dev/disk/by-partlabel/efiboot

    exit 0
    224 changes: 0 additions & 224 deletions zfscreate.sh
    Original file line number Diff line number Diff line change
    @@ -1,224 +0,0 @@
    # you only need to set this to the disk to want to install to
    # IT WILL BE WIPED
    # but a backup of the partition table (not the contents) will be made
    rootdisk="/dev/disk/by-id/some_device_id";

    # use keyfile (optional)
    keyfile=;
    keylength="4096";

    # set to "no" to not set a passphrase
    passphrase="yes";



    # No need to change anything below,
    # there be dragons
    # exit on error
    set -e

    # filename of partition backup
    gptbackup="gpt-backup_$(basename ${rootdisk})_$(date +%s)"

    # location to save the partition backup to
    backuplocation="/tmp/${gptbackup}"

    # absolute location for this script
    scriptlocation=$(dirname $(readlink -f $0))



    ##############
    ### Backup ###
    ##############
    # First we make a backup of the current table
    # at /tmp/gpt-backup_{id_of_device}_{current_timestamp}
    #
    # b: create backup
    # $backloc: location to write to
    gdisk ${rootdisk} >/dev/null <<EOF
    b
    ${backuplocation}
    q
    EOF
    # copy the backup next to this script (zfscreate.sh)
    cp "${backuplocation}" "${scriptlocation}"


    ####################
    ### Partitioning ###
    ####################
    # Now we have a backup, we can create
    # a new GPT table
    #
    # o: create new GPT table
    # y: confirm creation
    #
    # with the new partition table,
    # we now create the EFI partition
    #
    # n: create new partion
    # 1: partition number
    # 2048: start position
    # +300M: make it 300MB big
    # ef00: set an EFI partition type
    #
    # With the EFI partition, we
    # use the rest of the disk for LUKS
    #
    # n: create new partition
    # 2: partition number
    # <empty>: start partition right after first
    # <empty>: use all remaining space
    # 8300: set generic linux partition type
    #
    # We only need to set the partition labels
    #
    # c: change partition label
    # 1: partition to label
    # efiboot: name of the partition
    # c: change partition label
    # 2: partition to label
    # cryptroot: name of the partition
    #

    gdisk ${rootdisk} >/dev/null <<EOF
    o
    y
    n
    1
    2048
    +300M
    ef00
    n
    2
    8300
    c
    1
    efiboot
    c
    2
    cryptroot
    p
    w
    y
    EOF


    # check for the newly created partitions
    # this *might* give unrelated errors;
    # if so, change it to `partprobe || true`
    partprobe >/dev/null

    # wait for label to show up
    while [[ ! -e /dev/disk/by-partlabel/efiboot ]];
    do
    sleep 0.3;
    done

    # check if both labels exist
    ls /dev/disk/by-partlabel/efiboot >/dev/null
    ls /dev/disk/by-partlabel/cryptroot >/dev/null


    ## format the EFI partition
    mkfs.vfat /dev/disk/by-partlabel/efiboot



    ############
    ### LUKS ###
    ############

    # temporary keyfile, will be removed
    dd if=/dev/urandom of=/tmp/keyfile bs=1k count=8

    ## now we encrypt the second partition
    # pick a strong passphrase

    echo "Creating the encrypted partition, follow the instructions and use a strong password!"
    cryptsetup luksFormat /dev/disk/by-partlabel/cryptroot --key-size 512 --hash sha512 --key-file /tmp/keyfile

    if [[ $passphrase != "no" ]];
    then
    cryptsetup luksAddKey /dev/disk/by-partlabel/cryptroot --key-file /tmp/keyfile
    fi


    if [[ ! -z "${keyfile}" ]];
    then
    cryptsetup luksAddKey /dev/disk/by-partlabel/cryptroot -d /tmp/keyfile --new-keyfile-size="${keylength}" "${keyfile}"
    echo "added keyfile"
    fi


    # mount the cryptdisk at /dev/mapper/nixroot
    cryptsetup luksOpen /dev/disk/by-partlabel/cryptroot nixroot -d /tmp/keyfile

    # remove the temporary keyfile
    cryptsetup luksRemoveKey /dev/disk/by-partlabel/cryptroot /tmp/keyfile



    ###########
    ### ZFS ###
    ###########

    ## the actual zpool create is below
    #
    # zpool create \
    # -O atime=on \ #
    # -O relatime=on \ # only write access time (requires atime, see man zfs)
    # -O compression=lz4 \ # compress all the things! (man zfs)
    # -O snapdir=visible \ # ever so sligthly easier snap management (man zfs)
    # -O xattr=sa \ # selinux file permissions (man zfs)
    # -o ashift=12 \ # 4k blocks (man zpool)
    # -o altroot=/mnt \ # temp mount during install (man zpool)
    # rpool \ # new name of the pool
    # /dev/mapper/nixroot # devices used in the pool (in my case one, so no mirror or raid)

    zpool create \
    -O atime=on \
    -O relatime=on \
    -O compression=lz4 \
    -O snapdir=visible \
    -O xattr=sa \
    -o ashift=12 \
    -o altroot=/mnt \
    rpool \
    /dev/mapper/nixroot \


    # datasets for root
    zfs create -o mountpoint=none rpool/root
    echo created root dataset
    zfs create -o mountpoint=legacy rpool/root/nixos

    # dataset for home, make copies of all files agains corruption
    zfs create -o copies=2 -o mountpoint=legacy rpool/home

    # dataset for swap
    zfs create -o compression=off -V 8G rpool/swap
    mkswap -L SWAP /dev/zvol/rpool/swap
    swapon /dev/zvol/rpool/swap

    # mount the root dataset at /mnt
    mount -t zfs rpool/root/nixos /mnt

    # mount the home datset at future /home
    mkdir -p /mnt/home
    mount -t zfs rpool/home /mnt/home

    # mount EFI partition at future /boot
    mkdir -p /mnt/boot
    mount /dev/disk/by-partlabel/efiboot /mnt/boot

    # set boot filesystem
    zpool set bootfs=rpool/root/nixos rpool

    nixos-generate-config --root /mnt

    echo "done!"
    echo "old partition table is backed up at ${scriptlocation}/${gptbackup}"
  23. @techhazard techhazard revised this gist Apr 7, 2017. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions configuration.nix
    Original file line number Diff line number Diff line change
    @@ -14,6 +14,6 @@
    ./zfs.nix
    ];

    [rest of the file]
    ...
    #[rest of the file below]
    #...
    }
  24. @techhazard techhazard revised this gist Apr 7, 2017. 4 changed files with 46 additions and 60 deletions.
    65 changes: 6 additions & 59 deletions configuration.nix
    Original file line number Diff line number Diff line change
    @@ -5,68 +5,15 @@
    { config, pkgs, ... }:

    {
    # add zfs for zfs settings
    # add lukskey if using a keyfile for luks
    imports =
    [ # Include the results of the hardware scan.
    ./hardware-configuration.nix
    ./lukskey.nix
    ./zfs.nix
    ];

    # Use the systemd-boot EFI boot loader.
    boot.loader.systemd-boot.enable = true;
    boot.loader.efi.canTouchEfiVariables = true;

    # not sure if nessessary
    boot.supportedFilesystems = [ "zfs" ];

    # networking.hostName = "nixos"; # Define your hostname.
    # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.

    # required by ZFS
    networking.hostId = "dd03c40c";

    # Select internationalisation properties.
    i18n = {
    consoleFont = "Lat2-Terminus16";
    # luckily this also changes the keyboard layout at boot :-)
    consoleKeyMap = "dvorak-programmer";
    defaultLocale = "en_US.UTF-8";
    };

    # Set your time zone.
    # time.timeZone = "Europe/Amsterdam";

    # List packages installed in system profile. To search by name, run:
    # $ nix-env -qaP | grep wget
    environment.systemPackages = with pkgs; [
    tmux
    ];

    # List services that you want to enable:

    # Enable the OpenSSH daemon.
    # services.openssh.enable = true;

    # Enable CUPS to print documents.
    # services.printing.enable = true;

    # Enable the X11 windowing system.
    # services.xserver.enable = true;
    # services.xserver.layout = "us";
    # services.xserver.xkbOptions = "eurosign:e";

    # Enable the KDE Desktop Environment.
    # services.xserver.displayManager.kdm.enable = true;
    # services.xserver.desktopManager.kde4.enable = true;

    users.extraUsers.guest = {
    isNormalUser = true;
    uid = 1000;
    initialHashedPassword = "some hash";
    };
    security.sudo.enable = true;

    users.groups.wheel.members = ["guest"];

    # The NixOS release to be compatible with for stateful data such as databases.
    system.stateVersion = "16.09";

    [rest of the file]
    ...
    }
    2 changes: 1 addition & 1 deletion init.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    ## I always run these command right after booting tht install usb
    ## I always run these command right after booting the install usb

    # I use programmer dvorak instead of qwerty
    loadkeys dvorak-programmer
    15 changes: 15 additions & 0 deletions lukskeyfile.nix
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    # /etc/nixos/lukskeyfile.nix (Don't forget to add it to configuration.nix)
    # The minimal config required for a luksencrypted root with a keyfile
    # You can skip this file if you use a passphrase
    { config, lib, pkgs, ... }:
    {
    # uncomment if you use an usb-stick with a keyfile
    #boot.kernelModules = [ "usb_storage" ];
    boot.extraModulePackages = [ ];

    boot.initrd.luks.devices."nixroot" = {
    keyFile = "/path/to/keyfile";
    keyFileSize = 4096;
    };

    }
    24 changes: 24 additions & 0 deletions zfs.nix
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    # /etc/nixos/zfs.nix (Don't forget to add it to configuration.nix)
    # These are the options ZFS requires, but a normal system has, of course,
    # more options (like a bootloader, or installed software).
    { config, pkgs, ... }:
    {
    # remove this after 1st boot
    # see https://nixos.org/nixos/options.html#boot.zfs.forceimportroot
    boot.kernelParams = ["zfs_force=1"];

    boot.zfs.forceImportRoot = false;
    boot.zfs.forceImportAll = false;

    boot.supportedFilesystems = [ "zfs" ];

    # required by ZFS
    # see https://nixos.org/nixos/options.html#networking.hostid
    networking.hostId = "dd03c40c";

    # this enables the zfs-auto-snapshot
    services.zfs.autoSnapshot = {
    enable = true;
    flags = "-k -p --utc";
    };
    }
  25. @techhazard techhazard revised this gist Apr 7, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion hardware-configuration.nix
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,7 @@
    };

    fileSystems."/boot" =
    { device = "/dev/disk/by-uuid/95D1-E703";
    { device = "/dev/disk/by-uuid/[uuid of efiboot]";
    fsType = "vfat";
    };

  26. @techhazard techhazard revised this gist Apr 7, 2017. 1 changed file with 2 additions and 10 deletions.
    12 changes: 2 additions & 10 deletions hardware-configuration.nix
    Original file line number Diff line number Diff line change
    @@ -9,17 +9,9 @@
    ];

    boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];

    # added `usb_storage` because the keyfile is on an usb
    boot.kernelModules = [ "kvm-intel" "usb_storage" ];
    boot.kernelModules = [ "kvm-intel" ];
    boot.extraModulePackages = [ ];

    boot.initrd.luks.devices."nixroot" =
    { device = "/dev/disk/by-partuuid/[partuuid of cryptroot]";
    keyFile = "/dev/disk/by-partuuid/[partuuid of keyfile]";
    keyFileSize = 4096;
    };

    fileSystems."/" =
    { device = "rpool/root/nixos";
    fsType = "zfs";
    @@ -31,7 +23,7 @@
    };

    fileSystems."/boot" =
    { device = "/dev/disk/by-uuid/[uuid of efiboot]";
    { device = "/dev/disk/by-uuid/95D1-E703";
    fsType = "vfat";
    };

  27. @techhazard techhazard revised this gist Apr 5, 2017. 2 changed files with 4 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion Readme.md
    Original file line number Diff line number Diff line change
    @@ -3,6 +3,8 @@ I used the following resources:
    - https://nixos.org/wiki/ZFS_on_NixOS#How_to_install_NixOS_on_a_ZFS_root_filesystem
    - https://nixos.org/wiki/Encrypted_Root_on_NixOS
    - http://www.pavelkogan.com/2014/05/23/luks-full-disk-encryption/
    - https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF
    - https://github.com/zfsonlinux/zfs/wiki/Ubuntu-16.10-Root-on-ZFS

    I succesfully did the following:
    - Installed nixos on an unencrypted ZFS root filesystem;
    @@ -12,7 +14,7 @@ I succesfully did the following:
    system did not prompt for passphrase and was unable to boot.


    # Victory!!!
    ## Victory!!!
    After some effort (and asking for help on the nix-dev mailing list) I
    installed ZFS on an encrypted partition. The relevant configuration is
    below.
    1 change: 1 addition & 0 deletions init.sh
    Original file line number Diff line number Diff line change
    @@ -11,6 +11,7 @@ sed -i '' -e 's/^}/ boot.supportedFilesystems = ["zfs" "exfat"];\n}/' /etc/nixo
    nixos-rebuild switch

    mkdir ~/mount
    # mount the stick containing zfscreate.sh
    mount /dev/disk/by-id/[some id] ~/mount

    # this would be the point at which I run ~/mount/zfscreate.sh, or do other stuff
  28. @techhazard techhazard revised this gist Apr 5, 2017. No changes.
  29. @techhazard techhazard created this gist Apr 3, 2017.
    26 changes: 26 additions & 0 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    # My attempt at ZFS on LUKS
    I used the following resources:
    - https://nixos.org/wiki/ZFS_on_NixOS#How_to_install_NixOS_on_a_ZFS_root_filesystem
    - https://nixos.org/wiki/Encrypted_Root_on_NixOS
    - http://www.pavelkogan.com/2014/05/23/luks-full-disk-encryption/

    I succesfully did the following:
    - Installed nixos on an unencrypted ZFS root filesystem;
    I only booted it and logged in as root to shut it down.
    - Installed nixos on an encrypted ext4 root filesystem using a keyfile;
    Logged in as root to shut it down; after deleting the keyfile,
    system did not prompt for passphrase and was unable to boot.


    # Victory!!!
    After some effort (and asking for help on the nix-dev mailing list) I
    installed ZFS on an encrypted partition. The relevant configuration is
    below.

    The commands in `init.sh` I run manually, (so no sed :-P)

    The `zfscreate.sh` is used to set up a single-disk ZFS root filesystem inside of an encrypted LUKS container.

    The two `*.nix` files have the minimum config needed for this; The UUIDs should be filled-in by `nixos-generate-config`;
    the `"usb_storage"` addition is not needed for everyone, just like the `keyfile` options; and the other important changes
    are the `hostId`, which is required by ZFS; and the `boot.supportedFilesystems` which I'm not even sure of if that's necessary
    72 changes: 72 additions & 0 deletions configuration.nix
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,72 @@
    # Edit this configuration file to define what should be installed on
    # your system. Help is available in the configuration.nix(5) man page
    # and in the NixOS manual (accessible by running ‘nixos-help’).

    { config, pkgs, ... }:

    {
    imports =
    [ # Include the results of the hardware scan.
    ./hardware-configuration.nix
    ];

    # Use the systemd-boot EFI boot loader.
    boot.loader.systemd-boot.enable = true;
    boot.loader.efi.canTouchEfiVariables = true;

    # not sure if nessessary
    boot.supportedFilesystems = [ "zfs" ];

    # networking.hostName = "nixos"; # Define your hostname.
    # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.

    # required by ZFS
    networking.hostId = "dd03c40c";

    # Select internationalisation properties.
    i18n = {
    consoleFont = "Lat2-Terminus16";
    # luckily this also changes the keyboard layout at boot :-)
    consoleKeyMap = "dvorak-programmer";
    defaultLocale = "en_US.UTF-8";
    };

    # Set your time zone.
    # time.timeZone = "Europe/Amsterdam";

    # List packages installed in system profile. To search by name, run:
    # $ nix-env -qaP | grep wget
    environment.systemPackages = with pkgs; [
    tmux
    ];

    # List services that you want to enable:

    # Enable the OpenSSH daemon.
    # services.openssh.enable = true;

    # Enable CUPS to print documents.
    # services.printing.enable = true;

    # Enable the X11 windowing system.
    # services.xserver.enable = true;
    # services.xserver.layout = "us";
    # services.xserver.xkbOptions = "eurosign:e";

    # Enable the KDE Desktop Environment.
    # services.xserver.displayManager.kdm.enable = true;
    # services.xserver.desktopManager.kde4.enable = true;

    users.extraUsers.guest = {
    isNormalUser = true;
    uid = 1000;
    initialHashedPassword = "some hash";
    };
    security.sudo.enable = true;

    users.groups.wheel.members = ["guest"];

    # The NixOS release to be compatible with for stateful data such as databases.
    system.stateVersion = "16.09";

    }
    43 changes: 43 additions & 0 deletions hardware-configuration.nix
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,43 @@
    # Do not modify this file! It was generated by ‘nixos-generate-config’
    # and may be overwritten by future invocations. Please make changes
    # to /etc/nixos/configuration.nix instead.
    { config, lib, pkgs, ... }:

    {
    imports =
    [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
    ];

    boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];

    # added `usb_storage` because the keyfile is on an usb
    boot.kernelModules = [ "kvm-intel" "usb_storage" ];
    boot.extraModulePackages = [ ];

    boot.initrd.luks.devices."nixroot" =
    { device = "/dev/disk/by-partuuid/[partuuid of cryptroot]";
    keyFile = "/dev/disk/by-partuuid/[partuuid of keyfile]";
    keyFileSize = 4096;
    };

    fileSystems."/" =
    { device = "rpool/root/nixos";
    fsType = "zfs";
    };

    fileSystems."/home" =
    { device = "rpool/home";
    fsType = "zfs";
    };

    fileSystems."/boot" =
    { device = "/dev/disk/by-uuid/[uuid of efiboot]";
    fsType = "vfat";
    };

    swapDevices =
    [ { device = "/dev/zd0"; }
    ];

    nix.maxJobs = lib.mkDefault 4;
    }
    16 changes: 16 additions & 0 deletions init.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,16 @@
    ## I always run these command right after booting tht install usb

    # I use programmer dvorak instead of qwerty
    loadkeys dvorak-programmer

    # I add `boot.supportedFilesystems = ["zfs" "exfat"];` to /etc/nixos/configuration.nix
    # zfs would be obvious, The usb that has e.g. zfscreate.sh runs on exfat
    sed -i '' -e 's/^}/ boot.supportedFilesystems = ["zfs" "exfat"];\n}/' /etc/nixos/configuration.nix;

    # use the new config
    nixos-rebuild switch

    mkdir ~/mount
    mount /dev/disk/by-id/[some id] ~/mount

    # this would be the point at which I run ~/mount/zfscreate.sh, or do other stuff
    224 changes: 224 additions & 0 deletions zfscreate.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,224 @@
    # you only need to set this to the disk to want to install to
    # IT WILL BE WIPED
    # but a backup of the partition table (not the contents) will be made
    rootdisk="/dev/disk/by-id/some_device_id";

    # use keyfile (optional)
    keyfile=;
    keylength="4096";

    # set to "no" to not set a passphrase
    passphrase="yes";



    # No need to change anything below,
    # there be dragons
    # exit on error
    set -e

    # filename of partition backup
    gptbackup="gpt-backup_$(basename ${rootdisk})_$(date +%s)"

    # location to save the partition backup to
    backuplocation="/tmp/${gptbackup}"

    # absolute location for this script
    scriptlocation=$(dirname $(readlink -f $0))



    ##############
    ### Backup ###
    ##############
    # First we make a backup of the current table
    # at /tmp/gpt-backup_{id_of_device}_{current_timestamp}
    #
    # b: create backup
    # $backloc: location to write to
    gdisk ${rootdisk} >/dev/null <<EOF
    b
    ${backuplocation}
    q
    EOF
    # copy the backup next to this script (zfscreate.sh)
    cp "${backuplocation}" "${scriptlocation}"


    ####################
    ### Partitioning ###
    ####################
    # Now we have a backup, we can create
    # a new GPT table
    #
    # o: create new GPT table
    # y: confirm creation
    #
    # with the new partition table,
    # we now create the EFI partition
    #
    # n: create new partion
    # 1: partition number
    # 2048: start position
    # +300M: make it 300MB big
    # ef00: set an EFI partition type
    #
    # With the EFI partition, we
    # use the rest of the disk for LUKS
    #
    # n: create new partition
    # 2: partition number
    # <empty>: start partition right after first
    # <empty>: use all remaining space
    # 8300: set generic linux partition type
    #
    # We only need to set the partition labels
    #
    # c: change partition label
    # 1: partition to label
    # efiboot: name of the partition
    # c: change partition label
    # 2: partition to label
    # cryptroot: name of the partition
    #

    gdisk ${rootdisk} >/dev/null <<EOF
    o
    y
    n
    1
    2048
    +300M
    ef00
    n
    2
    8300
    c
    1
    efiboot
    c
    2
    cryptroot
    p
    w
    y
    EOF


    # check for the newly created partitions
    # this *might* give unrelated errors;
    # if so, change it to `partprobe || true`
    partprobe >/dev/null

    # wait for label to show up
    while [[ ! -e /dev/disk/by-partlabel/efiboot ]];
    do
    sleep 0.3;
    done

    # check if both labels exist
    ls /dev/disk/by-partlabel/efiboot >/dev/null
    ls /dev/disk/by-partlabel/cryptroot >/dev/null


    ## format the EFI partition
    mkfs.vfat /dev/disk/by-partlabel/efiboot



    ############
    ### LUKS ###
    ############

    # temporary keyfile, will be removed
    dd if=/dev/urandom of=/tmp/keyfile bs=1k count=8

    ## now we encrypt the second partition
    # pick a strong passphrase

    echo "Creating the encrypted partition, follow the instructions and use a strong password!"
    cryptsetup luksFormat /dev/disk/by-partlabel/cryptroot --key-size 512 --hash sha512 --key-file /tmp/keyfile

    if [[ $passphrase != "no" ]];
    then
    cryptsetup luksAddKey /dev/disk/by-partlabel/cryptroot --key-file /tmp/keyfile
    fi


    if [[ ! -z "${keyfile}" ]];
    then
    cryptsetup luksAddKey /dev/disk/by-partlabel/cryptroot -d /tmp/keyfile --new-keyfile-size="${keylength}" "${keyfile}"
    echo "added keyfile"
    fi


    # mount the cryptdisk at /dev/mapper/nixroot
    cryptsetup luksOpen /dev/disk/by-partlabel/cryptroot nixroot -d /tmp/keyfile

    # remove the temporary keyfile
    cryptsetup luksRemoveKey /dev/disk/by-partlabel/cryptroot /tmp/keyfile



    ###########
    ### ZFS ###
    ###########

    ## the actual zpool create is below
    #
    # zpool create \
    # -O atime=on \ #
    # -O relatime=on \ # only write access time (requires atime, see man zfs)
    # -O compression=lz4 \ # compress all the things! (man zfs)
    # -O snapdir=visible \ # ever so sligthly easier snap management (man zfs)
    # -O xattr=sa \ # selinux file permissions (man zfs)
    # -o ashift=12 \ # 4k blocks (man zpool)
    # -o altroot=/mnt \ # temp mount during install (man zpool)
    # rpool \ # new name of the pool
    # /dev/mapper/nixroot # devices used in the pool (in my case one, so no mirror or raid)

    zpool create \
    -O atime=on \
    -O relatime=on \
    -O compression=lz4 \
    -O snapdir=visible \
    -O xattr=sa \
    -o ashift=12 \
    -o altroot=/mnt \
    rpool \
    /dev/mapper/nixroot \


    # datasets for root
    zfs create -o mountpoint=none rpool/root
    echo created root dataset
    zfs create -o mountpoint=legacy rpool/root/nixos

    # dataset for home, make copies of all files agains corruption
    zfs create -o copies=2 -o mountpoint=legacy rpool/home

    # dataset for swap
    zfs create -o compression=off -V 8G rpool/swap
    mkswap -L SWAP /dev/zvol/rpool/swap
    swapon /dev/zvol/rpool/swap

    # mount the root dataset at /mnt
    mount -t zfs rpool/root/nixos /mnt

    # mount the home datset at future /home
    mkdir -p /mnt/home
    mount -t zfs rpool/home /mnt/home

    # mount EFI partition at future /boot
    mkdir -p /mnt/boot
    mount /dev/disk/by-partlabel/efiboot /mnt/boot

    # set boot filesystem
    zpool set bootfs=rpool/root/nixos rpool

    nixos-generate-config --root /mnt

    echo "done!"
    echo "old partition table is backed up at ${scriptlocation}/${gptbackup}"