Microordenadores - Desarrollos modernos para sistemas retro

Nextcloud en la Raspberry Pi
8 de Julio de 2017

Nextcloud se define como un reinicio de Owncloud; es un proyecto derivado con características similares. Con este software podrás tener tu propia nube en casa u ofrecer un servicio tipo Dropbox. En este tutorial voy a instalar Nextcloud en una Raspberry Pi 3 en el sistema operativo Raspbian para configurar una nube privada protegida con HTTPS.

Actualización: Ahora es más sencillo que nunca usar Nextcloud en la Raspberry Pi gracias a NextCloudPi, un proyecto bajo el paraguas de Nextcloud. Tienes a tu disposición las imagenes de Nextcloud Pi tanto en formato .img para grabar en una tarjeta MicroSD como en contenedor Docker.

Elección del software

Aunque la instalación típica se hace con Apache, he elegido Nginx fundamentalmente por razones de rendimiento y ahorro de recursos. Además su diseño es más moderno y la configuración más sencilla, por lo que no encuentro razones para usar Apache. Aunque PHP 7 rinde mucho mejor que PHP 5, he optado por la versión 5 para mantenerme fiel a los repositorios oficiales para tener mayor control de lo que se ejecuta y ahorrar problemas con las actualizaciones futuras.

En cuanto a base de datos he elegido MariaDB frente a MySQL por las mismas razones. Si quieres saber más te invito a leer el tutorial para configurar la Raspberry Pi como un servidor de bases de datos SQL

Como instalar Nextcloud

Partiré de una instalación de Raspbian con la configuración de servidor web Nginx + PHP + MariaDB, y la instalación tendrá las siguientes características:

  • https con certificado auto-firmado
  • Instalación en el directorio /nextcloud del servidor
  • Nextcloud será instalado al margen del sistema de paquetes

Lo primero es ir a la página de descarga de Nextcloud para conseguir la url del archivo. Ten en cuenta que seguramente haya una versión nueva de la 11.0.1, que era la que estaba disponible al editar este tutorial. En la línea de comandos de la Raspberry:

$ wget https://download.nextcloud.com/server/releases/nextcloud-11.0.1.zip
$ cd /var/www/html
$ sudo unzip /home/pi/nextcloud-11.0.1.zip

Permisos de escritura

Una vez hecho esto cargo pongo en el navegador http://192.168.2.121/nextcloud, donde 192.168.2.121 es la IP de la raspberry. La primera dificultad que encuentro es la siguiente:

Can't write into config directory!

This can usually be fixed by giving the webserver write access to the config directory.

Esto se debe a que Nginx no tiene acceso de escritura al directorio de configuración. Para arreglar esto cambia el propietario de los archivos de nextcloud al usuario con el que funciona Nginx, que es www-data:

$ sudo chown -R www-data /var/www/html/nextcloud

Como instalar los módulos de PHP necesarios

Una vez hecho esto vuelvo a intentarlo, y obtengo este mensaje:

PHP module cURL not installed.

Please ask your server administrator to install the module.

Esto se debe a que Nextcloud necesita la extensión curl de PHP. Instalarlo es tan simple como ejecutar este comando:

$ sudo apt-get install php5-curl

Como crear un certificado SSL autofirmado para el HTTPS

También necesitarás un certificado SSL para hacer funcionar Nextcloud, aunque no necesitas comprar uno, sino que puedes generarlo tú mismo. En este ejemplo voy a crear un certificado formado por estos dos archivos:

  • cloud.example.com.pem: es el certificado.
  • cloud.example.com.key: la llave del certificado.
$ sudo mkdir /etc/ssl/nginx
$ cd /etc/ssl/nginx
$ sudo openssl req -new -x509 -days 365 -nodes -out cloud.example.com.pem -keyout cloud.example.com.key

Pedirá una serie de datos aunque se puede pulsar simplemente Enter. Lo que hay que tener en cuenta es que, a diferencia de lo que ocurre con los certificados de pago, la primera vez que conectemos nos dirá que el certificado no es seguro. La forma correcta es comprobar el fingerprint y, si es correcto, añadir la excepción. A partir de ahí ya saldrá el candado y la conexión SSL se hará normalmente.

Configuración de Nginx

Consulto la documentación de Nextcloud, concretamente la sección de configuración de Nginx para Nextcloud. Después de desactivar una ocpión que no está disponible para esta versión de Nginx (revisando el archivo error.log después de reiniciar nginx) esta es mi configuración /etc/nginx/sites-available/default:

upstream php-handler {
    #server 127.0.0.1:9000;
    server unix:/var/run/php5-fpm.sock;
}

server {
        listen 80;
        return 301 https://$server_name$request_uri;
}

server {
        listen 443 ssl;

        ssl_certificate /etc/ssl/nginx/cloud.example.com.pem;
        ssl_certificate_key /etc/ssl/nginx/cloud.example.com.key;

        root /var/www/html;
        index index.html index.htm index.nginx-debian.html index.php;

        server_name _;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;

                # With php5-cgi alone:
                #fastcgi_pass 127.0.0.1:9000;
                # With php5-fpm:
                fastcgi_pass unix:/var/run/php5-fpm.sock;
        }
location ^~ /nextcloud {

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

        # Disable gzip to avoid the removal of the ETag header
        gzip off;

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

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

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

        location ~ ^/nextcloud/(?:build|tests|config|lib|3rdparty|templates|data)/ {
            deny all;
        }
        location ~ ^/nextcloud/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
            include fastcgi_params;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param HTTPS on;
            #Avoid sending the security headers twice
            fastcgi_param modHeadersAvailable true;
            fastcgi_param front_controller_active true;
            fastcgi_pass php-handler;
            fastcgi_intercept_errors on;
        }

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

        # Adding the cache control header for js and css files
        # Make sure it is BELOW the PHP block
        location ~* \.(?:css|js)$ {
            try_files $uri /nextcloud/index.php$uri$is_args$args;
            add_header Cache-Control "public, max-age=7200";
            # 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;";
            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;
            # Optional: Don't log access to assets
            access_log off;
        }

        location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
            try_files $uri /nextcloud/index.php$uri$is_args$args;
            # Optional: Don't log access to other assets
            access_log off;
        }
    }

}

Otro cambio que hay que hacer es en el parámetro keepalive_timeout en /etc/nginx/nginx.conf. Lo he cambiado de 65 a 265; esto se debe a que el proceso de instalación dura más de 65 segundos, y de esta forma se evita que la instalación falle.

Para que los cambios tomen efecto se reinicia Nginx:

  • Sin systemd: sudo /etc/init.d/nginx reload
  • Con systemd: sudo systemctl reload nginx.service

Configuración de la base de datos MariaDB

Una vez está instalado MariaDB con apt como se explica en los tutoriales anteriormente enlazados simplemente tienes que crear una base de datos con su usuario y contraseña. En este ejemplo usaré estos datos:

  • Usuario nexcloud
  • Base de datos nextcloud
  • Contraseña Cpn4aB~]ODeW^
$ mysql -u root -p
Enter password: 
MariaDB [(none)]> create database nextcloud;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> create user 'nextcloud'@'localhost' identified by 'Cpn4aB~]ODeW^';
Query OK, 0 rows affected (0.00 sec)

ariaDB [(none)]> grant all privileges on nextcloud.* to 'nextcloud'@'localhost';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> quit
Bye

Configuración de Nextcloud

Con esto ya tienes el sistema listo para instalar nextcloud. Para ello carga en el navegador la dirección https://192.168.2.121, siendo esta la IP de tu raspberry, y sin olvidar usar https ya que así es como funciona Nextcloud.

Como dije antes, al haber usado un certificado autofirmado hay que añadir la excepción en la primera conexión. Si no quieres que esto ocurra puedes conseguir un certificado gratuito Let's Encrypt o uno de pago, siendo el mejor en calidad, precio y sencillez el COMODO PositiveSSL. La ventaja del certificado de pago es que es más compatible y no necesitas tener un proceso en el sistema para manejar el certificado. Puede ser conveniente configurar una IP estática aunque no es necesario.

Aquí simplemente se establece un usuario y contraseña para administrador de Nextcloud y se indica el nombre de la base de datos, su usuario y su contraseña. Una vez hecho esto te mandará a la página de login y ya estará Nextcloud listo para ser usado:

Nextcloud recién instalado

Como acceder a Nextcloud desde el exterior

Para eso tendrás que redirigir el puerto 443 de tu router a la IP de tu raspberry. Aunque esto se puede hacer en cualquier router, una opción mucho más flexible y segura es el EdgeRouter Lite con OpenBSD. Tienes un tutorial para redirigir los puertos en un router LEDE o OpenWrt; el proceso es muy similar en cualquier router.

Si lo que buscas es alojar Nextcloud bajo un dominio propio, echa un ojo al tutorial para configurar un nombre de host para una IP dinámica con ddclient. Aunque se explica para OpenBSD la configuración de ddclient debe ser muy similar (si no la misma) en Raspbian.


Contenido relacionado: