The documentation repo contains the copy & paste variant of the server installation.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

46 KiB

Arch x86_64

Copy & paste Arch Linux x86_64 solution
from scratch.

 

Software Suite

------

[[TOC]]

 

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 ‘ctrl_interface=...’ 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 systemctl stop dhcpcd@interface 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 PwOSS - Gitea and create an issue or send us an email.

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?

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 192.168.1.76 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 ‘ctrl_interface=...’ 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 systemctl stop dhcpcd@interface 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 AllowUsers pwoss underneath of PermitRootLogin no.

systemctl restart sshd.service

Don’t forget to change your ssh connection command.
ssh root@192.168.1.76 to ssh pwoss@192.168.1.76

 

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

Enter (default=all)

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

sudo pacman -S xmlsec ffmpeg fuse2 libarchive vala libevent libldap libmariadbclient python2-chardet python2-dateutil python2-django python-flup python2-memcached python2-pillow python2-pytz python2-requests python2-requests-oauthlib python2-six mysql-python wget --noconfirm
pikaur -S python2-social-auth-core python2-flup python2-django-formtools libevhtp-seafile libsearpc python2-qrcode python2-cas python2-django-compressor python2-django-constance python2-django-picklefield python2-django-post-office python2-django-rest-framework python2-django-simple-captcha python2-django-statici18n python2-django-webpack-loader python2-django-pylibmc python2-wsgidav-seafile libselinux python2-gunicorn python2-openpyxl --noconfirm

Enter Y (Yes) for everything.

 

17.2. Seafile user

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

 

17.3. Seafile installation

sudo -u seafile -s /bin/sh
cd && mkdir installed && wget https://download.seadrive.org/seafile-server_7.0.4_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 = myServer
ip = your-server_ip
/srv/seafile/seafile-data = your-storage_path

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 8001

 

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 mariadb.service

[Service]
Type=oneshot
ExecStart=/srv/seafile/seafile-server-latest/seafile.sh start
ExecStop=/srv/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=Seafile hub
After=network-online.target network.target seafile.service

[Service]
# change start to start-fastcgi if you want to run fastcgi
ExecStart=/srv/seafile/seafile-server-latest/seahub.sh start 8001
ExecStop=/srv/seafile/seafile-server-latest/seahub.sh stop
User=seafile
Group=seafile
Type=oneshot
RemainAfterExit=yes

[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.76;

##################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 /srv/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 = plain
# 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 to your Family Member for example.

your-user1:your-user1_password
your-user2:your-user2_password
...

ctrl + x
yes

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

 

19. OpenVPN

sudo groupadd nogroup

 

19.1. DDClient-Dynamic DNS

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

 

19.1.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
##################################

 

19.2. Easy-RSA

sudo pacman -S openvpn easy-rsa --noconfirm && sudo su
cd /etc/easy-rsa
export EASYRSA=$(pwd)
easyrsa init-pki
easyrsa build-ca nopass

 

19.2.1. Input required:

Change ‘your-dyndns_domain’ to your domain.

Common Name (eg: your user, host, or server name) [Easy-RSA CA]:your-dyndns_domain
Your new CA certificate file for publishing is at:/etc/easy-rsa/pki/ca.crt
cp /etc/easy-rsa/pki/ca.crt /etc/openvpn/server/
easyrsa gen-req ArchServer nopass
your-dyndns_domain

Enter

cp /etc/easy-rsa/pki/private/ArchServer.key /etc/openvpn/server/
openssl dhparam -out /etc/openvpn/server/dh.pem 2048

This takes around 20 minutes

 

19.2.2. Input required:

Change ‘your-device’ like Smartphone / Laptop etc.

openvpn --genkey --secret /etc/openvpn/server/ta.key
easyrsa gen-req your-device

Enter your-password and NO COMMON NAME!!
Hit enter

easyrsa sign-req server ArchServer

yes

 

19.2.3. Input required:

Change ‘your-device’ like Smartphone / Laptop etc.

easyrsa sign-req client your-device

yes

mv /etc/easy-rsa/pki/issued/ArchServer.crt /etc/openvpn/server/
mkdir /etc/easy-rsa/pki/signed
mv /etc/easy-rsa/pki/issued/your-device.crt /etc/easy-rsa/pki/signed
exit

 

19.3. Client config & ovpngen AUR

cd && pikaur -S ovpngen --noconfirm

 

19.3.1. Input required:

Change ‘your-dyndns_domain’ to your domain.
Change ‘your-device’ like Smartphone / Laptop etc.

sudo ovpngen your-dyndns_domain /etc/openvpn/server/ca.crt /etc/easy-rsa/pki/signed/your-device.crt /etc/easy-rsa/pki/private/your-device.key /etc/openvpn/server/ta.key > your-device.ovpn
sudo nano your-device.ovpn

 

19.3.2. Input required:

Change ‘your-dyndns_domain’ to your domain.

remote your-dyndns_domain 1194 udp

and add behind ‘verb 3’

cipher AES-256-CBC
auth SHA512
resolv-retry infinite
tls-version-min 1.2
auth-nocache
remote-cert-tls server
comp-lzo

ctrl + x
yes

 

19.3.3. Input required:

Copy the file to your Phone and import the file to the “OpenVPN for Android” application or to your computer.

sudo scp your-device.ovpn your-copmputer/your-user@192.168.1.xxx:/home/your-user/

 

19.4. Server config

sudo nano /etc/openvpn/server/server.conf

Change the IP to your home network if it’s necessary.

# your local subnet
push "route 192.168.1.0 255.255.255.0"

Change the client’s number depends on your needs.

max-clients 2
port 1194
proto udp
dev tun
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/ArchServer.crt
key /etc/openvpn/server/ArchServer.key
dh /etc/openvpn/server/dh.pem
server 10.8.0.0 255.255.255.0
# server and remote endpoints
ifconfig 10.8.0.1 10.8.0.2
# Add route to Client routing table for the OpenVPN Server
push "route 10.8.0.1 255.255.255.255"
# Add route to Client routing table for the OPenVPN Subnet
push "route 10.8.0.0 255.255.255.0"
# your local subnet
push "route 192.168.1.0 255.255.255.0"
# Set your primary domain name server address for clients

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

###### https://dns.watch/
#push "dhcp-option DNS 84.200.69.80"
#push "dhcp-option DNS 84.200.70.40"
# Override the Client default gateway by using 0.0.0.0/1 and
# 128.0.0.0/1 rather than 0.0.0.0/0. This has the benefit of
# overriding but not wiping out the original default gateway.
#push "redirect-gateway def1"
push "redirect-gateway def1 bypass-dhcp"

client-to-client
duplicate-cn
keepalive 10 120
tls-version-min 1.2
tls-auth /etc/openvpn/server/ta.key 0
cipher AES-256-CBC
auth SHA512
#comp-lzo
compress lz4-v2
push "compress lz4-v2"
user nobody
group nogroup
persist-key
persist-tun
max-clients 2
remote-cert-tls client
#client-connect /etc/openvpn/vpn-connect.sh
#client-disconnect /etc/openvpn/vpn-disconnect.sh
#script-security 2
#crl-verify /etc/openvpn/crl.pem
status /var/log/openvpn-status.log 20
status-version 3
log /var/log/openvpn.log
verb 3
ifconfig-pool-persist ipp.txt
log-append /var/log/openvpn
status /tmp/vpn.status 10

ctrl + x
yes

sudo systemctl enable openvpn-server@server.service && sudo systemctl start openvpn-server@server.service

 

19.5. New clients

 

19.5.1. Input required:

Change ‘your-device’ like Smartphone / Laptop etc.

sudo su && cd /etc/easy-rsa
easyrsa gen-req your-device

Enter your password and NO COMMON NAME!!
Hit enter

 

19.5.2. Input required:

easyrsa sign-req client your-device

yes

 

19.5.3. Input required:

Change ‘your-dyndns_domain’ to your domain.
Change ‘your-device’ like Smartphone / Laptop etc.

mv /etc/easy-rsa/pki/issued/your-device.crt /etc/easy-rsa/pki/signed
sudo ovpngen yourDYNDNSdomain.com /etc/openvpn/server/ca.crt /etc/easy-rsa/pki/signed/your-device.crt /etc/easy-rsa/pki/private/your-device.key /etc/openvpn/server/ta.key > your-device.ovpn
sudo nano your-device.ovpn

 

19.5.4. Input required:

Change ‘your-dyndns_domain’ to your domain.

remote your-dyndns_domain 1194 udp

and add behind ‘verb 3’

cipher AES-256-CBC
auth SHA512
resolv-retry infinite
tls-version-min 1.2
auth-nocache
remote-cert-tls server
comp-lzo

ctrl + x
yes

 

19.5.5. Input required:

Copy the file to your Phone and import the file to the “OpenVPN for Android” application or to your computer.

sudo scp your-device.ovpn your-copmputer/your-user@192.168.1.xxx:/home/your-user/

 

20. UFW

sudo pacman -S ufw --noconfirm && sudo nano /etc/default/ufw

Change:

DEFAULT_FORWARD_POLICY="DROP"

to

DEFAULT_FORWARD_POLICY="ACCEPT"
sudo nano /etc/ufw/before.rules

 

20.0.6. Input required:

Add after header (# ufw-before-forward) and before (# Don’t delete these required lines, otherwise there will be errors and change the ‘your-interface

# NAT (Network Address Translation) table rules
*nat
:POSTROUTING ACCEPT [0:0]

# Allow traffic from clients to the interface
-A POSTROUTING -s 10.8.0.0/24 -o your-interface -j MASQUERADE

# do not delete the "COMMIT" line or the NAT table rules above will not be processed
COMMIT

ctrl + x
yes

sudo ufw allow ssh && sudo ufw allow 1194/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.7. 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.8. 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.9. 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 cp /usr/share/pihole/configs/nginx.example.conf /etc/nginx/sites-available/pihole && sudo nano /etc/nginx/sites-available/pihole

and change:

listen 80 default_server;
       listen [::]:80 default_server;
server_name _;

to

listen 987 default_server;
       listen [::]:987 default_server;
server_name 192.168.1.76; # Your server IP address

and change:

              fastcgi_pass  127.0.0.1:9000;

to

              fastcgi_pass unix:/run/php-fpm/php-fpm.sock;

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.10. 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.11. 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/
it work’s!
Is 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 ...

 

 

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