FreeBSD user gnugr shows us how to get ownCloud set up in a FreeBSD jail.

Original post: http://gnugr-blog.info/node/17

owncloud-logo-150x74

owncloud | ezjail | jails | freebsd | nginx
Moving to FreeBSD

I’ve had a ownCloud installation running for a good year or so on my unRAID server. As for ownCloud itself, I’ve been very happy with it. Managing non-unRAID things on unRAID though… not so fun. With that said, I’ve decided to move my installation to a FreeBSD 10.1 based system running on a Mac Mini. This box already services some minor things such as Murmur for our World of Warcraft guild The ORLY Factor, Git, etc. but is nearly idle most of the time.

Jail It!

A great feature of FreeBSD is jails. With a jail you can isolate an environment from the rest of the system such that if it comprimised, the rest of the system is not. Installations do not much with each other as well. All great stuff — lets put ownCloud in a jail!

ezjail

For jail management I choose ezjail. This makes working with jails… er, a bit eaezsier.

Install & Prepare ezjail

I did not have ezjail already installed. Below are the steps I took to get ezjail installed and prepped on the system:

Install (alternatively, cd /usr/ports/sysutils/ezjail && make install clean):

sudo pkg install ezjail
Create a base jail & update it:

sudo ezjail-admin install -sp
sudo ezjail-admin update -P
A few entries need added to /etc/rc.conf:

cloned_interfaces=”${cloned_interfaces} lo1″
ifconfig_bge0_alias=”inet 132.0.0.248 netmask 255.255.255.0″
ezjail_enable=”YES”
The ‘cloned_interfaces’ allows loopback isolation in the jail, while the second provides a new IP alias. Lastly, enable ezjail. Note that the interface name will vary depending on hadware. In this case, the NIC is bge0. This can be found by simply inspecting ifconfig.

Create the ownCloud Jail

Now it’s time to create an actual jail for ownCloud:

sudo ezjail-admin create owncloud 132.0.0.248
cp /etc/resolv.conf /usr/jails/owncloud/etc/
service ezjail start
Validate our jail is created & on the right IP:

jls
JID IP Address Hostname Path
1 132.0.0.248 owncloud /usr/jails/owncloud
Setting up the jailed ownCloud

Time to set up ownCloud and it’s dependencies in the ‘owncloud’ jail! First, attach to the jail’s console:

sudo ezjail-admin console owncloud
Next, some software installs & configures. This portion is heavily based on ownCloud 7 on FreeBSD 10.1 though I make various tweaks and have installed ownCloud 8.x.

MySQL Installation

Install and start Percona MySQL. The standard version of MySQL should work fine as well.

pkg install perl5 percona56-server
service mysql-server start
Create a standard install (Most if not all defaults can be accepted here):

mysql_secure_installation
The file /var/db/mysql/my.cnf has all the gory details.

Create a datbase and user for ownCloud:

mysql -p -e “create database owncloud;”
mysql -p -e “grant all on owncloud.* to ‘owncloud’@’localhost’ identified by ‘CHANGE_THIS_PASSWORD’; flush privileges;”
PHP / PHP-FPM

Install required packages

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
Create a PHP-FPM configuration in /usr/local/etc/php-fpm.conf. This file will already exist. Ensure at least the following is completed as per your needs:

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

[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=4
pm.start_servers=1
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.max_requests = 500
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
(Note: Tweak to your needs of course)

In order to avoid weird filename issues, ensure our default charset is UTF-8. Copy over /usr/local/etc/php.ini-production to /usr/local/etc/php.ini and find default_charset. Remove the comment line and make sure the value is “utf-8”. Example:

default_charset = “utf-8”
Start the service

service php-fpm start
Nginx

For a webserver, nginx is great. It’s lightweight and fast.

Install

sudo pkg install nginx
Create a configuration @ /usr/local/etc/nginx/nginx.conf. As an example, here is mine:

user www;
worker_processes 1;

pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

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

sendfile on;
server_tokens off;

#
# Generated with https://mozilla.github.io/server-side-tls/ssl-config-generator/
# 2015-Feb-23
#
ssl_certificate /path/to/my/SSLCert.pem;
ssl_certificate_key /path/to/my/SSLCertPrivateKey.pem;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:50m;

# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /path/to/my/DHParam.pem;

# modern configuration. tweak to your needs.
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers ‘ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK’;
ssl_prefer_server_ciphers on;

# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
# End of Generated

add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-DEMENTiA indeed;
ssl_stapling on;
ssl_stapling_verify on;

gzip off;
# See https://github.com/owncloud/client/issues/1291
#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 nu.l33t.codes;
return 301 https://nu.l33t.codes$request_uri;

add_header X-Frame-Options “SAMEORIGIN”;
}

server {
listen 443 ssl;

server_name nu.l33t.codes;
root /usr/local/www/owncloud;
index index.php;

client_max_body_size 10G;
fastcgi_buffers 64 4K;
add_header X-Frame-Options “SAMEORIGIN”;

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;
}

}
}
Ensure your /usr/local/etc/nginx/fastcgi_params looks correct. Again, here is my configuration:

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_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;

# PHP only, required if PHP was built with –enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
Start nginx

service nginx start
ownCloud

Finally! Time to install ownCloud itself. As of this writing, I am installing version 8.0.

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

I want everything installed to start automatically, so a few entries need added to /etc/rc.conf:

mysql_enable=”YES”
php_fpm_enable=”YES”
nginx_enable=”YES”
Done!

That’s it! ownCloud is up and running! A few changes to the firewall to NAT to the new jailed IP and I’m in business.

Update

Disabled gzip completely for now in nginx configuration. Having gzip enabled was causing some syncs to fail. See No E-Tag received from server, check Proxy/Gateway. I’d like gzip enabled so I’ll mess with this more as I have time.
Additional Resources

FreeBSD jails with ezjail
ownCloud 7 on FreeBSD 10.1
Mozilla SSL Configuration Generator
Everything you need to know about Jails
FreeBSD IP Alias Setup