Tip
There is a new and up-to-date version of this gist (with focus on the Raspi setup part): https://gist.github.com/ronau/462731589c44f91bb4a3b7d30d277ecf
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.
- Run Pi from flashdrive: https://www.stewright.me/2013/05/install-and-run-raspbian-from-a-usb-flash-drive/
- PHP7: https://getgrav.org/blog/raspberrypi-nginx-php7-dev
- Owncloud:
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/
- run
sudo raspi-config
and do stuff like- set locale
- enable sshd
- set hostname in
/etc/hostname
and/etc/hosts
, then restart or runsudo /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
: changeslaac private
toslaac hwaddr
- 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
- create
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install rpi-update
sudo rpi-update
sudo reboot
- 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
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
- create file
- 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
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
- 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
andlisten [::]: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
tolisten 443
- comment
ssl_certificate
andssl_certificate_key
lines in HTTPS section
- comment
- 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
, thengit 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
andssl_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 ...
- e.g. create new file in
- Create separate Nextcloud next to webroot, e.g.
mkdir /var/www/nextcloud-data
- Create mysql user and database
- Access mysql command line as root:
mysql -u root -p
- Create separate database:
CREATE DATABASE nextcloud;
- Create separate user:
CREATE USER 'new_user'@'localhost' IDENTIFIED BY 'new_password';
- Grant access to database:
GRANT ALL ON nextcloud.* TO 'new_user'@'localhost';
- Reload permissions:
FLUSH PRIVILEGES;
quit
- Access mysql command line as root:
- Download Nextcloud from website, verify checksum with
md5sum downloaded-archive.tar
, extract to webroot dir - Apply strong file/directory permissions: https://docs.nextcloud.com/server/11/admin_manual/installation/installation_wizard.html#strong-perms-label
- Run installation wizard by opening the site in the browser, provide admin user credentials, path to data directory and database credentials and then hit the Finish setup button. For more details, see https://docs.nextcloud.com/server/11/admin_manual/installation/installation_wizard.html
- Optionally: Adapt
upload_max_filesize
andpost_max_size
values by editing.user.ini
file in nextcloud directory - If you get a warning in Nextcloud admin area that some environment variables are not set: Configure environment variables by editing php-fpm config file
www.conf
. For more details, see https://docs.nextcloud.com/server/11/admin_manual/installation/source_installation.html#php-fpm-configuration-notes - If you get a warning about memory caching not being configured, please add to the Nextcloud config file
config/config.php
the following line:'memcache.local' => '\OC\Memcache\APCu',
. For more details, see https://docs.nextcloud.com/server/11/admin_manual/configuration_server/caching_configuration.html