Skip to content

Reproducible OpenBSD Installation with Org-Mode & Emacs

Notifications You must be signed in to change notification settings

andreoss/openbsd-ex-org

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenBSD Ex Org

Overview

This document is aimed to provide an enviroment for building a bootable OpenBSD system image, using QEMU and Org. The entire process can be automated and reproducible. The result image will be partitioned with GPT and bootable on UEFI machines.

It’s possible to build an entire system automatically by “publishing” this document:

emacs --quick README.org --batch --load=init.el --funcall=org-md-export-to-markdown --kill

Supported OpenBSD versions:

  1. 7.2
  2. 7.3

Prerequisites

The main requirements are QEMU, Expect & GNU Emacs. Pass is used to managed passwords, and can be changed to something else (i.e literals) in the definitions below.

Dependencies

emacs>= 27.2
qemu>= 6.0.0
expect>= 1.1
bash
pass

On Nix

See shell.nix

with import <nixpkgs> {};
stdenv.mkDerivation {
  name = "emacs-qemu-enviroment";
  buildInputs = [
    pkgs.gnutar
    pkgs.wget
    pkgs.qemu
    pkgs.coreutils
    pkgs.openssh
    pkgs.rsync
    pkgs.expect
    pkgs.emacs-nox
    pkgs.netcat-gnu
    pkgs.inetutils
    pkgs.pass
  ];
}

Current versions

(emacs-version)
qemu-kvm --version
expect -version

Lisp Variables & Functions

Definitions

This definitions are needed to provide dynamic values in `header-args`.

For example:

#+begin_src shell :eval (a-is-system-p 'openbsd)
zzz
#+end_src
(defvar a-ref-cache (make-hash-table :test 'equal))
(defun a-ref (name)
  (or (gethash name a-ref-cache)
      (let ((value
             (save-excursion
               (org-babel-execute-src-block nil
                                            (org-babel-lob-get-info
                                             (list
                                                                         'babel-call
                                                                         (list
                                                                          :call
                                                                          "ref-unquoted"
                                                                          :arguments
                                                                          (concat
                                                                           "'"
                                                                           name))))))))
        (puthash name value a-ref-cache))))
(defun a-is-system-p (sys)
  "Which is the host system-p. "
  (if (eq system-type sys) "yes" "no"))
(defun a-host ()
  (concat "#!" default-directory "host-shell"))
(defvar a-guest (concat "#!" default-directory "guest-shell"))
(defun a-sudo ()
  "Directory for executing as root. XS is sub directories. "
  (concat "/sudo::/" default-directory))
(defvar a-remote
  (let ((user (a-ref "user-name"))
        (port (a-ref "ssh-port")))
    (concat (format "/ssh:%s@localhost#%d:" user port))))
(defvar a-remote-sudo
  (let ((user (a-ref "user-name"))
        (port (a-ref "ssh-port")))
    (concat (format "/ssh:%s@localhost#%d|sudo:" user port))))
(defun a-contains-p? (needle haystack)
  (cl-assert
   (cl-search needle haystack)))
(defun a-not-contains-p? (needle haystack)
  (cl-assert
   (not (cl-search needle haystack))))

Remove all result blocks

Clean up this document from all result blocks.

(defun a-ob-clear-all-results ()
  "Clear all results in the buffer."
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (org-babel-next-src-block)
      (org-babel-remove-result))))

Rotate old log

«log»
if [ -e "$LOG" ]
then
    mv --verbose --force "$LOG" "${LOG//.log}$(date +%s).log"
fi

Expect scripts

Connect to serial port (via telnet).

log_user 0
spawn telnet localhost «ref('serial-port)»
log_user 1

Connect to monitor port (via telnet).

log_user 0
spawn telnet localhost «ref('monitor-port)»
log_user 1
expect -re {(?n)(?:[a-z]+)?[#]\s}

Set com0 as the main tty

Executed during boot of install.img

«serial»
«timeout»
expect "boot>"
send "stty com0 115200\r"
expect "boot>"
sleep 1
send "set tty com0\r"
expect "boot>"
sleep 1
send "boot\r\r\r"
sleep 1
expect "\r"
exit

Reset VM

Executed during boot of install.img

«monitor»
«timeout»
set command [lindex $argv 0];
expect "(qemu)"
send "$command\r"
expect "(qemu)"
exit

Timeouts

Disable timeout

set timeout -1

Enable timeout

set timeout 10

Start interactive shell.

«serial»
«notimeout»
send "\r";
expect "(I)nstall, (U)pgrade, (A)utoinstall or (S)hell?" { send "S\r" }
«expect-prompt»

Execute guest shell command (after interactive was started).

Execute a shell command via COM.

set command [lindex $argv 0];
«serial»
«timeout»
set send_human {.1 .3 1 .05 2}
send -h "$command"
send -h "\r"
after 1000 set stop_wait &
vwait stop_wait
unset stop_wait
«expect-prompt»

A wrapper for the script above to use it as part of shebang.

./execute "$(sed /^#!/d "$1")"

Emacs configuration

Startup

Run when file is being opened

This block is executed via Buffer settings & init.el.

(require 'ob-shell)
(require 'ob-eshell)
(require 'cl)
(setq org-babel-eval-verbose nil)
«definitions»

ANSI Colors in output

(defun a-babel-ansi-color-apply ()
  (when-let ((beg (org-babel-where-is-src-block-result nil nil)))
    (save-excursion
      (goto-char beg)
      (when (looking-at org-babel-result-regexp)
        (let ((end (org-babel-result-end))
              (ansi-color-context-region nil))
          (ansi-color-apply-on-region beg end))))))
(add-hook 'org-babel-after-execute-hook 'a-babel-ansi-color-apply)

Shell wrapper to capture logs

This is useful for debugging. All code with this shebang will log its stderr & stdout to $LOG.

LOG=${LOG:-output.log}
«log»
if [ "$LOG" ]
then
    exec 1> >(tee -a "$LOG") 2> >(tee -a "$LOG" >&2)
fi
exec "$SHELL" "$@" </dev/stdin

Reference parameter from the table below

(let ((files
       (eval
        contains-p)))
  (dolist (file files)
    (assert (file-exists-p (expand-file-name file)))))
(format "%s" block)
(eval contains-p)
(format "%s" block)

Reference a value from Parameters.

(let ((key (if (symbolp name)
               (symbol-name name) name)))
  (nth 2 (assoc key table)))
echo «ref("user-name")»

Parameters

The following table is to parameterize the system.

Options

ReferenceDescriptionValue
hostnameHostnamepuffy
domainDomaincx
volume-sizeVolume size16005464064B
time-zoneTimezoneAmerica/New_York
root-passwordRoot’s passwordtoor
serial-portTty Port1234
monitor-portMonitor Port1233
ssh-portSsh Port7922
archArchitecure (only amd64)amd64
system-imageResult image/dev/sdb
releaseRelease7.4
install-imageInstallation imageinstall74.img
image-formatResult image formatraw
(qcow2 or raw)
mirrorMirrorhttps://cdn.openbsd.org/pub/OpenBSD
user-nameRegular user namea
user-idId1337
user-groupPrimary groupstaff
user-shellShell of userbash

Password

The password for SoftRAID is generated by pass.

Show password:

(if (not (string-empty-p name))
    (string-trim (shell-command-to-string (concat "pass show" " " (a-ref "hostname") "/" name))))

Generate password:

(if (not (string-empty-p name))
    (string-trim (shell-command-to-string (concat "pass generate --no-symbols " (a-ref "hostname")
                                                  "/" name " " length))))

Installation media

Download installation image

wget --continue «ref("mirror")»/«ref("release")»/«ref("arch")»/«ref("install-image")» \
                «ref("mirror")»/«ref("release")»/«ref("arch")»/SHA256                 \
                «ref("mirror")»/«ref("release")»/«ref("arch")»/SHA256.sig
ftp  «ref("mirror")»/«ref("release")»/«ref("arch")»/«ref("install-image")» \
     «ref("mirror")»/«ref("release")»/«ref("arch")»/SHA256                 \
     «ref("mirror")»/«ref("release")»/«ref("arch")»/SHA256.sig

Verify SHA256

NOTE: The installation image is mutable, the checksum most likely won’t match after the first boot.

On GNU/Linux (verify SHA256)

sha256sum --ignore-missing --check SHA256

On OpenBSD

signify -C -x SHA256.sig «ref("install-image"

(Optional) Patch installation image in order to enable serial port

Less bug-prone than set-tty script.

On GNU/Linux

Make sure that UFS can be mounted with RW permissions. For example, on NixOS it can be enabled like this in boot.nix:

boot.kernelPatches = [
  {
    name = "ufs-rw-support";
    patch = null;
    extraConfig = "UFS_FS_WRITE y";
  }
];
zgrep UFS_FS /proc/config.gz
losetup --partscan /dev/loop0 install73.img
sfdisk -l /dev/loop0
mkdir -p /tmp/install
mount -t ufs -o ufstype=44bsd,rw /dev/loop0p4 /tmp/install
echo "stty com0 115200" >> /tmp/install/etc/boot.conf
echo "set tty com0"     >> /tmp/install/etc/boot.conf
umount /tmp/install
losetup --detach-all

On OpenBSD

Discussion on SO.

Script to control VM

Wait until port is open:
waitport() {
    while ! nc -z localhost "${1:?no argument}" ; do sleep 3; done
}
QEMU_MEM=4g
QEMU_CPU=host
QEMU_PID=.pid
QEMU_COMMAND=qemu-kvm

Ports for Monitor and Serial console:

QEMU_MON_PORT=«ref("monitor-port")»
QEMU_SER_PORT=«ref("serial-port"

QEMU arguments: System drive:

QEMU_SYSTEM_DRIVE=(
  -device scsi-hd,drive=hd0
  -drive file=«ref("system-image")»,media=disk,snapshot=off,if=none,id=hd0,format=«ref("image-format")»
)

Installation drive:

QEMU_INSTALL_DRIVE=(
    -drive file=«ref("install-image")»,media=disk,format=raw
)

Key-disk drive:

QEMU_KEY_DRIVE=(
    -device scsi-hd,drive=hd1
    -drive file=key.raw,media=disk,snapshot=off,if=none,id=hd1,format=raw
)

Monitor device:

QEMU_MONITOR=(
    -monitor chardev:mon0
    -chardev socket,id=mon0,server=on,wait=off,telnet=on,port=$QEMU_MON_PORT,host=localhost,ipv4=on,ipv6=off
)

Serial device:

QEMU_SERIAL=(
    -serial chardev:ser0
    -chardev socket,id=ser0,server=on,wait=off,telnet=on,port=$QEMU_SER_PORT,host=localhost,ipv4=on,ipv6=off
)

Network with port forwarding:

QEMU_NETWORK=(
    -netdev tap,id=mn0,br=virbr0,helper=$(type -p qemu-bridge-helper)
    -device virtio-net,netdev=mn0,mac=00:00:00:00:00:01
)
QEMU_SOUND=(
    -audio pipewire,model=es1370,out.frequency=48000
)
QEMU_OPTS=(
    -vnc :0
    -smp 3
    -cpu phenom
    -display none
    -vga virtio
    -m "$QEMU_MEM"
    -cpu "$QEMU_CPU"
    -bios bios/ovmf-x64/OVMF-pure-efi.fd
    -device virtio-scsi-pci,id=scsi
)
QEMU_OPTS+=("${QEMU_NETWORK[@]}")
QEMU_OPTS+=("${QEMU_MONITOR[@]}")
QEMU_OPTS+=("${QEMU_SERIAL[@]}")
QEMU_OPTS+=("${QEMU_SYSTEM_DRIVE[@]}")
QEMU_OPTS+=("${QEMU_SOUND[@]}")
QEMU_OPTS+=(-pidfile "$QEMU_PID" -daemonize)
__boot() {
   ./type-password «pass-show("bioctl")»
}
__status() {
        if [ ! -e "$QEMU_PID" ]
        then
            >&2 echo "Not running"
            exit 1
        fi
        PID="$(< "$QEMU_PID")"
        if kill -0 "$PID" >/dev/null 2>/dev/null
        then
            >&2 echo "Running: $PID"
        else
            >&2 echo "Stopped: $PID"
            exit 1
        fi
}
__start() {
        [ -e "$QEMU_PID" ] && >&2 echo "Already running" && exit 1
        "$QEMU_COMMAND" "${QEMU_OPTS[@]}"
        waitport "$QEMU_MON_PORT"
        waitport "$QEMU_SER_PORT"
        while :
        do
            PID=$(cat < "$QEMU_PID")
            kill -0 $PID && echo Running && break
        done
}
if [ "${USE_KEYDISK:-0}" -eq "1" ]
then
    QEMU_OPTS+=("${QEMU_KEY_DRIVE[@]}")
fi
if [ "${USE_INSTALL:-1}" -eq "1" ]
then
    QEMU_OPTS+=("${QEMU_INSTALL_DRIVE[@]}")
fi
case "${1:?no arg}" in
    start)
        __start
        __boot
        ;;
    status)
        __status
        ;;
    reset)
        __status
        ./qemu-command system_reset
        ;;
    poweroff)
        __status
        ./qemu-command system_powerdown
        ;;
    stop)
        [ -e "$QEMU_PID" ] && xargs kill < "$QEMU_PID"
        rm --force "$QEMU_PID"
        ;;
    restart)
        "$0" stop
        "$0" start
        ;;
esac

Qemu

Setup UEFI Bios

UEFI Bios image

Installing UEFI Bios for QEMU. This BIOS does not support CD, this is why we are using a USB image.

wget --continue https://packages.slackonly.com/pub/packages/14.2-x86_64/system/ovmf/ovmf-20171116-noarch-1_slonly.txz
tar  -C ./bios -xvf ovmf*txz --strip-components=2

Prepare image

Main volume

qemu-img create -f «ref("image-format")» «ref("system-image")» «ref("volume-size"

Instalation

Start QEMU & set TTY to com0

Stop VM:

./vm status
./vm stop

Start VM:

env USE_GRAPHIC=1 USE_INSTALL=0 ./vm start
./set-tty

Start interactive shell

./start-shell

Check available disks (sd0 & wd0 should present)

Print names of available disks:

sysctl hw.disknames

You should see the target image being attached as sd0.

dmesg | grep sd[0-9]

Installation media should be available as wd0 (if installing from img file)

dmesg | grep wd[0-9]

Prepare disk

Create devices for sd0 and sd1

cd /dev
sh MAKEDEV sd0
sh MAKEDEV sd1
sh MAKEDEV sd2
ls -l sd*a

Remove disk content

dd if=/dev/zero of=/dev/rsd0c bs=1m count=100

Run fdisk

fdisk -iy -g -b 960 sd0

The same for keydisk (Optional)

fdisk -iy -g -b 960 sd1

Disklabel

Create one RAID partition using entire disk space.

{
    echo a a
    echo
    echo
    echo raid
    echo w
    echo q
} | disklabel -E sd0
disklabel sd0

Prepare keydisk (Optional)

{
    echo a a
    echo
    echo
    echo raid
    echo w
    echo q
} | disklabel -E sd1
disklabel sd1

Create bioctl(8) Crypto RAID

Put passphase in a file

NOTE: New line at EOF is required.

echo «pass-show("bioctl"> /tmp/.passphrase
chmod 0600 /tmp/.passphrase
ls -l /tmp/.passphrase

Initialize RAID on sd0

bioctl -p /tmp/.passphrase -c C -l sd0a softraid0

Using keydisk (Optional)

bioctl -k sd1a -c C -l sd0a softraid0

Main setup

Setup dialog

Send ^D and press enter.

«serial»
set send_human {.1 .3 1 .05 2}
send "\x04"
send "\r"
expect "(I)nstall, (U)pgrade, (A)utoinstall or (S)hell?" { send "I\r" }
expect "Terminal type?" { send "vt220\r" }
expect "System hostname?" { send «ref("hostname")»; send "\r"  }

Do not configure network interfaces.

expect "Network interface to configure?" {
    send "done\r"
}

DNS Domain name.

expect "DNS domain name?" {
    send «ref("domain")»;
    send "\r";
}

DNS Domain name.

expect "DNS nameservers?" {
    send "1.1.1.1\r";
}

Root password.

expect "Password for root account?" {
    sleep 1
    send -h «ref("root-password")»
    send "\r"
}
expect "Password for root account? (again)" {
    sleep 1
    send -h «ref("root-password")»
    send "\r"
}

Do not start sshd(8) by default yet. Will be enabled later.

expect "Start sshd(8) by default?" {
    send "no\r"
}

Do not start xenodm(1) by default yet. Will be enabled later.

expect "Do you want the X Window System to be started by xenodm(1)?" {
    send "no\r"
}

Keep COM0 available after reboot to the freshly installed system. Will be disabled after sshd(8) is enabled.

expect "Change the default console to com0?" {
    send "yes\r"
    expect "Which speed should com0 use?" {
        send "115200\r"
    }
}

No need to add a user at this step.

expect "Setup a user?" {
    send "no\r"
}
expect "Allow root ssh login?" {
    send "no\r"
}
expect "Which disk is the root disk?" {
    send "sd1\r"
}
expect "Use (W)hole disk MBR, whole disk (G)PT" {
    send "gpt\r"
}

Use custom layout, use entire volume as /.

expect "Use (A)uto layout, (E)dit auto layout, or create (C)ustom layout?" {
    send "c"
    send "\r"
    expect ">"            { send "a a"  ; send "\r" }
    expect "offset:"      {               send "\r" }
    expect "size:"        { send "90%"  ; send "\r" }
    expect "FS type:"     {               send "\r" }
    expect "mount point:" { send "/"    ; send "\r" }
    expect ">"            { send "a b"  ; send "\r" }
    expect "offset:"      {               send "\r" }
    expect "size:"        { send "*"    ; send "\r" }
    expect "FS type:"     { send "swap" ; send "\r" }
    expect "*>"           { send "w"    ; send "\r" }
    expect ">"            { send "p"    ; send "\r" }
    expect ">"            { send "q"    ; send "\r" }
}

(Alternative) Use automatic layout, which produces different results depending on volume size.

expect "Use (A)uto layout, (E)dit auto layout, or create (C)ustom layout?" {
    send "a\r"
}
expect "Which disk do you wish to initialize?" {
    send "done\r"
}
expect "Location of sets?" {
    send "disk\r"
}
expect "Is the disk partition already mounted?" {
    send "no\r"
}

Install from `wd0`, which is USB installation media.

expect "Which disk contains the install media?" {
    send "wd0\r"
}
expect "Which wd0 partition has the install sets?" {
    send "a\r"
}
expect "Pathname to the sets?" {
    send "\r"
}

Install everything but games.

expect "Set name(s)?" {
    send -- "-game*\r\r"
}

There is no SHA256.sig on the installation drive. This step will triger installation, thus “notimeout”.

expect "Continue without verification?" {
    send "yes\r"
    «notimeout»
}
expect "Location of sets? (disk http nfs or 'done')" {
    send "done\r"
}
expect "What timezone are you in?" {
    send «ref("time-zone")»;
    send "\r";
}

Not ready to reboot yet. Go back to the shell to install UEFI.

expect "Exit to (S)hell, (H)alt or (R)eboot?" {
    send "S\r"
    «expect-prompt»
}

Start setup

./setup-dialog

Install UEFI Boot Loader

Mount partition & copy EFI

newfs_msdos /dev/sd0i
mount /dev/sd0i /mnt2
cp /mnt/usr/mdec/BOOTX64.EFI /mnt2/efi/boot/
mount
umount /dev/sd0i

Mount /tmp as mfs

echo 'swap /tmp mfs rw,nodev,nosuid,-s=300m 0 0' >> /mnt/etc/fstab
chmod 1777 /mnt/tmp

Reboot

halt

Stop VM

sleep 5
./vm stop

Login into the new system

Start VM without the installation media, and type cryptodisk password:

./vm stop
USE_INSTALL=0 ./vm start
./type-password «pass-show("bioctl"

Login as root via COM

./login root «ref("root-password"

Post-install (Serial)

Tcl scripts

Crypto-disk password

«serial»
set password [lindex $argv 0];
«timeout»
expect "boot>"        { send "set device sr0a\r"          }
expect "boot>"        { send "\r"          }
expect "Passphrase: " { send "$password\r" }
expect "boot>"        { send "machine gop 15\r"      }
expect "boot>"        { send "boot /bsd\r"      }
expect "booting"

Login via tty0

«notimeout»
«serial»
set user     [lindex $argv 0];
set password [lindex $argv 1];
send "\r\r\r"
expect "login:"
send "$user\r"
sleep 1
expect "Password:"
send "$password\r"
«expect-prompt»
sleep 1

Add a normal user

Tcl script

«serial»
send   "\r"
«expect-prompt»
send   "adduser\r"

If /etc/adduser.conf doesn’t exits…

expect "Couldn't find /etc/adduser.conf" {
    expect "Enter your default shell:"                { send "ksh\r"; }
    expect "Default login class:"                     { send "default\r"}
    expect "Enter your default HOME partition:"       { send "/home\r"; }
    expect "Copy dotfiles from:"                      { send "/etc/skel\r"; }
    expect "Send welcome message?"                    { send "no\r"; }
    expect "Prompt for passwords by default"          { send "no\r"; }
    expect "Default encryption method for passwords:" { send "blowfish\r" }
}

New user

expect "Enter username"             { send «ref('user-name)» ; send "\r" }
expect "Enter full name"            { send "\r" }
expect "Enter shell"                { send "ksh\r" }
expect "Uid"                        { send «ref('user-id)» ; send "\r" }
expect "Login group"                { send «ref('user-group)» ; send "\r" }
expect "Invite a into other groups" { send "no\r" }
expect "Login class"                { send "default\r" }
expect "OK?"                        { send "y\r" }
expect "Add another user?"          { send "n\r" }
«expect-prompt»

Add user

./adduser

Configure doas(8)

Disable password promt for staff group. See doas.conf(5)

echo permit nopass :«ref("user-group"| tee /etc/doas.conf

Configure SSH

Change default parameters of sshd(8)

Backup original config

cp /etc/ssh/sshd_config{,.orig}

Disable motd

rm /etc/motd
ln -s /dev/null /etc/motd

Disable banner

perl -i -pE 's/[#]?(Banner)                 \s+ \S+/$1 none/x' /etc/ssh/sshd_config
perl -i -pE 's/[#]?(PrintMotd)              \s+ \S+/$1 no/x' /etc/ssh/sshd_config

Disable/enable X11 Forwading

perl -i -pE 's/[#]?(X11Forwarding)          \s+ \S+/$1 yes/x' /etc/ssh/sshd_config

Disable password authentication & root login

perl -i -pE 's/[#]?(PasswordAuthentication) \s+ \S+/$1 no/x' /etc/ssh/sshd_config
perl -i -pE 's/[#]?(PermitRootLogin)        \s+ \S+/$1 no/x' /etc/ssh/sshd_config

Enable sshd(8)

rcctl enable sshd
rcctl restart sshd

Add RSA key

(string-trim (shell-command-to-string "ssh-add -L"))
echo «ssh-key()» | doas -u a tee /home/$user/.ssh/authorized_keys

Enable network

Use rcctl & /etc/hostname.vio0 instead of dhclient

{
    echo "-inet6"
    echo "dhcp"
    echo "up"
} | tee /etc/hostname.vio0
perl -i -pE 's/(nameserver) \s+ \S+/$1 8.8.8.8/x' /etc/resolv.conf
sh /etc/netstart

Add fingerprint to known_hosts

ssh-keyscan -p «ref("ssh-port")» -H localhost | tee -a ~/.ssh/known_hosts

Post-install (SSH)

Configure sudo

Tramp does not support doas(8). Let’s install & configure sudo with the same permissions as doas.

echo "%$group ALL=(ALL) NOPASSWD: SETENV: ALL" | doas tee /etc/sudoers

Update firmware

doas fw_update -a
doas fw_update iwm
doas fw_update iwi
doas fw_update iwn
doas fw_update iwx

Disable com0 at boot

doas perl -i.bak -nE 'print unless /com0/' /etc/boot.conf

Fix resolution for QEMU

echo "machine gop 15" | doas tee -a /etc/boot.conf

wscons

echo 'keyboard.bell.volume=0'                       | doas tee     /etc/wsconsctl.conf
echo 'keyboard.map+="keysym Caps_Lock = Control_L"' | doas tee -a /etc/wsconsctl.conf
echo 'display.screen_off=60000'                     | doas tee -a /etc/wsconsctl.conf

sysctl

echo 'vm.swapencrypt.enable=1'                      | doas tee     /etc/sysctl.conf
echo 'machdep.lidaction=2' | doas tee -a  /etc/sysctl.conf
echo 'machdep.pwraction=1' | doas tee -a  /etc/sysctl.conf

ntpd

doas rcctl disable ntpd
doas rcctl stop ntpd

noatime softdep

doas perl -i.bak -pE 's/(?<=rw)(?!,noatime)/,noatime/' /etc/fstab
doas perl -i.bak -pE 's/(?<=rw)(?!,softdep)/,softdep/' /etc/fstab

Fix audio in QEMU

doas rcctl set sndiod flags -b24000
doas rcctl restart sndiod

Configuration

Install packages

Unlock database in case it’s locked (see pkg_check(8)).

doas pkg_check -f

Install a package (see pkg_add(8)).

[ "$NAME" ] && doas pkg_add -x -r "$NAME"

Emacs

Firefox

UA_FIX=https://gist.githubusercontent.com/andreoss/91a0d21dc99bd9eae8bce5d573fb5a00/raw/64d0926caf60103efab55ea4cc4150d5d86b369a/ua.js
SER_JS=https://raw.githubusercontent.com/pyllyukko/user.js/master/user.js
FIREFOX_BASE=/usr/local/lib/firefox
doas cp "$FIREFOX_BASE"/browser/defaults/preferences/all-openbsd.js{,.back}
curl "$USER_JS" | grep -v captive-portal | \
    doas tee -a "$FIREFOX_BASE"/browser/defaults/preferences/all-openbsd.js >/dev/null
curl "$UA_FIX" | doas tee -a "$FIREFOX_BASE"/browser/defaults/preferences/all-openbsd.js
doas sed -i s/user_pref/pref/ "$FIREFOX_BASE"/browser/defaults/preferences/all-openbsd.js

Switch to prefered shell (i.e Bash)

chsh -s `which $XSHELL`

Switch back to Korn Shell

chsh -s "/bin/ksh"

Enable apmd

-A
enables performance adjustment mode
-Z 5
hibernate at 5% battery life

See apmd(8).

doas mkdir /etc/apm
echo "#!/bin/sh"         | doas tee  /etc/apm/suspend
echo "pkill -USR1 xidle" | doas tee -a  /etc/apm/suspend
doas chmod +x /etc/apm/suspend
doas rcctl enable apmd
doas rcctl set apmd flags -A -Z 5
doas rcctl start apmd
doas rcctl check apmd

Readline

$include  /etc/inputrc
set bell-style visible

set blink-matching-paren on
set visible-stats        on

$if mode=vi

set editing-mode vi
set keymap       vi
set vi-cmd-mode-string "*"
set vi-ins-mode-string " "
set show-mode-in-prompt on

Control-l: clear-screen

set keymap vi-command
Control-l: clear-screen

set keymap vi-insert
Control-l: clear-screen

$endif

set emacs-mode-string  "&"

DNS Crypt Proxy

Enable and start service

doas rcctl enable dnscrypt_proxy
doas rcctl start dnscrypt_proxy
doas rcctl check dnscrypt_proxy

Configure dhclient

See man dhclient.conf.

echo "supersede domain-name-servers 127.0.0.1;" | doas tee /etc/dhclient.conf

Restart network

doas sh /etc/netstart

Now resolv.conf should contains-p local DNS server

grep nameserver /etc/resolv.conf

Configure X11

Autologin

echo "DisplayManager.*.autoLogin: «ref('user-name)»" | doas tee -a /etc/X11/xenodm/xenodm-config

Enable

doas rcctl enable xenodm
doas rcctl start xenodm
doas rcctl check xenodm

Window manager

Ratpoison

which ratpoison
echo "exec ratpoison" > ~/.xsession

StumpWM

Common Lisp

Complier
Quicklisp

https://www.quicklisp.org/beta-

curl -O https://beta.quicklisp.org/quicklisp.lisp
curl -O https://beta.quicklisp.org/quicklisp.lisp.asc
gpg --keyserver pgp.mit.edu --recv-keys 028B5FF7
gpg --verify quicklisp.lisp.asc quicklisp.lisp
sbcl --non-interactive --load quicklisp.lisp --eval "(quicklisp-quickstart:install)"

Add Quicklisp to .sbclrc

sbcl --non-interactive --load quicklisp/setup.lisp --eval "(ql-util:without-prompting (ql:add-to-init-file))"

Install StumpWM

sbcl --non-interactive --eval "(ql:quickload :bt-semaphore)"
sbcl --non-interactive --eval "(ql:quickload :external-program)"
sbcl --non-interactive --eval "(ql:quickload :swank)"
sbcl --non-interactive --eval "(ql:quickload :stumpwm)"
git clone https://github.com/andreoss/.stumpwm.d
echo "exec ~/.stumpwm.d/start.sh" > ~/.xsession

Miscellaneous

which urxvt

Configure shell

git clone https://github.com/andreoss/.config
ln -s ~/.config/shrc ~/.kshrc
ln -s ~/.config/shrc ~/.bashrc
ln -s ~/.config/shrc ~/.bash_profile
ln -s ~/.config/inputrc ~/.inputrc

Configure Emacs

git clone https://github.com/andreoss/.emacs.d

Misc

Media

Tools

(Optional) Migrate current configuration

which rsync

SSH

rsync -Lahv -e 'ssh -p «ref('ssh-port)»' ~/.ssh localhost:

GPG

rsync -Lahv -e 'ssh -p «ref('ssh-port)»' ~/.gnupg localhost:

Pass

rsync -Lahv -e 'ssh -p «ref('ssh-port)»' "$PASSWORD_STORE_DIR" localhost:

Adblock with unbound

Extra

Build Emacs

#!/bin/sh
mkdir -p ~/src
cd ~/src
if [ ! -d emacs ]; then git clone https://github.com/emacs-mirror/emacs; fi
cd ~/src/emacs
git pull
gmake clean
AUTOCONF_VERSION=2.65
CC=egcc
MAKEINFO='/usr/local/bin/gmakeinfo'
export AUTOCONF_VERSION MAKEINFO CC
./autogen.sh
./configure --prefix=$HOME/.local --with-json --with-x=lucid
gmake bootstrap
gmake
gmake install

About

Reproducible OpenBSD Installation with Org-Mode & Emacs

Topics

Resources

Stars

Watchers

Forks