How I do my computing

This title shamelessly stolen from Richard Stallman

Since I sometimes get comments or questions on my computing setup, both on my workstations/laptops and my servers, I’ve decided to document my computing setup in some depth in this article.

This article is intended as a living document, so it will probably be extended and edited from time to time, as things change in my environment.

Though not specially aimed at complete beginners, I aim to write this document in a way understandable to beginners ready to learn by themselves and able to consult a search engine should the need arise.

Naturally, the server section will probably not be as newcomer-friendly as the workstation section.

Table of contents


Workstations & Laptops

This is the big one, since I spend most of my time in front of these.

These machines run mostly standard software, with the things I use most heavily customized to my needs. Consequently, I mostly use software I am able to customize when I feel the need (Mostly to save time, but sometimes out of a need for comfort).

Hardware

On the hardware side of things, I like the ThinkPad T-Series. Granted, they were better when IBM still made them, but the early-model Lenovo ones still feature the a better keyboard and general serviceability than all of the consumer Laptops manufactured today. Also, they are pretty easy to get cheap on eBay.

The latest model I use is currently a T410, though I also keep a stack of T60 and T61 models around, which are configured to be used interchangeably. That way, if one of them breaks irrecoverably, I can just use another one (and maybe replace the broken one in the future), saving a lot of buying stress. Another benefit is that each of the units usually come with a charger compatible across the product line.

You’ll notice that these machines are definitely not latest generation, and in most cases just have a basic dual core processor. That’s fine for me though, since I rarely game or indulge in other graphics- or CPU-heavy computing (except for compiling things, but that works well enough).

The main reasons I use these machines over other manufacturers or even later ThinkPad models are

  • Sturdiness
    • The older ThinkPad T-series computers are just built like tanks.
  • Linux support
    • Most ThinkPad models have excellent linux driver support (Probably since many kernel developers themselves use ThinkPads). This makes things such as setting up audio, wifi or graphics support extremely painless in comparison to other manufacturers.
  • Repairability
    • This point is somewhat diminished in newer models, but replacement parts for the older series are readily and cheaply available off the internet, and repairing those things takes opening 5 screws and popping out the keyboard. I’ve even changed TFTs in my ThinkPads for better ones more than once.
  • Price
    • Not the most important reason, but I like having a backup plan when machines fail. Also, having spare parts does not hurt.

Software overview

Almost all the software I use regularly is free and/or open-source, and most of it is available from the Debian package repositories.

  • OS: Debian stable
  • Synchronization: git
  • Window manager: ratpoison jwm
  • Shell: zsh
  • Terminal emulator: rxvt-unicode
  • Terminal multiplexer: tmux screen
  • Editor: vim scite
  • Development: gcc tcc clang git valgrind strace
  • Audio: ALSA (alsa-base alsa-utils)
  • Multimedia: vlc mplayer xli
  • Wireless connection manager: wicd-curses
  • PDF Viewer: zathura
  • Password management: keepassx
  • Web browsing: chromium firefox netsurf
  • Miscellaneous: htop xfe scrot xsel

Software detail

I probably won’t go into detail on every piece of software listed above, but I’ll cover the more important or interesting things.

If you’re interested in a particular piece of software listed in the overview above, but not detailed below, your options are either to ask me about it (see the Feedback section), or simply type the name into a search engine of your choice.

All of the configuration files listed are just my (more or less) current configurations. It may pay off greatly to put some time into customizing them to your own liking.

Most pieces of software mentioned also have a web presence of some sort, and some even have useful documentation.

In most cases, the documentation is also installed to the system and can be read by running

man <software>

in a terminal.

Operating system: Debian stable

This is one big holy war in the land of computing. Everyone you ask will most likely have his own opinions and preferences, especially when it comes to linux distributions.

Partly owing to the underwhelming feature-set of most of my machines, I rarely need bleeding-edge software, so instead I opt for non-breaking updates, solid security support and humungous repository breadth.

What little I need in latest releases, I can compile myself (though that mostly concerns software I am involved with myself in some way, so that would have happened anyway).

Since I want as few packages installed as possible (at least in the base system), I usually install Debian from the netboot image, which is intended for use with a network connection, but installs nicely without one - resulting in a very minimalistic installation.

The installation of netinst without net is (to my knowledge) only possible when using the Advanced setup option in the Debian installer menu and skipping all tasks that require a network connection.

My go-to keyboard layout, ever since I once had a ThinkPad featuring it in hardware, is the British layout, which is very similar to the American layout, but with a full-size Enter key and the backslash key being on opposite end of the forward slash, making for a very neat programming layout.

One big thing I do after first setting up the OS is teaching apt, Debians package manager, not to automatically install recommended packages in addition to things I myself request to be installed. This brings down the list of installed packages considerably.

To do that, create a file /etc/apt/apt.conf.d/00local with the contents

APT::install-recommends "false";
APT::install-suggests "false";

File name: /etc/apt/apt.conf.d/00local

Startup & X Server

Since I don’t use a desktop manager, my systems boot to a default tty login prompt. After I log in, I can work in text mode, which sometimes suits me just fine and is generally easier on the battery.

Once I decide I want to do something graphical such as browsing the web, I start the X server by running xinit. This, in the last instance, executes ~/.xinitrc, which is where my window manager is started as well as ~/.xserverrc, where I can control what X server to start (and more importantly, with which arguments).

Since I don’t really want my X server controllable over the network, my ~/.xserverrc looks like

#!/bin/bash
exec X -nolisten tcp

File name: ~/.xserverrc

In my ~/.xinitrc, I disable some powersaving options that turn off the screen after some minutes, then set my background to be black and continue by loading my color scheme settings into the X database. After that, there is some magic to allow me to test different window managers.

#!/bin/bash
session=${SESSION:-rptest}
printf "Starting %s session\n" "$session"
# Change to home directory before executing WM
cd
# Turn off powersaving stuff
xset -dpms
xset s off
# Background image
xsetroot -solid black -cursor_name left_ptr
# Merge xresources to database
xrdb -merge ~/.xresources
case $session in
        rptest) exec ./rp-test;;
        ratpoison) exec ratpoison;;
        jwm) exec jwm;;
        *) exec $1;;
esac

File name: ~/.xinitrc

This allows me to run my default window manager (which is currently a testing build of ratpoison) by just running xinit, while being able to, for example, start with jwm by running SESSION=jwm xinit.

For more information on this whole process, see man 1 xinit.

To change the keyboard layout while in an X session, run

# Set keyboard layout to German
setxkbmap de
# Set layout to British
setxkbmap gb

Colors and miscellaneous configuration

As mentioned in the previous paragraph, the X server keeps an internal database of configuration data, which is mostly used for color schemes and the like. This data is usually stored in ~/.xresources and loaded into the database during the execution of ~/.xinitrc. My color scheme is mostly copied from the solarized color scheme, with some changes and additions.

!!solarized dark colors
#define S_base03        #002b36
#define S_base02        #073642
#define S_base01        #586e75
#define S_base00        #657b83
#define S_base0         #839496
#define S_base1         #93a1a1
#define S_base2         #eee8d5
#define S_base3         #fdf6e3
#define S_yellow        #b58900
#define S_orange        #cb4b16
#define S_red           #dc322f
#define S_magenta       #d33682
#define S_violet        #6c71c4
#define S_blue          #268bd2
#define S_cyan          #2aa198
#define S_green         #859900
!!other colors
#define darkbg          #101010
#define textcol         #99ddff
!!urxvt cfg
URxvt*saveLines:        12000
URxvt*scrollBar:        true
URxvt*scrollstyle:      plain
URxvt*scrollBar_right:      true
URxvt*background:       darkbg
URxvt*foreground:       textcol
URxvt*fading:           40
URxvt*fadeColor:        S_base03
*cursorColor:           S_base1
URxvt*pointerColorBackground:   S_base01
URxvt*pointerColorForeground:   S_base1
!! black dark/light
URxvt*color0:           S_base02
URxvt*color8:           S_base03
!! red dark/light
URxvt*color1:           S_red
URxvt*color9:           S_orange
!! green dark/light
URxvt*color2:           S_green
URxvt*color10:          S_base01
!! yellow dark/light
URxvt*color3:           S_yellow
URxvt*color11:          S_base00
!! blue dark/light
URxvt*color4:           S_blue
URxvt*color12:          S_base0
!! magenta dark/light
URxvt*color5:           S_magenta
URxvt*color13:          S_violet
!! cyan dark/light
URxvt*color6:           S_cyan
URxvt*color14:          S_base1
!! white dark/light
URxvt*color7:           S_base2
URxvt*color15:          S_base3

File name: ~/.xresources

Synchronization: git

As mentioned before, I like to keep my machines synchronized in order to be able to switch over to another one should the need arise.

This is done by having all personal files I need synchronized in a git repository, which I can push to a remote server with a simple global command (which is aliased to execute a shell script). I can then pull the changes from all other machines with another command created in the same way. This is not done automatically, in order to be able to simply play around without creating unnecessary commits.

The repository also contains most of my configuration files, in order to maintain a unified experience. These configuration files are symlinked to my HOME in most cases.

Each machine has it’s own notes file in the repository, symlinked to ~/notes, which makes for easy note-taking, which is optionally visible on all machines.

Of course, this repository does only contain few binary files (and even fewer ‘large’ files), in order to keep the size down. Media files and browser “Download” folders are not synchronized, but large files to be archived (such as Photos, etc) are kept on my NAS or external hard drives.

Other than the aforementioned categories, most of my home directory consists of git repositories for software projects, which can be independently pulled on every machine.

To do the same, you will need a machine or service where you can store git repositories (preferrably non-publicly), create a new repository and check it out on every machine you want to synchronize.

In order to set up the push and pull scripts and aliases, see the section on my Terminal setup.

Window manager: ratpoison, jwm

ratpoison on dual monitors ratpoison on two monitors

ratpoison is a tiling window manager (as opposed to for example gnome, which is a floating window manager) that is completely keyboard driven. The mouse is only needed to click on things inside windows where necessary. Some other benefits are it’s high level of configurability, low memory footprint (both on disk and at runtime) and general unobtrusiveness. ratpoison does not even draw any window decorations.

Due to this window manager being my default environment for most of the day, this is one piece of software I have configured very extensively to my liking. Some other people seem to like that configuration, too, so I’m sharing some of the thoughts behind it.

Since ratpoison comes with a default set of keybindings which I mostly don’t care for or don’t need, a big chunk of my configuration is unbinding the default mapping.

# Command key
escape C-s
# Options
startup_message off
warp off
set winname class
set resizeunit 3
set border 1
set barpadding 0 0
set fwcolor grey
set bwcolor black
# Set up some commands
alias battery exec ratpoison -c "echo $(acpi)"
# Unbind most of the default mappings
unbind s
unbind S
unbind C-x
unbind g
unbind C-v
unbind C-V
unbind Q
unbind M-Left
unbind M-Right
unbind M-Up
unbind M-Down
unbind Return
unbind C-Return
unbind C-A
unbind C-a
unbind C-K
unbind C-b
unbind C-exclam
unbind exclam
unbind C-i
unbind C-m
unbind C-n
unbind C-p
unbind apostrophe
unbind C-apostrophe
unbind C-space
unbind C-w
unbind C-f
unbind C-r
unbind C-g
unbind k
unbind C-k
unbind C-l
unbind C-underscore
unbind u
unbind C-u
unbind U
unbind space
unbind K
unbind i
unbind c
# Do nothing, Go to window & Set window number
bind Escape abort
bind g select
bind G number
# Exit
bind Q quit
# Execute & urxvt
bind x exec
bind C-x exec
bind c exec x-terminal-emulator
# Close & Force close
bind C-c delete
bind C-C kill
# Fullscreen & undo
bind less only
bind greater undo
# Splits
bind v hsplit
bind h split
# Key info
bind i describekey root
# Tempwm
bind W tmpwm
# Tools
bind B battery
bind L exec rplock
# Meta key for C-s
bind s meta

File name: ~/.ratpoisonrc

To find out what all these options mean, see man ratpoison.

ratpoison works (much like tmux, screen, etc), by reacting to a special key combination (the command key), then entering a mode where it awaits further key combinations, which can be bound to actions such as executing a program, displaying a clock, etc.

My command key Ctrl-s has been chosen after a lot of consideration, being near Ctrl-a (used by screen) and not being used in my regular workflow that much. Most X applications use that combination for saving though, but one more keypress is tolerable to invoke that function.

If you decide to take that configuration for a test drive, the most important key bindings are

  • c bound to exec x-terminal-emulator
    • Start a terminal emulator instance
  • x bound to exec
    • Start arbitrary programs (watch out for the box in the top right)
  • h bound to vsplit
    • Split vertically (meaning, introduce a new horizon)
  • v bound to split
    • Split horizontally (v visually looks a bit like a scissor cutting the screen in half)
  • < bound to only
    • Take current window fullscreen
  • > bound to undo
    • Undo last frameset change
  • left/right/up/down bound to focusleft/focusright/focusup/focusdown
    • Select window to the left/right/up/down
  • Ctrl-c bound to kill
    • Close a window
  • Q bound to quit
    • Quit ratpoison (Note that this is Shift-q)

Keep in mind to press the command key sequence first, then the bound sequence.

Some of the bindings may be unintuitive with keyboard layouts other than British, which I can very much recommend for programming.

Some applications don’t really take to being tiled (most notable, The GIMP and some Java software). For these cases, I use a second window manager and a piece of functionality in ratpoison I miss in most other window managers I try: The option to not be obtrusive.

Ratpoison has a tmpwm command (bound to W in my config), which temporarily hands control of all windows over to another window manager, and takes back all windows once that window manager exits. I use this with jwm, which is a basic floating window manager with many of the same benefits ratpoison has: configurability and low memory footprint.

After having done whatever it is that needed floating windows, I can exit jwm and be back in ratpoison, with all windows now neatly tiling again.

Wireless connection manager: wicd-curses

Though, I should add, really only for wireless connections, since I can’t bring myself to learn the wpa-supplicant configuration file syntax by heart.

The wicd-curses interface The wicd-curses interface

Installing wicd-curses (the command-line management interface) also installs the wicd daemon, which runs as root and talks to wpa-supplicant and your DHCP client to configure network access. There are also graphical frontends to wicd available, but I’m quite content with the command line interface.

wicd is in principle also able to manage wired connections, but I prefer to do that on my own via the command line, mostly because as a network guy, you have to support some really funky network connections at work.

When you run wicd-curses, you’ll see some keys and their corresponding actions at the bottom. In the Preferences screen, you’ll be able to configure wicd to ignore the wired connection by just emptying the Wired Interface box. Everything else is probably best left to the defaults, though feel free to suggest otherwise!

Terminal: rxvt-unicode, zsh

zsh within tmux within urxvt zsh within tmux within urxvt

The shell takes up a big share of my daily screen time, making it another highly customized part of my setup.

My preferred terminal emulator is rxvt-unicode, also known as urxvt, though it is a weak preference, being mostly for better Unicode support over the default xterm.

It has some options set up in the X resources database, you can find them in the section on Colors and such.

Within the terminal emulator runs the actual shell, which is zsh in my case.

When first installing Debian, the default shell may still be bash, but this is easily changed by running

chsh -s /bin/zsh

zsh has a very powerful extension system, most of which I am currently ignoring. I do however like some nifty features it offers, as is seen in my configuration file below.

# Set up the prompt
autoload -Uz promptinit && promptinit

# Use prompt -l to see what else is possible
prompt adam1

# Ignore duplicates
setopt histignorealldups

# Enter directories by typing their name
setopt autocd

# Use emacs keybindings for zsh
bindkey -e

# History: 1000 lines in  ~/.zsh_history
HISTSIZE=1000
SAVEHIST=1000
HISTFILE=~/.zsh_history

# Use modern completion system
autoload -Uz compinit && compinit

# Set up completions
zstyle ':completion:*' auto-description 'specify: %d'
zstyle ':completion:*' completer _expand _complete _correct _approximate
zstyle ':completion:*' format 'Completing %d'
zstyle ':completion:*' group-name ''
zstyle ':completion:*' menu select=2
eval "$(dircolors -b)"
zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
zstyle ':completion:*' list-colors ''
zstyle ':completion:*' list-prompt %SAt %p: Hit TAB for more, or the character to insert%s
zstyle ':completion:*' matcher-list '' 'm:{a-z}={A-Z}' 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=* l:|=*'
zstyle ':completion:*' menu select=long
zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s
zstyle ':completion:*' use-compctl false
zstyle ':completion:*' verbose true
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'
zstyle ':completion:*:kill:*' command 'ps -u $USER -o pid,%cpu,tty,cputime,cmd'

# Some standard aliases
alias ll='ls -l'
alias llh='ls -lh'
alias la='ls -A'
alias l='ls -CF'
alias ls='ls --color -lh --group-directories-first'
alias lss='ls --color -lSh --group-directories-first'

# Synchronization aliases
alias push="(cd ~ && ./push)"
alias pull="(cd ~ && ./pull)"

# Log out of TTY when X is killed
alias xinit="xinit || logout"

# This is just me being lazy. This requires an entry in /etc/sudoers.d/
alias dhcp="sudo dhclient eth0 &"

# Functions for working with git
pll(){
    git pull ${1:-origin} ${2:-master}
}
psh(){
    git push ${1:-origin} ${2:-master}
}

# For quickly adding a key to the ssh agent
agent(){
    (cd ~ && ssh-add .ssh/$1)
}

# Record the screen
record(){
    avconv -video_size 1440x900 -framerate 20 -f x11grab -i :0 -pix_fmt yuv420p -c:v libx264 -crf 18 -preset ultrafast "$1.raw.mkv"
    avconv -i "$1.raw.mkv" -crf 18 -preset veryslow "$1.mkv"
    rm "$1.raw.mkv"
}

# Set terminal font size
fontsize(){
    printf '\33]50;%s%d\007' "xft:*:pixelsize=" $1
}

# Start an SSH agent if there is none
if [ -z "$SSH_AGENT_PID" ]; then
    eval `ssh-agent -s`
fi

# Stop terminal blanking and powersaving
if [[ "$TERM" == "linux" ]]; then
    setterm -blank 0
    setterm -powerdown 0
fi

File name: ~/.zshrc

Note the aliases for the push and pull scripts used in the section on Synchronization as well as the functions for pushing and pulling git repositories, which can be used like

# Pull from origin/master
pll
# Push to github/master
psh github
# Pull from github/cool-feature
pll github cool-feature

There’s some more interesting things in there, such as functions for setting the terminal font size and recording the screen.

Before anyone wants to tell me about oh-my-zsh: Yes, I know about it. I don’t like configuration with an integrated update system.

Editor: vim, scite

Another heavily contested topic between linux people is the choice of editor. I fall on the side of vim, though I admit it has a steep learning curve. It is worth it in my opinion though, greatly improving productivity while editing files.

vim is heavily extendable with lots and lots of options, modules and extension scripts available, but I’m very happy with the following few lines.

filetype plugin indent on
syntax on
set encoding=utf-8
" Disable the help popup on F1
map <F1> <Esc>
imap <F1> <Esc>

File name: ~/.vimrc

scite is just a basic graphical text editor based on the Scintilla project. It features pretty good syntax highlighting and is easier to grasp at first glance than vim. It is also pretty lightweight on resources.

Web browsing: chromium, firefox, netsurf

I use chromium as my main browser, with my sessions growing up to some few hundred tabs since I don’t really like to use bookmarks (They are, sadly, not as readily exportable as copying an URL).

In order to keep memory usage at an acceptable level, I use some plugins, namely

  • The great suspender: Replaces tabs with a static page after some time of inactivity.
  • uBlock Origin and uMatrix: For ad and script blocking
  • Disable HTML5 Autoplay: Because who likes autoplay.
  • Session Buddy: To manage sets of tabs should the need for some compartmentalization arise.

firefox (or iceweasel, as it likes to be called on Debian) is configured to forget all history after closing, making it my “incognito” or VPN browser. An AdBlocker as well as the NoScript extension are installed there.

netsurf I install actually just for fun. It’s a nice project to build a new browser from the ground up, and as such is missing many features (such as viable JavaScript support), but it loads pretty fast and is nice to use once in a while.


Servers

Much like with my workstations, I’m a great fan of keeping my server systems very light weight - meaning as few packages as possible installed, only running services that are needed and choosing lightweight software wherever possible.

Software overview

  • OS: Debian stable
  • git access control: fugit
  • Web server: lighttpd nginx
  • Database: sqlite3 postgres
  • Monitoring: munin vnstat
  • Firewall: iptables
  • Mail: cmail

Software detail

I’ll keep this mostly short and sweet, since you should hopefully already have some experience using Linux when you’re going to have a server reachable from the entire internet.

git access control

git does not ship a mechanism for authentication or authorization itself, instead relying on the ones provided by the transport mechanism of choice (WebDAV, HTTP, SSH, etc). Most people, me included, opt for SSH, at least for write access (with public read access optionally provided via HTTP).

This entails creating a system user that stores the actual repositories and granting collaborators login access to that user. Without any further configuration, this poses the problem that all users basically have unfettered access to all repositories stored as this user.

While it would be possible to create one user per project or repository, this quickly gets impractical, which is why there is a whole host of software dealing with this (and related) problems.

Sadly, most of these have features I don’t need bloating the codebase, are impossible to debug properly, have dependencies I’m not willing to install or change their interfaces more frequently than I am willing to delve into their configuration.

As with many things that irk me, I eventually decided on implementing what I need for myself and provide it as free and open source software. That is how fugit came to be.

Web server: lighttpd, nginx

My go-to HTTP daemon is currently lighttpd, mostly for its ease of configuration, wide range of modules and configurability, lightweight resource consumption and overall speed.

Most of my server machines handle multiple virtual hosts, which is easily configured using mod_evhost.

# Load necessary modules
server.modules = (
    "mod_access",
    "mod_alias",
    "mod_accesslog",
    "mod_compress",
    "mod_evhost",
    "mod_auth",
    "mod_fastcgi",
    "mod_rewrite",
    "mod_redirect",
    "mod_expire",
    "mod_evasive",
)

# Some standard setup
server.pid-file = "/var/run/lighttpd.pid"
server.document-root = "/var/www/default"
server.tag = "lighty [hostname]"
index-file.names = ( "index.php", "index.html", "index.htm" )
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
url.access-deny = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

# These might be Debian-specific
server.username = "www-data"
server.groupname = "www-data"

# Logfiles
server.errorlog = "/var/log/lighttpd/error.log"
accesslog.filename = "/var/log/lighttpd/access.log"
evasive.max-conns-per-ip = 10

# Set up virtual host pattern
evhost.path-pattern = "/var/www/%2/%3/"

# Enable HTTPS
$SERVER["socket"] == ":443" {
    ssl.engine  = "enable"
    ssl.use-sslv2 = "disable"
    ssl.use-sslv3 = "disable"
    ssl.cipher-list = "HIGH:!NULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4:!aNULL:!anon"
    ssl.pemfile = "/path/to/default_cert.pem"
    ssl.ca-file = "/path/to/default_ca.pem"
    ssl.dh-file = "/path/to/dhparams.pem"
    ssl.ec-curve = "secp384r1"
    $HTTP["host"] =~ "(^|)example\.org$" {
        ssl.pemfile = "/path/to/vhost_cert.pem"
        ssl.ca-file = "/path/to/vhost_ca.pem"
    }
}

# Enable directory listings
dir-listing.encoding        = "utf-8"
server.dir-listing          = "enable"

# Enable compression
compress.cache-dir          = "/var/cache/lighttpd/compress/"
compress.filetype           = ("text/plain", "text/html", "application/x-javascript", "text/css")

# Enable caching for static content
expire.url = (
    "/static/" => "access plus 7 days",
)

# Redirect www.foo.* to foo.*
$HTTP["host"] =~ "^www\.(.*)$" {
    url.redirect = ( "^/(.*)" => "http://%1/$1" )
}

# Use IPv6 if possible
include_shell "/usr/share/lighttpd/use-ipv6.pl"
# Mimetype mapping
include_shell "/usr/share/lighttpd/create-mime.assign.pl"

# Pass all .php files to php5
fastcgi.server = ( ".php" => ((
    "bin-path" => "/usr/bin/php5-cgi",
    "socket" => "/var/run/lighttpd/php.socket",
    "max-procs" => 10
)))

File name: /etc/lighttpd/lighttpd.conf

For fancier setups, such as UWSGI applications or reverse proxy setups, I tend to use nginx.

Database: sqlite3, postgres

For most of my database needs, I really like sqlite3, which is a file-based database.

This has it’s advantages, such as being able to simply copy a file to backup (or replace) the entire database, ease of setup (just create a file) and zero need for configuration of daemons.

It does also have some drawbacks though, such as rapdidly degrading performance when tasked with concurrent writes, no access control mechanism and only coarse-grained locking.

Still, in my experience most things requiring a database and serving under a few tens of users is perfectly fine with SQLite. If the load is mostly reading data, SQLite may even be a pretty good choice.

For things absolutely requiring a client-server database which implements a full standards compliant SQL dialect with all the features you could ever wish for and very good performance, I’d recommend looking into PostgreSQL (or postgres, as the binary is called).

Monitoring: munin

munin Example screenshot of munin

For monitoring of servers, I like the graphs provided by munin.

I run munin in cron-mode, which is kind of unnecessary when only accessing it from one user.

More interestingly, though, my munin setup gathers the data from the remote servers via ssh, not the normally open client protocol.

To do this, I created an SSH key for the munin user on the monitoring host by running

su munin -ls /bin/bash
ssh-keygen -t ecdsa

On each of the clients, first have the munin-node process listen only on localhost, preventing the unauthorized outside world from gathering information.

host 127.0.0.1
port 4949

File name: /etc/munin/munin-node.conf

Then allow the monitoring host to SSH into the monitored host by adding the following line to the authorized_keys file.

command="/bin/false",no-agent-forwarding,no-pty,no-user-rc,no-X11-forwarding,permitopen="127.0.0.1:4949" <SERVER-PUBLIC-KEY>

File name: /home/munin/.ssh/authorized_keys

Take care to replace <SERVER-PUBLIC-KEY> with the correct key.

Also do this on the monitoring host itself, though you may need to add

host_name <MYHOSTNAME>

File name: /etc/munin/munin-node.conf

to the munin-node configuration there.

Having done that, add the hosts to the munin daemon’s configuration by specifying them like so

[hostname.domain.foo]
    address ssh://<hostname.domain.foo> -W 127.0.0.1:4949

File name: /etc/munin/munin.conf

Add the monitoring host itself like this

[monitoring.domain.foo]
    address 127.0.0.1
    use_node_name yes

Firewall: iptables

Most of the firewall configuration on my server consists of explicitly allowing the ports the machine is supposed to server and then dropping all traffic to everything else.

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state INVALID -j DROP
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -p ipv6-icmp -j ACCEPT
-A INPUT -p tcp --dport 2222 -j ACCEPT
-A INPUT -p tcp --dport 25 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
-A INPUT -p tcp --dport 995 -j ACCEPT
-A INPUT -p tcp --dport 587 -j ACCEPT
-A INPUT -p tcp --dport 110 -j ACCEPT
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 465 -j ACCEPT
-A INPUT -p udp --dport 546 -j ACCEPT
-A INPUT -p udp --dport 68 -j ACCEPT
COMMIT

File name: /etc/iptables/rules.v4 /etc/iptables/rules.v6

To ensure the rules are loaded at boot time, install the package iptables-persistent, which loads the rules.v4 and rules.v6 files from /etc/iptables/ when started.

Mail: cmail

To be honest, this section is just a simple reference to the open-source cmail project, which is a mail server I started to write after being fed up with configuring the alternatives.

It does all I want in a mail server, is reasonably easy to set up (though running your own mail server requires some knowledge on deeper subjects in networking), and supports multiple domains perfectly.


Wrapping up

Links

As always, be careful when visiting external links. I can not guarantee that they won’t change.

Laptop

Server

Feedback

If you know some piece of software I should definitely know about, found something I do terribly wrong or that could be done in a prettier way, please tell me about that! Just send a short email to fjs@fabianstumpf.de.

Should some of the configurations not work for you, please include the software version you’re using in your email! Though it’d not be unlikely for me to have made a mistake, the configuration format may just have changed without me noticing.

Please accept that I probably will not be able to help you with your own setup in depth, especially over the internet.

Thanks & Acknowledgements