Tinker, Tailor, Soldier, Sponge

View Original

Owncloud on FreeNAS 9.2

In which I set-up a cloud file store on FreeNAS...

So firstly there is an easy way to do this. You can install the owncloud plugin provided through the FreeNAS GUI. There are a few reasons not to do this:

  • It only supports SQLite
  • The plugin, as usual, is not the most up-to-date version of the software*

MySQL/MariaDB should be faster than SQLite and also allows multiple concurrent connections.

*The FreeNAS devs do a good job of keeping up-to-date but if you want to be on the latest software you normally need to update your plugins manually.

Set-Up the Jail

Follow the users guide to set up a new jail. You can either set-up a portjail (which already includes and extracted version of ports) or use a standard jail (since you would likely need to update ports anyway).

The use the GUI to run a shell as the jail before continuing to issue these commands.

Extract ports:

portsnap fetch extract

Update pkg:

pkg update -f

Install Packages

First you're going to need to install all the packages for the webserver (nginx), php and MySQL:

pkg install nginx mariadb55-server php55-extensions php55-curl\
php55-exif php55-fileinfo php55-gd php55-mbstring php55-pdo_mysql\
php55-openssl php55-zip php55-zlib
make install clean -C /usr/ports/devel/pecl-APCu

During the install of pecl-APCu accept all prompts with the standard settings.

Then enable everything in /etc/rc.conf:

nginx_enable="YES" php_fpm_enable="YES" mysql_enable="YES"

Setup Webserver

Go to /usr/local/etc/nginx/nginx.conf and edit it to look like this:

### Change the number of workers to the same number of cores 
### your server has 
worker_processes 4;

events { 
    worker_connections 1024; 
}

http { 
    include mime.types; 
    default_type application/octet-stream;
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
    access_log logs/access.log main; 
    sendfile off; 
    keepalive_timeout 65; 
    gzip off;

    #SSL 
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_ciphers ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM; 
    ssl_prefer_server_ciphers on; 
    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;

    # Redirects HTTP to HTTPS 
    server {
        listen 80; 
        ### Change the following two lines to match your website name
        server_name www.example.com 192.168.; 
        return 301 https://example.com$request_uri;

        # Prevent Clickjacking 
        add_header X-Frame-Options "SAMEORIGIN";
        }
     server { 
         listen 443 ssl;
        ### Change the following line to match your website name
        server_name www.example.com 192.168.0.X; 
        root /usr/local/www;

        # Prevent Clickjacking 
        add_header X-Frame-Options "SAMEORIGIN";
        # SSL Settings 
        ### If you are using different names for your SSL certificate and key, change them below: 
        ssl_certificate /usr/local/etc/nginx/ssl-bundle.crt;
        ssl_certificate_key /usr/local/etc/nginx/server.key; 
        add_header Strict-Transport-Security "max-age=16070400;
        includeSubdomains";
        location = /robots.txt { allow all; access_log off; log_not_found off; }
        location = /favicon.ico { access_log off; log_not_found off; }
        location ^~ /owncloud { 
            index index.php;
            try_files $uri $uri/ /index.php?$args;
            client_max_body_size 5120M; 
            location ~ ^/owncloud/(?:\.|data|config|db_structure\.xml|README) { 
                deny all;
            } 
            location ~ \.php(?:$|/) { 
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php-fpm.sock;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info; 
                include fastcgi_params;
                fastcgi_param MOD_X_ACCEL_REDIRECT_ENABLED on;
            } 
            location ~* \.(?:jpg|gif|ico|png|css|js|svg)$ {
                expires max; add_header Cache-Control public;
            }
            location ^~ /owncloud/data { 
                internal;
                ### Change this to the directory you wish to use for files
                alias /mnt/files;
            }
        }
    }
}
}

If you have an SSL certificate install it. If you want to use a self-signed certificate use these commands and follow the on screen prompts:

cd /usr/local/etc/nginx 
openssl genrsa -des3 -out server.key 2048 
openssl req -new -key server.key -out server.csr 
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out ssl-bundle.crt 
cp server.key server.key.orig 
openssl rsa -in server.key.orig -out server.key

Configure PHP

Copy the default php.ini file:

cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini

Then edit the following lines of the /usr/local/etc/php.ini file:

date.timezone =Europe/London
cgi.fix_pathinfo=0 
upload_max_filesize = 5120M 
post_max_size = 5120M

Make sure to set date.timezone to your own timezone.

Edit the following lines of /usr/local/etc/php-fpm.conf:

listen = /var/run/php-fpm.sock 
listen.owner = www 
listen.group = www 
env[PATH] = /usr/local/bin:/usr/bin:/bin

Setup MySQL

Create the MySQL configuration file at /var/db/mysql/my.cnf:

[server] socket = /tmp/mysql.sock 
skip-networking 
skip-name-resolve 
default-storage-engine = innodb 
innodb_flush_method = O_DIRECT 
skip-innodb_doublewrite 
innodb_flush_log_at_trx_commit = 2 
innodb_file_per_table 
expire_logs_days = 1

Then start the web server and initilaise the MySQL database:

service nginx start
service php-fpm start
service mysql-server
start mysql_secure_installation
mysql -u root -p
CREATE DATABASE owncloud; 
GRANT ALL PRIVILEGES ON owncloud.* TO 'ocuser'@'localhost' IDENTIFIED BY 'ocpass'; 
FLUSH PRIVILEGES; 
quit;

Make sure to change <ocpass> to a password of your choice.

Install OwnCloud

Install the owncloud source files:

fetch "http://download.owncloud.org/community/owncloud-7.0.1.tar.bz2" 
tar jxf owncloud-*.tar.bz2 -C /usr/local/www 
rm owncloud-*.tar.bz2

Make sure to change the source file to the latest file available from http://owncloud.org/install/.

Then ensure the user 'www' can access the mount point for your files and:

chown -R www:www /usr/local/www/owncloud /mnt/files

Setup cron:

crontab -u www -e

Then append† the following:

*/15 * * * * /usr/local/bin/php -f /usr/local/www/owncloud/cron.php

†The vi command is :a. Then use :wq to write and quit.

Setup OwnCloud

Now point your web browser to https://<jail ip>/owncloud and you'll get this setup screen:

And make sure to change the details to match your mount point and MySQL database.‡

Once you've logged in go to the Admin settings on the top-right and make sure to tick 'Enforce HTTPS'. This will force anyone connecting to your server to use a secure connection.

If you already have a lot of data on your server and want to make it available to your OwnCloud then you can make mount points through the FreeNas GUI:

Jail storage in FreeNAS

Currently there is a problem where the FreeNAS GUI can't create a mount point. You'll need to make them using the jail shell. Then the GUI will be able to mount the folder correctly.

‡Set localhost to be localhost:/tmp/mysql.sock

Allow Access Across the Internet

The error message when accessing owncloud from outside your LAN.

If you wish to use a dynamic DNS service to allow access to your storage from anywhere you will need to add one line to config.php. The file in question is /usr/local/www/owncloud/config/config.php:

'trusted_domains' => array('foo.example.com'),

Tom Out!

References

This post is an amalgamation of sources that got me most of the way to a working environment. I have chosen the relevant parts from each reference to make this guide:

[1] [How-To] ownCloud using NGINX, PHP-FPM, and MySQL by Joshua Parker Ruehlig

[2] Pydio: Installing on FreeBSD (nginx and PHP-FPM) by Abstrium SAS

[3] FreeNAS 9.2.1 User's Guide  by iXsystems, Inc

[4] PHP: List of Supported Timezones by The PHP Group

[5] Untrusted Domain by RandolphCarter