The Linux nerd inside me was screaming for a new RPi project. What to build? What to do? You can’t read any modern IT literature nowadays without stumbling upon the word “cloud”. Well, cloud it is. Owncloud in my case. I guess almost everyone is familiar with this open source cloud software, but for those of you that aren’t you can find information at:
https://owncloud.org/features/
The idea was to access my trusty old Buffalo NAS remotely, without having the need to map network drives etc. Buffalo is actually offering some sort of cloud solution also, but hey, it’s much more fun configuring your own stuff 🙂 The idea is quite simple – The RPi is a front-end for the NAS. Clients are connecting to the RPi, which in turn mount network storage from the NAS. Here’s the setup:
- Raspberry Pi 2
- Buffalo Terastation III http://www.buffalotech.com/products/network-storage/professional-and-business-class-nas/terastation-iii-1
- OwnCloud 9.0.2
- Nginx instead of Apache
- PHP
- MySQL
- Fail2ban for additional security
Fig 1. RPi + Buffalo NAS
Initial questions and ideas
- Should Raspberry Pi / ownCloud be visible on the Internet? If so, how to secure it properly?
- Port forwarding with restrictions / reverse proxy?
- If not visible on the Internet, how should one connect from the outside world?
- VPN?
I actually decided to go with option 2, not visible on the Internet. My decision is based on the fact that I’m already running a VPN server. It’s one more extra step before getting/synchronizing the files, but I think it’s worth it in the end. Besides, all my other services are behind VPN also.
That said, I STILL configured ownCloud to be “future-proof” even if the server won’t be Internet-facing (with port forwarding etc.) right now. (See the securing ownCloud chapter). Better safe than sorry 🙂
Installation
As with almost every project, I usually follow an existing guide. ownCloud is quite a mainstream product, so there are tons and tons of documentation available. The guide that I used as my baseline this time was: http://www.htpcguides.com/install-owncloud-8-x-raspberry-pi-for-personal-dropbox/ . Thanks to the author 🙂 Steps:
- Followed the guide down to “Now make your ownCloud directory adjust your path as necessary to your mounted hard drive folder..”. As I’ll be using a NAS, it was time for another guide:
- http://sharadchhetri.com/2013/10/23/how-to-mount-nas-storage-in-owncloud-to-keep-all-users-data/
- created a share on the NAS (named owncloud). Gave the share read/write access for a user also named “owncloud”.
- mounted the share on the RPi. The guide uses backslash, but it should be forward slash:
- e.g. mount -t cifs //192.168.10.20/owncloud /mnt -o username=owncloud,password=owncloud
- Did not follow step 3 completely because there was no data-directory created during the installation (yet). The installer GUI will look for a data directory though, so this is the time to create and mount it properly.
- Got the uid of www-data or apache user by using id command:
- root@owncloud:~# id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data),1000(pi) - OK. ID is 33
- root@owncloud:~# id www-data
- Created a local data-directory which will mount the owncloud share (from the NAS).
- mkdir -p /var/www/owncloud/data
- changed ownership and permission on the data directory;
- chmod -R 770 /var/www/owncloud/data ; chown -R www-data:www-data /var/www/owncloud/data
- Added the following line to /etc/fstab (bottom of file) to make the data directory available in owncloud (setup):
- //192.168.10.20/owncloud /var/www/owncloud/data cifs user,uid=33,rw,suid,username=owncloud,password=owncloud,file_mode=0770,dir_mode=0770,noperm 0 0
- changed ownership and permission on the data directory;
- Ran mount –a and checked if the NAS got properly mounted. For me it did. In other words the “local” /var/www/owncloud/data was now actually living on the NAS.
- Finished the configuration via ownClouds own GUI setup. Everything went fine…
- …however, after a reboot the share was NOT auto mounted 😦
- I got an error when trying to access owncloud over the web interface: Please check that the data directory contains a file “.ocdata” in its root
- Scratched my head and wondered what the hell went wrong. I was quite sure it had to do with permissions. Turned out I was right. Short version:
- http://htyp.org/Please_check_that_the_data_directory_contains_a_file_%22.ocdata%22_in_its_root
- created an empty .ocdata –file (after I had manually mounted /var/www/owncloud/data directory from the NAS).
- chmodded that file and the data-directoy with “new rights” ;
- chmod 777 .ocdata ; chmod 777 /var/www/owncloud/data
- success, the NAS now got automounted after a RPi-reboot 🙂
- Everything worked, so moving over to the (optional) security part.
Securing ownCloud
Owncloud’s own Security & setup warnings will warn you about things to fix. Here’s a screenshot with almost no security measurements taken. (Actual screenshot is not mine, it’s “borrowed” from the Internet):
Fig 2. Before fixing Security & Setup warnings. I’ll write about memory cache in the next chapter (Optimizing ownCloud).
… and here’s a screenshot with fixed security (also memcached fixed):
Fig 3. No security & setup warnings 🙂
Basic security
The initial setup guide I followed had already done some basic security measurements (luckily):
- Redirected all unencrypted traffic to HTTPS (in /etc/nginx/sites-available/owncloud):
server { listen 80; server_name htpcguides.crabdance.com 192.168.40.135; return 301 https://$server_name$request_uri; # enforce https }
ssl_certificate /etc/nginx/ssl/owncloud.crt;
ssl_certificate_key /etc/nginx/ssl/owncloud.key;
# Protecting sensitive files from the evil outside world
location ~ ^/owncloud/(data|config|\.ht|db_structure.xml|README) {
deny all;
server {
listen 443 ssl;
add_header Strict-Transport-Security “max-age=15768000; includeSubDomains; preload”;
Source: https://raymii.org/s/tutorials/HTTP_Strict_Transport_Security_for_Apache_NGINX_and_Lighttpd.html
More information about security can be found in ownClouds own Hardening and Security Guidance:
https://doc.owncloud.org/server/8.0/admin_manual/configuration_server/harden_server.html
Advanced security
If you are going to deploy a server that’s facing the Internet you have to think about security. The basic security measurements are a must, but what if you want to secure it even more? You certainly want your site protected against DDOS and brute-force attacks, don’t you? Well, here’s where one of my favorites come into play – fail2ban. If you have no idea what I’m talking about I suggest that you read at least the following:
http://www.fail2ban.org/wiki/index.php/Main_Page
https://www.techandme.se/fail2ban-owncloud/ (<- Specifically THIS link)
https://snippets.aktagon.com/snippets/554-how-to-secure-an-nginx-server-with-fail2ban
https://easyengine.io/tutorials/nginx/fail2ban/
If you’re lazy, just follow the above guides and setup accordingly. However, use common sense and double check that everything seems to be in order before going production. I myself created the following jail-files and configuration files, and restarted fail2ban. Everything was working as expected 🙂 My configuration files:
root@owncloud:/etc/fail2ban/filter.d# ls -la ngin*.*
-rw-r–r– 1 root root 345 May 23 09:28 nginx-auth.conf
-rw-r–r– 1 root root 422 Mar 15 2014 nginx-http-auth.conf
-rw-r–r– 1 root root 280 May 23 09:29 nginx-login.conf
-rw-r–r– 1 root root 300 May 23 09:28 nginx-noscript.conf
-rw-r–r– 1 root root 230 May 23 09:28 nginx-proxy.conf
-rw-r–r– 1 root root 282 May 24 09:53 nginx-req-limit.conf
and
root@owncloud:/etc/fail2ban/filter.d# ls -la own*
-rw-r–r– 1 root root 146 May 23 09:08 owncloud.conf
(Contents of these files can be found in the links above)
…and jail-files:
root@owncloud:/etc/fail2ban# cat jail.local
[owncloud]
enabled = true
filter = owncloud
port = https
bantime = 3000
findtime = 600
maxretry = 3
logpath = /var/www/owncloud/data/owncloud.log
[nginx-auth]
enabled = true
filter = nginx-auth
action = iptables-multiport[name=NoAuthFailures, port=”http,https”]
logpath = /var/log/nginx*/*error*.log
bantime = 600 # 10 minutes
maxretry = 6
[nginx-login]
enabled = true
filter = nginx-login
action = iptables-multiport[name=NoLoginFailures, port=”http,https”]
logpath = /var/log/nginx*/*access*.log
bantime = 600 # 10 minutes
maxretry = 6
[nginx-badbots]
enabled = true
filter = apache-badbots
action = iptables-multiport[name=BadBots, port=”http,https”]
logpath = /var/log/nginx*/*access*.log
bantime = 86400 # 1 day
maxretry = 1
[nginx-noscript]
enabled = false
action = iptables-multiport[name=NoScript, port=”http,https”]
filter = nginx-noscript
logpath = /var/log/nginx*/*access*.log
maxretry = 6
bantime = 86400 # 1 day
[nginx-proxy]
enabled = true
action = iptables-multiport[name=NoProxy, port=”http,https”]
filter = nginx-proxy
logpath = /var/log/nginx*/*access*.log
maxretry = 0
bantime = 86400 # 1 day
[nginx-req-limit]
enabled = true
filter = nginx-req-limit
action = iptables-multiport[name=ReqLimit, port=”http,https”, protocol=tcp]
logpath = /var/log/nginx/*error*.log
findtime = 600
bantime = 7200
maxretry = 10
After you’ve created the jails and the configuration files you should restart the fail2ban service, “sudo service fail2ban restart”. You can then have a look in the log file, /var/log/fail2ban.log to see if everything looks ok. For me it did:
2016-05-24 09:55:53,094 fail2ban.jail [4778]: INFO Jail ‘ssh’ started
2016-05-24 09:55:53,136 fail2ban.jail [4778]: INFO Jail ‘owncloud’ started
2016-05-24 09:55:53,162 fail2ban.jail [4778]: INFO Jail ‘nginx-auth’ started
2016-05-24 09:55:53,190 fail2ban.jail [4778]: INFO Jail ‘nginx-login’ started
2016-05-24 09:55:53,223 fail2ban.jail [4778]: INFO Jail ‘nginx-badbots’ started
2016-05-23 10:28:13,243 fail2ban.jail [1350]: INFO Jail ‘nginx-noscript’ started
2016-05-24 09:55:53,249 fail2ban.jail [4778]: INFO Jail ‘nginx-proxy’ started
2016-05-24 09:55:53,281 fail2ban.jail [4778]: INFO Jail ‘nginx-req-limit’ started
All this configuration is a bit overkill for me as I’m not going to expose the ownCloud server on the Internet. Instead I’m using VPN + ownCloud. This is however a great opportunity to learn about ownCloud and it’s security so it would be a shame NOT to configure it as secure as possible 🙂 (The ssh-jail is a very nice bonus if you’re also forwarding that port towards the Internet).
Optimizing ownCloud
After all the security hardening stuff it was time to look at optimization. The initial guide includes some optimization and it installs all the PHP modules needed for memory caching. I’m quite sure I could optimize ownCloud much more, but there’s no need to overdo it in such a small home environment. In other words, memory caching is enough in my case. More info about memory caching can be found in ownClouds own documentation: https://doc.owncloud.org/server/8.1/admin_manual/configuration_server/caching_configuration.html
Even though this topic is already covered at the bottom in the initial guide (http://www.htpcguides.com/install-owncloud-8-x-raspberry-pi-for-personal-dropbox/), I’ll write a summary here:
- Edit /var/www/owncloud/config/config.php
- At the bottom of the file, add:
'memcache.local' => '\OC\Memcache\Memcached', 'memcache.distributed' => '\OC\Memcache\Memcached', 'memcached_servers' => array ( 0 => array ( 0 => '127.0.0.1', 1 => 11211, ), ),
- Check that memcached is running:
root@owncloud:# netstat -nap | grep memcached
tcp 0 0 127.0.0.1:11211 0.0.0.0:* LISTEN 457/memcached
udp 0 0 127.0.0.1:11211 0.0.0.0:* 457/memcached
unix 3 [ ] STREAM CONNECTED 7961 457/memcached
unix 3 [ ] STREAM CONNECTED 7955 457/memcached
unix 3 [ ] STREAM CONNECTED 7753 457/memcached
unix 3 [ ] STREAM CONNECTED 7967 457/memcached
unix 3 [ ] STREAM CONNECTED 7960 457/memcached
unix 3 [ ] STREAM CONNECTED 7954 457/memcached
unix 3 [ ] STREAM CONNECTED 7966 457/memcached
unix 3 [ ] STREAM CONNECTED 7964 457/memcached
unix 3 [ ] STREAM CONNECTED 7958 457/memcached
unix 3 [ ] STREAM CONNECTED 7963 457/memcached
unix 3 [ ] STREAM CONNECTED 7957 457/memcached - Done. You should now have a pretty safe (and optimized) environment to play with 🙂
ownCloud works pretty much the same way as Dropbox and others. Here’s a screenshot from a Mac client and one test-file synchronized:
Fig 4. ownCloud + Mac.
Useful configuration paths
I’ll finish this blog post with a short summary of useful configuration paths. Here you go:
/var/www/owncloud/config/config.php (https://doc.owncloud.org/server/8.1/admin_manual/configuration_server/config_sample_php_parameters.html)
/var/www/owncloud/data
/var/www/owncloud/data/owncloud.log
/etc/nginx/sites-available/owncloud
/etc/fstab
/etc/fail2ban/jail.local
/etc/fail2ban/filter.d/*.conf
/var/log/fail2ban.log