Install Nextcloud on Arch Linux

From Open Source Ecology
Revision as of 20:15, 23 June 2020 by Pieter (talk | contribs) (Basic setup of Arch Linux)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Comment

For some reason the <source> tags don't work, will fix it later.

Introduction

This document describes how to set up Nextcloud on a virtual private server (VPS) hosted by a cloud service provider that provides images for Arch Linux. We assume there is a DNS record in place that points the address cloud.mydomain.net to the IP address provided by the cloud service provider.

Basic setup Arch Linux

Initial setup

Since the system comes preinstalled with Arch Linux on it, the first thing to do is to update the system:

<source lang="bash">pacman -Syu

reboot

pacman -S base base-devel </source>

Add an administration user

We add a day-to-day administrator account:

<source lang="bash">useradd -m -g users -s /bin/bash admin passwd admin </source> Make sure that pacman can be executed as user admin:

<source lang="bash">visudo </source> And add the following:

<source lang="bash">admin ALL=(ALL) NOPASSWD: /usr/bin/pacman </source>

Create a swap partition

The swap partition has already been activated, so there is nothing to do.

Configure the language and locales

In file /etc/locale.gen:

<source lang="bash">en_US.UTF-8 UTF-8 </source> Then execute:

<source lang="bash">locale-gen

echo LANG=en_US.UTF-8 > /etc/locale.conf export LANG=en_US.UTF-8 </source> Add the correct time zone, for example:

ln -s /usr/share/zoneinfo/Europe/Amsterdam /etc/localtime

Time configuration

Since Arch sits in a virtual machine, we assume that the time is always correct.

Random number generation

Random number generation is important for security, so we install the following tools:

<source lang="bash">pacman -S rng-tools

systemctl start rngd systemctl enable rngd </source> To check the level of entropy we can do:

<source lang="bash">cat /proc/sys/kernel/random/entropy_available </source> Since it runs on a virtual machine, we are not really sure how representative the entropy is.

We can also run the following tests which should have very few failures:

<source lang="bash">cat /dev/random | rngtest -c 1000 cat /dev/urandom | rngtest -c 1000 </source> The rng-tools service is preferred over haveged.

Setting the hostname

Assuming we have a hostname mydomainname.net that points to our server's IP address:

In /etc/hostname:

<source lang="bash">cloud.mydomainname.net </source> In /etc/hosts:

<source lang="bash">127.0.1.1 cloud.mydomainname.net </source> After a reboot, we can check whether everything is set with the command hostname -f.

Setting up the network

The network has been set up fine by the cloud provider.

Setting up the firewall

We use iptables to set up the firewall. A chain is a set of rules. The chain INPUT is predefined for packets that enter the system.

First we set the policy for chain INPUT to target ACCEPT:

<source lang="bash">iptables -P INPUT ACCEPT ip6tables -P INPUT ACCEPT </source> We then flush all the chains:

<source lang="bash">iptables -F ip6tables -F </source> A table in this context is a packet matching table. There are five predefined tables. The default table filter, the tables nat, mangle, raw, and security. We flush the table nat:

<source lang="bash">iptables -t nat -F ip6tables -t nat -F </source> We then delete all the user-defined chains:

<source lang="bash">iptables -X ip6tables -X </source> We then set the policy to drop every packet that enters the system (make sure you are logged in via a video display and not SSH):

<source lang="bash">iptables -P INPUT DROP ip6tables -P INPUT DROP </source> We append to chain INPUT on the loopback interface lo to jump to target ACCEPT. This is important for applications that use local servers.

<source lang="bash">iptables -A INPUT -i lo -j ACCEPT ip6tables -A INPUT -i lo -j ACCEPT </source> We then append to chain INPUT on interface ens3 a rule to accept connections with states ESTABLISHED and RELATED:

<source lang="bash">iptables -A INPUT -i ens3 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A INPUT -i ens3 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT </source> We then make sure that incomming TCP connections are SYN packets to prevent SYN flooding:

<source lang="bash">iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP ip6tables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP </source> We also drop packets with incoming fragments. This is only for IPv4:

<source lang="bash">iptables -A INPUT -f -j DROP </source> We also drop bogons:

<source lang="bash">iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP iptables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP ip6tables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP ip6tables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP ip6tables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP </source> We also reject malformed NULL packets:

<source lang="bash">iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP ip6tables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP </source> We can then store the firewall rules with the following commands:

<source lang="bash">iptables-save > /etc/iptables/iptables.rules ip6tables-save > /etc/iptables/ip6tables.rules </source> To make the changes permanent, we can enable and start the Systemd service:

<source lang="bash">systemctl start iptables.service systemctl enable iptables.service systemctl status iptables.service

systemctl start ip6tables.service systemctl enable ip6tables.service systemctl status ip6tables.service </source>

Fail2ban

The service fail2ban is a service for detecting login attempts and blocking it.

We install it with:

<source lang="bash">pacman -S fail2ban </source> Using systemd we can sandbox the fail2ban service with capabilities. To do so, we create a new file /etc/systemd/system/fail2ban.service.d/capabilities.conf with the following contents:

<source lang="bash">[Service] PrivateDevices=yes PrivateTmp=yes ProtectHome=read-only ProtectSystem=strict NoNewPrivileges=yes ReadWritePaths=-/var/run/fail2ban ReadWritePaths=-/var/lib/fail2ban ReadWritePaths=-/var/log/fail2ban ReadWritePaths=-/var/spool/postfix/maildrop ReadWritePaths=-/run/xtables.lock CapabilityBoundingSet=CAP_AUDIT_READ CAP_DAC_READ_SEARCH CAP_NET_ADMIN CAP_NET_RAW </source> Create configuration file /etc/fail2ban/fail2ban.local with the correct logtarget path:

<source lang="bash">[Definition] logtarget = /var/log/fail2ban/fail2ban.log </source> Create the /var/log/fail2ban/ directory as root.

We have to set up paths for Arch Linux in a jail.local file:

<source lang="bash">[INCLUDES] before = paths-arch.conf </source>

Yay

With yay, we can keep also the AUR packages up to date.

<source lang="bash">git clone https://aur.archlinux.org/yay.git tar xvzf yay.tar.gz cd yay makepkg -s pacman -U yay*.pkg.tar.xz </source>

SSH access

Configuration

The first service we would like to set up is SSH. We first configure the SSH daemon itself in file /etc/ssh/sshd_config:

<source lang="bash">PermitRootLogin no TCPKeepAlive no ClientAliveInterval 60 Ciphers aes256-ctr,aes192-ctr,aes128-ctr MACs hmac-sha2-512,hmac-sha2-256 KexAlgorithms diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1 </source> We then restart the daemon:

<source lang="bash">systemctl restart sshd </source>

The firewall

We have to open port 22 for SSH in our firewall:

<source lang="bash">iptables -A INPUT -i ens3 -p tcp --dport 22 -j ACCEPT </source> <source lang="bash">iptables-save > /etc/iptables/iptables.rules ip6tables-save > /etc/iptables/ip6tables.rules </source>

Fail2ban

We add the following jails in /etc/fail2ban/jail.d/:

In sshd.conf:

<source lang="bash">[sshd] enabled = true </source>