<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Bluish Coder: nixos</title>
 <link href="http://bluishcoder.co.nz/tag/nixos/atom.xml" rel="self"/>
 <link href="http://bluishcoder.co.nz/"/>
 <updated>2018-01-10T15:35:12+13:00</updated>
 <id>http://bluishcoder.co.nz/</id>
 <author>
   <name>Bluishcoder</name>
   <email>admin@bluishcoder.co.nz</email>
 </author>

 
 <entry>
   <title>Installing NixOS on Linode with Encrypted Partitions</title>
   <link href="http://bluishcoder.co.nz/2014/10/22/install-nixos-on-linode-with-encrypted-root.html"/>
   <updated>2014-10-22T21:00:00+13:00</updated>
   <id>http://bluishcoder.co.nz/2014/10/22/install-nixos-on-linode-with-encrypted-root</id>
   <content type="html">&lt;p&gt;A while back I updated the instructions to &lt;a href=&quot;https://nixos.org/wiki/Install_NixOS_on_Linode&quot;&gt;install NixOS on Linode&lt;/a&gt; on the NixOS Wiki. This post adds to this to include encrypted partitions. It&#39;s based on those wiki instructions and my previous post on &lt;a href=&quot;http://bluishcoder.co.nz/2014/05/14/installing-nixos-with-encrypted-root-on-thinkpad-w540.html&quot;&gt;installing NixOS to an encrypted drive&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Some points to keep in mind when running a Linode with an encrypted drive are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you reboot you will need to access the Linode console to enter the password to mount the encrypted partition.&lt;/li&gt;
&lt;li&gt;Because the server is located remotely it&#39;s possible for Linode or a party in a similar position to trap the console input to capture your password. So while encryption prevents a malicious admin from scanning your disks it won&#39;t prevent someone located at Linode from rebooting and capturing the password you enter.&lt;/li&gt;
&lt;li&gt;I&#39;m sure there are other weaknesses such as keys existing in memory while the Linode is running. Make sure you are ok with the attack points in this setup.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Boot a Linode into Rescue Mode&lt;/h2&gt;

&lt;p&gt;First step is to create the Linode as usual. I tested with a $20/month Linode 2048. Create two disk images. They should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A boot disk that will be unencrypted. I made this 1GB which is way oversized for what it needs to be but makes math easy.&lt;/li&gt;
&lt;li&gt;A root disk that will be encrypted. I made this the remainder of my free disk space.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;From the Linode manager choose the option to boot into the new Linode in Rescue mode. Make sure the disks are setup as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/dev/xvda&lt;/code&gt; is the boot disk.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/dev/xvdb&lt;/code&gt; is the root disk.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;When the recovery image is booted you can &lt;code&gt;ssh&lt;/code&gt; into it with the instructions in the &lt;code&gt;Remote Access&lt;/code&gt; tab of the Linode manager under &lt;code&gt;Console Access&lt;/code&gt;. This will get you to a root prompt on the Linode to perform the rest of the steps.&lt;/p&gt;

&lt;h2&gt;Encryption Setup&lt;/h2&gt;

&lt;p&gt;Perform the following commands to setup the disk encryption:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# cryptsetup luksFormat /dev/xvdb
# cryptsetup luksOpen /dev/xvdb enc-pv
# pvcreate /dev/mapper/enc-pv
# vgcreate vg /dev/mapper/enc-pv
# lvcreate -L 1G -n swap vg
# lvcreate -l 11525 -n root vg
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that these operate on the &lt;code&gt;/dev/xvdb&lt;/code&gt; disk which is the root disk we created earlier. You will be prompted for a passphrase during the &lt;code&gt;luksFormat&lt;/code&gt; and &lt;code&gt;luksOpen&lt;/code&gt; commands. Make sure you remember this as this is the passphrase needed when rebooting.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;lvcreate&lt;/code&gt; lines create the partitions for swap and root partition. The &lt;code&gt;1G&lt;/code&gt; means a one gigabyte swap file. The &lt;code&gt;11525&lt;/code&gt; is the extent for the remainder of the disk space. I found this number by initally running &lt;code&gt;lvcreate -L 99G -n root vg&lt;/code&gt; which is bigger than the 40GB available on the linode. This gave an error message showing the maximum extent to use which was &lt;code&gt;11525&lt;/code&gt; for me.&lt;/p&gt;

&lt;h2&gt;Formatting and Mounting&lt;/h2&gt;

&lt;p&gt;Format the new partitions with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# mkfs.ext4 -L boot /dev/xvda
# mkfs.ext4 -O dir_index -j -L root /dev/vg/root
# mkswap -L swap /dev/vg/swap
# swapon /dev/vg/swap
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To install NixOS we need to mount the partitions under &lt;code&gt;/mnt&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# mount /dev/vg/root /mnt
# mkdir /mnt/boot
# mount /dev/xvda /mnt/boot
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Installing NixOS&lt;/h2&gt;

&lt;p&gt;The installation is relatively simple. First install the &lt;code&gt;Nix&lt;/code&gt; package manager:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# bash &amp;lt;(curl https://nixos.org/nix/install)
# . /root/.nix-profile/etc/profile.d/nix.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Set the channel to be NixOS:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# nix-channel --remove nixpkgs
# nix-channel --add http://nixos.org/channels/nixos-14.04 nixos
# nix-channel --update
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create a default configuration file for some NixOS packages we will need for the install later:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# cat &amp;lt;&amp;lt;EOF &amp;gt; configuration.nix
  { fileSystems.&quot;/&quot; = {};
    boot.loader.grub.enable = false;
  }
  EOF
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Install the NixOS installation software:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# export NIX_PATH=nixpkgs=/root/.nix-defexpr/channels/nixos:nixos=/root/.nix-defexpr/channels/nixos/nixos
# export NIXOS_CONFIG=/root/configuration.nix
# nix-env -i -A config.system.build.nixos-install \
             -A config.system.build.nixos-option \
             -A config.system.build.nixos-generate-config \
             -f &quot;&amp;lt;nixos&amp;gt;&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Generate a default configuration file for the bootable system:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# nixos-generate-config --root /mnt
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This creates a &lt;code&gt;/mnt/etc/nixos/configuration.nix&lt;/code&gt; file which should be edited to install the software you want. It also requires some changes for Grub and the disk encryption. Replace the existing section related to Grub 2 in this file with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Use the GRUB 1 boot loader.
boot.loader.grub = {
 enable = true;
 version = 1;
 extraPerEntryConfig = &quot;root (hd0)&quot;;
 device = &quot;nodev&quot;;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For the encryption support add:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;boot.initrd.luks.devices = [
  { name = &quot;root&quot;; device = &quot;/dev/xvdb&quot;; preLVM = true; }
];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To enable OpenSSH access to the Linode add:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;services.openssh.enable = true;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now run the install:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# nixos-install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will take some time to download and install things.&lt;/p&gt;

&lt;h2&gt;Post install&lt;/h2&gt;

&lt;p&gt;Once &lt;code&gt;nixos-install&lt;/code&gt; completes the following commands will need to be run to fixup Grub 1 usage on Linode. This must be done before rebooting:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# mkdir -p /mnt/boot/boot/grub
# cd /mnt/boot/boot/grub
# ln -sv ../../grub/menu.lst /mnt/boot/boot/grub
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;First boot&lt;/h2&gt;

&lt;p&gt;Create a new Configuration Profile in the Linode Manager for the Linode. Set the kernel to &lt;code&gt;pv-grub-x86_64&lt;/code&gt;. Set the disks as they were setup in the Rescue boot. Everything else can be left at the default.&lt;/p&gt;

&lt;p&gt;Boot the new Configuration. Now you will need to &lt;code&gt;ssh&lt;/code&gt; back into the Linode console so you can enter your passphrase. This will continue the booting process. Login as &lt;code&gt;root&lt;/code&gt;. There is no initial password. Set one:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# passwd
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By default you won&#39;t be able to &lt;code&gt;ssh&lt;/code&gt; as &lt;code&gt;root&lt;/code&gt; so you should set up a normal user:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# useadd -m myuser
# passwd myuser
# usermod -a -G wheel myuser
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The latter command lets you use &lt;code&gt;sudo&lt;/code&gt; as that user. You should now be able to &lt;code&gt;ssh&lt;/code&gt; into the Linode with the newly created user.&lt;/p&gt;

&lt;h2&gt;Customization&lt;/h2&gt;

&lt;p&gt;These steps install the stable version of NixOS. This does not receive new packages, only updates to existing ones. I like to live on the bleeding edge so I use &lt;code&gt;nixos-unstable&lt;/code&gt;. You can switch to this by running the following as &lt;code&gt;root&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# nix-channel --add http://nixos.org/channels/nixos-unstable nixos
# nixos-rebuild switch --upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you prefer &lt;code&gt;vim&lt;/code&gt; to &lt;code&gt;nano&lt;/code&gt; as an editor, add the following to &lt;code&gt;/etc/nixos/configuration.nix&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;environment.systemPackages = with pkgs; [
  vim
];

environment.variables.EDITOR = pkgs.lib.mkOverride 0 &quot;vim&quot;;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you need non-free packages, add:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nixpkgs.config.allowUnfree = true;
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Firefox Development on NixOS</title>
   <link href="http://bluishcoder.co.nz/2014/05/15/firefox-development-on-nixos.html"/>
   <updated>2014-05-15T19:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2014/05/15/firefox-development-on-nixos</id>
   <content type="html">&lt;p&gt;Now that I&#39;ve &lt;a href=&quot;http://bluishcoder.co.nz/2014/05/14/installing-nixos-with-encrypted-root-on-thinkpad-w540.html&quot;&gt;got NixOS installed&lt;/a&gt; I needed a way to build and make changes to Firefox and Firefox OS. This post goes through the approach I&#39;ve taken to work on the Firefox codebase. In a later post I&#39;ll build on this to do Firefox OS development.&lt;/p&gt;

&lt;p&gt;Building Firefox isn&#39;t difficult as NixOS has definitions for standard Firefox builds to follow as examples. To build from a local source repository it requires all the pre-requisite packages to be installed. I don&#39;t want to pollute my local user environment with all these packages though as I develop on other things which may have version clashes. As an example, Firefox requires &lt;code&gt;autoconf-2.13&lt;/code&gt; whereas other systems I develop with require different verisons.&lt;/p&gt;

&lt;p&gt;NixOS (through the Nix package manager) allows setting up build environments that contain specific packages and versions. Switching between these is easy. The file &lt;code&gt;~/.nixpkgs/config.nix&lt;/code&gt; can contain definitions specific for a user. I add the definitions as a &lt;code&gt;packageOverride&lt;/code&gt; in this file. The structure of the file looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  packageOverrides = pkgs : with pkgs; rec {
    ..new definitions here..
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;My definition for a build environment for Firefox is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;firefoxEnv = pkgs.myEnvFun {
  name = &quot;firefoxEnv&quot;;
  buildInputs = [ stdenv pkgconfig gtk glib gobjectIntrospection
                  dbus_libs dbus_glib alsaLib gcc xlibs.libXrender
                  xlibs.libX11 xlibs.libXext xlibs.libXft xlibs.libXt
                  ats pango freetype fontconfig gdk_pixbuf cairo python
                  git autoconf213 unzip zip yasm alsaLib dbus_libs which atk
                  gstreamer gst_plugins_base pulseaudio
                ];

  extraCmds = &#39;&#39;
   export C_INCLUDE_PATH=${dbus_libs}/include/dbus-1.0:${dbus_libs}/lib/dbus-1.0/include
   export CPLUS_INCLUDE_PATH=${dbus_libs}/include/dbus-1.0:${dbus_libs}/lib/dbus-1.0/include
   LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:${gcc.gcc}/lib64
   for i in $nativeBuildInputs; do
     LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:\$i/lib
   done
   export LD_LIBRARY_PATH
   export AUTOCONF=autoconf
  &#39;&#39;;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The Nix function &lt;code&gt;pkgs.myEnvFun&lt;/code&gt; creates a program that can be run by the user to set up the environment such that the listed packages are available. This is done using symlinks and environment variables. The resulting shell can then be used for normal development. By creating special environments for development tasks it becomes possible to build with different versions of packages. For example, replace &lt;code&gt;gcc&lt;/code&gt; with &lt;code&gt;gcc46&lt;/code&gt; and the environment will use that C compiler version. Environments for different versions of pango, gstreamer and other libraries can easily be created for testing Firefox builds with those specific versions.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;buildInputs&lt;/code&gt; field contains an array of the packages to be avaliable. These are all the pre-requisites &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Linux_Prerequisites&quot;&gt;as listed in the Mozilla build documentation&lt;/a&gt;. This could be modified by adding  developer tools to be used (Vim, Emacs, Mercurial, etc) if desired.&lt;/p&gt;

&lt;p&gt;When creating definitions that have a build product Nix will arrange the dynamic loader and paths to link to the correct versions of the libraries so that they can be found at runtime. When building an environment we need to change &lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt; to include the paths to the libraries for all the packages we are using. This is what the &lt;code&gt;extraCmds&lt;/code&gt; section does. It is a shell script that is run to setup additional things for the environment.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;extraCmds&lt;/code&gt; in this definition adds to &lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt; the &lt;code&gt;lib&lt;/code&gt; directory of all the packages in &lt;code&gt;buildInputs&lt;/code&gt;. It exports an &lt;code&gt;AUTOCONF&lt;/code&gt; environment variable to be the &lt;code&gt;autoconf&lt;/code&gt; executable we are using. This variable is used in the Mozilla build system to find &lt;code&gt;autoconf-2.13&lt;/code&gt;. It also adds to the C and C++ include path to find the DBus libraries which are in a nested &lt;code&gt;dbus-1.0&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;To build and install this new package use &lt;code&gt;nix-env&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ nix-env -i env-firefoxEnv
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Running the resulting &lt;code&gt;load-env-firefoxEnv&lt;/code&gt; command will create a shell environment that can be used to build Firefox:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ load-env-firefoxEnv
...
env-firefoxEnv loaded
$ git clone git://github.com/mozilla/gecko-dev
...
$ cd gecko-dev
$ ./mach build
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Exiting the shell will remove access to the pre-requisite libraries and tools needed to build Firefox. This keeps your global user environment free and minimizes the chance of clashes.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Installing NixOS on a ThinkPad W540 with encrypted root</title>
   <link href="http://bluishcoder.co.nz/2014/05/14/installing-nixos-with-encrypted-root-on-thinkpad-w540.html"/>
   <updated>2014-05-14T12:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2014/05/14/installing-nixos-with-encrypted-root-on-thinkpad-w540</id>
   <content type="html">&lt;p&gt;I recently got a ThinkPad W540 laptop and I&#39;m trying out the &lt;a href=&quot;https://nixos.org/nixos/&quot;&gt;NixOS&lt;/a&gt; Linux distribution:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;NixOS is a GNU/Linux distribution that aims to improve the state of the art in system configuration management. In existing distributions, actions such as upgrades are dangerous: upgrading a package can cause other packages to break, upgrading an entire system is much less reliable than reinstalling from scratch, you can&#39;t safely test what the results of a configuration change will be, you cannot easily undo changes to the system, and so on.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;I use the &lt;a href=&quot;https://nixos.org/nix/&quot;&gt;Nix package manager&lt;/a&gt; alongside other distributions and decided to try out the full operating system. This post outlines the steps I took to install NixOS with full disk encryption using LVM on LUKS.&lt;/p&gt;

&lt;h2&gt;Windows&lt;/h2&gt;

&lt;p&gt;The W540 comes with Windows 8.1 pre-installed and recovery partitions to enable rebuilding the system. I followed the install procedure to get Windows working and proceeding to make a &lt;a href=&quot;http://support.lenovo.com/en_US/downloads/detail.page?DocID=HT076024&quot;&gt;recovery USB drive&lt;/a&gt; so I could get back to the starting state if things went wrong. Once this completed I went on with installing NixOS.&lt;/p&gt;

&lt;h2&gt;NixOS Live CD&lt;/h2&gt;

&lt;p&gt;I used the &lt;a href=&quot;http://nixos.org/nixos/download.html&quot;&gt;NixOS Graphical Live CD&lt;/a&gt; to install. I could have used the minimal CD but I went fo the graphical option to make sure the basic OS worked fine on the hardware. I installed the Live CD to a USB stick from another Linux machine using &lt;a href=&quot;http://unetbootin.sourceforge.net/&quot;&gt;unetbootin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To boot from this I had to change the W540 BIOS settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change the USB drive in the boot sequence so it was the first boot option.&lt;/li&gt;
&lt;li&gt;Disable Secure Boot.&lt;/li&gt;
&lt;li&gt;Change UEFI to be UEFI/Legacy Bios from the previous UEFI only setting.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Booting from the USB drive on the W540 worked fine and got me to a login prompt. Logging in with &lt;code&gt;root&lt;/code&gt; and no password gives a root shell. Installation can proceed from there or the GUI can be started with &lt;code&gt;start display-manager&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Networking&lt;/h2&gt;

&lt;p&gt;The installation process requires a connected network. I used a wireless network. This is configured in the Live CD using &lt;a href=&quot;http://hostap.epitest.fi/wpa_supplicant/&quot;&gt;wpa_supplicant&lt;/a&gt;. This required editing &lt;code&gt;/etc/wpa_supplicant.conf&lt;/code&gt; to contain the settings for the network I was connecting to. For a public nework it was something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;network={
  ssid=&quot;My Network&quot;
  key_mgmt=NONE
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;wpa_supplicant&lt;/code&gt; service needs to be restarted after this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# systemctl restart wpa_supplicant.service
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&#39;s important to get the syntax of the &lt;code&gt;wpa_supplicant.conf&lt;/code&gt; file correct otherwise it will fail to restart with no visible error.&lt;/p&gt;

&lt;h2&gt;Partition the disk&lt;/h2&gt;

&lt;p&gt;Partitioning is done manually using &lt;a href=&quot;http://www.rodsbooks.com/gdisk/&quot;&gt;gdisk&lt;/a&gt;. Three partitions are needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A small partition to hold GPT information and provide a place for GRUB to store data. I made this 1MB in size and it must have a partition type of &lt;code&gt;ef02&lt;/code&gt;. This was &lt;code&gt;/dev/sda1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;An unencrypted boot partition used to start the initial boot, and load the encrypted partition. I made this 1GB in size (which is on the large side for what it needs to be) and left it at the partition type &lt;code&gt;8300&lt;/code&gt;. This was &lt;code&gt;/dev/sda2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The full disk encrypted partition. This was set to the size of the rest of the drive and partition type set to &lt;code&gt;8e00&lt;/code&gt; for &quot;Linux LVM&quot;. This was &lt;code&gt;/dev/sda3&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Create encrypted partitions&lt;/h2&gt;

&lt;p&gt;Once the disk is partitioned above we need to encrypt the main root partition and use LVM to create logical partitions within it for swap and root:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# cryptsetup luksFormat /dev/sda3
# cryptsetup luksOpen /dev/sda3 enc-pv
# pvcreate /dev/mapper/enc-pv
# vgcreate vg /dev/mapper/enc-pv
# lvcreate -L 40G -n swap vg
# lvcreate -l 111591 -n root vg
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;lvcreate&lt;/code&gt; commands create the logical partitions. The first is a 40GB swap drive. The laptop has 32GB of memory so I set this to be enough to store all of memory when hibernating plus extra. It could be made quite a bit smaller. The second creates the root partition. I use the &lt;code&gt;-l&lt;/code&gt; switch there to set the exact number of extents for the size. I got this number by trying a &lt;code&gt;-L&lt;/code&gt; with a larger size than the drive and used the number in the resulting error message.&lt;/p&gt;

&lt;h2&gt;Format partitions&lt;/h2&gt;

&lt;p&gt;The unencrypted boot partition is formatted with &lt;code&gt;ext2&lt;/code&gt; and the root partition with &lt;code&gt;ext4&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# mkfs.ext2 -L boot /dev/sda2
# mkfs.ext4 -O dir_index -j -L root /dev/vg/root
# mkswap -L swap /dev/vg/swap
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These should be mounted for the install process as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# mount /dev/bg/root /mnt
# mkdir /mnt/boot
# mount /dev/sda2 /mnt/boot
# swapon /dev/vg/swap
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Configure NixOS&lt;/h2&gt;

&lt;p&gt;NixOS uses a declarative language for the configuration file that is used to install and configure the operating system. An initial file ready to be edited should be created with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ nixos-generate-config --root /mnt
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This creates the following files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/mnt/etc/nixos/configuration.nix&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/mnt/etc/nixos/hardware-configuration.nix&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The latter file is rewritten everytime this command is run. The first file can be edited and is never rewritten. For the initial boot I had to make one change to &lt;code&gt;hardware-configuration.nix&lt;/code&gt;. I commented out this line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# services.xserver.videoDrivers = [ &quot;nvidia&quot; ];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I can re-add it later when configuring the X server if I want to use the &lt;code&gt;nvidia&lt;/code&gt; driver.&lt;/p&gt;

&lt;p&gt;The changes that need to be made to &lt;code&gt;configuration.nix&lt;/code&gt; involve setting the GRUB partition, the Luks data and any additional packages to be installed. The Luks settings I added were:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;boot.initrd.luks.devices = [
  { 
    name = &quot;root&quot;; device = &quot;/dev/sda3&quot;; preLVM = true;
  }
];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I changed the GRUB boot loader device to be:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;boot.loader.grub.device = &quot;/dev/sda&quot;;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To enable wireless I made sure I had:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;networking.wireless.enable = true;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I added my preferred editor, vim, to the system packages:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;environment.systemPackages = with pkgs; [
  vim
];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Enable OpenSSH:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;services.openssh.enable = true;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I&#39;ve left configuring X and other things for later.&lt;/p&gt;

&lt;h2&gt;Install NixOS&lt;/h2&gt;

&lt;p&gt;To install based on the configuration made above:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# nixos-install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If that completes successfully the system can be rebooted into the newly installed NixOS:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You&#39;ll need to enter the encryption password that was created during &lt;code&gt;cryptsetup&lt;/code&gt; when rebooting.&lt;/p&gt;

&lt;h2&gt;Completing installation&lt;/h2&gt;

&lt;p&gt;Once rebooted re-enable the network by performing the &lt;code&gt;/etc/wpa_supplicant.conf&lt;/code&gt; steps done during the install.&lt;/p&gt;

&lt;p&gt;Installation of additional packages can continue following the &lt;a href=&quot;http://nixos.org/nixos/manual/&quot;&gt;NixOS manual&lt;/a&gt;. This mostly involves adding or changing settings in &lt;code&gt;/etc/nixos/configuration.nix&lt;/code&gt; and then running:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# nixos-rebuild switch
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is outlined in &lt;a href=&quot;http://nixos.org/nixos/manual/#sec-changing-config&quot;&gt;Changing the Configuration&lt;/a&gt; in the manual.&lt;/p&gt;

&lt;h2&gt;Troubleshooting&lt;/h2&gt;

&lt;p&gt;The most common errors I made were syntax errors in &lt;code&gt;wpa_supplicant.conf&lt;/code&gt; and &lt;code&gt;configuration.nix&lt;/code&gt;. The other issue I had was not creating the initial GPT partition. GRUB will give an error in this case explaining the issue. You can reboot the Live USB drive at any time and mount the encrypted drives to edit files if needed. The commands to mount the drives are:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# cryptsetup luksOpen /dev/sda3 enc-pv
# vgscan --mknodes
# vgchange -ay
# mount /dev/bg/root /mnt
# mkdir /mnt/boot
# mount /dev/sda2 /mnt/boot
# swapon /dev/vg/swap
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Tips&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;environment.systemPackages&lt;/code&gt; in &lt;code&gt;/etc/configuration.nix&lt;/code&gt; is where you add packages that are seen by all users. When this is changed you need to run the following for it to take effect:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# nixos-rebuild switch
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To find the package name to use, run something like (for vim):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ nix-env -qaP &#39;*&#39;|grep vim
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A user can add their own packages using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ nix-env -i vim
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And remove with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ nix-env -e vim
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A useful GUI for connecting to wireless networks is &lt;code&gt;wpa_gui&lt;/code&gt;. To enable this add &lt;code&gt;wpa_supplicant_gui&lt;/code&gt; to &lt;code&gt;environment.systemPackages&lt;/code&gt; in &lt;code&gt;/etc/nixos/configuration.nix&lt;/code&gt; followed by a &lt;code&gt;nixos-rebuild switch&lt;/code&gt;. Add the following line to &lt;code&gt;/etc/wpa_supplicant.conf&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ctrl_interface=/var/run/wpa_supplicant
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Restart &lt;code&gt;wpa_supplicant&lt;/code&gt; and run the gui:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ systemctl restart wpa_supplicant.service
$ sudo wpa_gui
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&#39;s possible to make custom changes to Nix packages for each user. This is controlled by adding definitions to &lt;code&gt;~/.nixpkgs/config.nix&lt;/code&gt;. The following &lt;code&gt;config.nix&lt;/code&gt; will provide Firefox with the official branding:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  packageOverrides = pkgs : with pkgs; rec {
    firefoxPkgs = pkgs.firefoxPkgs.override { enableOfficialBranding = true; };
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Installing or re-installing for the user will use this version of Firefox:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ nix-env -i firefox
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 
</feed>
