Copy & paste Arch Linux x86_64 solution
from scratch.

Software Suite

Table of Contents

 

Important

Before you start, check the following:

  1. Your router needs the possibility of port forwarding and the possibility to configure the DNS server for Pi-hole.
  2. You’ll need a DynDNS-Domain. For example, at https://www.noip.com/sign-up.

 

Info / Tip

Some commands must be changed by you. The keywords will start with 'your-'.

  • your-interface
  • your-password
  • your-location
  • etc.

We will mark it with the words 'Input required:' above the commands.

Hit the tab key for autocompletion when typing commands.

 

1. Wireless connection & test

If you're using Ethernet (cable) connection, go to Test Connection. Keep going if you want to use your WIFI.

systemctl stop dhcpcd@interface.service
Check the wireless interface, this usually starts with a "w" for e.g. wlp2s1
ip link

 

1.0.1. Input required:

Setup the wireless interface, replace the keyword 'your-interface' with the one that starts with "w" e.g. wlp2s1.

Do not change <code>ctrl_interface=...</code> to your interface.
ip link set your-interface up
echo 'ctrl_interface=/run/wpa_supplicant' > wifi.conf
wpa_passphrase SSID passphrase >> wifi.conf
wpa_supplicant -B -i your-interface -c wifi.conf
dhcpcd -A your-interface

 

1.1. Test connection

ping archlinux.org

It should look like this:

PING archlinux.org (138.201.81.199) 56(84) bytes of data.  
64 bytes from apollo.archlinux.org (138.201.81.199): icmp_seq=1 ttl=42 time=285 ms  
64 bytes from apollo.archlinux.org (138.201.81.199): icmp_seq=2 ttl=42 time=285 ms  
64 bytes from apollo.archlinux.org (138.201.81.199): icmp_seq=3 ttl=42 time=285 ms  
...
stop it with:
ctrl + c
If no connection is available, stop the dhcpcd service with <code>systemctl stop dhcpcd@interface</code> where the interface name can be tab-completed.

 

2. Keyboard

 

2.0.1. Input required:

If you have another keyboard that isn't en you can change it with the following command:

ls /usr/share/kbd/keymaps/**/*.map.gz
loadkeys your-keyboard

 

3. Format and delete all your partitions/HDD with parted

We will delete all partitions and add 2 new partitions. If you have more than 1 HDD, you can use your first HDD (/dev/sda) for your /swap partition /root partition and /boot partition.
Your second HDD can be used as the /home partition.

The tutorial applies to one HDD (/dev/sda). If you have more than one, please go to <a href='https://git.pwoss.org/server/documentation/issues'>PwOSS - Gitea</a> and create an issue or send us an <a href='mailto:team@pwoss.org'>email</a>.

parted -a optimal /dev/sda
Hereafter, your storage will be listed. Write it down. Our example is 750 GB.

print
Depending on the list of partitions - If you have more than two, continue with the rm number command.

rm 1
rm 2
rm ...
Change Partition Table.
mklabel msdos

Add two partitions for /boot and /root. We will use LVM on LUKS. There will be more "partitions" later.

 

/boot

mkpart primary ext4 5 500
toggle 1 boot

 

/root

mkpart primary ext4 500 100%
quit

 

4. LVM on LUKS

4.1. Preparing storage

 

4.1.1. Input required:

cryptsetup luksFormat --type luks2 /dev/sda2
Choose your-password.

 

4.1.2. Input required:

cryptsetup open /dev/sda2 cryptlvm
Enter your-password.

 

4.1.3. Preparing the logical volumes

pvcreate /dev/mapper/cryptlvm
vgcreate myStorage /dev/mapper/cryptlvm
lvcreate -L 4G myStorage -n swap
lvcreate -L 40G myStorage -n root
lvcreate -l 100%FREE myStorage -n home
mkfs.ext4 /dev/myStorage/root
mkfs.ext4 /dev/myStorage/home
mkswap /dev/myStorage/swap
mount /dev/myStorage/root /mnt
mkdir /mnt/home
mount /dev/myStorage/home /mnt/home
swapon /dev/myStorage/swap

 

4.1.4. Preparing the boot partition

cryptsetup luksFormat --type luks1 /dev/sda1
Choose your-password like before. You can use the same one if you want.
cryptsetup open /dev/sda1 lvm
pvcreate /dev/mapper/lvm
vgcreate boot /dev/mapper/lvm
lvcreate -l 100%FREE boot -n boot
mkfs.ext4 /dev/boot/boot
mkdir /mnt/boot
mount /dev/boot/boot /mnt/boot

 

5. Select the mirrors

Search for your nearest mirror and put 2-3 of them on top of the list. Or just delete the lines before with ctrl + k.

nano /etc/pacman.d/mirrorlist
ctrl + x
yes

 

6. Install the base packages

Check the processor type of your computer and use only one of the following command. intel-ucode OR amd-ucode? <<Note("Delete wpa_supplicant if you are using Ethernet (cable).

 

amd-ucode

pacstrap /mnt base base-devel openssh grub wpa_supplicant amd-ucode

 

intel-ucode

pacstrap /mnt base base-devel openssh grub wpa_supplicant intel-ucode

 

6.1. Configuring the boot loader

Change the GRUB_CMDLINE_LINUX="".

nano /mnt/etc/default/grub
GRUB_CMDLINE_LINUX=""
to

HDD

GRUB_CMDLINE_LINUX="cryptdevice=/dev/sda1:lvm cryptdevice=/dev/sda2:cryptlvm root=/dev/myStorage/root resume=/dev/myStorage/swap"

SSD

GRUB_CMDLINE_LINUX="cryptdevice=/dev/sda1:lvm cryptdevice=/dev/sda2:cryptlvm root=/dev/myStorage/root resume=/dev/myStorage/swap root_trim=yes"

and change...

#GRUB_ENABLE_CRYPTODISK=y
to

GRUB_ENABLE_CRYPTODISK=y
You can also change GRUB_TIMEOUT. The computer starts immediately with your Arch system. Without waiting.
Just change:

GRUB_TIMEOUT=5
to

GRUB_TIMEOUT=0
ctrl + x
yes

 

7. Configure the system

7.1. Fstab

genfstab -U /mnt >> /mnt/etc/fstab
If the boot partition is listed. You'll need to add # before the boot line.

nano /mnt/etc/fstab
Change:

UUID=your-number /boot ext4 rw,realtime,stripe=4
to

#UUID=your-number /boot ext4 rw,realtime,stripe=4
ctrl + x
yes

 

If you have problems to mount the swap partition after reboot. Change the swap line as well.

UUID=your-number   none    swap    defaults,pri=2 0 0
to

/dev/mapper/myStorage-swap  none    swap    defaults,pri=2 0 0
ctrl + x
yes

 

7.2. Device /dev/xxx not initialized in udev database even after waiting 10000000 microseconds

mkdir /mnt/hostlvm
mount --bind /run/lvm /mnt/hostlvm
arch-chroot /mnt
ln -s /hostlvm /run/lvm

 

7.3. Time zone

 

7.3.1. Input required:

Hit TAB after .../zoneinfo/... .
ln -sf /usr/share/zoneinfo/your-region/your-city /etc/localtime
hwclock --systohc

 

7.4. Localization

Choose your location. For example:en_US.UTF-8 UTF-8

nano /etc/locale.gen
ctrl + x
yes

locale-gen
nano /etc/locale.conf
add - for example:en_US.UTF-8 UTF-8

LANG=en_US.UTF-8
ctrl + x
yes

 

7.4.1. Input required:

If you set the keyboard layout (check position 2 again).
/etc/vconsole.conf
KEYMAP=your-keyboard

 

7.5. Network configuration

nano /etc/hostname
myServer or myDesktop
ctrl + x
yes

nano /etc/hosts
add

127.0.0.1 localhost
127.0.1.1 myserver.localdomain myServer
ctrl + x
yes

 

7.6. Auto login /root partition with key file (only one passphrase for boot partition)

dd bs=512 count=4 if=/dev/urandom of=/crypto_keyfile.bin
cryptsetup luksAddKey /dev/sda2 /crypto_keyfile.bin
chmod 000 /crypto_keyfile.bin
Use your created password for the root partition. You created it a few steps further up.

 

7.7. Automount boot partition

dd bs=512 count=4 if=/dev/urandom of=/.crypto_keyfile-boot.bin
cryptsetup luksAddKey /dev/sda1 /.crypto_keyfile-boot.bin
chmod 000 /.crypto_keyfile-boot.bin
sudo nano /etc/fstab
Add:

/dev/boot/boot                                  /boot           ext4            rw,relatime     0 2
ctrl + x
yes

and

sudo nano /etc/crypttab
add to the bottom:

boot /dev/sda1 /.crypto_keyfile-boot.bin luks
ctrl + x
yes

 

7.8. Configuring mkinitcpio

nano /etc/mkinitcpio.conf
Change:

FILES=()
to

FILES=(/crypto_keyfile.bin)
and change:

HOOKS=(base udev autodetect modconf block filesystem keyboard fsck)
to

HOOKS=(base udev autodetect keyboard keymap modconf block encrypt lvm2 resume filesystems fsck)
ctrl + x
yes
mkinitcpio -p linux

 

7.9. Grub installation

grub-install /dev/sda
grub-mkconfig -o /boot/grub/grub.cfg
chmod -R g-rwx,o-rwx /boot

 

7.10. SSH connection

nano /etc/ssh/sshd_config
Change:

#port 22
#PermitRootLogin prohibit-password
to

port 22
PermitRootLogin yes
ctrl + x
yes
We will change the root login back later when we add another user.

systemctl enable sshd.service && systemctl start sshd.service
Check your server IP address:

ip a s
Depends on your setup you'll see a line like:

inet 192.168.1.76/24
Don't take attention to the loopback (Number 1). Check Number 2 or 3 and write the IP down. Only write <i>192.168.1.76</i> down.

 

7.11. Set root password and reboot

 

7.11.1. Input required:

Set the root password:

passwd
your-password
You can start your freshly installed Arch Linux system now.

exit
umount -R /mnt
reboot now -h
Don't forget to change the BIOS - Boot Priority. Change it back to your HDD.

7.12. SSH Server connection from another device

ssh root@192.168.1.76

 

8. Change timezone

timedatectl set-ntp true && timedatectl list-timezones

Choose your timezone and copy it.
ctrl z

 

8.0.1. Input required:

timedatectl set-timezone your-location
ctrl + x
yes

 

9. Wpa_supplicant

If you're using Ethernet (cable) connection, go to Test Connection. Keep going if you want to use your WIFI.

ip link

 

9.0.2. Input required:

Setup the wireless interface, replace the keyword 'your-interface' with the one that starts with "w" e.g. wlp2s1.

wpa_passphrase SSID passphrase > /etc/wpa_supplicant/wpa_supplicant-your-interface.conf
nano /etc/wpa_supplicant/wpa_supplicant-your-interface.conf
Add on top:
Do not change <code>ctrl_interface=...</code> to your interface.

# Giving configuration update rights to wpa_cli
ctrl_interface=/run/wpa_supplicant
ctrl_interface_group=wheel
update_config=1
ctrl + x
yes

 

9.0.3. Input required:

systemctl enable wpa_supplicant@your-interface
ln -s /usr/share/dhcpcd/hooks/10-wpa_supplicant /usr/lib/dhcpcd/dhcpcd-hooks/
systemctl enable dhcpcd.service
Reboot and check it.
reboot now -h

 

9.1. Test connection

ping archlinux.org

It should look like this:

PING archlinux.org (138.201.81.199) 56(84) bytes of data.  
64 bytes from apollo.archlinux.org (138.201.81.199): icmp_seq=1 ttl=42 time=285 ms  
64 bytes from apollo.archlinux.org (138.201.81.199): icmp_seq=2 ttl=42 time=285 ms  
64 bytes from apollo.archlinux.org (138.201.81.199): icmp_seq=3 ttl=42 time=285 ms  
...
stop it with:
ctrl + c
If no connection is available, stop the dhcpcd service with <code>systemctl stop dhcpcd@interface</code> where the interface name can be tab-completed.

 

10. Add another user

 

10.0.1. Input required:

useradd -m -G wheel -s /bin/bash pwoss
passwd pwoss
your-password

 

10.1. Change SSH connection to user pwoss

nano /etc/ssh/sshd_config
Change:

PermitRootLogin yes
to

PermitRootLogin no
and allow user pwoss instead

AllowUsers pwoss
ctrl + x
yes
You can add <code>AllowUsers pwoss</code> underneath of <code>PermitRootLogin no</code>.
systemctl restart sshd.service
Don't forget to change your ssh connection command. <code>ssh root@192.168.1.76</code> <b>to</b> <code>ssh pwoss@192.168.1.76</code>.

 

11. Add user to sudo

pacman -S sudo --noconfirm && visudo

Uncomment:

# %wheel ALL=(ALL) ALL

to

%wheel ALL=(ALL) ALL
shift + : wq
su - pwoss

 

12. Pikaur

(AUR-Helper)

sudo pacman -S packer git base-devel
<code>Enter (default=all)</code>
cd && mkdir software && cd software && git clone https://github.com/actionless/pikaur.git && cd pikaur && makepkg -fsri --noconfirm

 

13. Downgrade

pikaur -S downgrade --noconfirm

 

14. Crontab

sudo pacman -S cronie --noconfirm && sudo systemctl enable cronie.service && sudo systemctl start cronie.service

 

15. Change editor to nano

sudo nano /etc/environment

Paste under the lines:

export EDITOR=/usr/bin/nano

ctrl + x
yes

 

16. MariaDB

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

Hit enter and set up the mysql root password (use a good password) and hit the following enter for yes.

 

17. Seafile

17.1. Needed packages

pikaur -S seahub libselinux python-wsgidav-seafile --noconfirm

17.2. Seafile user

sudo useradd -m -r -d /home/seafile -s /usr/bin/nologin seafile

 

17.3. Seafile installation

sudo -u seafile -s /bin/sh
cd && mkdir installed && wget https://s3.eu-central-1.amazonaws.com/download.seadrive.org/seafile-server_7.1.1_x86-64.tar.gz && tar -xzf seafile-server_* && mv seafile-server_* installed && cd seafile-server-* && ./setup-seafile-mysql.sh

 

17.3.1. Input required:

servername = newserver
ip = your-server_ip

Hit enter for “8082”
Hit 1
Hit enter for “localhost” and “3306”

What is the password of the mysql root user?

 

17.3.2. Input required:

your-password

Hit enter for “mysql user”

 

17.3.3. Input required:

Create a seafile-mysql user password:

Enter the password for mysql user "seafile": your-password

Hit enter for “[ ccnet database ]”
Hit enter for “[ seafile database ]”
Hit enter for “[ seahub database ]”
Enter through and wait until it’s done

./seafile.sh start
./seahub.sh start 8000

 

17.3.4. Input required:

enter admin email
your-@emailaddress.com

 

17.3.5. Input required:

enter admin password
your-password

 

17.4. Seafile server autostart

sudo nano /etc/systemd/system/seafile.service
[Unit]
Description=Seafile
# add mysql.service or postgresql.service depending on your database to the line below
After=network-online.target network.target NetworkManager-wait-online.service NetworkManager.service mariadb.service

[Service]
Type=oneshot
ExecStart=/home/seafile/seafile-server-latest/seafile.sh start
ExecStop=/home/seafile/seafile-server-latest/seafile.sh stop
RemainAfterExit=yes
User=seafile
Group=seafile

[Install]
WantedBy=multi-user.target
ctrl + x
yes

sudo nano /etc/systemd/system/seahub.service
[Unit]
Description=Seahub
After=network-online.target network.target NetworkManager-wait-online.service NetworkManager.service seafile.service

[Service]
Type=oneshot
ExecStart=/home/seafile/seafile-server-latest/seahub.sh start
ExecStop=/home/seafile/seafile-server-latest/seahub.sh stop
RemainAfterExit=yes
User=seafile
Group=seafile

[Install]
WantedBy=multi-user.target
ctrl + x
yes
sudo systemctl enable seafile.service && sudo systemctl enable seahub.service

 

17.5. SeafDav (WebDav)

cd && cd conf && nano seafdav.conf

Change:

enabled = false

to

enabled = true

ctrl + x
yes

cd && cd seafile-server-latest && ./seafile.sh restart && ./seahub.sh restart

 

17.6. Seafile Nginx

sudo nano /etc/nginx/sites-available/seafile

17.6.1. Input required:

Change to the server_name to your IP

server {
        listen 8001;
        server_name 192.168.1.141;

##################Seafile WSGI mode config##################

location / {
      proxy_pass         http://127.0.0.1:8000;
      proxy_set_header   Host $host;
      proxy_set_header   X-Real-IP $remote_addr;
      proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header   X-Forwarded-Host $server_name;
            proxy_http_version 1.1; # if you use http2 or you get errors in nginx like connection refused ... HTTP/1.1
      proxy_read_timeout  1200s;

     # used for view/edit office file via Office Online Server
     client_max_body_size 0;

     access_log      /var/log/nginx/seahub.access.log;
     error_log       /var/log/nginx/seahub.error.log;
}


   location /seafhttp {
        rewrite ^/seafhttp(.*)$ $1 break;
        proxy_pass http://127.0.0.1:8082;
        client_max_body_size 0;
        # This option is only available for Nginx >= 1.8.0. See more details below.
        proxy_request_buffering off;
    }

############################################seafdav-WSGI
 location /seafdav {
        proxy_pass                http://127.0.0.1:8080;
        proxy_set_header          Host $host;
        proxy_set_header          X-Real-IP $remote_addr;
        proxy_set_header          X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header          X-Forwarded-Host $server_name;
        proxy_set_header          X-Forwarded-Proto https;
        proxy_http_version        1.1;
#####################################################################
        client_max_body_size 0;
        proxy_connect_timeout  36000s;
        proxy_read_timeout  36000s;
        proxy_send_timeout  36000s;
        send_timeout  36000s;

        # This option is only available for Nginx >= 1.8.0. See more details below.
       proxy_request_buffering off;

        access_log      /var/log/nginx/seafdav.access.log;
        error_log       /var/log/nginx/seafdav.error.log;
    }

    location /seafmedia {
        root /home/seafile/seafile-server-latest/seahub;
    }

}
sudo ln -s /etc/nginx/sites-available/seafile /etc/nginx/sites-enabled/ && sudo systemctl restart nginx.service

 

18. Radicale

sudo pacman -S radicale python-setuptools --noconfirm && su
The root user password
mkdir -p /var/lib/radicale/collections && chown -R radicale:radicale /var/lib/radicale/collections && chmod -R o= /var/lib/radicale/collections && nano /etc/systemd/system/radicale.service

Hit enter until the nano editor window pop up and add:

[Unit]
Description=A simple CalDAV (calendar) and CardDAV (contact) server
After=network.target
Requires=network.target

[Service]
ExecStart=/usr/bin/env python3 -m radicale
Restart=on-failure
User=radicale

# Deny other users access to the calendar data
UMask=0027

# Optional security settings
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
NoNewPrivileges=true
ReadWritePaths=/var/lib/radicale/collections

[Install]
WantedBy=multi-user.target

ctrl + x
yes

nano /etc/radicale/config

Change:

# hosts = 127.0.0.1:5232
to

hosts = 192.168.1.76:5232
and the following too
# type = none
type = htpasswd
# htpasswd_filename = /etc/radicale/users
htpasswd_filename = /etc/radicale/users
# htpasswd_encryption = bcrypt
htpasswd_encryption = bcrypt
# delay = 1
delay = 1
# max_connections = 20
max_connections = 20
# max_content_length = 10000000
max_content_length = 10000000
# timeout = 10
timeout = 10

ctrl + x
yes

nano /etc/radicale/users

 

18.0.2. Input required:

Change <code>your-user</code> and <code>your-password</code> to your Family Member for example.
echo -e "your-user:`perl -le 'print crypt("your-password","salt")'`" >> /etc/radicale/users
...

ctrl + x
yes

systemctl enable radicale && systemctl start radicale && systemctl status radicale
su - pwoss

 

19. WireGuard

19.1. Server

Do everything with root.

su

19.1.1. Packages

pacman -S wireguard-tools

 

19.1.2. Keys

cd /etc/wireguard/
umask 077; wg genkey | tee privatekey | wg pubkey > publickey

 

19.1.3. Config (wg0.conf)

19.1.3.1. Interface

Copy the private key number.

cat privatekey
nano wg0.conf
[Interface]
PrivateKey = <Private Key>
Address = 10.0.0.1/24, fd86:ea04:1115::1/64
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
SaveConfig = true
Change your interface <code>eth0</code> to your interface.

 

19.1.3.2. Peer

  1. Go to clients first and follow the instructions.

  2. Copy the publickey and presharedkey of your client.

    cat /etc/wireguard/clients/phones/pinephone/publickey && cat /etc/wireguard/clients/phones/pinephone/presharedkey
  3. Add the peer
    nano /etc/wireguard/wg0.conf
    [Peer]
    # PinePhone
    PublicKey = <client public key>
    PresharedKey = <preshared key>
    AllowedIPs = 10.0.0.2/32

 

19.2. Clients

19.2.1. Folder structure

Create clients for laptop, desktop, phones etc.. Whatever you prefer.

mkdir -p /etc/wireguard/clients/phones/pinephone/

 

19.2.2. Keys

cd /etc/wireguard/clients/phones/pinephone/
umask 077; wg genkey | tee privatekey | wg pubkey > publickey | wg genpsk > presharedkey
cat privatekey && cat presharedkey && cat /etc/wireguard/publickey
nano pinephone.conf
[Interface]
PrivateKey = <pinephones-privatekey>
Address = 10.0.0.2/24,fd42:42:42::2/64

## Optional. Leave it like it is if you want to use your server DNS. 
# DNS = 

[Peer]
#Home server
PublicKey = <server public key>
PresharedKey = <preshared key>
Endpoint = <server public IP or domain>:51820
AllowedIPs = 0.0.0.0/0,::/0

 

19.2.3. Permissions

Set the right permissions.

chmod -R 600 /etc/wireguard/clients/

 

19.2.4. Copy file

Copy your .conf file to your device.

scp pinephone.conf dan@192.168.1.248:~/

 

19.2.4.1. Generate QR Code

You can also create an QR code.

pacman -S qrencode
qrencode -t ansiutf8 < pinephone.conf

 

19.2.5. Back to peer

Click

 

19.2.6. More clients

If you need more clients, just follow the clients process again and add the peer to your server among your other clients.

 

19.3. Start service

systemctl enable wg-quick@wg0.service && systemctl start wg-quick@wg0.service

 

19.4. DDClient-Dynamic DNS

sudo pacman -S ddclient --noconfirm && sudo nano /etc/ddclient/ddclient.conf

 

19.4.1. Input required:

Add following lines and change the "login=","password=", and the domain at the bottom.

For noip
protocol=dyndns2
use=web, if=eth0
server=dynupdate.no-ip.com
login=your-@emailaddress.com
password='your-password'
your-dyndns_domain
sudo crontab -e

add

#######################DDClient
45 04 * * * /usr/sbin/ddclient --force
##################################

 

20. UFW

sudo pacman -S ufw --noconfirm
sudo ufw allow ssh && sudo ufw allow 51820/udp && sudo ufw allow 8001/tcp && sudo ufw allow 8080/tcp && sudo ufw allow 8082/tcp && sudo ufw allow 5232/tcp

y

sudo nano /etc/ufw/sysctl.conf

Uncomment:

#net/ipv4/ip_forward=1

to

net/ipv4/ip_forward=1

ctrl + x
yes

sudo ufw enable && sudo systemctl enable ufw.service && sudo systemctl start ufw.service
YES

 

21. Bash completion

sudo pacman -S bash-completion --noconfirm && nano ~/.bashrc
Add to the bottom:
if [ -f /etc/bash_completion ]; then          
. /etc/bash_completion
fi
export EDITOR=/usr/bin/nano
export VISUAL=$EDITOR

ctrl + x
yes

 

22. Nginx

sudo pacman -S nginx-mainline --noconfirm && sudo nano /etc/nginx/nginx.conf
Change worker_processes  1;
to

worker_processes  4;
And add to the bottom one line before
}

include sites-enabled/*; # See Server blocks
ctrl + x
yes
sudo mkdir /etc/nginx/sites-available && sudo mkdir /etc/nginx/sites-enabled && sudo systemctl enable nginx.service && sudo systemctl start nginx.service

 

23. PHP7

sudo pacman -S php php-fpm php-gd php-sqlite --noconfirm
sudo nano /etc/php/php-fpm.d/www.conf

Add ; before the following:

;listen.owner = http
;listen.group = http

and uncomment

listen.acl_users = http
listen.acl_groups = http

 

23.0.2. Input required:

Uncomment the following lines in /etc/php/php.ini: (Delete ; )

sudo nano /etc/php/php.ini
date.timezone = your-location
Change:

;open_basedir =
to

open_basedir = /srv/http/:/home/:/tmp/:/usr/share/pear/:/usr/share/webapps/
...
extension=pdo_sqlite
extension=sockets
extension=sqlite3
extension=pdo_mysql
extension=mysqli
extension=gd
and change:

expose_php = On
to

expose_php = Off
ctrl + x
yes
sudo systemctl enable php-fpm.service && sudo systemctl start php-fpm.service

 

24. Adminer

pikaur -S adminer --noconfirm && sudo nano /etc/nginx/sites-available/adminer
Add the following lines and change the IP address to your server IP:

server {
  listen 22322;
  server_name 192.168.1.76;

  root /usr/share/webapps/adminer;

# If you want to use a .htpass file, uncomment the three following lines.
#auth_basic "Admin-Area! Password needed!";
#auth_basic_user_file /usr/share/webapps/adminer/.htpass;
#access_log /var/log/nginx/adminer-access.log;

error_log /var/log/nginx/adminer-error.log;

location / {
  index index.php;
  try_files $uri $uri/ /index.php?$args;
  }

  location ~ .php$ {
    include fastcgi.conf;
#    fastcgi_pass localhost:9000;
    fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /usr/share/webapps/adminer$fastcgi_script_name;
  }
}
ctrl + x
yes

sudo ln -s /etc/nginx/sites-available/adminer /etc/nginx/sites-enabled/ && sudo ufw allow 22322/tcp && sudo systemctl restart nginx.service
Check http://your-server_ip:22322/adminer

 

25. Msmtp

sudo pacman -S msmtp msmtp-mta --noconfirm && sudo nano /etc/msmtprc

 

25.0.3. Input required:

Add and change all PwOSS, your-@emailaddress.com and your-password settings to your provider.

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

# PwOSS
account        pwoss
host           smtp.pwoss.org
port           587
from           your-@emailaddress.com
user           your-@emailaddress.com
password       your-password


# Set a default account
account default : pwoss
ctrl + x
yes

If you want to get info/emails from your crontab add the following line:

sudo nano /usr/lib/systemd/system/cronie.service
Change:

ExecStart=/usr/bin/crond -n
to

ExecStart=/usr/bin/crond -n -m '/usr/bin/msmtp -t'
ctrl + x
yes
sudo systemctl daemon-reload && sudo systemctl restart cronie.service

 

25.0.4. Input required:

Test it:

Change email

echo "PwOSS - Server" | msmtp -a default your-@emailaddress.com
Check your spam folder.

 

26. Pi-hole

pikaur -S pi-hole-server --noconfirm && sudo nano /etc/resolvconf.conf
Uncomment:

#name_servers=127.0.0.1
to

name_servers=127.0.0.1
ctrl + x
yes

sudo resolvconf -u
sudo nano /etc/hosts
Add to the bottom (change the IP to yours)

192.168.1.76 pi.hole myServer
ctrl + x
yes

sudo nano /etc/nginx/nginx.conf
Change:

#gzip  on;
to

gzip  on;
and add under gzip on;

gzip_min_length 1000;
gzip_proxied    expired no-cache no-store private auth;
gzip_types      text/plain application/xml application/json application/javascript application/octet-stream text/css;
include /etc/nginx/conf.d/*.conf;
ctrl + x
yes

sudo nano /etc/nginx/sites-available/pihole
Change the IP (server_name)
server {
        listen 987 default_server;
        listen [::]:987 default_server;

        root /srv/http/pihole;
        server_name 192.168.1.141;

        autoindex off;

        index pihole/index.php index.php index.html index.htm;

        location / {
                expires max;
                try_files $uri $uri/ =404;
        }

        location ~ \.php$ {
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
                fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
                fastcgi_param FQDN true;
#               auth_basic "Restricted"; # For Basic Auth
#               auth_basic_user_file /etc/nginx/.htpasswd; # For Basic Auth
        }

        location /*.js {
                index pihole/index.js;
#               auth_basic "Restricted"; # For Basic Auth
#               auth_basic_user_file /etc/nginx/.htpasswd; # For Basic Auth
        }

        location /admin {
                root /srv/http/pihole;
                index index.php index.html index.htm;
#               auth_basic "Restricted"; # For Basic Auth
#                auth_basic_user_file /etc/nginx/.htpasswd; # For Basic Auth
        }

        location ~ /\.ht {
                deny all;
        }
}
ctrl + x
yes

sudo ln -s /etc/nginx/sites-available/pihole /etc/nginx/sites-enabled/ && sudo nano /etc/php/php.ini
Add behind the others /srv/http/:/home/:/tmp/:/usr/share/pear/:/usr/share/webapps/

:/srv/http/pihole:/run/pihole-ftl/pihole-FTL.port:/run/log/pihole/pihole.log:/run/log/pihole-ftl/pihole-FTL.log:/etc/pihole:/etc/hosts:/etc/hostname:/etc/dnsmasq.d:/proc/meminfo:/proc/cpuinfo:/sys/class/thermal/thermal_zone0/temp:/dev/null
ctrl + x
yes

 

26.0.5. Input required:

Set a password:

pihole -a -p
your-password
sudo nano /etc/dnsmasq.d/00-openvpn.conf
add

interface=tun0
ctrl + x
yes

sudo ufw allow 987/tcp && sudo ufw allow from 10.8.0.0/24
sudo crontab -e
add

#######################pihole flush logs
45 23 * * 0,3 pihole -f
################################


#######################pihole update new blocks
15 23 * * 0,3 pihole -g
################################
ctrl + x
yes

sudo nano /etc/openvpn/server/server.conf
Change the VPN route through Pi-hole and change the IP Address

########################Pi-hole
#push "dhcp-option DNS 192.168.1.76"
###############################
to

########################Pi-hole
push "dhcp-option DNS 192.168.1.76" # (< change the IP to your server IP)
###############################
ctrl + x
yes

26.0.6. Input required:

Change the home network IP (192.168.1.0)!!

sudo ufw allow from 192.168.1.0/24
sudo systemctl stop systemd-resolved.service && sudo systemctl disable systemd-resolved.service && sudo systemctl restart pihole-FTL.service && sudo systemctl restart nginx.service && sudo systemctl restart php-fpm.service
Check http://your-server_ip:987/admin

 

26.1. Recursive DNS server (unbound)

sudo pacman -S unbound expat --noconfirm && wget -O root.hints https://www.internic.net/domain/named.cache && sudo mv root.hints /etc/unbound/ && sudo mv /etc/unbound/unbound.conf /etc/unbound/unbound.conf.backup && sudo nano /etc/unbound/unbound.conf

26.1.1. Input required:

Add the following and change private-address: 192.168.1.0/16 to your IP network.

server:
    # If no logfile is specified, syslog is used
    # logfile: "/var/log/unbound/unbound.log"
    verbosity: 0

    port: 5353
    do-ip4: yes
    do-udp: yes
    do-tcp: yes
    do-daemonize: no
    trust-anchor-file: trusted-key.key

    # May be set to yes if you have IPv6 connectivity
    do-ip6: no

    # Use this only when you downloaded the list of primary root servers!
    root-hints: "/etc/unbound/root.hints"

    # Trust glue only if it is within the servers authority
    harden-glue: yes

    # Require DNSSEC data for trust-anchored zones, if such data is absent, the zone becomes BOGUS
    harden-dnssec-stripped: yes

    # Don't use Capitalization randomization as it known to cause DNSSEC issues sometimes
    # see https://discourse.pi-hole.net/t/unbound-stubby-or-dnscrypt-proxy/9378 for further details
    use-caps-for-id: no

    # Reduce EDNS reassembly buffer size.
    # Suggested by the unbound man page to reduce fragmentation reassembly problems
    edns-buffer-size: 1472

    # TTL bounds for cache
    cache-min-ttl: 3600
    cache-max-ttl: 86400

    # Perform prefetching of close to expired message cache entries
    # This only applies to domains that have been frequently queried
    prefetch: yes

    # One thread should be sufficient, can be increased on beefy machines
    num-threads: 1

    # Ensure kernel buffer is large enough to not loose messages in traffic spikes
    so-rcvbuf: 1m

    # Ensure privacy of local IP ranges
    private-address: 192.168.1.0/16
    private-address: 10.0.0.0/8
    #private-address: fd00::/8 # IPv6
    #private-address: fe80::/10 # IPv6
ctrl + x
yes

sudo systemctl enable unbound.service && sudo systemctl start unbound.service
sudo nano /etc/systemd/system/roothints.service
[Unit]
Description=Update root hints for unbound
After=network.target

[Service]
ExecStart=/usr/bin/curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache
ctrl + x
yes

sudo nano /etc/systemd/system/roothints.timer
[Unit]
Description=Run root.hints monthly

[Timer]
OnCalendar=monthly
Persistent=true

[Install]
WantedBy=timers.target
ctrl + x
yes
sudo systemctl enable roothints.timer && sudo systemctl start roothints.timer

You need to change the settings of your Pi-hole.
Go to http://your-server_ip:987/admin/settings.php?tab=dns and disable all DNS server on the left side and add to Custom 1 (IPv4)

127.0.0.1#5353
and save it.

26.2. Dnscrypt-proxy

sudo pacman -S dnscrypt-proxy && sudo nano /etc/dnscrypt-proxy/dnscrypt-proxy.toml
Change
listen_addresses = ['127.0.0.1:53', '[::1]:53']
to
listen_addresses = ['127.0.0.1:53000', '[::1]:53000']
ctrl + x
yes

sudo nano /etc/unbound/unbound.conf
Add the following under the other lines.
# dnscrypt-proxy
  do-not-query-localhost: no
forward-zone:
  name: "."
  forward-addr: ::1@53000
  forward-addr: 127.0.0.1@53000
ctrl + x
yes
sudo systemctl enable dnscrypt-proxy.service && sudo systemctl start dnscrypt-proxy.service && sudo systemctl restart unbound.service

 

27. Samba

sudo pacman -S samba --noconfirm && mkdir ~/samba && sudo nano /etc/samba/smb.conf
Add:

[global]
workgroup = WORKGROUP
security = user
encrypt passwords = yes

[PwOSS - User]
comment = samba
path = /mnt/samba/
read only = no
ctrl + x
yes

 

27.0.1. Input required:

sudo smbpasswd -a pwoss
your-password
sudo ufw allow 139/tcp && sudo ufw allow 445/tcp && sudo systemctl enable smb.service && sudo systemctl start smb.service
Check smb://your-server_ip/samba

 

28. FreshRSS

pikaur -S freshrss --noconfirm && sudo nano /etc/nginx/sites-available/freshrss
Add and change your IP address:

server {
        listen 7666; # http on port 80

        # your server's url(s)
        server_name 192.168.1.76; # Your server IP address

        # the folder p of your FreshRSS installation
        root /usr/share/webapps/freshrss/p/;

        index index.php index.html index.htm;

        # nginx log files
        access_log /var/log/nginx/rss.access.log;
        error_log /var/log/nginx/rss.error.log;


        # php files handling
        # this regex is mandatory because of the API
        location ~ ^.+?\.php(/.*)?$ {

#               fastcgi_pass 127.0.0.1:9000;
                fastcgi_pass unix:/run/php-fpm/php-fpm.sock;

                fastcgi_split_path_info ^(.+\.php)(/.*)$;

        # By default, the variable PATH_INFO is not set under PHP-FPM
        # But FreshRSS API greader.php need it. If you have a "Bad Request" error, double check this var !
                fastcgi_param PATH_INFO $fastcgi_path_info;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }


        location / {
                try_files $uri $uri/ index.php;
        }

}
ctrl + x
yes
sudo ufw allow 7666/tcp && sudo nano /etc/php/php.ini

Add:

/var/lib/webapps/freshrss/

behind

open_basedir = ....:

and uncomment:

;extension=gmp
to

extension=gmp
ctrl + x
yes

sudo ln -s /etc/nginx/sites-available/freshrss /etc/nginx/sites-enabled/
sudo systemctl restart php-fpm.service && sudo systemctl restart nginx

 

28.0.2. Input required:

mysql -u root -p
your-password

 

28.0.3. Input required:

CREATE DATABASE FreshRSS;
CREATE USER 'FreshRSS'@'localhost' IDENTIFIED BY 'your-password';
GRANT ALL ON FreshRSS.* TO 'FreshRSS'@'localhost';
FLUSH PRIVILEGES;
exit
Check http://your-server_ip:7666 and follow the instructions.

Database = FreshRSS
Database USER = FreshRSS
Password = your-password

 

28.1. Automatic feed update

sudo crontab -e
Add:
#######################FreshRSS Updates
0 */3 * * * php -f /usr/share/webapps/freshrss/app/actualize_script.php > /tmp/FreshRSS.log 2>&1
################################

 

29. Firefox sync server

sudo pacman -S python2-virtualenv --noconfirm && cd && cd software && git clone https://github.com/mozilla-services/syncserver.git && cd syncserver && make build

 

29.0.1. Input required:

mysql -u root -p
your-password

 

29.0.2. Input required:

CREATE DATABASE ffsync;
CREATE USER 'ffsync'@'localhost' IDENTIFIED BY 'your-password';
GRANT ALL ON ffsync.* TO 'ffsync'@'localhost';
FLUSH PRIVILEGES;
exit
nano syncserver.ini
Add under
#sqluri = sqlite:////tmp/syncserver.db

 

29.0.3. Input required:

sqluri = pymysql://ffsync:your-password@localhost:3306/ffsync
and change the IP address

public_url = http://192.168.1.76:5000/
ctrl + x
yes

crontab -e
Add:
This is only for your pwoss user. Do not be surprised if the others are not listed.

#####################ffsync
@reboot sleep 120 && cd /home/pwoss/software/syncserver/ && make serve
##########################################
ctrl + x
yes

sudo ufw allow 5000/tcp
cd && cd /home/pwoss/software/syncserver/ && make serve
Check http://your-server_ip:5000/. <code>It work's!</code> Should be the answer!

ctrl + c
To cancel the action.

 

29.1. Clients

To configure desktop Firefox to talk to your new Sync server, go to “about:config”, search for “identity.sync.tokenserver.uri” and change its value to the URL of your server with a path of “token/1.0/sync/1.5”:

Alternatively, if you’re running your own Firefox Accounts server, and running Firefox 52 or later, see the documentation on how to Run your own Firefox Accounts Server for how to configure your client for both Sync and Firefox Accounts with a single preference.

Since Firefox 33, Firefox for Android has supported custom sync servers. To configure Android Firefox 44 and later to talk to your new Sync server, just set the “identity.sync.tokenserver.uri” exactly as above before signing in to Firefox Accounts and Sync on your Android device.

Important: after creating the Android account, changes to “identity.sync.tokenserver.uri” will be ignored. (If you need to change the URI, delete the Android account using the Settings > Sync > Disconnect... menu item, update the pref, and sign in again.) Non-default TokenServer URLs are displayed in the Settings > Sync panel in Firefox for Android, so you should be able to verify your URL there.

Prior to Firefox 44, a custom add-on was needed to configure Firefox for Android. For Firefox 43 and earlier, see the blog post How to connect Firefox for Android to self-hosted Firefox Account and Firefox Sync servers.

(Prior to Firefox 42, the TokenServer preference name for Firefox Desktop was “services.sync.tokenServerURI”. While the old preference name will work in Firefox 42 and later, the new preference is recommended as the old preference name will be reset when the user signs out from Sync causing potential confusion.)

 

29.2. Updating the server

You should periodically update your code to make sure you’ve got the latest fixes. The following commands will update syncserver in place:

cd /home/pwoss/software/syncserver  
$ git stash       # to save any local changes to the config file  
$ git pull        # to fetch latest updates from github  
$ git stash pop   # to re-apply any local changes to the config file  
$ make build      # to pull in any updated dependencies  

 

29.3. Restart ff-sync-server

ps aux | grep make
Check “make serve” and copy the id (first number)
kill (id number)
cd /home/pwoss/software/syncserver/ && make serve

 

30. Fail2ban

sudo pacman -S fail2ban --noconfirm && sudo systemctl enable fail2ban.service && sudo systemctl start fail2ban.service

 

31. (Optional) - If you want to change the boot text

sudo nano /etc/motd
################################################
Welcome to your PwOSS-Server

     Website: https://pwoss.org
        Wiki: https://wiki.pwoss.org
         Git: https://git.pwoss.org
################################################
This image is based on Arch Linux | ARM

     Website: http://archlinuxarm.org
       Forum: http://archlinuxarm.org/forum
         IRC: #archlinux-arm on irc.Freenode.net
################################################

 

32. REBOOT

sudo reboot now -h

   

33. Your servers are running at ...

 

  • Radicale = Contact and Calendar Server ----> http://your-server_ip:5232
  • Seafile = Cloud Server ----> http://your-server_ip:8001
  • WebDav = WebDav Server ----> http://your-server_ip:8080
  • VPN = Virtual Private Network ----> your-dyndns_domain
  • Samba = File Server ----> smb://your-server_ip/externalHD
  • FireFox = Sync Bookmarks/History ----> http://your-server_ip:5000/
  • Pi-hole = Advertising blocker ----> http://your-server_ip:987/admin/
  • FreshRSS = RSS Reader ----> http://your-server_ip:7666

 

Now you’re able to save your personal data on your own servers. To keep it safe against a burglar, natural disasters, hardware defects we suggest to set up the same or similar servers with a friend or family member.

 

ENJOY