树莓派配置nextcloud

1.修改软件源

备份并编辑source.list文件

$ cp /etc/apt/sources.list /etc/apt/sources.back.list
$ nano /etc/apt/sources.list

注释所有内容,添加以下内容

deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main non-free contrib
deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main non-free contrib

备份并编辑raspi.list文件

$ cp /etc/apt/sources.list.d/raspi.list /etc/apt/sources.list.d/raspi.back.list
$ nano /etc/apt/sources.list.d/raspi.list

注释所有内容,替换如下内容

deb http://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ buster main
2.刷新软件源并更新操作系统
sudo apt-get update && sudo apt-get upgrade -y
3.安装nginx redis mariadb PHP及模块:
sudo apt-get install -y nginx
sudo apt-get install -y redis
sudo apt-get install -y mariadb-server
sudo apt-get install -y php php-fpm php-curl php-gd php-dom php-iconv php-openssl php-redis php-mysql php-zip php-bz2 php-intl php-imagick php-opcache
4.下载nextcloud软件包并解压
https://nextcloud.com/install/#instructions-server
解压部署程序:
unzip nextcloud-19.0.1.zip

将nextcloud文件移动到网站根目录
sudo mv nextcloud /var/www/html/

  1. 创建数据目录,更改目录权限

    创建数据目录

    mkdir /mnt/data
    mount -o umask=0007,uid=www-data,gid=www-data /dev/sda1 /mnt/data/

配置文件夹权限

cd /var/www/html/
sudo chown -R root:root nextcloud
更改子文件夹权限
cd /var/www/html/nextcloud
sudo chown -R www-data:www-data config apps
6.配置mysql
优化mysqld
sudo vim /etc/mysql/my.cnf

[client-server]
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mariadb.conf.d/

[client]
default-character-set = utf8mb4

[mysqld]
bind-address = [ip path]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
transaction_isolation = READ-COMMITTED
binlog_format = ROW
innodb_large_prefix=on
innodb_file_format=barracuda
innodb_file_per_table=1
skip-name-resolve
innodb_buffer_pool_size = 256M
innodb_buffer_pool_instances = 1
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 32M
innodb_max_dirty_pages_pct = 90
innodb_io_capacity=4000
query_cache_type = 1
query_cache_limit = 2M
query_cache_min_res_unit = 2k
query_cache_size = 64M
tmp_table_size= 64M
max_heap_table_size= 64M
slow-query-log = 1
slow-query-log-file = /var/log/mysql/slow.log
long_query_time = 1

sudo systemctl restart mariadb.service

设置mariadb管理员密码并创建nextlcoud数据库
mysqladmin -uroot password 'P@ssw0rd'
mysql -uroot -pP@ssw0rd -e 'CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;'
mysql -uroot -pP@ssw0rd -e 'GRANT ALL PRIVILEGES on nextcloud.* to "nextcloud"@"localhost" IDENTIFIED BY "nextcloud";'
mysql -uroot -pP@ssw0rd -e 'FLUSH privileges;'
7.配置php
sudo vim /etc/php/7.3/fpm/php.ini
expose_php = off
date.timezone = Asia/Shanghai

启用opcache

opcache.enable=1
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.memory_consumption=128
opcache.save_comments=1
opcache.validate_timestamps=1
opcache.revalidate_freq=30

启用大文件上传,更改文件限制:

upload_max_filesize=1G
post_max_size=1G
max_input_time = 3600
max_execute_time = 3600
memory_limit = 512M
8.配置php-fpm
sudo vim /etc/php/7.3/fpm/pool.d/www.conf
clear_env=no
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

设置动态进程数量:

pm = dynamic
pm.max_children = 50
pm.start_servers = 3
pm.min_spare_servers = 3
pm.max_spare_servers = 10

sudo systemctl restart php7.3-fpm.service
9.配置nginx:
在/etc/nginx/sites-enabled目录下,创建一个nextcloud文件,其内容如下:
生成SSL证书

sudo mkdir /etc/nginx/nextcloud_SSL/
cd /etc/nginx/nextcloud_SSL/
sudo openssl genrsa -out privkey.pem 2048
sudo openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095
sudo vim /etc/nginx/sites-enabled/nginx

nextcloud

upstream php-handler {
server unix:/var/run/php/php7.3-fpm.sock;
}

server {

listen 6080;

listen [::]:6080;

server_name szy.nextcloud.local;

# enforce https

return 301 https://$server_name:6088$request_uri;

}

server {
listen 6088 ssl http2;

listen [::]:6088 ssl http2;

server_name [your domain];

# Use Mozilla's guidelines for SSL/TLS settings
# https://mozilla.github.io/server-side-tls/ssl-config-generator/
# NOTE: some settings below might be redundant
ssl_certificate /etc/nginx/nextcloud_SSL/cacert.pem;
ssl_certificate_key /etc/nginx/nextcloud_SSL/privkey.pem;

# 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;" always;
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;

# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;

# Path to the root of your installation
root /var/www/html/nextcloud;

location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}

# The following 2 rules are only needed for the user_webfinger app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;

# The following rule is only needed for the Social app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/webfinger /public.php?service=webfinger last;

location = /.well-known/carddav {
  return 301 $scheme://$host:$server_port/remote.php/dav;
}
location = /.well-known/caldav {
  return 301 $scheme://$host:$server_port/remote.php/dav;
}

# set max upload size
client_max_body_size 16G;
fastcgi_buffers 64 128K;

# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

# Uncomment if your server is build with the ngx_pagespeed module
# This module is currently not supported.
#pagespeed off;

location / {
    rewrite ^ /index.php;
}

location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
    deny all;
}
location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
    deny all;
}

location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy)\.php(?:$|\/) {
    fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
    set $path_info $fastcgi_path_info;
    try_files $fastcgi_script_name =404;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $path_info;
    fastcgi_param HTTPS on;
    # Avoid sending the security headers twice
    fastcgi_param modHeadersAvailable true;
    # Enable pretty urls
    fastcgi_param front_controller_active true;
    fastcgi_pass php-handler;
    fastcgi_intercept_errors on;
    fastcgi_request_buffering off;
}

location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
    try_files $uri/ =404;
    index index.php;
}

# Adding the cache control header for js, css and map files
# Make sure it is BELOW the PHP block
location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
    try_files $uri /index.php$request_uri;
    add_header Cache-Control "public, max-age=15778463";
    # Add headers to serve security related headers (It is intended to
    # have those duplicated to the ones above)
    # Before enabling Strict-Transport-Security headers please read into
    # this topic first.
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
    #
    # WARNING: Only add the preload option once you read about
    # the consequences in https://hstspreload.org/. This option
    # will add the domain to a hardcoded list that is shipped
    # in all major browsers and getting removed from this list
    # could take several months.
    add_header Referrer-Policy "no-referrer" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Download-Options "noopen" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Permitted-Cross-Domain-Policies "none" always;
    add_header X-Robots-Tag "none" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Optional: Don't log access to assets
    access_log off;
}

location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$ {
    try_files $uri /index.php$request_uri;
    # Optional: Don't log access to other assets
    access_log off;
}

}

另一个版本
upstream php-handler {

server 127.0.0.1:9000;

server unix:/var/run/php/php7.3-fpm.sock;

}

server {
listen 80;
listen [::]:80;
server_name 192.168.2.103;

# Enforce HTTPS
return 301 https://$server_name$request_uri;

}

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name 192.168.2.103;

# Use Mozilla's guidelines for SSL/TLS settings
# https://mozilla.github.io/server-side-tls/ssl-config-generator/
ssl_certificate     /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/cert.key;

# HSTS settings
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains;                                                                                                                                                     preload;" always;

# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;

# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth                                                                                                                                                    ;
gzip_types application/atom+xml application/javascript application/json appl                                                                                                                                                    ication/ld+json application/manifest+json application/rss+xml application/vnd.ge                                                                                                                                                    o+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-ap                                                                                                                                                    p-manifest+json application/xhtml+xml application/xml font/opentype image/bmp im                                                                                                                                                    age/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text                                                                                                                                                    /vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

# Pagespeed is not supported by Nextcloud, so if your server is built
# with the ngx_pagespeed module, uncomment this line to disable it.
#pagespeed off;

# HTTP response headers borrowed from Nextcloud .htaccess
add_header Referrer-Policy                      "no-referrer"   always;
add_header X-Content-Type-Options               "nosniff"       always;
add_header X-Download-Options                   "noopen"        always;
add_header X-Frame-Options                      "SAMEORIGIN"    always;
add_header X-Permitted-Cross-Domain-Policies    "none"          always;
add_header X-Robots-Tag                         "none"          always;
add_header X-XSS-Protection                     "1; mode=block" always;

# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;

# Path to the root of your installation
root /var/www/mycloud;

# Specify how to handle directories -- specifying /index.php$request_uri
# here as the fallback means that Nginx always exhibits the desired behaviou                                                                                                                                                    r
# when a client requests a path that corresponds to a directory that exists
# on the server. In particular, if that directory contains an index.php file                                                                                                                                                    ,
# that file is correctly served; if it doesn't, then the request is passed t                                                                                                                                                    o
# the front-end controller. This consistent behaviour means that we don't ne                                                                                                                                                    ed
# to specify custom rules for certain paths (e.g. images and other assets,
# /updater, /ocm-provider, /ocs-provider), and thus
# try_files $uri $uri/ /index.php$request_uri
# always provides the desired behaviour.
index index.php index.html /index.php$request_uri;

# Default Cache-Control policy
expires 1m;

# Rule borrowed from .htaccess to handle Microsoft DAV clients
location = / {
    if ( $http_user_agent ~ ^DavClnt ) {
        return 302 /remote.php/webdav/$is_args$args;
    }
}

location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}

# Make a regex exception for /.well-known so that clients can still
# access it despite the existence of the regex rule
# location ~ /(\.|autotest|...) which would otherwise handle requests
# for /.well-known.
location ^~ /.well-known {
    # The following 6 rules are borrowed from .htaccess

    rewrite ^/\.well-known/host-meta\.json  /public.php?service=host-meta-js                                                                                                                                                    on  last;
    rewrite ^/\.well-known/host-meta        /public.php?service=host-meta                                                                                                                                                           last;
    rewrite ^/\.well-known/webfinger        /public.php?service=webfinger                                                                                                                                                           last;
    rewrite ^/\.well-known/nodeinfo         /public.php?service=nodeinfo                                                                                                                                                            last;

    location = /.well-known/carddav     { return 301 /remote.php/dav/; }
    location = /.well-known/caldav      { return 301 /remote.php/dav/; }

    try_files $uri $uri/ =404;
}

# Rules borrowed from .htaccess to hide certain paths from clients
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { re                                                                                                                                                    turn 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)              { retu                                                                                                                                                    rn 404; }

# Ensure this block, which passes PHP files to the PHP process, is above the                                                                                                                                                     blocks
# which handle static assets (as seen below). If this block is not declared                                                                                                                                                     first,
# then Nginx will encounter an infinite rewriting loop when it prepends /in                                                                                                                                                    dex.php
# to the URI, resulting in a HTTP 500 error response.
location ~ \.php(?:$|/) {
    fastcgi_split_path_info ^(.+?\.php)(/.*)$;
    set $path_info $fastcgi_path_info;

    try_files $fastcgi_script_name =404;

    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $path_info;
    fastcgi_param HTTPS on;

    fastcgi_param modHeadersAvailable true;         # Avoid sending the secu                                                                                                                                                    rity headers twice
    fastcgi_param front_controller_active true;     # Enable pretty urls
    fastcgi_pass php-handler;

    fastcgi_intercept_errors on;
    fastcgi_request_buffering off;
}

location ~ \.(?:css|js|svg|gif)$ {
    try_files $uri /index.php$request_uri;
    expires 6M;         # Cache-Control policy borrowed from .htaccess
    access_log off;     # Optional: Don't log access to assets
}

location ~ \.woff2?$ {
    try_files $uri /index.php$request_uri;
    expires 7d;         # Cache-Control policy borrowed from .htaccess
    access_log off;     # Optional: Don't log access to assets
}

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

}

sudo systemctl restart nginx php7.3-fpm

10.nextcloud性能优化

1.用cron替代后台ajax刷新执行定时任务。执行命令:
crontab -u www-data -e
/5 php -f /var/www/mycloud/cron.php
crontab -u www-data -l
sudo echo '
/5 www-data php /var/www/mycloud/cron.php' >> /etc/crontab

2.使用缓存。需要安装redis以及编辑nextcloud的配置文件并使用redis锁代替文件锁
sudo apt-get install php-apcu php-redis
sudo vim /etc/redis/redis.conf
daemonize = yes
unixsocket /var/run/redis/redis-server.sock
unixsocketperm 777

授权redis

usermod -g www-data redis
chown -R redis:www-data /var/run/redis
systemctl restart redis-server.service

sudo vim /var/www/html/nextcloud/config/config.php
'memcache.local' => '\OC\Memcache\APCu',
'filelocking.enabled' => true,
'memcache.locking' => '\OC\Memcache\Redis',
'memcache.distributed' => '\OC\Memcache\Redis',
'redis' => [
'host' => '/var/run/redis/redis.sock',
'port' => 0,
'dbindex' => 0,
'password' => 'secret',
'timeout' => 1.5,
],

其他优化:

sudo nano /var/www/html/nextcloud/config/config.php
'check_data_directory_permissions' => false,

接着编辑/etc/nginx/nginx.conf,在http块中修改上传限制:
client_max_body_size 1G;
fastcgi_read_timeout 60S;

This manual describes how to setup a Raspberry Pi 3 with nginx, PHP 7.3, 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
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:

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

install PHP and nginx:

sudo apt-get install nginx openssl ssl-cert php7.3-xml php7.3-dev php7.3-curl php7.3-gd php7.3-fpm php7.3-zip php7.3-intl php7.3-mbstring php7.3-cli php7.3-mysql php7.3-common php7.3-cgi php7.3-apcu php7.3-redis redis-server php-pear curl libapr1 libtool libcurl4-openssl-dev
sudo apt-get install 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 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

Setting up NGINX for Owncloud and HTTPS

  1. Now we need to create an SSL certificate you can do this by running the following command:

sudo openssl req $@ -new -x509 -days 730 -nodes -out /etc/nginx/cert.pem -keyout /etc/nginx/cert.key

Just enter the relevant data for each of the questions it asks you.

  1. In addition to the SSL certificate, we also need to generate a custom dhparam file. This file helps ensure that our SSL connections are kept secure. By default, this would use a default one that isn’t nearly as secure.

To generate a 2048 byte long dhparam file, run the following command on your Raspberry Pi. This process will take quite a long time, up to 2 hours.

Adding the dhparam flag to the command will help speed up the process, but arguably is less secure.

sudo openssl dhparam -out /etc/nginx/dh2048.pem 2048

  1. Now we need to chmod the three cert files we just generated.
    sudo chmod 600 /etc/nginx/cert.pem
    sudo chmod 600 /etc/nginx/cert.key
    sudo chmod 600 /etc/nginx/dh2048.pem
  2. Let’s clear the server config file since we will be copying and pasting our own version in it.

sudo sh -c "echo '' > /etc/nginx/sites-available/default"

  1. Now let’s configure the web server configuration so that it runs Owncloud correctly.

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

  1. Now simply copy and paste the following code into the file.
    
    upstream php-handler {
    server unix:/var/run/php/php7.3-fpm.sock;
    }

server {
listen 80;
servername ;

#Allow letsencrypt through
location /.well-known/acme-challenge/ {
    root /var/www/owncloud;
}

# enforce https
location / {
    #return 301 https://$host$request_uri;
    root /var/www//var/www/mycloud/;
}

}

server {
listen 443 ssl http2;
servername ;

ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/cert.key;

ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:AES256+EDH';
ssl_dhparam /etc/nginx/ssl/dh2048.pem;
ssl_prefer_server_ciphers on;
keepalive_timeout    70;
ssl_stapling on;
ssl_stapling_verify on;

add_header Strict-Transport-Security "max-age=15552000; includeSubDomains; preload" always;
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;

root /var/www//var/www/mycloud/;

location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}

# The following 2 rules are only needed for the user_webfinger app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;

location = /.well-known/carddav {
    return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
    return 301 $scheme://$host/remote.php/dav;
}

# set max upload size
client_max_body_size 512M;
fastcgi_buffers 8 4K;
fastcgi_ignore_headers X-Accel-Buffering;

gzip off;

error_page 403 /core/templates/403.php;
error_page 404 /core/templates/404.php;

location / {
    rewrite ^ /index.php$uri;
}

location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
    return 404;
}

location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
    return 404;
}

location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param SCRIPT_NAME $fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param HTTPS on;
    fastcgi_param modHeadersAvailable true;
    fastcgi_param front_controller_active true;
    fastcgi_read_timeout 180;
    fastcgi_pass php-handler;
    fastcgi_intercept_errors on;
    fastcgi_request_buffering off; #Available since NGINX 1.7.11
}

location ~ ^/(?:updater|ocs-provider)(?:$|/) {
    try_files $uri $uri/ =404;
    index index.php;
}

location ~ \.(?:css|js)$ {
    try_files $uri /index.php$uri$is_args$args;
    add_header Cache-Control "max-age=15778463";
    add_header Strict-Transport-Security "max-age=15552000; includeSubDomains";
    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;
    access_log off;
}

location ~ \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg|map)$ {
    add_header Cache-Control "public, max-age=7200";
    try_files $uri /index.php$uri$is_args$args;
    access_log off;
}

}

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

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 and post_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

 Tweaking PHP for Owncloud
With NGINX now set up, we can now go ahead and prepare PHP to work with our Owncloud installation. As we use php-fpm, there are a few additional things we need to do.

1. Now that is done, there are a few more configurations we will need to update, first open up the PHP config file by entering.

sudo nano /etc/php/7.3/fpm/php.ini
2. In this file, we want to find and update the following lines. (CTRL + W allows you to search)

Find

upload_max_filesize = 2M
Replace With

upload_max_filesize = 2000M
Find

post_max_size = 8M
Replace With

post_max_size = 2000M
3. Once done, save and then exit by pressing CTRL + X, followed by Y, then ENTER.

4. Our next step is to make some changes to the php-fpm pool configuration. The reason for this is that php-fpm can’t access environment variables.

Run the following command to begin modifying the configuration file.

sudo nano /etc/php/7.3/fpm/pool.d/www.conf
5. Within this file, find the following block of code and replace it with what we have below.

You can use CTRL + W to find this block of code faster. Typically its located near the bottom of the file.

Find

;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
Replace With

env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
6. With these changes made, go ahead and save the file by pressing CTRL + X, followed by Y, then ENTER.

 Adding Swap Memory
Our next step is to add some swap memory to our system.

Adding swap memory allows the Raspberry Pi to work further beyond its memory by making use of space on the storage device. While a lot slower then RAM it is better then the program crashing

1. To increase the amount of swap memory, we need to modify a file called dphys-swapfile.

To modify this file, make use of the following command:

sudo nano /etc/dphys-swapfile
2. Within this file, find the following line and change it to what we have below.
Find

CONF_SWAPSIZE=100
Replace With

CONF_SWAPSIZE = 512
3. Once done, save and then quit by pressing CTRL + X, followed by Y, then ENTER.

4. For our changes to take effect, we will need to now restart the Raspberry Pi by running the command below.

sudo reboot
 Setting up a MySQL Database & User for Owncloud
Before beginning this section, you must have already set up a MySQL server on your Raspberry Pi.

1. To be able to create our database, we will need to make use of the MySQL command-line interface.

We can load up the tool by running the following command.

sudo mysql -u root -p
2. Once logged in, you can begin interacting with your MySQL server.

The database we will be creating is called ownclouddb. We can create this database by running the following command.

CREATE DATABASE ownclouddb;
3. With the database created, let’s now create a user that can interact with it.

We can create a user called ownclouduser by running the command below. Make sure that you replace [PASSWORD] with a secure password and make a note of it for later.

CREATE USER 'myclouduser'@'localhost' IDENTIFIED BY '[passwd]';
4. Our next step is to give access permissions to our new user.

We can grant these privileges by running the following command.

GRANT ALL PRIVILEGES ON myownclouddb.* TO 'myclouduser'@'localhost';
5. The final task is to flush the privileges. If we don’t do this, then our changes won’t be utilized by the server.

To flush the privileges, all we need to do is run the following command.

FLUSH PRIVILEGES;
Once the privilege table has been flushed, we can proceed to install and set up the Owncloud software.

About: kiah