Configuring Arch Linux on Dell XPS 15
In the previous post, we’ve successfully booted into Arch Linux from our encrypted root partition.
Let’s now configure it to our (my) liking.
Contents
- User management
- Arch User Repository
- X11 and Window Manager: dwm
- Terminal: xterm
- Input: Trackpad gestures (libinput)
- Sound
- Storage: NVMe SSD
- Graphics: Nvidia and Bumblebee
- Power Management
- Suspend/hibernate
- Networking: netctl, Unbound
- Security
- Browser: Firefox
- Backups: rsnapshot
- Password Management: pass
- Gaming: Steam/Wine
- iPhone
- Sources
User management
# Add new user
$ useradd -m -G wheel saminiir
# Uncomment wheel group
$ grep wheel /etc/sudoers
%wheel ALL=(ALL) ALL
# %wheel ALL=(ALL) NOPASSWD: ALL
# Harden the root pasword if necessary
$ passwd
Arch User Repository
The Arch User Repository (AUR) contains community-driven packages. yaourt
is a popular front-end for it. Enable it by:
$ pacman -S git
$ git clone https://aur.archlinux.org/package-query.git
$ cd package-query
$ makepkg -si
$ cd ..
$ git clone https://aur.archlinux.org/yaourt.git
$ cd yaourt
$ makepkg -si
$ cd ..
X11 and Window Manager: dwm
Determine your 3D card:
$ lspci | grep -e VGA -e 3D
01:00.0 3D controller: NVIDIA Corporation GM107M [GeForce GTX 960M] (rev a2)
# Install nvidia proprietary drivers (pulls in xorg as well)
# Be sure to select nvidia and libinput if it prompts for the repo extras
$ pacman -S nvidia
$ pacman -S xorg-server-utils xorg-xinit
$ pacman -S openssh slock terminus-font
$ git clone https://github.com/saminiir/dotfiles.git
$ ln -s ~/dotfiles/xorg/xinitrc .xinitrc
$ ln -s ~/dotfiles/xorg/Xresources .Xresources
Configure dwm
to e.g. use xterm
as terminal and change the modifier key to Windows key (Mod4Mask
):
$ git clone https://aur.archlinux.org/dwm-git.git
$ cd dwm-git && makepkg
$ grep "define MODKEY" src/dwm/config.h
#define MODKEY Mod4Mask
$ grep "char \*termcmd" src/dwm/config.h
static const char *termcmd[] = { "xterm", NULL };
$ makepkg -fi
$ startx
dwm
should start.
Terminal: xterm
For some reason, I’m stuck on using xterm
. Even its manual page says that it needs to be rewritten, so feel free to go find an alternative.
For the rest of us, at least the following tweaks are useful:
# Make bash auto-complete better
$ pacman -S bash-completion
# Install Google's `noto` font package
$ pacman -S noto-fonts
# For easy command-on-key binding
$ pacman -S xbindkeys
Finally, use the .Xresources
from my dotfiles:
$ git clone git@github.com:saminiir/dotfiles.git
$ cd ~ && ln -s ~/dotfiles/xorg/Xresources .Xresources
Important things for me is that Caps Lock is mapped as a Control key, and that the Alt (or whatever is left of space bar) acts as Meta. These can be found from the dotfiles
, but I’ll highlight them here too:
# No caps lock - Map it as ctrl instead
$ setxkbmap -option ctrl:nocaps
# Kill X11 with ctrl+alt+backspace
$ setxkbmap -option terminate:ctrl_alt_bksp
# Change keyboard layout on right shift
$ setxkbmap -layout us,fi -option grp:rshift_toggle
$ grep meta~/.Xresources
xterm*metaSendsEscape: true
Furthermore, I like to have my tilde character lower on the keyboard, on the right side of left-shift:
$ grep tilde /usr/share/X11/xkb/symbols/pc
key <LSGT> { [ grave, asciitilde, grave, asciitilde ] };
Additionally, increase the Linux console font size:
$ cat /etc/vconsole.conf
FONT=ter-i32n
And apply it to early userspace too:
$ grep consolefont /etc/mkinitcpio.conf
HOOKS="base udev autodetect modconf block encrypt lvm2 resume filesystems keyboard fsck consolefont"
$ mkinitcpio -p linux
Input: Trackpad gestures (libinput)
I chose to use libinput
over synaptics for the touchpad driver.
$ pacman -S libinput xf86-input-libinput
$ libinput-list-devices
$ xinput list-props "DLL06E4:01 06CB:7A13 Touchpad"
# Enable tap-click
$ xinput set-prop "DLL06E4:01 06CB:7A13 Touchpad" "libinput Tapping Enabled" 1
# Increase pointer acceleration
$ xinput set-prop "DLL06E4:01 06CB:7A13 Touchpad" "libinput Accel Speed" 1
These can be found from xutils
in my dotfiles (described above).
Sound
Just install alsa-utils
, and use alsamixer
to unmute the master channel. Should just work.
For keyboard hotkeys, add the following to xbindkeys
configuration:
$ grep -A1 amixer ~/.xbindkeysrc
"/usr/bin/amixer set Master 5%+"
XF86AudioRaiseVolume
--
"/usr/bin/amixer set Master 5%-"
XF86AudioLowerVolume
--
"/usr/bin/amixer set Master toggle"
XF86AudioMute
Storage: NVMe SSD
Trimming is an operation SSDs benefit greatly of. However, enabling it for encrypted drives is a security risk1. The options are to enable trim and suffer the weakened security, or at regular intervals take maintenance on the drive.
One way of minimizing writes, which can especially wear down SSD, is to use the noatime
or relatime
in the drives mount options. For me, this was enabled by default:
$ grep relatime /etc/fstab
.. relatime ..
Graphics: Nvidia and Bumblebee
Let’s install bumblebee for smart switching of the integrated and dedicated graphics:
$ pacman -S bumblebee primus bbswitch
# Should show the traditional 3D-accelerated gears
$ primusrun glxgears
# Reboot. After rebooting, you should see that bbswitch has disabled the card,
# which is good for saving the battery on the laptop
$ cat /proc/acpi/bbswitch
0000:01:00.0 OFF
Power Management
Powertop
powertop
is the best. Install it.
$ pacman -S powertop
Run calibration as many times as you like. Eventually, powertop will start to show accurate power consumption estimates. Additionally, run it also with --auto-tune
:
$ powertop --calibrate
$ powertop --auto-tune
Also, add a systemd service for autotuning on startup:
$ cat /etc/systemd/system/powertop.service
[Unit]
Description=Powertop tunings
[Service]
Type=oneshot
ExecStart=/usr/bin/powertop --auto-tune
[Install]
WantedBy=multi-user.target
$ systemctl enable powertop.service
Battery status
I use the command acpi -b
for checking battery status. You need the package acpi
for it.
Backlight
The display’s backlight is a huge power drain, and it is often convenient to have a hotkey to adjust it.
$ pacman -S light
Now, add commands to xbindkeys
for manipulating the backlight:
$ grep -A3 light ~/.xbindkeysrc
"/usr/bin/light -U 5"
m:0x0 + c:232
XF86MonBrightnessDown
"/usr/bin/light -A 5"
m:0x0 + c:233
XF86MonBrightnessUp
Laptop mode
Also, activate laptop-mode2:
$ cat /etc/sysctl.d/laptop.conf
vm.laptop_mode = 5
Suspend/hibernate
Add resume
to the kernel parameters:
$ vi /boot/loader/entries/arch-encrypted-lvm.conf
options ... resume=/dev/mapper/MyVol-swap quiet rw
Add the resume
hook to initramfs.
$ vi /etc/mkinitcpio.conf
HOOKS="base ... lvm2 resume ..."
Note that the resume
hook should be after lvm2
!
Then, regenerate the initramfs:
$ mkinitcpio -p linux
Debugging suspend/hibernation
If suspend/hibernation does not work at first, debug it by setting pm_test
$ cat /sys/power/pm_test
none core processors platform devices freezer
$ echo freezer | sudo /sys/power/pm_test
$ systemctl suspend
$ systemctl hybrid-sleep
Go through the different stages (freezer
, devices
..) and watch the output of journalctl -r
for what goes wrong.
Locking screen on sleep
I want to lock the screen (slock
) whenever the system is put to sleep.
This can be achieved by setting systemd units that have the sleep.target
activated3. See more examples from dotfiles/systemd
:
$ cat /etc/systemd/system/suspend@saminiir.service
[Unit]
Description=User suspend actions
Before=sleep.target
[Service]
User=%I
Type=simple
Environment=DISPLAY=:0
ExecStart=/usr/bin/slock
ExecStartPost=/usr/bin/sleep 1
[Install]
WantedBy=sleep.target
$ systemctl enable suspend@saminiir.service
Networking: netctl, Unbound
Use whatever network manager that rows your boat. I have experience in NetworkManager, but the default netctl
in Arch Linux might be worth using too.
I’ve used dnsmasq
in the past, but unbound
seems like a cool caching DNS resolver that handles DNSSEC as well.
$ pacman -S expat unbound
See the documentation how to configure it. Most importantly your /etc/resolv.conf
should point to 127.0.0.1
to use your own DNS program.
$ cat /etc/resolv.conf
# Generated by resolvconf
domain lan
nameserver 127.0.0.1
Security
These are the basic steps I took to harden my Arch Linux.
To lockout a user for ten minutes after three failed login attempts:
$ grep pam_tally /etc/pam.d/system-login
#auth required pam_tally.so onerr=succeed file=/var/log/faillog
auth required pam_tally.so deny=2 unlock_time=600 onerr=succeed file=/var/log/faillog
Do not allow SSH login as root:
$ grep PermitRootLogin /etc/ssh/sshd_config
PermitRootLogin no
Restrict access to dmesg:
$ cat /etc/sysctl.d/50-dmesg-restrict.conf
kernel.dmesg_restrict = 1
Configure firewall to drop pretty much all incoming connections, but allow outgoing and already established ones:
$ cat /etc/iptables/iptables.rules
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p icmp -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
COMMIT
Do the same for IPv6 (ip6tables). You have to adjust some of the rules to IPv6.
Harden the Linux TCP/IP stack:
$ cat /etc/sysctl.d/51-tcp-ip-stack.conf
net.ipv4.tcp_rfc1337 = 1
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.all.send_redirects = 0
## ICMP routing redirects (only secure)
##net.ipv4.conf.all.secure_redirects = 1 (default)
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.all.accept_redirects=0
net.ipv6.conf.default.accept_redirects=0
net.ipv6.conf.all.accept_redirects=0
Browser: Firefox
I use Firefox. With a high DPI screen, however, you should increase the pixel density. Go to about:config
and set the layout.css.devPixelsPerPx
to 2.
Backups: rsnapshot
I use rsnapshot
4. TODO.
Password Management: pass
This is kind of an extra section, since password management is pretty personal. I, however, have liked the utility pass
, which is a simplistic bash script for linux utilities like pwgen
.
$ pacman -S pass
# Or if you have an existing pass-store, e.g. in a private cloud, symlink the folder ~/.password-store to it
$ pass init
pass
uses your gpg-keys for encrypting/decrypting the files by default. See my earlier blog post on how to establish GPG.
Then, synchronize the ~/.password-store
between computers however you like.
Gaming: Steam/Wine
Because Wine uses 32-bit libraries, you have to enable the multilib
repo
# Uncomment multilib repo
$ vi /etc/pacman.conf
$ pacman -S wine lib32-alsa-lib lib32-alsa-plugins
$ pacman -S wine-mono wine_gecko winetricks
Setup a 32-bit wine environment:
$ WINEARCH=win32 WINEPREFIX=~/win32 winecfg
# Install .NET Framework 4.0, just for laughs
$ WINEARCH=win32 WINEPREFIX=~/win32 winetricks -q dotnet45 corefonts
Then, use `winetricks to install Steam:
$ WINEARCH=win32 WINEPREFIX=~/win32 winetricks steam
You should be able to start Steam/Wine. Your mileage may vary. It is easy to have missed lib32 packages on a 64-bit system, so you might have to chase down dependencies.
$ WINEARCH=win32 WINEPREFIX=~/wine32 primusrun wine ~/wine32/drive_c/Program\ Files/Steam/Steam.exe
Gamepad
My generic xbox pad just worked out-of-the-box. See the kernel docs for more info5.
$ dmesg | tail -n3
[ 3508.420268] usb 1-1: new full-speed USB device number 5 using xhci_hcd
[ 3508.609392] input: Generic X-Box pad as /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/input/input21
[ 3508.609619] usbcore: registered new interface driver xpad
You can test the pad:
$ pacman -S joyutils
$ jstest /dev/input/js0
iPhone
I like the robustness of iPhones. I tried a Sony Z5 Compact, but the first drop broke the glass. My iPhone 5 of three years has taken a substantial amount of beating and does not have a dent. Go figure.
Install libimobiledevice
to access the iPhone in Linux:
$ pacman -S libimobiledevice usbmuxd
$ systemctl start usbmuxd
Then, connect your iPhone via USB. Have the screen unlocked. It should be detected:
Jun 28 18:43:24 localhost kernel: ipheth 1-2:4.2: Apple iPhone USB Ethernet device attached
Jun 28 18:43:24 localhost kernel: usbcore: registered new interface driver ipheth
Jun 28 18:43:24 localhost kernel: ipheth 1-2:4.2 enp0s20f0u2c4i2: renamed from eth0
$ idevicepair pair
Then, you can backup your iPhone:
$ idevicebackup2 backup ~/Documents/iphone-backups/
If you liked this post, you can share it with your followers and follow me on Twitter!