Though you should be able to follow instructions given on the Odroid Wiki about Ubuntu NAS, I am adding the commands I used to create the NAS server which is accessible anywhere on the internet using an ODroid HC1, 5V/4A Power Supply, with Ubuntu Mate 16.04.3-4.9

First thing first. Login into the HC1 via SSH using the IP that its connected on. The username and password for login are “odroid”. Once you have logged in, run these commands one by one:

sudo apt update
sudo reboot now
sudo apt full-upgrade

When prompted, click on OK

sudo apt install linux-image-xu3

When prompted, select NO

sudo reboot now
sudo dpkg-reconfigure tzdata

When prompted, select your correct timezone.
Now let’s mount the hard drive.

sudo apt install autofs
sudo mkdir -p /media/nas
sudo nano /etc/auto.master

Copy below line and paste it under the “#/misc /etc/auto.misc” line:

/media/nas /etc/auto.ext --timeout 20

Now find your disk’s UUID

ls -al /dev/disk/by-uuid

The output of this should be something similar to:
lrwxrwxrwx 1 root root 10 Oct 10 17:05 fb028ad6-097a-494d-9d87-d055b8f8c359 -> ../../sda1

The highlighted portion is the UUID you need to copy and then run:

sudo nano /etc/auto.ext

Copy paste this line in the file:

hdd1 -fstype=ext4,rw,noatime,data=journal,commit=1 :/dev/disk/by-uuid/ 
fb028ad6-097a-494d-9d87-d055b8f8c359

The UUID “fb02…” will be replaced by the UUID of your disk. Exit nano and type these commands:

sudo service autofs restart
ls -al /media/nas/
ls -al /media/nas/hdd1
ls -al /media/nas/
df -Th
sudo chown -R odroid:odroid /media/nas

Now let’s configure NextCloud. This is where things get tricky, so pay extra attention from this point on.

sudo apt update
systemctl start mysql.service

If the last command returns any error because mysql is not installed, then do this:

sudo apt-get install mysql-server
sudo mysql -u root -p

When prompted by >, add the following lines one by one. password-here is any password that you want to set for the database.

> CREATE DATABASE `nextcloud-db`;
> CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'password-here';
> GRANT ALL PRIVILEGES ON `nextcloud-db`.* TO 'nextcloud'@'localhost' IDENTIFIED BY 'password-here';
> FLUSH PRIVILEGES;
> EXIT;

Check which groups you belong to and make the following edits according to the groupname in the result.

groups
sudo usermod -a -G groupname www-data
sudo mkdir /media/nas/hdd1/nextcloud-data
sudo chown -R www-data:groupname /media/nas/hdd1/nextcloud-data

If php is not installed on your machine the command sudo apt install php7.1-gd might fail. You can check which version is installed in /etc/php/ directory. If its 7.3 or up, you should be ok. Make sure only one folder of 7.x exists in /etc/php. If there is more than one 7.x folder, run sudo rm -r /etc/php/7.x command to delete the folder. If 7.3 does not exist, you will install php from scratch using the following instructions:

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt update
sudo apt upgrade

This has not installed php yet, just updated the apt so it knows where to find it. Open up your browser and check the highest release of NextCloud from https://download.nextcloud.com/server/releases/
At the time of this, the highest (latest) version available was 16.0.1 which is compatible with php7.3
Download NextCloud and install php.

wget https://download.nextcloud.com/server/releases/nextcloud-16.0.1.tar.bz2
tar xvf nextcloud-16.0.1.tar.bz2
sudo cp -r nextcloud /var/www/
sudo chown -R www-data:www-data /var/www/nextcloud

sudo apt-get install apache2 php7.3 bzip2
sudo apt-get install libapache2-mod-php7.3 php7.3-cli php7.3-mysql php7.3-gd php7.3-imagick php7.3-recode php7.3-tidy php7.3-xmlrpc
sudo apt install php7.3-json php7.3-curl php7.3-mbstring php7.3-intl php7.3-xml php7.3-zip php7.3-apcu
sudo apt-get install php-fpm

cd /var/www/nextcloud

If you remove the 7.3 next to each php in the above statements it should install the latest version which is fine as your NextCloud is set to the latest version as well. Now initialize NextCloud. The
password-here is the password you set earlier at the time of the database initialization. while the admin-user-name and admin-password are the ones you will use to login to NextCloud on your browser.

sudo -u www-data php occ maintenance:install --database "mysql" --database-name "nextcloud-db" --database-user "nextcloud" --database-pass "password-here" --admin-user "admin-user-name" --admin-pass "admin-password" --data-dir "/media/nas/hdd1/nextcloud-data"

The above command should display Nextcloud was successfully installed once its done. Now open up the config file and add the ip of the odroid (odroid-ip) you used to login through the ssh. and add that memcache.local line.

sudo nano /var/www/nextcloud/config/config.php

<?php
$CONFIG = array (

‘trusted_domains’ => array (
0 => ‘localhost’,
1 => ‘odroid-ip:8002’,
),

‘memcache.local’ => ‘\OC\Memcache\APCu’,
);

Save and exit nano.

sudo printenv PATH

The above command will give you an output like this:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin

There should be a folder fpm in the /etc/php/7.3/

Run this command if it does:

sudo nano /etc/php/7.3/fpm/pool.d/www.conf

Make changes to the env[PATH] line in the file. Remove the ; in front of the the lines mentioned below.

...
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
...

Save and close nano

sudo nano /etc/php/7.3/fpm/php.ini

Find each of these opcache lines below and make changes accordingly.

opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=1
opcache.save_comments=1

Save and close nano

sudo service php7.3-fpm restart

Before you can run nginx, you have to check whether it exists or not by using the command systemctl -l status nginx
If it does not exist, run the following commands:

sudo service apache2 stop
sudo apt-get install nginx
sudo nano /etc/nginx/sites-available/nextcloud

Add the following to the file as it is. Make sure that the line on top with server unix:/var/run/php/php7.3-fpm.sock; is the version you have installed, if not, change it to the 7.x version of php you have.

# Reference: https://docs.nextcloud.com/server/12/admin_manual/installation/nginx.html
upstream php-handler {
    server unix:/var/run/php/php7.3-fpm.sock;
}
 
server {
    listen 8002;
    listen [::]:8002;
 
    root /var/www/nextcloud;
 
    server_name _;
 
    # Add headers to serve security related headers
    # Before enabling Strict-Transport-Security headers please read into this
    # topic first.
    # add_header Strict-Transport-Security "max-age=15768000;
    # includeSubDomains; preload;";
    #
    # WARNING: Only add the preload option once you read about
    # the consequences in https://hstspreload.org/. This option
    # will add the domain to a hardcoded list that is shipped
    # in all major browsers and getting removed from this list
    # could take several months.
    add_header X-Content-Type-Options nosniff;
    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; 
 
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
 
    # The following 2 rules are only needed for the user_webfinger app.
    # Uncomment it if you're planning to use this app.
    #rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
    #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json
    # last;
 
    location = /.well-known/carddav {
      return 301 $scheme://$host/remote.php/dav;
    }
    location = /.well-known/caldav {
      return 301 $scheme://$host/remote.php/dav;
    }
 
    # set max upload size
    client_max_body_size 512M;
    fastcgi_buffers 64 4K;
 
    # Enable gzip but do not remove ETag headers
    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
 
    # Uncomment if your server is build with the ngx_pagespeed module
    # This module is currently not supported.
    #pagespeed off;
 
    location / {
        rewrite ^ /index.php$uri;
    }
 
    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
        deny all;
    }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
        deny all;
    }
 
    location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\.php(?:$|/) {
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        #Avoid sending the security headers twice
        fastcgi_param modHeadersAvailable true;
        fastcgi_param front_controller_active true;
        fastcgi_pass php-handler;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
	fastcgi_read_timeout 300;
 
    }
 
    location ~ ^/(?: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|woff|svg|gif)$ {
        try_files $uri /index.php$uri$is_args$args;
        add_header Cache-Control "public, max-age=15778463";
        # 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;";
        #
        # WARNING: Only add the preload option once you read about
        # the consequences in https://hstspreload.org/. This option
        # will add the domain to a hardcoded list that is shipped
        # in all major browsers and getting removed from this list
        # could take several months.
        add_header X-Content-Type-Options nosniff;
        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 ~ \.(?:png|html|ttf|ico|jpg|jpeg)$ {
        try_files $uri /index.php$uri$is_args$args;
        # Optional: Don't log access to other assets
        access_log off;
    }
 
}

Save and close nano

sudo ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/nextcloud
sudo service nginx reload

You should now be able to enter your odroid’s ip on the browser with :8002 at the end and do an admin login into NextCloud. For example: 192.168.1.10:8002

I could not successfully run the following as my ISP blocks almost every port. But these instructions should work for anyone who does not have that problem. Currently looking to find a solution to this issue.
The following uses DuckDNS.org, but I have tried with NoIP.com as well and have not successed using that either. For ddns instructions of noip, visit this link.

Go to DuckDns.org and create an account. In the domain choose the domain of your liking which will be followed by .duckdns.org automatically. Once that is done, go to https://www.duckdns.org/install.jsp and choose linux cron as your operating system and select your domain name. follow the instructions on the page from here on out.

sudo ps -ef | grep cr[o]n
sudo mkdir duckdns
cd duckdns
sudo nano duck.sh

Add the line from DuckDns. It should look something like this:

echo url="https://www.duckdns.org/update?domains=domainname&token=x00x00x0-0x00-0x00-0000-xxx000x0xxx0&ip=" | curl -k -o ~/duckdns/duck.log -K -

Save and close nano

sudo chmod 700 duck.sh
sudo crontab -e
*/5 * * * * ~/duckdns/duck.sh >/dev/null 2>&1
sudo apt install curl
sudo ./duck.sh
cat duck.log

Now edit the nginx config

sudo nano /etc/nginx/nginx.conf
...
http {
    ...
    # Uncomment this line below.
    server_names_hash_bucket_size 64;
    ...
}
...
sudo service nginx reload
sudo nano /etc/nginx/sites-available/nextcloud
upstream php-handler {
    server unix:/var/run/php/php7.3-fpm.sock;
}
 
server {
    # Delete below.
    #listen 80;
    #listen [::]:80;
    #server_name _;
 
    listen 80;
    listen [::]:80;
    server_name domainname.duckdns.org;
    ...
}
sudo service nginx reload
sudo nano /var/www/nextcloud/config/config.php
$CONFIG = array (
  ...
  array (
    0 => 'localhost',
    #1 => 'your-odroid-ip:8002', 
    1 => 'domainname.duckdns.org',
  ),
  ...
)
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
sudo nano /etc/nginx/snippets/ssl-params.conf
# https://cipherli.st/
 
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on; 
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA;
ssl_ecdh_curve secp384r1;
ssl_session_timeout  10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s; 
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none; 
sudo nano /etc/nginx/sites-available/nextcloud

When you’re using it for NextCloud, the following block must be located before “location / { rewrite ^ /index.php$uri; }” block.

location ~ /.well-known {
        # If you attempt to apply a SSL certificate to the service that
        # hasn't website source file at the webroot(/var/www in general) path
        # like Transmission or Seafile
        # uncomment following code to specify a webroot path temporally
        # with referring to the example.
        #
        # Make sure that you've created a directory that is named same as the domain.
        # example) 
        # $ sudo mkdir -p /var/www/letsencrypt_temp/my-transmission.duckdns.org
        # root /var/www/letsencrpyt_temp/my-transmission.duckdns.org;
 
        #root /var/www/letsencrypt_temp/domain-name;
        allow all;
        default_type "text/plain";
    }
sudo service nginx reload


sudo certbot certonly --webroot -w /var/www/nextcloud/ -d domainname.duckdns.org


sudo crontab -e

Add the following line at the end

0 4 1 * * /bin/bash -l -c certbot renew --no-self-upgrade
sudo nano /etc/nginx/snippets/ssl-domainname.duckdns.org.conf
ssl_certificate /etc/letsencrypt/live/domainname.duckdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domainname.duckdns.org/privkey.pem;
sudo nano /etc/nginx/sites-available/nextcloud
# Reference:
# https://docs.nextcloud.com/server/12/admin_manual/installation/nginx.html
# https://cipherli.st/
upstream php-handler {
    server unix:/var/run/php/php7.3-fpm.sock;
}
 
server {
    listen 80;
    listen [::]:80;
    server_name my-nextcloud.duckdns.org;
    # enforce https
    return 301 https://$server_name$request_uri;
}
 
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    include snippets/ssl-my-nextcloud.duckdns.org.conf;
    server_name my-nextcloud.duckdns.org;   
 
    ssl_protocols TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA;
    ssl_ecdh_curve secp384r1;
    ssl_session_timeout  10m;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
 
    # Add headers to serve security related headers
    # Before enabling Strict-Transport-Security headers please read into this
    # topic first.
    # add_header Strict-Transport-Security "max-age=15768000;
    # includeSubDomains; preload;";
    #
    # WARNING: Only add the preload option once you read about
    # the consequences in https://hstspreload.org/. This option
    # will add the domain to a hardcoded list that is shipped
    # in all major browsers and getting removed from this list
    # could take several months.
    add_header X-Content-Type-Options nosniff;
    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;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
 
    # Path to the root of your installation
    root /var/www/nextcloud/;
 
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
 
    # The following 2 rules are only needed for the user_webfinger app.
    # Uncomment it if you're planning to use this app.
    #rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
    #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json
    # last;
 
    location = /.well-known/carddav {
      return 301 $scheme://$host/remote.php/dav;
    }
    location = /.well-known/caldav {
      return 301 $scheme://$host/remote.php/dav;
    }
 
    location ~ /.well-known {
        # If you attempt to apply a SSL certificate to the service that
        # hasn't website source file at the webroot(/var/www in general) path
        # like Transmission or Seafile
        # uncomment following code to specify a webroot path temporally
        # with referring to the example.
        #
        # Make sure that you've created a directory that is named same as the domain.
        # example) 
        # $ sudo mkdir -p /var/www/letsencrypt_temp/my-transmission.duckdns.org
        # root /var/www/letsencrpyt_temp/my-transmission.duckdns.org;
 
        #root /var/www/letsencrypt_temp/domain-name;
        allow all;
        default_type "text/plain";
    }
 
    # set max upload size
    client_max_body_size 512M;
    fastcgi_buffers 64 4K;
 
    # Enable gzip but do not remove ETag headers
    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
 
    # Uncomment if your server is build with the ngx_pagespeed module
    # This module is currently not supported.
    #pagespeed off;
 
    location / {
        rewrite ^ /index.php$uri;
    }
 
    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
        deny all;
    }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
        deny all;
    }
 
    location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\.php(?:$|/) {
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        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;
        fastcgi_request_buffering off;
    }
 
    location ~ ^/(?: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|woff|svg|gif)$ {
        try_files $uri /index.php$uri$is_args$args;
        add_header Cache-Control "public, max-age=15778463";
        # 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;";
        #
        # WARNING: Only add the preload option once you read about
        # the consequences in https://hstspreload.org/. This option
        # will add the domain to a hardcoded list that is shipped
        # in all major browsers and getting removed from this list
        # could take several months.
        add_header X-Content-Type-Options nosniff;
        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;
        add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
 
        # Optional: Don't log access to assets
        access_log off;
    }
 
    location ~ \.(?:png|html|ttf|ico|jpg|jpeg)$ {
        try_files $uri /index.php$uri$is_args$args;
        # Optional: Don't log access to other assets
        access_log off;
    }
}
sudo service nginx reload
Categories: Projects

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *