Archlinux configuration

From gr0x0rd
Jump to navigation Jump to search

Installation

Start the ssh daemon

Once up and running, you should check to see that you have a network connection. Once you do, enable connections via root to ssh:

nano /etc/sshd/ssh_config

Add the directive PermitRootLogin yes to the file. Once done, start the ssh daemon.

systemctl start sshd.service

You should now be able to connect via another machine with, say, access to this wiki. This will allow you to copy and paste commands instead of typing.

Prepare the disks

This guide assumes a RAID1 installation on a UEFI motherboard.

fdisk -l

The disks should be recognized as /dev/sda and /dev/sdb. Your boot USB should be recognized as /dev/sdc.

fdisk /dev/sda

If there are any existing partitions on the disk, delete them by pressing d. This will, of course, delete all data on the disk. Press p to see existing partitions. When there are none, let's create the EFI system partition.

n
<press enter>
<press enter>
+512M

Set the partition type to "EFI System".

t
1

Create a swap partition. This should be half the size of the RAM in your system. We will have a non-RAID swap partition on each disk. This provides the benefit of striping while still remaining redundant.

n
<press enter>
<press enter>
+16G  

Set the partition type to swap.

t
<press enter>
19

Finally, create the root partition.

n
<press enter>
<press enter>
<press enter>

Set the type of filesystem to RAID.

t
<press enter>
29

Now that you have your pretty disk partitioned, save what you've done.

w

Finally, copy the partition table you've created to the second disk.

sfdisk -d /dev/sda | sfdisk /dev/sdb

Prepare filesystems

The EFI system partitions need to be formatted as FAT.

mkfs.fat -F32 /dev/sda1
mkfs.fat -F32 /dev/sdb1

Create the swap space on both drives.

mkswap /dev/sda2
swapon /dev/sda2
mkswap /dev/sdb2
swapon /dev/sdb2

Before we can create the filesystem for the root partition, we need to set up and enable the RAID.

mdadm --create --verbose --level=1 --metadata=1.2 --raid-devices=2 --name=root1 /dev/md0 /dev/sda3 /dev/sdb3

It's probably wise to let the RAID complete before formatting the filesystem. You can watch it sync up via

watch cat /proc/mdstat

Once it's done, create the filesystem.

mkfs.ext4 /dev/md0

Mount the file systems

Set the system clock.

timedatectl set-ntp true

First let's mount the newly created RAID root partition.

mount /dev/md0 /mnt

We now need to mount the ESP partition from the first disk as /efi.

mkdir /mnt/efi
mount /dev/sda1 /mnt/efi

Install the base packages

This will create a base archlinux system on your newly created RAID root volume.

pacstrap /mnt base

Configure the system

genfstab -U /mnt >> /mnt/etc/fstab
arch-chroot /mnt

Make a copy of the fstab in case of disk failure in the future:

cp /etc/fstab /etc/fstab.sda

Preserve your RAID configuration in the new installation.

mdadm --detail --scan >> /etc/mdadm.conf

It might also be helpful to add your email address to the file, and enable monitoring.

nano /etc/mdadm.conf

Adjust the MAILADDR and PROGRAM lines accordingly. The mdadm package will be required to assemble the array, so let's install it.

pacman -S mdadm

Configure the mdadm service to start at boot so monitoring alerts can be sent.

Next, set the time zone.

ln -sf /usr/share/zoneinfo/Canada/Pacific /etc/localtime
hwclock --systohc
nano /etc/locale.gen

Uncomment: en_US.UTF-8 UTF-8

locale-gen
nano /etc/locale.conf

add: LANG=en_US.UTF-8

nano /etc/hostname

add: system_name

nano /etc/hosts

add any relevant references for your local network.

ln -s /dev/null /etc/udev/rules.d/80-net-setup-link.rules

Since our system is RAID, we need to add support for mdadm into the initramfs image.

nano /etc/mkinitcpio.conf

Find the HOOKS section and be sure to add mdadm before filesystems. Then, generate the image

mkinitcpio -p linux
passwd

Bootloader

pacman -S grub efibootmgr intel-ucode

Edit the grub configuration file so it loads the appropriate RAID modules.

nano /etc/default/grub

Add the following to the GRUB_CMDLINE_LINUX_DEFAULT= section:

root=/dev/md0

Add the following to the GRUB_PRELOAD_MODULES section:

mdraid09 mdraid1x

Next we install the bootloader.

grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB

For the sake of redundancy, we also need to install it on the other drive as well.

umount /efi
mount /dev/sdb1 /efi
grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB

Make a backup of the fstab configuration with this drive's efi UUID.

genfstab >> /etc/fstab.sdb

Revert to the previous configuration.

umount /efi
mount /dev/sda1 /efi

Generate the configuration file.

grub-mkconfig -o /boot/grub/grub.cfg

Start network at boot

systemctl enable dhcpcd

Reboot the system

exit
umount /mnt/efi
umount /mnt
reboot

Optional: RAID testing

During testing it was found that if mdadm_udev was used in the place of mdadm in the initramfs HOOKS configuration, the system would not boot.

Have a look at the /etc/fstab.sda and /etc/fstab.sdb files. In each, ensure that the correct efi entry is listed, and remove the swap dependency for the other drive.

Be sure to preserve a copy of the master fstab.

cp /etc/fstab /etc/fstab.raid

Failure of /dev/sda

Power off the system and remove the cable from /dev/sda. Start the system. It should fail on the missing efi and swap partitions.

Enter the root password to enter maintenance mode. Make the sdb fstab the primary and reboot.

cp /etc/fstab.sdb /etc/fstab
reboot

Your system should be up and running with the single drive. Once you have a replacement for the failed drive, you will need to boot with an iso image and copy the partition table to the new disk. If you're testing and you've reconnected the cable for the missing drive, mdadm might now automatically rebuilt it. To do so,

mdadm --manage /dev/md0 --add /dev/sda3

Watch as the rebuild completes.

watch cat /proc/mdstat

Failure of /dev/sdb

This did not yield, the expected result, the system ended at a GRUB screen (something wrong with efi installation on /dev/sdb or the initramfs image).

After booting with the iso image, it was necessary to remove and restart the RAID with the correct enumeration.

mdadm --stop /dev/md127
mdadm --assemble --force /dev/md0 /dev/sda3

Mount the volumes and chroot.

mount /dev/md0 /mnt
mount /dev/sda1 /mnt/efi
arch-chroot /mnt

Re-generate the initramfs image.

mkinitcpio -p linux

Reinstall grub.

grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB

Reboot.

exit
umount /mnt/efi
umount /mnt
reboot

Upon reboot, you will run into a similar scenario as with when sda was missing (timeout on the missing swap). After the 90 second timeout, log in as root and copy the backup fstab.

cp /etc/fstab.sda /etc/fstab
reboot

The system should come up clean. Restore the raid fstab file:

cp /etc/fstab.raid /etc/fstab
shutdown -h now

Reconnect /dev/sdb and power on. As before, the RAID won't resume on its own, which is stupid. So kick that off.

mdadm --manage /dev/md0 --add /dev/sdb3

At this point we have demonstrated we can boot from either drive with some minor tinkering.

Synchronization of boot partitions

My initial thought was to do this via cron. But envision a scenario where a drive fails, the drive letters are reordered, and the script runs? That could be disastrous. So I think the script is run best ad-hoc, after reboots or changes to the system, as required. Here is a script to do this:

file: /usr/bin/syncefi

#/bin/bash
umount /efi
dd if=/dev/sda1 of=/dev/sdb1 bs=64K conv=noerror,sync status=progress
mount /dev/sda1 /efi

After creating the script, make it executable

sudo chmod +x /usr/bin/syncefi

Optional: configure the /home

This section assumes you have a 4-disk RAID5 configuration for /home, and assumes you have connected the drives. First ensure raid5 support is enabled:

modprobe raid5

Check the status of the array. Chances are it's already running, but under the wrong md value.

cat /proc/mdstat

Stop the array and start it up again under the correct name.

mdadm --stop /dev/md127
mdadm --assemble /dev/md1 /dev/sd[cdef]3

Preserve the configuration.

mdadm --detail --scan >> /etc/mdadm.conf
nano /etc/mdadm.conf

Remove any redundant entries, and ensure the correct md names are set. Next, mount the volume.

mount /dev/md1 /home

Generate a new version of fstab.

pacman -S arch-install-scripts
genfstab -U / >> /etc/fstab.home

Examine the new file and copy the entry for md1 into the other versions of the file. If you don't want the file system check running with every boot, be sure to end the entry with "0 0".

Basic system configuration

log in as root

Create a user

useradd -m -G wheel,audio -s /bin/bash gr0x0rd
passwd gr0x0rd

Set up sudo

pacman -S sudo
nano /etc/sudoers

comment out wheel group

exit

ssh daemon

log in as gr0x0rd

sudo pacman -S polkit
sudo pacman -S openssh
sudo nano /etc/ssh/sshd_config

change port 22 to 2112 and disable root login

sudo systemctl start sshd
sudo systemctl enable sshd

Cron

sudo pacman -S cronie
sudo systemctl enable cronie
sudo systemctl start cronie

smtp server

sudo pacman -S msmtp msmtp-mta

To set up msmtp to work with shawmail, use the following settings.
file: /etc/msmtprc

# Set default values for all following accounts.
defaults
#auth           on
#tls            on
#tls_trust_file /etc/ssl/certs/ca-certificates.crt
#tls_starttls   off
logfile        ~/.msmtp.log
auto_from       on
maildomain      gr0x0rd.com

# Gmail
account        gmail
host           smtp.gmail.com
port           587
from           gr0x0rd@gmail.com
user           gr0x0rd
password       supersecretpassword

# shawmail
account         shawmail
host            mail.shaw.ca
port            25
domain          gr0x0rd.com

# lightspeed
account		lightspeed
host		mail.lightspeed.ca
port		587
domain		gr0x0rd.com

# Set a default account
#account default : gmail
#account default : shawmail
account default : lightspeed

antivirus

sudo pacman -S clamav
sudo systemctl enable clamav-daemon.service
sudo systemctl start clamav-daemon.service
sudo freshclam

Arch User Repository

sudo pacman -S --needed base-devel
sudo mkdir -p /usr/local/aur
sudo pacman -S git
sudo chmod -R 777 /usr/local/aur

Yay

Yay is a package manager for aur, similar to pacman, which can be used to facilitate management of aur packages on your system.

cd /usr/local/aur
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si

After yay has been installed, you can use it to install packages listed in the aur via

yay -S <packagename>

Enable multilib

sudo nano /etc/pacman.conf

uncomment [multilib] and Include = /etc/pacman.d/mirrorlist

Tools

sudo pacman -S dnsutils net-tools nmap

Hide a volume

If there is a disk volume appearing on your desktop that you'd prefer to have hidden, create the following file:

sudo nano /etc/udev/rules.d/hide-partitions.rules

Add the following directive:

KERNEL=="nvme0n1",ENV{UDISKS_IGNORE}="1"

Where nvme0n1 is the name of the volume you'd like to hide.

Desktop environment

Graphic driver

sudo pacman -S nvidia nvidia-settings
sudo mkinitcpio 
sudo reboot

confirm the system is using the nvidia driver via lspci -v

Window Manager

sudo pacman -S xorg xterm
sudo pacman -S xfce4 xfce4-goodies gvfs gvfs-afc udisks2 file-roller ark xarchiver thunar-volman
sudo nano /etc/X11/xinit/xinitrc

add: exec startxfce4

sudo pacman -S lightdm lightdm-gtk-greeter
sudo nano /etc/lightdm/lightdm.conf

add to [Seat:*] section: greeter-session=lightdm-yourgreeter-greeter

sudo systemctl enable lightdm

reboot or start the desktop environment via startxfce4

sudo pacman -S ttf-dejavu

resolves messed up terminal fonts in xfce

Multiple Displays

Despite the nvidia-generated xorg.conf file articulating the various displays and layouts, newer versions of xfce did not play nicely with the configuration. The solution was to use xfce's display manager. In order to get the xfce display manager to recognize the screens properly, xrandr had to be used.

$ xrandr

The output only displayed one screen; the others needed to be added.

$ xrandr --output DVI-D-0 --right-of HDMI-0
$ xrandr --output DP-0 --mode 1280x1024 --rate 60.02
$ xrandr --output DP-0 --right-of DVI-D-0

The screens were not recognized, and could be managed via the xfce display manager (Settings->Display).

compiz

yay -S compiz emerald emerald-themes fusion-icon

Once compiz is running, xfce seems to "remember" it, even after logon/off. To start it

compiz --replace &

There is a bug in the xfce panel where it squishes the multiple desktop viewport. For that, a patched version of the panel is needed.

yay -S xfce4-panel-compiz

Sound

sudo pacman -S alsa-utils lib32-libpulse lib32-alsa-plugins alsa-oss
alsamixer

unmute the master, set the volume to a decent level

Basic desktop software

sudo pacman -S firefox gedit libreoffice-fresh epdfview gftp xfce4-screenshooter
yay -S ttf-ms-fonts

Brave browser

Prerequisites.

sudo pacman -S gconf gtk3 libgnome-keyring libxss nss
yay -S brave-bin

Google chrome browser

Let's face it, now that Google have fired James Damore and removed "don't be evil" from their terms of service, and collaborated to nuke Parler, there's no need to ever use this browser again. See Brave above.

Image viewer

sudo pacman -S eog

Screen saver

sudo pacman -S xscreensaver xfce4-power-manager

Disable screensaver when playing video in browser

This is best accomplished using caffeine-ng.

yay -S caffeine-ng

Multimedia

sudo pacman -S pulseaudio xfce4-pulseaudio-plugin pavucontrol pulseaudio-alsa gst-plugins-good
sudo pacman -S mplayer vlc ffmpeg kodi mencoder devede

vlc chromecast support

sudo pacman -S libmicrodns protobuf

Torrent client

sudo pacman -S transmission-gtk transmission-cli

Password Manager

yay -S password-gorilla

Barrier

Allows you to control another computer using the keyboard/mouse from the server. Needs to be installed on the server and client.

sudo pacman -S barrier

Mobile devices

Android

To mount android phones under xfce using Thunar, you'll need...

sudo pacman -S gvfs gvfs-mtp

A GUI based too that I haven't figured out how to use is

sudo pacman -S android-file-transfer

iPhone

Install the package so that thunar can pick up iOS devices.

pacman -S gvfs-afc

TODO: This isn't work- the photos didn't show up after mounting, some other files did. Maybe there is some way to initiate the storage access as happens in windows?

Bluetooth headset

Install the bluetooth stack.

sudo pacman -S bluez bluez-utils bluez-libs

Load the bluetooth kernel module

sudo modprobe btusb

Enable and start the service

sudo systemctl enable bluetooth.service
sudo systemctl start bluetooth.service

Install the components for a bluetooth headset.

sudo pacman -S pulseaudio-bluetooth pulseaudio-alsa

After this, the headset was available as an output device in volume control through the pulseaudio stack.

Java

sudo pacman -S jre-openjdk

Remote display connections

To log into an X session remotely using Microsoft's RDP client, there is likely a solution, but I don't currently have one. This could be researched if needed, but right now I don't need it at all...

Audio over chromecast

Audio works when casting a tab in chrome, but not for casting apps or your entire desktop, because let's face it- google sucks. In order to get that feature working, you'll need a handy tool call mkchromecast. First, some dependencies...

sudo pacman -S python-pyqt5

The rest you'll need from AUR.

yay -S python-casttube python-pychromecast mkchromecast

Once installed, you can run mkchromecast from the menu, and it will appear in the system tray. To cast, you'll need to direct your audio to mkchromecast using your favourite audio mixer.

Server settings

System monitor

sudo pacman -S conky

restored .conkyrc from backup. Here's a sample .conkyrc:

--################################
--
-- gr0x0rds .conkyrc
--
--################################ 

conky.config = {
	double_buffer = true, -- stops flickering
	alignment = 'bottom_right',
	xinerama_head = 2,
	update_interval = 3.0,
	own_window = true,
	own_window_transparent = false,
	own_window_class = 'conky', -- override -- conky 
	own_window_type = 'desktop', -- override -- normal  
	own_window_type = 'normal',
	own_window_hints = 'undecorated,below,sticky,skip_taskbar,skip_pager',
	own_window_argb_visual = true, -- this provides transparency
	own_window_argb_value = 0,
};

conky.text = [[
${alignc}$nodename - $sysname $kernel on $machine
${color darkslateblue}System${hr 1}
${color steelblue}Uptime:$color $uptime ${alignr}${color steelblue}Load:$color $loadavg
${alignr}${color}Mem usage       PID    CPU%   MEM%    CPU usage       PID    CPU%   MEM%
${alignr}${color #ddaa00} ${top_mem name 1}${top_mem pid 1} ${top_mem cpu 1} ${top_mem mem 1}    ${top name 1}${top pid 1} ${top cpu 1} ${top mem 1}
${alignr}${color steelblue} ${top_mem name 2}${top_mem pid 2} ${top_mem cpu 2} ${top_mem mem 2}    ${top name 2}${top pid 2} ${top cpu 2} ${top mem 2}
${alignr}${color steelblue} ${top_mem name 3}${top_mem pid 3} ${top_mem cpu 3} ${top_mem mem 3}    ${top name 3}${top pid 3} ${top cpu 3} ${top mem 3}
${alignr}${color steelblue} ${top_mem name 4}${top_mem pid 4} ${top_mem cpu 4} ${top_mem mem 4}    ${top name 4}${top pid 4} ${top cpu 4} ${top mem 4}
${color steelblue}Swap Usage:$color $swap${color steelblue}/$color$swapmax - $swapperc% ${swapbar}
${color steelblue}RAM Usage:$color $mem${color steelblue}/$color$memmax - $memperc% ${membar}
${color steelblue}Processes:$color $processes  ${alignr}${color steelblue}Running:$color $running_processes
# --- cpu settings --- #
${color darkslateblue}${exec cat /proc/cpuinfo | grep 'model name' | sed -e 's/.*: //' | uniq}${hr 1}
${color #ddaa00}Core1 ${color steelblue}Frequency: $color${freq cpu1} ${color steelblue}MHz          ${alignr}Temperature: ${color}${execi 3 sensors | grep "Core 0:" | cut -d+ -f2 | cut -c1-2} ${color steelblue}C
${color steelblue}Usage:${color #cc2222} ${cpu cpu1}% ${cpubar cpu1}
${color red}${cpugraph cpu1 0000ff 00ff00}
${color #ddaa00}Core2 ${color steelblue}Frequency: $color${freq cpu1} ${color steelblue}MHz          ${alignr}Temperature: ${color}${execi 3 sensors | grep "Core 1:" | cut -d+ -f2 | cut -c1-2} ${color steelblue}C
${color steelblue}Usage:${color #cc2222} ${cpu cpu2}% ${cpubar cpu2}
${color red}${cpugraph cpu2 0000ff 00ff00}
${color #ddaa00}Core3 ${color steelblue}Frequency: $color${freq cpu1} ${color steelblue}MHz          ${alignr}Temperature: ${color}${execi 3 sensors | grep "Core 2:" | cut -d+ -f2 | cut -c1-2} ${color steelblue}C
${color steelblue}Usage:${color #cc2222} ${cpu cpu3}% ${cpubar cpu3}
${color red}${cpugraph cpu3 0000ff 00ff00}
${color #ddaa00}Core4 ${color steelblue}Frequency: $color${freq cpu1} ${color steelblue}MHz          ${alignr}Temperature: ${color}${execi 3 sensors | grep "Core 3:" | cut -d+ -f2 | cut -c1-2} ${color steelblue}C
${color steelblue}Usage:${color #cc2222} ${cpu cpu4}% ${cpubar cpu4}
${color red}${cpugraph cpu4 0000ff 00ff00}
${color #ddaa00}Core5 ${color steelblue}Frequency: $color${freq cpu1} ${color steelblue}MHz          ${alignr}Temperature: ${color}${execi 3 sensors | grep "Core 4:" | cut -d+ -f2 | cut -c1-2} ${color steelblue}C
${color steelblue}Usage:${color #cc2222} ${cpu cpu3}% ${cpubar cpu5}
${color red}${cpugraph cpu5 0000ff 00ff00}
${color #ddaa00}Core6 ${color steelblue}Frequency: $color${freq cpu1} ${color steelblue}MHz          ${alignr}Temperature: ${color}${execi 3 sensors | grep "Core 5:" | cut -d+ -f2 | cut -c1-2} ${color steelblue}C
${color steelblue}Usage:${color #cc2222} ${cpu cpu4}% ${cpubar cpu6}
${color red}${cpugraph cpu6 0000ff 00ff00}
# --- graphics settings --- #
${color darkslateblue}nVidia Corporation ${execi 10 nvidia-smi | grep "GeForce" | cut -d+ -f2 | cut -c8-22}0 Ti${hr 1}
#${color steelblue}Max GPU Frequency: ${color}1683${color steelblue} MHz${alignr}${color steelblue}Memory Frequency: ${color}2002${color steelblue} MHz
${color steelblue}GPU Temperature: ${color}${execi 10 nvidia-smi -q -d TEMPERATURE | grep "GPU Current" | grep C | cut -d+ -f2 | cut -c39-40} ${color steelblue}C${alignr}${color steelblue}Fan Speed: ${color}${execi 10 nvidia-smi | grep "%" | cut -c3-4} ${color steelblue}%
# --- wireless settings --- #
#${color darkslateblue}Wi-Fi${hr 1}
#${color steelblue}SSID: $color${wireless_essid wlan0}${color steelblue}     Strength: $color${wireless_link_qual wlan0} ${alignr} ${color steelblue}IP address: $color${addr wlan0}
# --- traffic settings --- #
${color darkslateblue}Traffic${hr 1}
${color #ddaa00}Port(s)${alignr}#Connections
$color Inbound: ${tcp_portmon 1 32767 count} Outbound: ${tcp_portmon 32768 61000 count} ${alignr}ALL: ${tcp_portmon 1 65535 count}
${color #ddaa00}Inbound Connection ${alignr} Local Service/Port$color
 ${tcp_portmon 1 32767 rhost 0} ${alignr} ${tcp_portmon 1 32767 lservice 0}
 ${tcp_portmon 1 32767 rhost 1} ${alignr} ${tcp_portmon 1 32767 lservice 1}
 ${tcp_portmon 1 32767 rhost 2} ${alignr} ${tcp_portmon 1 32767 lservice 2}
 ${tcp_portmon 1 32767 rhost 3} ${alignr} ${tcp_portmon 1 32767 lservice 3}
 ${tcp_portmon 1 32767 rhost 4} ${alignr} ${tcp_portmon 1 32767 lservice 4}
# ${tcp_portmon 1 32767 rhost 5} ${alignr} ${tcp_portmon 1 32767 lservice 5}
${color #ddaa00}Outbound Connection ${alignr} Remote Service/Port$color
 ${tcp_portmon 32768 61000 rhost 0} ${alignr} ${tcp_portmon 32768 61000 rservice 0}
 ${tcp_portmon 32768 61000 rhost 1} ${alignr} ${tcp_portmon 32768 61000 rservice 1}
 ${tcp_portmon 32768 61000 rhost 2} ${alignr} ${tcp_portmon 32768 61000 rservice 2}
 ${tcp_portmon 32768 61000 rhost 3} ${alignr} ${tcp_portmon 32768 61000 rservice 3}
 ${tcp_portmon 32768 61000 rhost 4} ${alignr} ${tcp_portmon 32768 61000 rservice 4}
# ${tcp_portmon 32768 61000 rhost 5} ${alignr} ${tcp_portmon 32768 61000 rservice 5}
# --- bandwidth settings --- #
${color darkslateblue}Bandwidth${hr 1}
#${color steelblue}wlan0${alignr}${color #8844ee}Down: ${downspeed wlan0}
#${color #0000ff}${downspeedgraph wlan0 10,* ff0000 0000ff}
#${alignr}${color #22ccff}Up:   ${upspeed wlan0}
#${upspeedgraph wlan0 10,* 0000ff ff0000}
${color steelblue}eth0${alignr}${color #8844ee}Down: ${downspeed eth0}
${color #0000ff}${downspeedgraph eth0 ff0000 0000ff} 
${alignr}${color #22ccff}Up:   ${upspeed eth0}
${upspeedgraph eth0 0000ff ff0000}
# --- file system settings ---#
${color darkslateblue}File Systems${hr 1}${color #ddaa00}
Device    Used     Size    ${alignr}%Free${color}
/         ${fs_used /}  ${fs_size /}   ${fs_free_perc /} ${fs_bar /}
/home     ${fs_used /home}  ${fs_size /home}  ${fs_free_perc /home} ${fs_bar /home}
#/dev/sda ${alignr}${color steelblue}Temperature: ${color}${hddtemp /dev/sda}${color steelblue} C
# --- drive temperature --- #
${color darkslateblue}Drive Temperature${hr 1}${color #ddaa00}
${alignr}${color steelblue}/dev/sdc: $color${execi 10 nc localhost 7634 | cut -c32-33} ${color steelblue}C /dev/sdd: $color${execi 10 nc localhost 7634 | cut -c66-67} ${color steelblue}C /dev/sde: $color${execi 10 nc localhost 7634 | cut -c100-101} ${color steelblue}C /dev/sdf: $color${execi 10 nc localhost 7634 | cut -c136-137} ${color steelblue}C
#${execi 10 nc localhost 7634}
# --- UPS status --- #
${color darkslateblue}UPS Status${hr 1}
${alignr}${apcupsd localhost 3551}${color #ddaa00}Status: $color${apcupsd_status} ${color #ddaa00}Load: $color${apcupsd_load} ${color #ddaa00}% Charge: $color${apcupsd_charge} ${color #ddaa00}% Time Remaining: $color${apcupsd_timeleft} ${color #ddaa00}minutes
]]

Hard disk temperature monitoring

sudo pacman -S hddtemp netcat

In order to monitor more than the first drive found in the system, a systemctl override is required.

sudo systemctl edit hddtemp.service

Add the following:

[Service]
ExecStart=
ExecStart=/usr/bin/hddtemp -dF /dev/sda /dev/sdb /dev/sdc ... /dev/sdx

Save the file and reload the systemctl daemon

sudo systemctl daemon-reload
sudo systemctl enable hddtemp
sudo systemctl start hddtemp

You can now use the netcat command to display hard disk temperature in conky:

nc localhost 7634

UPS

sudo pacman -S apcupsd

restore /etc/apcupsd/apcupsd.conf from backup

sudo systemctl enable apcupsd.service
sudo systemctl start apcupsd.service

NFS Server

sudo pacman -S nfs-utils

/etc/exports was copied from backup

sudo systemctl enable nfs-server.service
sudo systemctl start nfs-server.service

Samba Server

sudo pacman -S samba

Create your /etc/samba/smb.conf . Example file:

#######################
#
# gr0x0rd's smb.conf
#
#######################

[global]
workgroup = CYBERTRON
netbios name = TELETRAN5
server string = Samba Server %v
printcap name = cups
printing = cups
load printers = no
log file = /var/log/samba/log.%m
max log size = 50
socket options = TCP_NODELAY SO_RCVBUF=65536 SO_SNDBUF=65536
interfaces = lo eth0
bind interfaces only = yes
hosts allow = 127.0.0.1 192.168.78.
hosts deny = 0.0.0.0/0
security = user
guest ok = yes

	log level = 1                       
	read raw = yes                     
	write raw = yes                     
	oplocks = yes                       
	max xmit = 65535                    
	dead time = 15                     
	getwd cache = yes

#vfs object = vscan-clamav
#vscan-clamav: config-file = /etc/samba/vscan-clamav.conf

[private]
comment = Cybertron Repository
valid users = gr0x0rd
browseable = yes
writeable = yes
public = no
create mode = 0766
guest ok = no
path = /home/gr0x0rd

[public]
comment = public
browseable = yes
writeable = no
public = no
create mode = 0766
guest ok = no
path = /home/gr0x0rd/Videos
veto files = /home/gr0x0rd/Videos/tv

Create a samba user.

sudo smbpasswd -a samba_user

Configure and start the service.

sudo systemctl enable smb.service
sudo systemctl enable nmb.service
sudo systemctl start smb.service
sudo systemctl start nmb.service

Printing

Install cups (maybe it's already been pulled in by other packages?)

sudo pacman -S cups

Once cups is installed, enable and start the service.

sudo systemctl enable cups.service
sudo systemctl start cups.service

We will also need some drivers and additional components:

sudo pacman -S foomatic-db cups-filters

Once everything is installed, you can access the CUPS interface. Click "Administration" and enter your login creds when prompted to access the Admin UI. Click the "Add Printer" button to add your printer. In order to add it successfully, you'll need to download a .ppd file from your printer's manufacturer or openprinting.org.

Database server

sudo pacman -S mariadb
sudo mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
sudo systemctl enable mariadb.service
sudo systemctl start mariadb.service
sudo mysql_secure_installation

Backup mySQL

#!/bin/sh
datum=`/bin/date +%Y%m%d-%H`
/usr/bin/mysqldump --user=root --password=password --lock-all-tables \
--all-databases | gzip -9 > /path/to/backup-${datum}.sql.gz

Restore database from backup

gunzip < mysql_backup.sql.gz | mysql -u root -p

passwords for users did not work after restore. accounts had to be deleted and re-created. permissions persisted after restoring.

Web Server

apache

sudo pacman -S apache
sudo systemctl enable httpd.service
sudo systemctl start httpd.service

php

sudo pacman -S php php-apache
sudo nano /etc/php/php.ini

enable: date.timezone = America/Vancouver enable: short_open_tag = On enable: display_errors = On enable: open_basedir = /srv/http/

sudo nano /etc/httpd/conf/httpd.conf

comment the line: LoadModule mpm_event_module modules/mod_mpm_event.so

uncomment the line: LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

add the following to the LoadModule list:

LoadModule php7_module modules/libphp7.so

AddHandler php7-script .php

add the following to the Include list:

Include conf/extra/php7_module.conf

Include conf/vhosts/*.conf

sudo mkdir /etc/httpd/conf/vhosts

copy the backups from the previous vhosts to the above folder and edit accordingly

sudo systemctl restart httpd

nginx

sudo pacman -S nginx
cd /etc/nginx
sudo mkdir sites-available
sudo mkdir sites-enabled
sudo nano /etc/nginx/nginx.conf
user http;
worker_processes  auto;
worker_cpu_affinity auto;

events {
    multi_accept on;
    worker_connections  1024;
}

http {
    charset utf-8;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    server_tokens off;
    log_not_found off;
    types_hash_max_size 4096;
    client_max_body_size 16M;

    # MIME
    include       mime.types;
    default_type  application/octet-stream;

    # logging
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    # other options
    keepalive_timeout  65;
    #gzip  on;
    
    # load configs
    include /etc/nginx/sites-enabled/*;
}

To get a basic site up and running

sudo nano /etc/nginx/sites-available/default
    server {
        listen	80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }


    }

Create a symlink so the server will pick up the config (remove the symlink to easily disable the site):

sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default

Enable and start the nginx service.

sudo systemctl enable nginx.service
sudo systemctl start nginx.service

php

sudo pacman -S php php-fpm
sudo nano /etc/php/php-fpm.conf

Check your configs.

sudo systemctl enable php-fpm.service
sudo systemctl start php-fpm.service

LetsEncypt certificate management

sudo pacman -S certbot certbot-apache certbot-nginx

apache

sudo nano /etc/httpd/conf/extra/httpd-acme.conf

paste the contents from https://wiki.archlinux.org/index.php/Certbot#Apache

sudo nano /etc/httpd/conf/httpd.conf

add: Include conf/extra/httpd-acme.conf

sudo systemctl restart httpd
sudo certbot certonly --email gr0x0rd@gmail.com --webroot -w /var/lib/letsencrypt/ -d gr0x0rd.com,blog.gr0x0rd.com,1291.gr0x0rd.com,pool.gr0x0rd.com,pooldev.gr0x0rd.com,wiki.gr0x0rd.com,www.gr0x0rd.com,build.gr0x0rd.com,ums.gr0x0rd.com,video.gr0x0rd.com,awaken.gr0x0rd.com,meet.gr0x0rd.com,auth.meet.gr0x0rd.com,cloud.gr0x0rd.com

certs are now available at /etc/letsencrypt/live/gr0x0rd.com

note: to add a new cert, simply add the new subdomain to the above command and run it again. Once complete, add the new entry to the config file

sudo nano /etc/letsencrypt/renewal/gr0x0rd.com.conf

private key: privkey.pem

cert: cert.pem

chain: chain.pem (for nginx)

fullchain: fullchain.pem

sudo nano /etc/httpd/conf/httpd.conf

uncomment: LoadModule ssl_module modules/mod_ssl.so

uncomment: LoadModule socache_shmcb_module modules/mod_socache_shmcb.so

uncomment: Include conf/extra/httpd-ssl.conf

uncomment: LoadModule rewrite_module modules/mod_rewrite.so

sudo nano /etc/httpd/conf/extra/httpd-ssl.conf

add: SSLCertificateFile "/etc/letsencrypt/live/gr0x0rd.com/cert.pem"

add: SSLCertificateKeyFile "/etc/letsencrypt/live/gr0x0rd.com/privkey.pem"

add: SSLCertificateChainFile "/etc/letsencrypt/live/gr0x0rd.com/fullchain.pem"

add the same directives to the secure directive area in the applicable vhost file

sudo systemctl restart httpd

Automatic renewal was attempted via the approach documented at https://wiki.archlinux.org/index.php/Certbot#Automatic_renewal, but that didn't seem to work. Alternatively, a manual approach was taken to do this. It was found that when the renewal process was run, the provisioning side was unable to confirm all of the hosted sites due to the login/password restrictions. A mechanism around this was to create .conf files for those sites without login restriction, restart the webserver, update the certs, then roll back the .conf file changes and restart the web server yet again. Here was the final result.

file: /usr/bin/certrenew

#!/bin/bash
# this script removes the authentication settings from the vhosts
# on the server, restarts the apache service, renews the certificates, 
# restores the authentication settings and restart apache again.
# start by removing authentication from the vhosts.
cp /etc/httpd/conf/vhosts/01_wiki.gr0x0rd.com.conf.noauth /etc/httpd/conf/vhosts/01_wiki.gr0x0rd.com.conf
cp /etc/httpd/conf/vhosts/02_blog.gr0x0rd.com.conf.noauth /etc/httpd/conf/vhosts/02_blog.gr0x0rd.com.conf
cp /etc/httpd/conf/vhosts/03_1291.gr0x0rd.com.conf.noauth /etc/httpd/conf/vhosts/03_1291.gr0x0rd.com.conf
mv /etc/httpd/conf/vhosts/05_ums.gr0x0rd.com.conf /etc/httpd/conf/vhosts/05_ums.gr0x0rd.com.conf.ignore
cp /etc/httpd/conf/vhosts/06_build.gr0x0rd.com.conf.noauth /etc/httpd/conf/vhosts/06_build.gr0x0rd.com.conf
cp /etc/httpd/conf/vhosts/08_video.gr0x0rd.com.conf.noauth /etc/httpd/conf/vhosts/08_video.gr0x0rd.com.conf
cp /etc/httpd/conf/vhosts/09_awaken.gr0x0rd.com.conf.noauth /etc/httpd/conf/vhosts/09_awaken.gr0x0rd.com.conf
# restart httpd
systemctl restart httpd
# sites are now open- renew the certs.
sleep 5
/usr/bin/certbot renew
# restore the authentication files.
cp /etc/httpd/conf/vhosts/01_wiki.gr0x0rd.com.conf.auth /etc/httpd/conf/vhosts/01_wiki.gr0x0rd.com.conf
cp /etc/httpd/conf/vhosts/02_blog.gr0x0rd.com.conf.auth /etc/httpd/conf/vhosts/02_blog.gr0x0rd.com.conf
cp /etc/httpd/conf/vhosts/03_1291.gr0x0rd.com.conf.auth /etc/httpd/conf/vhosts/03_1291.gr0x0rd.com.conf
mv /etc/httpd/conf/vhosts/05_ums.gr0x0rd.com.conf.ignore /etc/httpd/conf/vhosts/05_ums.gr0x0rd.com.conf
cp /etc/httpd/conf/vhosts/06_build.gr0x0rd.com.conf.auth /etc/httpd/conf/vhosts/06_build.gr0x0rd.com.conf
cp /etc/httpd/conf/vhosts/08_video.gr0x0rd.com.conf.auth /etc/httpd/conf/vhosts/08_video.gr0x0rd.com.conf
cp /etc/httpd/conf/vhosts/09_awaken.gr0x0rd.com.conf.auth /etc/httpd/conf/vhosts/09_awaken.gr0x0rd.com.conf
# restart httpd again.
systemctl restart httpd

nginx

Note that the above approach is deprecated as it's possible to configure nginx to bypass the authentication for renewals by including the following in each site's conf file:

include /etc/letsencrypt/options-ssl-nginx.conf;
include /etc/nginx/allowrenew.conf;

File: /etc/nginx/allowrenew.conf

location ~ /\.well-known/acme-challenge/ {
	allow all;
	default_type "text/plain";
	root /usr/share/nginx/html;
	try_files $uri =404;
}

To add another subdomain

$ sudo certbot --nginx -v certonly --email gr0x0rd@gmail.com -d dev.gr0x0rd.com,1291.gr0x0rd.com,auth.meet.gr0x0rd.com,awaken.gr0x0rd.com,blog.gr0x0rd.com,build.gr0x0rd.com,cloud.gr0x0rd.com,meet.gr0x0rd.com,office.gr0x0rd.com,pool.gr0x0rd.com,pooldev.gr0x0rd.com,ums.gr0x0rd.com,video.gr0x0rd.com,wiki.gr0x0rd.com

To renew the certificates

$ sudo certbot renew

You may need to add the --force-renewal switch if you've added a new subdomain and have recently renewed.

Mediawiki

sudo pacman -S mediawiki imagemagick php-gd php-intl
sudo nano /etc/php/php.ini

add: /var/lib/mediawiki/:/usr/share/webapps/:/tmp/:/usr/bin/ to the open_basedir directive

uncomment: extension=gd

uncomment: extension=intl

uncomment: extension=iconv

uncomment: extension=mysqli

uncomment: session.save_path = "/tmp"

sudo mkdir -p /srv/http/mediawiki
sudo cp -r /usr/share/webapps/mediawiki/* /srv/http/mediawiki/

create the necessary file in /etc/httpd/conf/vhosts/

sudo systemctl restart httpd

Upgrading Mediawiki

Make a backup of your current database and filesystem:

sudo cp -r /srv/http/mediawiki /srv/http/mediawiki.bak

Copy the new files and folders to the instance:

sudo cp -r /usr/share/webapps/mediawiki/* /srv/http/mediawiki

Run the update script:

cd /srv/http/mediawiki/maintenance
sudo php update.php

Wordpress

sudo pacman -S wordpress
sudo mkdir -p /srv/http/wordpress
sudo cp -r /usr/share/webapps/wordpress/* /srv/http/wordpress/

If you have any backed up content or an existing site, copy the relevant files (such as wp-content) to the new instance.

There are a number of php extensions that need to be enabled for wordpress to work properly. If you've already completed the steps above, these should all be ready to go.

When satisfied, create the applicable vhosts file in apache and...

sudo systemctl restart httpd

Upgrading Wordpress

Before getting started, back up your environment.

sudo cp -r /srv/http/wordpress /srv/http/wordpress.bak

Upgrade the environment based on the updated wordpress packages.

sudo cp -r /usr/share/webapps/wordpress/* /srv/http/wordpress/

Head to your browser and log into the instance. You'll be prompted to upgrade the database. Once done, deal with the fallout.

Universal Media Server

sudo pacman -S jdk8-openjdk
sudo pacman -S dcraw lib32-gcc-libs 
sudo nano /etc/pacman.conf

uncomment [multilib] and Include = /etc/pacman.d/mirrorlist

sudo pacman -Syu
sudo pacman -S lib32-freetype2
yay -S lib32-libmng ums

copy the .config/UMS from backup to the desired location.

create the file /usr/lib/systemd/system/ums.service

copy the contents from http://www.universalmediaserver.com/forum/viewtopic.php?f=3&t=1240&start=10#p7392 to the file and save it

change the user "UMS" to running user

sudo systemctl enable ums.service
sudo systemctl start ums.service

Plex Media Server

yay -S plex-media-server-plexpass

Arch does not apply any group or user permissions to home directories when users are created. For PMS to read media in my home folder, I had to add

chmod +rx /home/gr0x0rd

Enable and start the service

sudo systemctl enable plexmediaserver.service
sudo systemctl start plexmediaserver.service

To restore previous library configuration, overwrite the contents of the "Plex Media Server" folder with your backup.

OTA TV

For this setup I used a Hauppage WinTV DualHD USB TV tuner, model 01595. After insertion, dmesg indicated the kernel picked up the device, but a few things were necessary to get things up and running:

yay -S linuxtv-dvb-apps w_scan2

After this w_scan reported inability to load the driver, so...

sudo modprobe dvb_usb_rtl28xxu
sudo modprobe rtl2830
sudo modprobe rtl2832

w_scan was able to find channels after this. Another fantastic troubleshooting application is kaffeine. Note that after migrating from w_scan to w_scan2, it took some fiddling to get kaffeine working again. It wasn't possible to change the source in the channels modal, and then all of a sudden it was...

sudo pacman -S kaffeine

In order for plex to pick up the TV tuner and add it to the DVR configuration, the plex user needs to be part of the video group.

sudo gpasswd -a plex video

Restart the plex service to pick up these changes.

Virtualbox

sudo pacman -S virtualbox virtualbox-guest-iso 
sudo pacman -S linux-headers
yay -S virtualbox-ext-oracle
sudo modprobe vboxdrv
sudo modprobe vboxnetadp
sudo modprobe vboxnetflt
sudo modprobe vboxpci
sudo gpasswd -a gr0x0rd vboxusers

splunk

yay -S splunk
sudo systemctl enable splunk
sudo systemctl start splunk

docker

sudo pacman -S docker docker-compose
sudo gpasswd -a http docker
sudo nano /etc/systemd/system/docker.service.d/execstart.conf

Paste the following into the file:

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:424
sudo systemctl enable docker.service
sudo systemctl start docker.service

To view all docker containers on the system

$ docker container list --all

To remove an old or stale container

$ docker rm <container id>

jitsi

As per the arch wiki, install the required packages and components.

$ sudo pacman -S prosody nginx coturn lua52 lua52-sec lua52-zlib

There are also packages from AUR required.

$ yay -S lua52-event jitsi-meet jitsi-meet-prosody jitsi-meet-turnserver jitsi-videobridge jicofo

Before getting started it is advisable to configure a few of the domains in the local hosts file.

$ sudo nano /etc/hosts

Ensure the following are set:

127.0.0.1 JITSIFQDN auth.JITSIFQDN
::1 JITSIFQDN auth.JITSIFQDN

Configure prosody

Before getting started a handy module to list all prosody users should be downloaded.

$ cd /usr/lib/prosody/modules/share/lua/5.2/
$ sudo wget https://prosody.im/files/mod_listusers.lua

This will allow you to list all prosody users via

$ sudo prosodyctl mod_listusers

The first component is a prosody server. Check the configuration file

$ sudo nano /etc/prosody/prosody.cfg.lua

Add an admin in the format "user@domain.ext", and the users "focus@JITSIFSQN" and "focus@auth.JITSIFQDN". To check the configuration file for errors

$ sudo luac5.2 -p /etc/prosody/prosody.cfg.lua

Enable and start the prosody service.

$ sudo systemctl enable prosody.service
$ sudo systemctl start prosody.service

Add the admin user you entered into the file above.

$ sudo prosodyctl adduser user@domain.ext

Confirm the password twice as you'd expect. Next, create a folder for the jitsi configuration in prosody. Leverage the sample config file from the jitsi-meet-prosody package.

$ cd /etc/prosody
$ sudo mkdir conf.d
$ sudo cp /usr/share/doc/jitsi-meet-prosody/prosody.cfg.lua-jvb.example conf.d/jitsi.cfg.lua

Have the prosody server configuration import the jitsi config file by adding Include "conf.d/*.cfg.lua" to the bottom of /etc/prosody/prosody.cfg.lua . Now edit the jitsi config file.

$ sudo nano /etc/prosody/conf.d/jitsi.cfg.lua

-- replace all occurences of jitmeet.example.com with JITSIFQDN -- replace all occurences of focusUser by focus Ensure the following are set in the file (replace JITSIFQDN with your own, and equivalent for certificate path and files):

VirtualHost "JITSIFQDN"
    ssl = {
        key = "/etc/prosody/certs/JITSIFQDN.key";
        certificate = "/etc/prosody/certs/JITSIFQDN.crt";
    }

VirtualHost "auth.JITSIFQDN"
    ssl = {
        key = "/etc/prosody/certs/auth.JITSIFQDN.key";
        certificate = "/etc/prosody/certs/auth.JITSIFQDN.crt";
    }
    authentication = "internal_plain"

-- Proxy to jicofo's user JID, so that it does not have to register as a component.
Component "focus.JITSIFQDN" "client_proxy"
    target_address = "focus@auth.JITSIFQDN"

Attempts at using letsencrypt certs failed, so self-signed certs using prosodyctl was done instead.

$ sudo -u prosody prosodyctl cert generate JITSIFQDN
$ sudo -u prosody prosodyctl cert generate auth.JITSIFQDN
$ sudo mv /var/lib/prosody/JITSIFQDN.{crt,cnf,key} /etc/prosody/certs/
$ sudo mv /var/lib/prosody/auth.JITSIFQDN.{crt,cnf,key} /etc/prosody/certs/
$ sudo trust anchor /etc/prosody/certs/JITSIFQDN.crt
$ sudo trust anchor /etc/prosody/certs/auth.JITSIFQDN.crt
$ sudo update-ca-trust

We now need to register the jvb and focus users.

$ sudo prosodyctl register jvb auth.JITSIFQDN <password>
$ sudo prosodyctl register focus auth.JITSIFQDN <password>
$ sudo prosodyctl mod_roster_command subscribe focus.JITSIFQDN focus@auth.JITSIFQDN

The restart the prosody service.

$ sudo systemctl restart prosody

Prosody modules

listusers is a handy module which will show who is registered in the system (not obvious). To do this, try to invoke the module

$ sudo prosodyctl mod_listusers

If it works, great; if not it will spit out a path where it's looking for said module. Copy that path and create it.

$ sudo mkdir -p <copied path>

Go to that folder

$ cd <copied path>

Download the module

$ sudo wget https://prosody.im/files/mod_listusers.lua

You'll now be able to run the initial command.

Configure jitsi-videobridge

Next, we need to configure the jitsi-videobridge.

$ sudo nano /etc/jitsi-videobridge/config

Set the jvb hostname and user:

JVB_HOSTNAME=JITSIFQDN
JVB_SECRET=<password>

Next we configure the sip-communicator.properties files. Note that beforehand, run the command

$ uuidgen 

and make a note of it for the file below as UUIDGEN_RESULT.

$ sudo nano /etc/jitsi-videobridge/sip-communicator.properties

Make the appropriate entries:

org.jitsi.videobridge.xmpp.user.shard.DOMAIN=auth.JITSIFQDN
org.jitsi.videobridge.xmpp.user.shard.PASSWORD=SECRET_JVB_USER
org.jitsi.videobridge.xmpp.user.shard.MUC_JIDS=JvbBrewery@internal.auth.JITSIFQDN
org.jitsi.videobridge.xmpp.user.shard.MUC_NICKNAME=UUIDGEN_RESULT

Start and enable the videobridge service.

$ sudo systemctl enable jitsi-videobridge.service
$ sudo systemctl start jitsi-videobridge.service

Configure jicofo

$ sudo nano /etc/jicofo/config

Ensure the following settings are configured:

JICOFO_HOSTNAME=JITSIFQDN
JICOFO_AUTH_DOMAIN=auth.JITSIFQDN
JICOFO_AUTH_PASSWORD=SECRET_FOCUS_USER

Configure the jifoco sip communicator properties file.

$ sudo nano /etc/jicofo/sip-communicator.properties

Ensure that the following is set:

org.jitsi.jicofo.BRIDGE_MUC=JvbBrewery@internal.auth.JITSIFQDN

Configure the jicofo conf file.

$ sudo nano /etc/jicofo/jicofo.conf

Set the appropriate JITSIFQDN settings:

jicofo {
  xmpp: {
    client: {
      client-proxy: "focus.JITSIFQDN"
      xmpp-domain: "JITSIFQDN"
      domain: "auth.JITSIFQDN"
      username: "focus"
      password: "SECRET_FOCUS_USER"
      conference-muc-jid = conference.YOUR_DOMAIN
    }
    trusted-domains: [ "recorder.JITSIFQDN" ]
  }
  bridge: {
    brewery-jid: "JvbBrewery@internal.auth.JITSIFQDN"
  }
}

Start and enable the jifoco service.

$ sudo systemctl enable jicofo.service
$ sudo systemctl start jicofo.service

Configure jitsi-meet

$ sudo nano /etc/webapps/jitsi-meet/config.js

Again, set the appropriate FQDN values.

var config = {
  hosts: {
    domain: 'JITSIFQDN',
    // ...
    muc: 'conference.JITSIFQDN'
  },
  bosh: '//JITSIFQDN/http-bind',
  // ...
}

Configure web server

For this example we will use nginx. This assumes the folders sites-available and sites-enabled are inherited parts of the configuration, and letsencrypt certs are configured and include the JITSIFQDN.

$ sudo cp /usr/share/doc/jitsi-meet/jitsi-meet.example /etc/nginx/sites-available/JITSIFQDN
$ sudo nano /etc/nginx/sites-available/JITSIFQDN

Example:

server {
  # ...
  server_name YOUR_DOMAIN;

  # ...
  # use letencrypt path
  ssl_certificate /etc/letsencrypt/live/JITSIFQDN/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/JITSIFQDN/privkey.pem;

  # set the config path
  # replace alias /etc/jitsi/meet/jitmeet.example.com-config.js by
  location = /config.js {
    alias /etc/webapps/jitsi-meet/config.js;
  }
  # ...
  location ~ ^/([^/?&:'"]+)/config.js$
  {
    set $subdomain "$1.";
    set $subdir "$1/";
    alias /etc/webapps/jitsi-meet/config.js;
  }
}

Restart nginx.

$ sudo systemctl restart nginx

You should now be able to access the instance via the JITSIFQDN.

Domain security

This will allow you to register a user with prosody in order to restrict who can create and start meetings. First add the guest domain to the jitsi config lua.

$ sudo nano /etc/prosody/conf.d/jitsi.cfg.lua

Ensure the following are changed or added:

VirtualHost "JITSIFQDN"
    -- enabled = false -- Remove this line to enable this host
    authentication = "internal_plain"
...
-- add guest virtual host to allow anonymous user to join your room
VirtualHost "guest.JITSIFQDN"
    authentication = "anonymous"
    c2s_require_encryption = false
    modules_enabled = {
        -- copy the content of the modules_enabled
        -- of the VirtualHost "JITSIFQDN"
        -- remove only the module "muc_lobby_rooms" of the list
        -- example:
        "bosh";
        "pubsub";
        "ping"; -- Enable mod_ping
        "speakerstats";
        "external_services";
        "conference_duration";
    }

Add the guest domain in the jitsi-meet config file.

$ sudo nano /etc/webapps/jitsi-meet/config.js

Ensure the following is set:

var config = {
  hosts: {
    // anonymous users need to use a dedicated muc without authentication
    anonymousdomain: 'guest.JITSIFQDN',
  },
}

Enable authentication in jicofo.

$ sudo nano /etc/jicofo/sip-communicator.properties

Add the following line:

org.jitsi.jicofo.auth.URL=XMPP:JITSIFQDN

Register the desired admin user with prosody.

$ sudo prosodyctl register <username> JITSIFQDN <password>

Restart the services for the changes to take effect.

$ sudo systemctl restart prosody
$ sudo systemctl restart jicofo
$ sudo systemctl restart jitsi-videobridge

Customizations

file: /usr/share/webapps/jitsi-meet/interface_config.js
To disable the list of recent meetings from the interface

RECENT_LIST_ENABLED = false

To hide the footer on the welcome page with the logos for mobile apps

DISPLAY_WELCOME_FOOTER = false

To change the branding logo in the top left, download your customlogo.png to the images folder, then

DEFAULT_LOGO_URL: 'images/customlogo.png',
DEFAULT_WELCOME_PAGE_LOGO_URL: 'images/customlogo.png',

To change the application title in the Browser tab

APP_NAME: 'Desired Name'

file: /etc/webapps/jitsi-meet/config.js To start with audio only

startAudioOnly: true,

To improve desktop sharing performance

     desktopSharingFrameRate: {
         min: 5,
         max: 25
     },

In order to ensure people have to enter their names to join the meeting

requireDisplayName: true,

file: /usr/share/webapps/jitsi-meet/css/all.css
To replace the background image, download your preferred image into the images folder and change

welcome-background.png

file: /usr/share/webapps/jitsi-meet/lib/app.bundle.min.js To change the title on the main page, edit the following directive:

"headerTitle":"Jitsi Meet"

Helpful:

$ sed -i 's/"headerTitle":"Jitsi Meet"/"headerTitle":"PUT HERE YOUR NEW TITLE"/g' app.bundle.min.js

To change the "Secure and high quality meetings" phrase, edit the same file.

nextcloud

Before getting started, configure an external DNS record, such as cloud.example.org . Next, install the package and recommended dependencies.

$ sudo pacman -S nextcloud php-imagick php-intl

Make a backup of the existing php.ini file and set the ownership of the backup to the nextcloud user.

$ sudo cp /etc/php/php.ini /etc/webapps/nextcloud/
$ sudo chown nextcloud:nextcloud /etc/webapps/nextcloud/php.ini

Edit the file and ensure the appropriate extensions are enabled, increase the memory limit, and specify writable directories.

$ sudo nano /etc/webapps/nextcloud/php.ini
extension=bcmath
extension=bz2
extension=exif
extension=gd
extension=iconv
extension=imagick
extension=intl
extension=pdo_mysql
...
memory_limit = 512M
...
open_basedir=/var/lib/nextcloud/data:/var/lib/nextcloud/apps:/tmp:/usr/share/webapps/nextcloud:/etc/webapps/nextcloud:/dev/urandom:/usr/lib/php/modules:/var/log/nextcloud:/proc/meminfo

Edit the nextcloud configuration file.

$ sudo nano /etc/webapps/nextcloud/config/config.php

Set the following accordingly:

'trusted_domains' =>
  array (
    0 => 'localhost',
    1 => 'cloud.example.org',
  ),    
'overwrite.cli.url' => 'https://cloud.example.org/',
'htaccess.RewriteBase' => '/',

Next we will export the NEXTCLOUD_PHP_CONFIG and make the setting permanent.

$ export NEXTCLOUD_PHP_CONFIG=/etc/webapps/nextcloud/php.ini
$ sudo nano /etc/bash.bashrc

Add the same export above to the file. To confirm the command worked

$ printenv | grep NEXT

Create a dedicated directory for session data.

$ sudo install --owner=nextcloud --group=nextcloud --mode=700 -d /var/lib/nextcloud/sessions

nextcloud database configuration

Due to a bug with compressed innodb tables, a few settings are required in the mariadb server.cnf.

$ sudo nano /etc/my.cnf.d/server.cnf

Ensure the file contains the following directives:

[mysqld]
transaction_isolation=READ-COMMITTED
...
[mariadb-10.6]
innodb_read_only_compressed=OFF

Next log into mySQL and create the nextcloud database and user. Save the password (xxxxxxxx below) in a password vault.

$ mysql -u root -p
> CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'xxxxxxxx';
> CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
> GRANT ALL PRIVILEGES on nextcloud.* to 'nextcloud'@'localhost';
> FLUSH privileges;
> exit

To complete the database initialization, set up the database schema. Note you will need to create and save an admin password, and provide an admin email.

occ maintenance:install \
    --database=mysql \
    --database-name=nextcloud \
    --database-host=localhost:/run/mysqld/mysqld.sock \
    --database-user=nextcloud \
    --database-pass=xxxxxxxx \
    --admin-pass=zzzzzzzz \
    --admin-email=aaaa@bbbbb \
    --data-dir=/var/lib/nextcloud/data

You should see a message "Nextcloud was successfully installed".

nextcloud application server

Since we are already using php-fpm for nginx, an attempt to use that was tried first. It did not go well. The documentation had uWSGI listed first, maybe that's why.

==== uWSGI

$ sudo pacman -S uwsgi uwsgi-plugin-php

Make a backup of the canned config file.

$ sudo cp /etc/uwsgi/nextcloud.ini /etc/uwsgi/nextcloud.ini.orig

Grab a working example of the file from here and paste it into the working file:

$ sudo nano /etc/uwsgi/nextcloud.ini

Next, start and enable the service

$ sudo systemctl enable uwsgi@nextcloud.service
$ sudo systemctl start uwsgi@nextcloud.service

abandoned: php-fpm

First, make a copy of the php.ini file for this fpm instance.

$ sudo cp /etc/php/php.ini /etc/php/php-fpm.ini

Ensure the file is owned and only writable by root (-rw-r--r-- 1 root root). Edit the file

$ sudo nano /etc/php/php-fpm.ini

Enable the zend opcache extension and configure its settings:

zend_extension=opcache
...
[opcache]
; Determines if Zend OPCache is enabled
opcache.enable=1
opcache.interned_strings_buffer = 8
opcache.max_accelerated_files = 10000
opcache.memory_consumption = 128
opcache.save_comments = 1
opcache.revalidate_freq = 1

Next you have to create a so called pool file for php-fpm. It is responsible for spawning dedicated php-fpm processes for the Nextcloud application.

$ sudo nano /etc/php/php-fpm.d/nextcloud.conf

Paste the base working copy of this example as a starting point. Be sure to set the correct date.timezone in the file.

There is an existing www.conf that should be preserved and then commented out so it doesn't become operable after an update.

$ sudo mv /etc/php/php-fpm.d/www.conf /etc/php/php-fpm.d/www.conf.orig
$ sudo nano /etc/php/php-fpm.d/www.conf

Enter the following line:

; dummy file not to be usurped by package updates

Next we are going to need to make some modifications to the php-fpm service by means of a drop-in file.

$ sudo mkdir /etc/systemd/system/php-fpm.service.d
$ sudo nano /etc/systemd/system/php-fpm.service.d/override.conf

Paste the following:

[Service]
ExecStart=
ExecStart=/usr/bin/php-fpm --nodaemonize --fpm-config /etc/php/php-fpm.conf --php-ini /etc/php/php-fpm.ini
ReadWritePaths=/var/lib/nextcloud
ReadWritePaths=/etc/webapps/nextcloud/config

In my troubleshooting I found that the defaults referenced a logging directory that was missing so

$ sudo mkdir -p /var/log/php-fpm/access

Finally, reload the daemon and restart the php-fpm service.

$ sudo systemctl daemon-reload
$ sudo systemctl restart php-fpm

nextcloud web server

Create a dummy site and use certbot to pull down the desired cert. Once done, the suggested documentation config is available at https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html .

As we are using uswgi, the php location block needs to be changed to:

location ~ \.php(?:$|/) {
    include uwsgi_params;
    uwsgi_modifier1 14;
    # Avoid duplicate headers confusing OC checks
    uwsgi_hide_header X-Frame-Options;
    uwsgi_hide_header X-XSS-Protection;
    uwsgi_hide_header X-Content-Type-Options;
    uwsgi_hide_header X-Robots-Tag;
    uwsgi_hide_header X-Download-Options;
    uwsgi_hide_header X-Permitted-Cross-Domain-Policies;
    uwsgi_pass unix:/run/uwsgi/nextcloud.sock;
}

Note that within the example provided by nextcloud the archlinux root for nextcloud is /usr/share/webapps/nextcloud. Other considerations:

  • Your server name (server_name clauses 2x), i.e. the server part of the URL your Nextcloud installation will be reachable with.
  • The name of the certificate and key you use for SSL / TLS.
  • If and where you want an access log written to.
  • The location where Certbot (or any other ACME client) will put the domain verification challenges. Usage of alias instead of try_files is probably more adequate here.
  • The path used to reach your Nextcloud installation. (The part right to the server name & port section in the URL.)
  • What application server (uWSGI or php-fpm) you are using, i.e. how and where nginx will pass requests that need to trigger some PHP code. (See above.)
  • Configure OCSP stapling.

background cron and cacheing

Nextcloud requires certain tasks to be run on a scheduled basis. We will use systemd to do this.

$ sudo mkdir -p /etc/systemd/system/nextcloud-cron.service.d
$ sudo nano /etc/systemd/system/nextcloud-cron.service.d/override.conf

Paste the following:

[Service]
ExecStart=
ExecStart=/usr/bin/php -c /etc/webapps/nextcloud/php.ini -f /usr/share/webapps/nextcloud/cron.php

Save the file and have systemd pick up the changes:

$ sudo systemctl daemon-reload
$ sudo systemctl enable nextcloud-cron.timer
$ sudo systemctl start nextcloud-cron.timer

cacheing - this did not work and was rolled back

For cacheing, we will use what the arch docs recommend, which is php-apcu:

$ sudo pacman -S php-apcu 

Next, we will edit the following files to enabling extension=apcu in the following file:

$ sudo nano /etc/webapps/nextcloud/php.ini

And php-set = extension=apcu in this file:

$ sudo nano /etc/uwsgi/nextcloud.ini

Next restart the application server

$ sudo systemctl restart uwsgi@nextcloud

Finally edit the nextcloud config file:

$ sudo nano /etc/webapps/nextcloud/config/config.php

Add the following line to the end of the file:

'memcache.local' => '\OC\Memcache\APCu',

Online office

For this we will use nextcloud along with the collabora online server, which is based on libreoffice. To run it, docker needs to be up and running. You will also need an external DNS record and an ssl certificate configured for it to work.

Install the server.

$ docker pull collabora/code

Activate the node based on your nextcloud FDQN. This was taken from https://sdk.collaboraonline.com/docs/installation/CODE_Docker_image.html .

$ docker run -t -d -p 127.0.0.1:9980:9980 -e "aliasgroup1=https://cloud.example.com:443,https://cloud\\.example\\.com" -e "username=admin" -e "password=S3cRet" --restart always --privileged collabora/code

Afterward it appeared that the container was running, but it didn't seem to be listening on port 9980:

$ docker ps

To stop the docker continer,

$ docker container stop <id>

You should already have a config file for office.example.com in your nginx's sites-available folder. For the configuration, check out https://sdk.collaboraonline.com/docs/installation/Proxy_settings.html#reverse-proxy-with-nginx-webserver and paste in the appropriate directives. Test nginx

$ nginx -c /etc/nginx/nginx.conf -t

If happy, restart nginx

$ sudo systemctl restart nginx

Next, log into nextcloud and go to Apps from your profile, then Office & Text. Add the "Nextcloud office" option. Then from your profile choose settings, then scroll down to the Administration section and choose "Office". Select the "User your own server" option and paste in the URL you used to generate the certificate in the prerequisite step prefixed by https.

You should now have a working office online instance. If you do not, you can

  • check the nextcloud logs.
  • check the docker container logs.
  • check the nginx logs for both the nextcloud server and office server.

It is strongly recommended to create a file and save the command to successfully start the instance, for example

$ sudo nano /usr/bin/startcollabora

Paste the above example based on your specific environment.

$ sudo chmod +x /usr/bin/startcollabora

You can the run the script if you need to restart it, after an upgrade for example.

Upgrading collabora

As a docker container it will need to be upgraded manually. Before upgrading, if you have a working version, it may be pragmatic to save the details so you can revert if necessary.

$ docker image inspect collabora/code > /path/to/collabora-version

To upgrade the instance run the same docker pull command above. Use the docker ps and container stop commands to stop the instance currently running. Start the new instance with the command you saved in the previous step.

If you have done this upgrade more than once, you will have more than one old stopped container. You can now remove all versions older than the rollback version if you like using docker tools.

Rolling back collabora

To be completed when the need arises...

Updating

If the instance starts complaining about a new version and you want to try it out, grab new docker image:

$ docker pull collabora/code

List docker images:

$ docker ps

From the output you can glean the Container ID of your Collabora Online docker image. Stop and remove the Collabora Online docker image:

$ docker stop CONTAINER_ID
$ docker rm CONTAINER_ID

Start the new image with the same docker run command above.

s3 storage

Install the packages to enable the s3 command tools.

$ sudo pacman -S s3cmd

Configure access to a wasabi bucket using

$ s3cmd --configure

Enter in the access and secret key. When prompted for region

us-east-1

For the S3 endpoint

s3.wasabisys.com

Buckets are provisioned on the wasabi side (Roman did this first time).

%(bucket)s.s3.wasabisys.com

Provide an encryption key. Store it in the vault. The path to gpg should be default. Use HTTPS. Leave the proxy blank.

Test the connection. It should work.

View files on the s3 bucket

$ s3cmd la

This will also tell us the bucket name.

Send a file to the s3 storage

$ s3cmd put /path/to/file s3://<bucket_name>

Recursively send all files in a folder

$ s3cmd sync --acl-private --recursive --skip-existing --multipart-chunk-size-mb=256 /path/to/files/ s3://<bucket-name>

Download files via

$ s3cmd get s3://<bucket name>/<files> /path/to/destination

Gaming

The following nvidia packages were required before anything worked, really.

sudo pacman -S nvidia-libgl
sudo pacman -S lib32-nvidia-libgl

playonlinux

sudo pacman -S playonlinux

steam

Install an appropriate multilib opengl driver and compatible fonts, in addition to steam.

sudo pacman -S lib32-nvidia-utils ttf-liberation steam

On first run, some library errors came up.

sudo pacman -S lib32-libva lib32-libvdpau

streaming

LazyMan

LazyMan is great for streaming live NHL games... but the creator was legally threatened, the git repos removed, and the servers shut down. The info below is deprecated, but saved for posterity.

cd /usr/local/aur
git clone git clone https://aur.archlinux.org/python-iso3166.git
cd python-iso3166
makepkg -si
cd /usr/local/aur
git clone https://aur.archlinux.org/python-iso639.git
cd python-iso639
makepkg -si
cd /usr/local/aur
git clone https://aur.archlinux.org/streamlink-git.git 
cd streamlink-git
makepkg -si
git clone https://aur.archlinux.org/lazyman.git 
cd lazyman
makepkg -si

Download the latest lazyman from https://www.reddit.com/r/LazyMan/wiki/downloads . Once downloaded, extract the zip. Place the jar file where ever you like.

ping -c 3 powersports.ml
sudo nano /etc/hosts

Based on the IP the results, add the appropriate entries to your hosts file.

ip.from.previous.command mf.svc.nhl.com
ip.from.previous.command mlb-ws-mf.media.mlb.com
ip.from.previous.command playback.svcs.mlb.com

If the version you've downloaded is newer than that in the AUR repository, simply create a symbolic link to the newer version:

cd /usr/share/java/lazyman/
sudo ln -s /path/to/lazyman/LazyMan.jar LazyMan.jar

LazyMan can now be run from the desktop shortcut created by the AUR package.

bitcoin

The wiki and docs say there are official packages but I can't seem to find them. So to AUR we go.

yay -S bitcoin-core bitcoin-qt bitcoin-cli

Tips & Tricks

Installing older versions of packages

Find the package via https://archive.archlinux.org/packages/ . Once you've found it, copy the link. Install via

sudo pacman -U <url>

If you can't find the package in the archives, you may also be able to find an older version in your pacman cache at /var/cache/pacman/pkg/.

Xfce panel not responding

If the panel stops responding to mouse or keyboard commands, restart it via

xfce4-panel -r

Run compiz on secondary screen

If compiz runs on your primary screen only try this to get it running on the other:

compiz --replace --display :0.1