Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@ronau
Last active October 16, 2023 19:47
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save ronau/b88fb9608aff7bd43027b265c16d461b to your computer and use it in GitHub Desktop.
Save ronau/b88fb9608aff7bd43027b265c16d461b to your computer and use it in GitHub Desktop.
Nextcloud on Raspberry Pi 3 Setup

Nextcloud on Raspberry Pi 3 Setup

This manual describes how to setup a Raspberry Pi 3 with nginx, PHP 7.0, MariaDB and use it as a Nextcloud server. Strong TLS encryption with Let's Encrypt certificates is also used. Of course, Owncloud can be used instead of Nextcloud. As of February 2017, the installation instructions are basically the same.

Useful links and knowledge sources for this step-by-step manual

Install and run Raspbian from a USB flash drive

Running Raspbian from a USB flash drive instead of from an SD card will boost the overall performance.

Check out this tutorial: https://www.stewright.me/2013/05/install-and-run-raspbian-from-a-usb-flash-drive/

Basic Raspi configuration after first start

  • run sudo raspi-config and do stuff like
    • set locale
    • enable sshd

Network Setup

  • set hostname in /etc/hostname and /etc/hosts, then restart or run sudo /etc/init.d/hostname.sh
  • set static ipv4 address in /etc/dhcpcd.conf:
interface eth0
static ip_address=10.0.0.100/24
static routers=10.0.0.1
static domain_name_servers=10.0.0.1
  • if necessary (e.g. for firewall exceptions) disable IPv6 privacy extensions in /etc/dhcpcd.conf: change slaac private to slaac hwaddr

Users, Passwords and Authentication

  • change password of default pi user: passwd
  • create new user for normal usage: sudo adduser mynewuser
  • check groups of pi user groups pi and add your new user to the same groups, except the pi group: sudo adduser mynewuser [group]
  • switch to new user
  • remove pi user from sudo and adm group: sudo deluser pi sudo, sudo deluser pi adm
  • remove from /etc/sudoers.d/ the file for the pi user or rename and edit it for your new user
  • SSH setup
    • create .ssh dir with 700 permisisons in home folder: install -d -m 700 ~/.ssh
    • copy your public key to the RPi: cat ~/.ssh/id_rsa.pub | ssh <USERNAME>@<IP-ADDRESS> 'cat >> .ssh/authorized_keys'
    • test login via key authentication
    • edit /etc/ssh/sshd_config, make sure the following is set:
    PermitRootLogin no
    PasswordAuthentication no
    

Update system

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install rpi-update
sudo rpi-update
sudo reboot

Ease of Use stuff

  • add alias ll='ls -lA' to .bashrc
  • (optional) choose editor: sudo apt-get install vim
  • curl and git are always useful: sudo apt-get install curl git

nginx, PHP and MariaDB installation

PHP7 and nginx from Raspbian testing branch

As of the writing of this manual (February 2017), PHP 7.0 is not included in the stable Raspbian repositories yet. That's why we take it from the testing branch.

  • edit /etc/apt/sources.list, add after first jessie line:
deb http://mirrordirector.raspbian.org/raspbian/ stretch main contrib non-free rpi
  • adjust priorities so that jessie release is used by default
    • create file /etc/apt/preferences
    • paste in the following:
    Package: *
    Pin: release n=jessie
    Pin-Priority: 600
    
    • save file and update: sudo apt-get update
  • install PHP and nginx:
sudo apt-get install -t stretch php7.0 php7.0-bz2 php7.0-cli php7.0-curl php7.0-fpm php7.0-gd php7.0-intl php7.0-json php7.0-mbstring php7.0-mcrypt php7.0-mysql php7.0-opcache php7.0-sqlite3 php7.0-xml php7.0-zip php-apcu php-pear
sudo apt-get install -t stretch nginx libnginx-mod-http-dav-ext

PHP, nginx and MariaDB from default Raspbian repositories

Warning, needs some more reduction, still too bloated:
sudo apt-get install curl git libapr1 libcurl4-openssl-dev libtool mariadb-client mariadb-server memcached nginx openssl php-apc php-pear php-xml-parser php5 php5-apcu php5-cgi php5-cli php5-common php5-curl php5-dev php5-fpm   php5-gd php5-memcache php5-mysql php5-sqlite sqlite3 ssl-cert varnish

or if PHP7 and nginx are already installed from testing branch, then install just MariaDB:

sudo apt-get install mariadb-client mariadb-server

Of course, you could also use Nextcloud with sqlite3 instead, but MariaDB is actually more recommended.

sudo apt-get install sqlite3

Setup nginx site for Nextcloud

  • Optional: register/configure domain and/or setup port forwarding at DSL router
  • Create root dir in /var/www, e.g. /var/www/nextcloud, and place a test file (e.g. index.html) into the webroot dir
  • Create nginx config file in /var/nginx/sites-available
    • paste example config e.g. from https://docs.nextcloud.com/server/11/admin_manual/installation/nginx_nextcloud_9x.html
    • don't forget to add IPv6 listen line: listen [::]:80 and listen [::]:443 ssl, respectively
    • temporarily disable TLS:
      • comment return 301 https://$server_name$request_uri; in HTTP section
      • add line root /var/www/www-rootdir/; there (adapt for your actual rootdir)
      • change listen 443 ssl to listen 443
      • comment ssl_certificate and ssl_certificate_key lines in HTTPS section
  • Switch to directory /var/nginx/sites-enabled and place softlink to config file there: sudo ln -s /etc/nginx/sites-available/newconfig
  • sudo service nginx restart and test your configuration, e.g. open your dedicated domain in browser
  • LetsEncrypt
    • sudo su, then git clone https://github.com/letsencrypt/letsencrypt /root/letsencrypt
    • cd /root/letsencrypt/ and then run ./certbot-auto certonly --webroot --rsa-key-size 4096 -w /var/www/www-rootdir/ -d my.domain.tld
  • Adapt nginx config file again:
    • revert the changes described befored to restore HTTPS configuration
    • adapt ssl_certificate and ssl_certificate_key lines in HTTPS section
    • download Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits or more (e.g. group16.pem), and place it somewhere, e.g. /etc/letsencrypt/group16.pem
    • complete TSL config to match the following:
    ## Here comes the SSL configuration
    ## Powered by https://bettercrypto.org/static/applied-crypto-hardening.pdf and
    ##            https://mozilla.github.io/server-side-tls/ssl-config-generator/
    
    ssl_certificate /etc/letsencrypt/live/my.domain.tld/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/my.domain.tld/privkey.pem;
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:20m;
    
    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits or more
    ssl_dhparam /etc/letsencrypt/group16.pem;
    
    # Protocols and Ciphers
    ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
    ssl_prefer_server_ciphers on;
    # last two ciphersuites only added because of Android 4.3
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA';
    
    # Add headers to serve security related headers
    # Before enabling Strict-Transport-Security headers please read into this
    # topic first.
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;
    
    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;
    
    ## verify chain of trust of OCSP response using Root CA and Intermediate certs
    ssl_trusted_certificate /etc/letsencrypt/live/my.domain.tld/chain.pem;
    
    # Use Google's DNS servers, if you want
    # resolver 8.8.4.4 8.8.8.8 valid=300s;
    resolver 10.0.0.1 valid=300s;
    resolver_timeout 10s;
    
    ##
    ## End of SSL configuration
    
  • test your SSL config on ssllabs.com
  • test renewal of LetsEncrypt certs by running as root: /root/letsencrypt/certbot-auto renew --force-renewal --pre-hook "service nginx stop" --post-hook "service nginx start"
  • add cert renewal command to crontab to be executed once a month
    • e.g. create new file in /etc/cron.monthly, insert following:
    #!/bin/sh
    
    /root/letsencrypt/certbot-auto renew --force-renewal --pre-hook "service nginx stop" --post-hook "service nginx start"
    
    • make file executable: chmod +x ...

Nextcloud installation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment