diff --git a/MediaTemple/README.md b/MediaTemple/README.md new file mode 100644 index 0000000..84afa28 --- /dev/null +++ b/MediaTemple/README.md @@ -0,0 +1,168 @@ +# NixOS on Media Temple + +On Media Temple we can install NixOS on Ubuntu servers by using a custom infect script. + +## Add a new server + +1. Click on `Add New Service` and select `Self Managed VPS`. +1. Select appropriate server resources (e.g. 2 CPU, 4GB RAM and 100GB storage) and tick `No control panel`. +1. After order has been processed you will need to finish the installation (selecting Ubuntu + version, setting username and password) + +## Infect Ubuntu 20.04 + +After executing the infect script (`bash infect.sh`) you will need to modify the +`hardware-configuration.nix` file. The script will stop and you will need to do it +manually. You will need to remove all `squashfs` and `vfat` (efi boot) entries. +The automatically generated config will look something like this: + +``` +# 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, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ "ata_piix" "virtio_pci" "virtio_scsi" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/e46da1b8-55a0-4df9-842e-8d80c3a22ffc"; + fsType = "ext4"; + }; + + fileSystems."/snap/snapd/12883" = + { device = "/var/lib/snapd/snaps/snapd_12883.snap"; + fsType = "squashfs"; + options = [ "loop" ]; + }; + + fileSystems."/snap/core20/1081" = + { device = "/var/lib/snapd/snaps/core20_1081.snap"; + fsType = "squashfs"; + options = [ "loop" ]; + }; + + fileSystems."/boot/efi" = + { device = "/dev/disk/by-uuid/7341-10DC"; + fsType = "vfat"; + }; + + fileSystems."/snap/lxd/21545" = + { device = "/var/lib/snapd/snaps/lxd_21545.snap"; + fsType = "squashfs"; + options = [ "loop" ]; + }; + + fileSystems."/snap/snapd/14549" = + { device = "/var/lib/snapd/snaps/snapd_14549.snap"; + fsType = "squashfs"; + options = [ "loop" ]; + }; + + fileSystems."/snap/core20/1270" = + { device = "/var/lib/snapd/snaps/core20_1270.snap"; + fsType = "squashfs"; + options = [ "loop" ]; + }; + + fileSystems."/snap/lxd/21835" = + { device = "/var/lib/snapd/snaps/lxd_21835.snap"; + fsType = "squashfs"; + options = [ "loop" ]; + }; + + swapDevices = [ ]; + +} +``` +It's also recommended to name `fileSystem."/"` device to `/dev/sda3` in case the server +gets relocated (disk UUID will change) and add `nvme` to `boot.initrd.kernelModules`. + +How do I know it's `/dev/sda3` and not e.g. sda1 or sda2? Run `lsblk` and you will see +the correct pact. In our case: + +``` +root@ip:~# lsblk +NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT +loop0 7:0 0 32.3M 1 loop /snap/snapd/12883 +loop1 7:1 0 61.8M 1 loop /snap/core20/1081 +loop2 7:2 0 67.3M 1 loop /snap/lxd/21545 +loop3 7:3 0 43.4M 1 loop /snap/snapd/14549 +loop4 7:4 0 61.9M 1 loop /snap/core20/1270 +loop5 7:5 0 67.2M 1 loop /snap/lxd/21835 +sda 8:0 0 100G 0 disk +├─sda1 8:1 0 4M 0 part +├─sda2 8:2 0 106M 0 part /boot/efi +└─sda3 8:3 0 99.9G 0 part / +``` + +Optional: +- Add a bit of swap. +- Mount `/dev/sda2` partition on `/boot` + +After you remove all the `squashfs` and the efi boot entries you will be left with: + +``` +# 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, modulesPath, ... }: + +{ + imports = [ ]; + + boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" ]; + boot.initrd.kernelModules = [ "nvme" ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/sda3"; + fsType = "ext4"; + }; + + fileSystems."/boot" = + { device = "/dev/sda2"; + fsType = "vfat"; + }; + + swapDevices = [ + { + device = "/swapfile"; + size = 1024; + priority = 0; + } + ]; + +} +``` + +The last few lines of infect output will look something like this: + +``` +perl: warning: Setting locale failed. +perl: warning: Please check that your locale settings: + LANGUAGE = (unset), + LC_ALL = "en_US.UTF-8", + LC_CTYPE = "UTF-8", + LANG = "C.UTF-8" + are supported and installed on your system. +perl: warning: Falling back to a fallback locale ("C.UTF-8"). +updating GRUB 2 menu... +installing the GRUB 2 boot loader on /dev/sda... +Installing for i386-pc platform. +/nix/store/jx1qj6fh98fnifslhllpcaqaia2nhxz5-grub-2.06/sbin/grub-install: warning: cannot open directory `/nix/store/jx1qj6fh98fnifslhllpcaqaia2nhxz5-grub-2.06/share/locale': No such file or directory. +Installation finished. No error reported. +``` + +Verify `/etc/nixos/*.nix` config files and make sure they are correct (especially IPs in +`configuration.nix`). + +After reboot, you should be able to SSH to the server. diff --git a/MediaTemple/configuration.nix b/MediaTemple/configuration.nix new file mode 100644 index 0000000..e3bbb1e --- /dev/null +++ b/MediaTemple/configuration.nix @@ -0,0 +1,40 @@ +{ pkgs, ... }: { + imports = [ + ./hardware-configuration.nix + # Including this by default now to avoid potential problems with missing kernel modules + + ]; + boot.loader.grub.device = "/dev/sda"; + networking.useDHCP = false; + networking.enableIPv6 = false; + networking.interfaces.ens3.useDHCP = false; + networking.defaultGateway = "169.254.0.1"; + networking.nameservers = [ "1.1.1.1" "1.0.0.1" ]; + networking.interfaces.ens3 = { + ipv4.addresses = [ + { address = "1.2.3.4"; prefixLength = 32; } # Primary IP + { address = "1.2.3.5"; prefixLength = 32; } # Secondary IP + ]; + ipv4.routes = [{ + address = "169.254.0.1"; # IP of the gateway + prefixLength = 32; + }]; + }; + + services.openssh = { + enable = true; + permitRootLogin = "prohibit-password"; + passwordAuthentication = false; + }; + + # Set initial root password in case we need to use the rescue console. + # IMPORTANT: change the password! + users.users.root.initialPassword = "secret"; + + # IMPORTANT: replace with your own key(s)! + users.users.root.openssh.authorizedKeys.keys = [ + "ssh-rsa AAAAB3NzaC1yc2EAAAAD..." + ]; + + system.stateVersion = "21.05"; +} diff --git a/MediaTemple/infect.sh b/MediaTemple/infect.sh new file mode 100644 index 0000000..656a732 --- /dev/null +++ b/MediaTemple/infect.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +set -e -o pipefail + +# Add build group and user +groupadd nixbld -g 30000 || true +for i in {1..10}; do + useradd -c "Nix build user $i" -d /var/empty -g nixbld -G nixbld -M -N -r -s "$(which nologin)" "nixbld$i" || true +done + +# Install NixOS +curl -L https://nixos.org/nix/install | sh +. /root/.nix-profile/etc/profile.d/nix.sh +nix-channel --add https://nixos.org/channels/nixos-21.05 nixpkgs +nix-channel --update + +# Install NixOS installation tools, TODO: Make nicer +nix-env -iE "_: with import { configuration = {}; }; with config.system.build; [ nixos-generate-config ]" + +# Set up configurations and install it in a profile +nixos-generate-config +echo "---" +echo "Remove the lxcfs (on Ubuntu 16.04) or squashfs (on Ubuntu 20.04 and 21.04) entry with nano" +sleep 5 +nano /etc/nixos/hardware-configuration.nix +cp configuration.nix /etc/nixos +nix-env -p /nix/var/nix/profiles/system -f '' -I nixos-config=/etc/nixos/configuration.nix -iA system + +# Set NixOS to boot and replace the original distro +touch /etc/NIXOS +cat > /etc/NIXOS_LUSTRATE <