Personal Salt Setup Documentation Release 0

Kyle Isom

Apr 10, 2017

Contents

1 Background and Motivation 3

2 Introduction 5 2.1 Current machines...... 5

3 The states 7 3.1 Custom modules...... 8

4 State: devel 9 4.1 State: devel.go...... 9 4.2 State: devel.rust...... 9 4.3 State: devel.haskell...... 10 4.4 State: devel.python...... 10 4.5 State: devel.hashicorp...... 10 4.6 State: devel....... 10 4.7 State: devel.quicklisp...... 10

5 State: docker 11

6 State: iptables 13

7 State: keys 15

8 State: laptop 17 8.1 State: laptop.logind...... 17 8.2 State: laptop.keyboard...... 18 8.3 State: laptop.mail...... 18 8.4 State: laptop.network...... 18 8.5 State: laptop.redshift...... 18 8.6 State: laptop.xorg...... 18

9 State: packages 19 9.1 State: packages.apparmor...... 19 9.2 State: packages.audio...... 19 9.3 State: packages.chrome...... 19 9.4 State: packages.common...... 19 9.5 State: packages.devel...... 19 9.6 State: packages.dropbox...... 20

i 9.7 State: packages.embedded...... 20 9.8 State: packages.laptop...... 20 9.9 State: packages.repo...... 20 9.10 State: packages.spotify...... 20 9.11 State: packages.stumpwm...... 20 9.12 State: packages.xorg...... 20

10 State: ssh 21

11 State: sync 23 11.1 State: sync.dropbox...... 23 11.2 State: sync.syncthing...... 23

12 State: systemd 25

13 State: usbarmoury 27

14 State: users 29 14.1 State: users.kyle...... 29 14.2 State: users....... 29

15 Packages 31 15.1 Package list...... 31 15.2 Directly downloaded...... 37

16 Documentation Overview 39

17 Indices and tables 41

ii Personal Salt Setup Documentation, Release 0

Contents:

Contents 1 Personal Salt Setup Documentation, Release 0

2 Contents CHAPTER 1

Background and Motivation

This project was motivated by getting a new T460s at work to replace the previous T440s. I’ve had to set up this machine from scratch a few times: 1. When I first got it (May 2014ish) 2. When a work tool hosed my system (July 2014ish) 3. When I switched from Ubuntu 14.04 to Jessie (after seeing xscreensaver segfault and having a lot of problems with Ubuntu) The first install wasn’t so bad, because I didn’t have much to deal with. The other two were multi-day ordeals, mostly because I kept forgetting what needed to be done to set up the laptop; several times I had to deep dive into browser history, or dig through pinboard links, or otherwise try to recreate search history to figure a few things out. Also, the bump from Debian Jessie to Debian Testing (to get a grsec kernel) took a day of handholding. When I got the T460s, I’d wanted to find a way to have a fairly specific, light core system (.f. this README). This effort took entirely too long and didn’t pan out, so I caved in and went with an Ubuntu Xenial install. However, to prevent losing several days worth of time to setting up a new laptop, I started working on a bootstrap project. The bootstrap process is this: 1. Install a new copy of Ubuntu server and reboot into the new installation. • This will set up the user and disk encryption, and is a fairly easy to acquire install media, unlike the case where I have a custom distribution. 2. Insert the bootstrap media (currently a LUKS-encrypted SD card). 3. Unpack a bare-minimum backup tarball to $HOME. • This backup is the absolute minimum needed by Salt and to start being productive before the full backup is done. For example, on the work machine, this is my work SSH key, VPN key, and the repos I work on actively or need for work (such as a Vagrant setup). 4. Go to the salt directory (which is a copy of this repo) and run the bootstrap script. A highstate can take 30-90 minutes, depending on network speeds. 5. Restore the full backup.

3 Personal Salt Setup Documentation, Release 0

While using Salt is a time saver (it’s automated work that I don’t have to do), the biggest benefit for me is that it gets my laptop into a known state. When I make changes, I effect them with Salt: I’ll edit/write the relevant state, apply the state, then run a high state. There’s a history too, which provides some background on how my laptop setup has changed. I’d also argue it’s more useful the less often you set up a new machine, as you don’t have to dig deep into your memory or notes to get it right. The idea is that if I make a change to my laptop, and then end up doing a reinstall, that change should live on.

4 Chapter 1. Background and Motivation CHAPTER 2

Introduction

The state selection is decided entirely on the roles list grain in the minion config. For example,

~ [2016-08-10T09:30:05 PDT] (0) $ sudo salt-call --local grains.get roles [sudo] password for kyle: [INFO ] Determining pillar cache local: - laptop - container - cloudflare - devel

The roles that are used right now are: • container: machines that should have Docker installed. • devel: machines that are used for software development. • cloudflare: machines that are used at work. • headless: machine is a VM. This also assumes that this is occurring on a laptop or other single-user machine, as it sets up certain services to run as me. For a list of all the specific places this is done, ag kyle (or grep -HRn kyle *).

Current machines

• straka: work ThinkPad T460s • madison: home ThinkPad X220 • snotra: development and systems management VM

5 Personal Salt Setup Documentation, Release 0

6 Chapter 2. Introduction CHAPTER 3

The states

At a glance, the states are currently organised under the following top-level states: • devel • docker • iptables • keys • laptop • packages • ssh • sync • systemd • usbarmoury • users For a work laptop, the states generally work something like: • set up my user (and make sure there’s no default , e.g. for VMs / Vagrant images) • install common packages • set up the firewall • configure some laptop-specific things • set up the SSH server • set up development environment • set up docker • install whatever tools I need for work that aren’t covered above

7 Personal Salt Setup Documentation, Release 0

My home laptop follows up through the last step; and a headless install is generally the same as either of those (depending on whether it’s being used in a work or home role) minus some things.

Custom modules debremote debremote is a custom Salt state module that I wrote. It allows for remotely fetching a . file and comparing it against a SHA-256 digest (the pkg.installed source-install will let you install from a .deb, but it won’t let you check it against a digest). It will install the package only if it isn’t present or the remote version is greater than the installed version. Hashicorp doesn’t have an apt repo, but Vagrant is provided as a deb file: vagrant: debremote.installed: - name: vagrant - version: {{ salt['pillar.get']('devel:hashicorp:vagrant:version') }} - digest: {{ salt['pillar.get']('devel:hashicorp:vagrant:hash') }} - source: {{ salt['pillar.get']('devel:hashicorp:vagrant:source') }}

8 Chapter 3. The states CHAPTER 4

State: devel

The devel state is broken down into a number of sub-states: • packages.devel will install a set of packages that are useful in my development environment. This state is documented in the packages state docs. • devel.go sets up a Go environment. • devel.rust sets up a Rust toolchain. • devel.haskell sets up a Go environment. • devel.python sets up a Go environment. • packages.embedded installs embedded development tools; this is deselected for machines with the cloudflare role, unfortunately. • devel.hashicorp installs some Hashicorp tools. • devel.apt installs • devel.quicklisp sets up a Go environment.

State: devel.go

This is a fairly simple state; it just ensures the go package is installed. However, it will pull this package from my personal package repo, because the upstream repos are usually out of date. To do this, I use godeb to create a package. Commented out, but retained in the state file in the event that the godeb route becomes untenable in the future, is an alternate method that downloads directly from Google.

State: devel.rust

If $HOME/.multirust doesn’t exist, this will call the rustup script. The entirety of the security from this relies on the TLS cert, but c’est la vie. I’d like to find a better way to do this, but I don’t have one yet.

9 Personal Salt Setup Documentation, Release 0

The state will also make sure that I (e.g. not root) own the multirust directory.

State: devel.haskell

The FPComplete repo is added to get the Haskell stack tool. The state also makes sure GHC and cabal are installed.

State: devel.python

Both Python 2 and Python 3 are installed by this state; as well as IPython, SciPy, NumPy, virtualenv, Sphinx, some linting tools, requests, and some GnuPG packages. For the most part, both the Python 2 and Python 3 versions are installed, except where the Python 3 version isn’t available.

State: devel.hashicorp

This installs some Hashicorp tooling that’s useful for infrastructure management with any plugins that are needed to support a virtualbox testing environment. Currently, those tools are packer for building images, terraform for managing my infrastructure, and vagrant for setting up test VMs.

State: devel.apt

This state ensures the tools for managing my apt server are available. Reprepro is what I’ve been using to manage the repo, and the debian packaging build tools are also included. The state also includes aptly, as I’ve been looking into switching over to aptly.

State: devel.quicklisp

As a precursor to StumpWM and also generally getting things done, SBCL and Quicklisp need to be installed. Fortu- nately, this is doable by installing SBCL and the cl-quicklisp package. The latter installs the quicklisp bootstrap program, which is this fed into SBCL with a few ‘‘–eval‘‘s. The state makes sure that I own the Quicklisp directory and that I have an SBCL dotfile that autoloads Quicklisp.

10 Chapter 4. State: devel CHAPTER 5

State: docker

Docker is a top-level module that installs the docker toolchain: docker-engine, docker-compose, and docker-machine. The first two are installed via the Docker apt repo (which is managed by Salt), and the latter is installed via the Github releases. docker-machine will download to /usr/bin/docker-machine-VERSION with a symlink to /usr/bin/docker-machine. The signing key for the apt repo is in the states/keys/ directory.

11 Personal Salt Setup Documentation, Release 0

12 Chapter 5. State: docker CHAPTER 6

State: iptables

The firewall configuration for all personal machines has three components: 1. The SSH port is opened. SSH access is public-key only. 2. Docker support. 3. USB armoury support: this sets up a NAT forwarding from usb0 to the two outbound connections. The iptables-persistent package restores these rules, and a systemd oneshot service is provided to make sure this happens on boot. IPv6 support isn’t enabled yet.

13 Personal Salt Setup Documentation, Release 0

14 Chapter 6. State: iptables CHAPTER 7

State: keys

Right now, this is a sort of .PHONY state: it only contains public keys (e.g. for package repos). Current public keys: • docker • my apt signing key • syncthing

15 Personal Salt Setup Documentation, Release 0

16 Chapter 7. State: keys CHAPTER 8

State: laptop

If the machine isn’t headless, the following states are applied: • laptop.logind • laptop.network • laptop.mail • packages.xorg • laptop.xorg • laptop.redshift • packages.xorg • packages.audio • packages.chrome • packages.spotify • usbarmoury The following are always applied: • laptop.keyboard • packages.laptop • sync The states/laptop/files/ directory contains the static config files that are copied over.

State: laptop.logind

Somewhere along the way, Ubuntu figured it would try to be trendy, like Apple, and made the choice to have your laptop go to sleep when the lid is closed. Personally, especially for a dev laptop, I think this the wrong choice and would rather not do anything when the lid is closed. This state fixes this default-broken behaviour.

17 Personal Salt Setup Documentation, Release 0

State: laptop.keyboard

The keyboard receives the following mappings: • the compose key is mapped to right alt; it was originally right super, but the T460s doesn’t have that key. • control and caps are swapped. The mappings are valid both in the console and in X. If the keyboard configuration file is changed, a udev trigger is fired to force X to pick up the changes.

State: laptop.mail

The mail state only installs the packages useful for command-line mail reading, and passing IMAP/SMTP off to external programs. notmuch is used for indexing mail.

State: laptop.network

The network substate installs the tools needed for networking. It doesn’t do any network configuration though; that’s handled by wicd.

State: laptop.redshift

Redshift is a f.lux analogue for . This state makes sure the package is installed and installs a systemd service to automatically run it.

State: laptop.xorg

Instead of forgetting to setup xscreensaver to lock when blanking the screen, this state will install a new config file that has safe defaults. xdm is also installed and enabled. For ThinkPads, an Xorg synaptics configuration is provided that will disabled the trackpad. On older thinkpads, this can be done in the BIOS, but I noticed that even with the Trackpad disabled this way on the T460s, it was still enabled. This is a double check to make sure that trackpad is disabled.

18 Chapter 8. State: laptop CHAPTER 9

State: packages

The packages state doesn’t have a top-level package (you can’t just include packages). Instead, states pull in the packages they need.

State: packages.apparmor

Apparmor is the devil I know in the space of mandatory access control systems; this makes sure the proper apparmor packages are installed.

State: packages.audio

The C* player (and flac support) is installed, as are some PulseAudio and ALSA utilities.

State: packages.chrome

The Google Chrome apt repository is added, and the stable version of Chrome is installed.

State: packages.common

The packages that should be on every personal machine are installed. These are utilities like lightweight editors (mg and nvi), some systems management tools (*top), and a few CLI browsers.

State: packages.devel

This selects a common set of tools for development; this includes packages like build-essential, gdb, and so forth.

19 Personal Salt Setup Documentation, Release 0

State: packages.dropbox

This installs the Dropbox apt repository and the dropbox command line tool. On first run, the command line tool will install the Dropbox tools.

State: packages.embedded

This state installs toolchains for ARM, AVR, and MIPS development.

State: packages.laptop

This pulls in packages.repo, and installs a number of laptop-specific tools. This can probably be rolled into pack- ages.common, but I’ve separated them into this package to make it easier to sync the common packages with my infrastructure Salt setup. The packages installed cover power management, accessing my iPod, various user tools (such as the cryptutils, and miscellaneous system tools. State: packages.python Several Python packages required by various other packages are defined here.

State: packages.repo

This sets up and installs my personal apt repository into apt’s sources.

State: packages.spotify

Spotify is installed via the Spotify apt repo. Both are managed in this state.

State: packages.stumpwm

This is an in-progress state to manage my installation of StumpWM.

State: packages.xorg

This installs a number X-specific programs, including web browsers, display managers ( and are provided by default), and various other X tools.

20 Chapter 9. State: packages CHAPTER 10

State: ssh

It’s almost always desirable to have an SSH server running (e.g. for file transfers). This sets up an OpenSSH server (including a custom sshd_config) and makes sure the server is running and enabled at boot. The SSH config includes the following: • MACs: hmac-sha2-512,hmac-sha2-256,hmac-ripemd160 • Ciphers: [email protected],[email protected],[email protected] • KexAlgorithms: [email protected],ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256 • root logins are disabled • password logins are disabled • reverse DNS lookups aren’t done (due to the most common use case of SSHing from a LAN) • PAM authentication is provided, but is only used for account and session checks

21 Personal Salt Setup Documentation, Release 0

22 Chapter 10. State: ssh CHAPTER 11

State: sync

Sync contains states for file synchronisation. I currently use Dropbox and Syncthing.

State: sync.dropbox

This pulls in packages.dropbox and adds a systemd service. Due to the fact that the Dropbox service requires user intervention to start up, a systemd service is installed but isn’t enabled or started — the user has to do that once Dropbox is fully setup.

State: sync.syncthing

The syncthing repository and package are installed, and the syncthing configuration is setup. It will default to syncing with the central server (currently freeside). A systemd service is installed, enabled, and started; it runs syncthing as the laptop user.

23 Personal Salt Setup Documentation, Release 0

24 Chapter 11. State: sync CHAPTER 12

State: systemd

This state contains only a systemd template for defining new services.

25 Personal Salt Setup Documentation, Release 0

26 Chapter 12. State: systemd CHAPTER 13

State: usbarmoury

I have a pair of USB armouries; one is a vault that is used to store long-term secrets, and the other is a portable, secure execution environment and data store. They’re ARM computers on a stick that communicate over a CDC ethernet connection; to access them, this state makes sure that the usb0 device is up with the IP address that they are expecting, and that IPv4 forwarding is turned on so that the iptables rules for forwarding work properly.

27 Personal Salt Setup Documentation, Release 0

28 Chapter 13. State: usbarmoury CHAPTER 14

State: users

This state does two things: • ensures the default Ubuntu user (present on some test VMs) is removed, and • sets up my user. Note that my user is expected to have the password set during installation. If that’s not the case, the state will have to be temporarily modified with a password hash.

State: users.kyle

This state • Makes sure my user is present, in the right groups, and has the right shell set. • Installs an authorized_keys file with my current set of public keys. • Installs some sudoers no-password programs (currently, these are all *top programs). • Sets up a cronjob to fetch email (which requires that the offlineimap config file has been synced over).

State: users.ubuntu

If present, the ‘ubuntu’ user should be removed.

29 Personal Salt Setup Documentation, Release 0

30 Chapter 14. State: users CHAPTER 15

Packages

Package list

This doesn’t include dependencies, only packages that are directly referenced. Actual package selection is based on grains. • acpitool • alsa-base • alsa-utils • apg • apparmor • apparmor-docs • apparmor-profiles • apparmor-profiles-extra • apparmor-utils • apt-file • • aptly • apt-transport-https • arandr • arduino • atop • autoconf • automake

31 Personal Salt Setup Documentation, Release 0

• avrdude • avr-libc • binutils-avr • bison • bsdutils • bsd-mailx • build-essential • bzip2 • cabal-install • chromium-browser • clang • • cloc • cmake • cmus • cmus-plugin- • cppcheck • cryptutils • cscope • ctags • debhelper • debootstrap • devscripts • devscripts • dh-apparmor • dh-make • disper • dmenu • docker-compose • docker-engine • dropbox • duplicity • elinks • • evince • feh

32 Chapter 15. Packages Personal Salt Setup Documentation, Release 0

• figlet • filezilla • firefox • firmware-iwlwifi • firmware-linux-free • flac • flex • fonts- • gcc-arm-none-eabi • gcc-avr • gdb • gforth • ghc • gimp • git • gnat • gnupg2 • go-1.6.3 • google-chrome-stable • gparted • gthumb • gtkpod • hfsplus • hfsprogs • hfsutils • htop • i3 • iftop • imagemagick • iotop • iptables-persistent • ipython • ipython3 • ipython3-notebook • ipython-doc • ipython-notebook

15.1. Package list 33 Personal Salt Setup Documentation, Release 0

• keepass2 • keychain • libnewlib-arm-none-eabi • libtool • lighttpd • lighttpd-doc • lynx • mercurial • mercurial-git • mg • msmtp • mutt • mysql-client • notmuch • nvi • octave • offlineimap • openssh-client • openssh-server • pandoc • paprefs • pavucontrol • picocom • pinentry-curses • postgresql-client • powertop • prospector • prospector • pylint • pylint3 • python2.7 • python2.7-dbg • python2.7-dev • python2.7-doc • python3.5 • python3.5-dbg

34 Chapter 15. Packages Personal Salt Setup Documentation, Release 0

• python3.5-dev • python3.5-doc • python3-alabaster • python3-flake8 • python3-gnupg • python3-gpgme • python3-numpy • python3-pep8 • python3-requests • python3-scipy • python3-sphinx • python-3to2 • python3-virtualenv • python-alabaster • python-apparmor • python-flake8 • python-gnupg • python-gpgme • python-libapparmor • python-mutagen • python-numpy • python-pep8 • python-pip • python-requests • python-scipy • python-sphinx • python-virtualenv • quilt • redshift • reprepro • rlwrap • rmtmp • rofi • rsync • rtorrent • sbcl

15.1. Package list 35 Personal Salt Setup Documentation, Release 0

• sbcl • scrot • silversearcher-ag • spotify-client • sqlite3 • sqlitebrowser • srm • ssh-askpass-fullscreen • stack • strace • sudo • surfraw • tcpdump • texlive-full • thunar • tig • tree • ttf-anonymous-pro • ubuntu-core-security-apparmor • vim- • virtualbox • virtualbox-dkms • virtualbox-guest-additions-iso • virtualenvwrapper • virtualenvwrapper • vlc • wicd • wicd-curses • wireless-tools • xbacklight • xclip • xdm • xfce4- • xmonad • xorg

36 Chapter 15. Packages Personal Salt Setup Documentation, Release 0

• yaklog • zsh

Directly downloaded

The following have binaries installed directly, without using the apt cache. • rust toolchain • packer • terraform • terraform-provider-virtualbox • docker-machine • leiningen Additional apt repos: • mine • fpcomplete • docker • chrome • dropbox • spotify • syncthing

15.2. Directly downloaded 37 Personal Salt Setup Documentation, Release 0

38 Chapter 15. Packages CHAPTER 16

Documentation Overview

This documentation is split into three parts: • A introduction to my setup. • The Salt states • The Pillar states

39 Personal Salt Setup Documentation, Release 0

40 Chapter 16. Documentation Overview CHAPTER 17

Indices and tables

• genindex • modindex • search

41