ownCloud 7 on FreeBSD 10.1

Introduction

ownCloud[0] is Open-Source software for sharing files and editing documents. This blog post shows one of the many ways to run ownCloud on the current RELEASE branch of FreeBSD[1] . PHP 5.5 with PHP-FPM, MySQL (Percona Server[2]) 5.6 and the current mainline versin of NGINX is used.

Notes

With FreeBSD as Operating system it suggests itself to set up your ownCloud with Jails. Not only the web server but also the database management system (DBMS) can get its own Jail.

If you prefer using the www/owncloud port of the port system you can skip some of the steps below.

Percona Server, an drop-in replacement for the Oracle MySQL server, is used for managing our owncloud database. MySQL and MariaDB are also the recommended DBMS but if you want to you cloud use PostgreSQL or SQLite instead.

The tutorial is based on FreeBSD-10.1-RELEASE ut should mostly work with FreeBSD versions other than that too.

In this tutorial binary versions of the software is installed with pkg, of course you can also compile the ports manually.

MySQL (Percona Server)

Compared with the community editon of MySQL provided by Oracle, Percona Server comes with some improvements that are especially noticeable under higher loads.

Installing Percona server is trivial because it is part of the FreeBSD ports collection:

pkg install perl5 percona56-server

After we add mysql_enable="YES" in /etc/rc.conf and start the mysql server with service mysql sart we execute an interactive script to set up our mysql instance in a secure manner:

mysql_secure_installation

It is save to accept the suggested options.

/var/db/mysql/my.cnf is the default location for adding custom MySQL options. Don't just copy-paste values there, if you don't know what to set, don't create the file, the default settings are reasonable.

Now the database is created:

mysql -p -e "create database owncloud;"

Next we define a user for this database:

mysql -p -e "grant all on owncloud.* to 'owncloud'@'10.0.23.42' identified by 'foobar23'; flush privileges;"

Of course the IP address has to be adjusted according to the specific setup.

PHP and PHP-FPM

PHP versions 5.4 upwards are suggested for running ownCloud 7, in this tutorial version 5.5 is used. Some of the modules mentioned in the next step are providing additional features you may not need, like LDAP support or enabling to mount SFTP shares. Detailed information about the modules needed can be found in the ownCloud documentation for administrators[3].

pkg install php55-extensions php55-mysql php55-pdo_mysql php55-zlib php55-openssl php55-bcmath php55-gmp php55-gd php55-curl php55-ldap php55-exif php55-fileinfo php55-mbstring php55-gmp php55-bz2 php55-zip php55-mcrypt

After PHP-FPM is enabledby adding php_fpm_enable="YES" to /etc/rc.conf an suitable configuration is created in /usr/local/etc/php-fpm.conf:

[global]
pid = run/php-fpm.pid

[owncloud]
listen = /var/run/php-fpm.socket
listen.owner = www
listen.group = www
listen.mode = 0666

listen.backlog = -1
listen.allowed_clients = 127.0.0.1

user = www
group = www

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 5
pm.max_requests = 1000

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

Now PHP-FPM can be starte with service php-fpm start.

NGINX

The current mainline version of NGINX is uses as web server[4].

pkg install nginx-devel

The following steps can be used with the stable version of NGINX (FreeBSD port nginx without -devel) too, no modifications necessary.

Once again an entry in /etc/rc.conf is necessary to enable the automatic startup of our web server: nginx_enable="YES".

The configuration used for NGINX in /usr/local/etc/nginx/nginx.conf.

user  www;
worker_processes  16;

pid        /var/run/nginx.pid;

events {
        worker_connections  2048;
}

http {
        include       mime.types;
        default_type  application/octet-stream;

        sendfile                on;
        server_tokens           off;

        ssl_ciphers "AES256+EECDH:AES256+EDH";
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;
        ssl_stapling on;
        ssl_stapling_verify on;

        gzip              on;
        gzip_types        text/css text/javascript text/mathml text/plain text/xml application/x-javascript application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml;

    upstream php-handler {
            server unix:/var/run/php-fpm.socket;
    }

        server {
                listen 80;
                server_name owncloud.example.com;
                return 301 https://owncloud.example.com$request_uri;

                add_header X-Frame-Options "SAMEORIGIN";
        }

        server {
                listen 443 ssl;

                server_name owncloud.example.com;
                root /usr/local/www/owncloud;
                index index.php;

                client_max_body_size 10G;
                fastcgi_buffers 64 4K;

                add_header X-Frame-Options "SAMEORIGIN";

                ssl_certificate /usr/local/etc/nginx/ssl/example.com.crt;
                ssl_certificate_key /usr/local/etc/nginx/ssl/example.com.key;
                add_header Strict-Transport-Security "max-age=16070400; includeSubdomains";

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

                error_log /var/log/nginx-owncloud.error.log;

        location ~ ^/(?:\.htaccess|data|config|db_structure\.xml|README){
            deny all;
        }

                location ~* ^/(favicon.ico|robots.txt) {
            allow all;
            log_not_found off;
            access_log off;
                }

            rewrite ^/caldav(.*)$ /remote.php/caldav$1 redirect;
            rewrite ^/carddav(.*)$ /remote.php/carddav$1 redirect;
            rewrite ^/webdav(.*)$ /remote.php/webdav$1 redirect;
                location /shares {
                        if (!-f $request_filename) {
                                rewrite ^/shares /dav.php last;
                                break;
                        }

                        if (!-d $request_filename) {
                                rewrite ^/shares /dav.php last;
                                break;
                        }
                }

            location ~ ^(.+?\.php)(/.*)?$ {
                    try_files $1 =404;
                    include fastcgi_params;
                    fastcgi_param SCRIPT_FILENAME $document_root$1;
                    fastcgi_param PATH_INFO $2;
                    fastcgi_param HTTPS on;
                    fastcgi_param MOD_X_ACCEL_REDIRECT_ENABLED on;
                    fastcgi_pass php-handler;
            }

        }
}

This configuration is based on the example in the the ownCloud administration documentation[3].

The following Fast-CGI parameters were used in /usr/local/etc/nginx/fastcgi_params:

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

fastcgi_param  REDIRECT_STATUS    200;

Now it's time to fetch the latest version of owncloud and set the permissions:

cd /usr/local/www/
fetch https://download.owncloud.org/community/owncloud-7.0.3.tar.bz2
tar xf owncloud-7.0.3.tar.bz2
chown -R www:www owncloud
find owncloud -type d -exec chmod 751 {} \;
find owncloud -type f -exec chmod 444 {} \;

After that NGINX can be started with service nginx start.

Configuring ownCloud

The final steps of the setup as well as well as further customizations can be done via the web browser.

Once the admin account is set up and the connection to the database is established the ownCloud instance is ready for use.

Editing Office Documents

With ownCloud it is possible to edit office documents directly in the browser. To do so, OpenOffice or LibreOffice has to be installed. On an FreeBSD server without X-Window components this means that additional 800 MB of software have to be installed:

pkg install libreoffice

For the ones preferring to compile /editors/libreoffice manually, this probably is the right time for an extended coffee break.

Basic Web Server Security

Introduction

Linux and *BSD web server security does not have to be hard. In fact, some basic technical understand combined with common sense will get you quite far.

Keeping Things Up-To-Date

Thousands of developers are constantly improving open-source software for you by fixing bugs and security issues. Please don't ignore their effort by not applying the patches they provide. Software maintainer provide you with security advisories, please check them on a daily basis. If you haven't updated software on your server between Heartbleed and Shellshock you know you have to improve your patch management. Waiting longer between updates will also increase the chances of things going wrong. If multiple parties work on the server don't forget to define who is responsible for keeping the system up to date.

Uptime

Huge uptimes are nothing to be proud of. There are multiple projects working on replacing the kernel on a running system but most systems today have to reboot to apply kernel updates. Not having a box rebooted for three years also means you have ignored every kernel security improvement your operating system was offering you in the meantime.

SSH

SSH is the most important tool for accessing servers. It's great for so many things it really pays of to learn about every single option it's predominant implementation OpenSSH is offering. Here we will just focus on the most impoortant option as far as security is concerned: Disabling password authentication and forcing the usage of puiblic key authentication instead.

If you are not familiar with the OpenSSH public key infrastructure search for a tutorial online. After placing your public key on the server make sure the following options are set in your sshd config, usually /etc/ssh/sshd_config:

ChallengeResponseAuthentication no
PasswordAuthentication no
PubkeyAuthentication yes

Restarting the SSH daemon activates the changes.

Don't Trust Your LAN

Just because a service is not directly accessible from the Internet does not justify weak authentication mechanismns. Terms written in leetspeak that can be guessed with ease are a bad idea in private networks too.

Virtualization can Help

Security researchers often point out that virtualization is not an security feature at all. That might be right but in practice it can help to protect your server. Even if one of your services got infected by malware techniques like the FreeBSD Jails can help you to contain the problem and limit the consequences.

Keep it Simple

Complexity is your enemy: The lower the complexity of the system and its components is, the easier it is to keep things secure. Additionally we know that some services are just not as reliable as others (e.g. always favour SFTP over FTP). Install a minimal version of your operating system and start only the services you need to get your job done. Aavoid installing software like FTP daemons, a web interface for server or database administration or an X-window system.

If you are using Apache httpd disallow the usage of .htaccess files by setting AllowOverride None. Altering the Apache server config via .htaccess is a constant source for confusion.

Don't forget to avoid complexity with the software you are running on your web server too. Most software is extendable with plugins these days. While the base software gets fixed quickly in case of security bugs, many third party plugins are maintained poorly.

Reduce Verbosity

Many services are quite verbose by default, try not to give away too much information for free. Set ServerSignature Off and ServerTokens Prod in Apache httpd or use the equivalent options for your web daemon. If you are using PHP turn off expose_php. On a production system turn off every unnecessary logging.

Controversial Tools

Altough they could make sense in some rare cases in general it's better to avoid the following methods and tools:

  • disabling ICMP responses (ping)
  • using non-standard ports
  • Fail2ban and similar tools
  • port knocking
  • web application firewalls
  • virus scanners

It's much more useful to think about how to reduce the existing attack surface without the introduction of new tools.