How to install NextCloud 14/15 on FreeNAS 11.2 in an iocage jail with hardened security

UPDATED FOR NEXTCLOUD 15

I’ve recently been through the process of standing up my own personal cloud server, and found that there were a few points of difficulty not directly covered in existing guides on the topic (such as improving security/hardening the server), and a number of the guides on the topic suggested implementing bad practices, such as the use of mod_php (I’ll be using php-fpm!). My aim here is to be as explicit as possible about the process I followed so that even a relatively new beginner is able to follow them. A lot of this is adapted from dureal99d’s post on the same topic, who did a great job at explaining the process, however it discussed the installation of Nextcloud 13, and the certificate installation process was unsuccessful for me so my thought is to share my learnings to save the next person the trouble. The target audience for this guide is the person with very little exposure to the command line in either Linux or FreeBSD. With this in mind, my aim is to be complete as possible with the information I provide, and also to provide some context about why certain tasks are being undertaken rather than just direction on which commands to run. A disclaimer to this is that I am by no means an expert, and am still learning, so if you spot any errors or have any suggestions please leave a comment below!

One thing I’ve noticed a lot of people get hung up on is dataset structure, so to be explicit, I’ll describe my configuration. I have two data pools (Storage > Pools). One, titled “vault”, is my primary storage pool, comprised of 6x4TB WD Red drives. The second, “jailhouse”, is a 500GB Samsung SSD, and is the pool I store all of my jails on so that they benefit from the faster IO operations an SSD affords. The final dataset structure I have is as follows:

├── vault
│   └── cloud
└── jailhouse
    ├── apps
    │   ├── nextcloud
    │   │   ├── config
    │   │   ├── themes
    │   │   ├── db
    └── iocage
        ├── ...
        ├── jails
        │   └── nextcloud
        └── ...

According to the Nextcloud 14 Manual, there are four things required to restore a Nextcloud installation:
1. The configuration directory
2. The data directory
3. The database
4. The theme directory

Therefore, it makes sense to make this data independent of the jail (more on this later). This means that if for whatever reason your Nextcloud jail has been broken or deleted, you should be able to restore back to your previous configuration with minimal hassle. In the above structure, the ‘cloud’ directory represents the data directory; this is where all of your files will be stored. It’s important that this is on your primary storage pool so that it can grow in size as required. I’ve stored the remaining data in their own datasets on my jailhouse pool. To organise this, I’ve created an ‘app’ dataset which holds a dataset for each jail I create. As can be seen, there is a dataset named ‘nextcloud’, which then contains ‘config’, ‘themes’ and ‘db’ datasets for the required information.

The remaining dataset is the ‘iocage’ dataset. This is created automatically when you create a jail, so you don’t need to worry about doing anything here, however it is important to note that this is where the local storage for your iocage jails is held. Specifically, in jails > jailname, or in this case jails > nextcloud. A number of other datasets are created within the iocage dataset, however these aren’t particularly relevant to this guide, so if you see them and wonder if they’re supposed to be there; don’t stress, they are.

I’m sure many of you will have organised your datasets differently – that’s fine; this has worked well for me, feel free to adopt it, or don’t; it will be the context in which I explain this guide though. For those of you who do want to adopt it, and are confused about how to go about it, I’ll explain it below. At the time of writing, the current version of FreeNAS is 11.2-RC2. This is an awkward time, as both the new and old user interfaces are present. For longevity, this explanation will be given in terms of the new interface, as this is most likely to be more relevant to new users. If you’re using the legacy UI, the steps will be the same, however the buttons will be in different spots.

Create Your Datasets

Storage Dataset

On the left navigation bar, select Storage > Pools

Expand your primary storage pool. In the right most column of the resulting table, locate the three dots on the row of your primary storage dataset (vault in my case):

Select “Add Dataset”.
Populate the form with the following:

Name: cloud
Compression level: lz4
Enable atime: Off 

i.e:

Note that the atime value is set to off, which is different from the default. From the FreeNAS User Guide, disabling atime prevents the production of log traffic while files are being read, and results in significant performance gains, which is desirable for our data folder.

Leave the rest of the values as default and press “Save”. This creates the dataset /vault/cloud

Application Dataset

If you don’t already have a folder for your application data, go ahead and create that now. If you don’t have a dedicated pool for your jails or an SSD, it’s not crucial, so just put this on whatever pool is most appropriate for you. My recommendation would be to maintain the data structure listed earlier however, so have an entirely separate dataset earmarked for this purpose.

Select “Add Dataset”.
Populate the form with the following:

Name: apps
Compression level: lz4
Enable atime: On 

Note that here, atime is set to the default value of ‘on’. It is enabled here because application data is considered less critical as lower performance here won’t impact the usability experience materially.

Leave the rest of the values as default and press “Save”. In my case, I’ve placed this on the jailhouse pool and this creates the dataset /jailhouse/apps

Nextcloud Application Data Dataset

As described previously, select the “apps” dataset and select “Add Dataset”

Populate the form with the following:

Name: nextcloud
Compression Level: lz4
Enable atime: On

Leave the rest of the values as default and press “Save”. This creates the dataset /jailhouse/apps/nextcloud

Nextcloud Database Dataset

Select the “apps/nextcloud” dataset and select “Add Dataset”

Populate the form with the following:

Name: db
Compression Level: lz4
Enable atime: Off

Again, note that in this case atime is off. Leave the rest of the values as default and press “Save”. The database will see steady read and write operations, so performance is a factor here. This creates the dataset /jailhouse/apps/nextcloud/db, and will be used to store the nextcloud database

Nextcloud Configuration Dataset

Select the “apps/nextcloud” dataset and select “Add Dataset”

Populate the form with the following:

Name: config
Compression Level: lz4
Enable atime: On

Leave the rest of the values as default and press “Save”. This creates the dataset /jailhouse/apps/nextcloud/config, and will store configuration settings for Nextcloud

Nextcloud Themes Dataset

Select the “apps/nextcloud” dataset and select “Add Dataset”

Populate the form with the following:

Name: themes
Compression Level: lz4
Enable atime: On

Leave the rest of the values as default and press “Save”. This creates the dataset /jailhouse/apps/nextcloud/themes

Create users and set permissions

Navigate to Accounts > Users, and press the big “+” to add a user:

Populate the resulting form as follows:

Username: mysql
Full Name: MySQL User
User ID: 88
New Primary Group: Checked
Enable Password login: No

Now press Save. Navigate back to your “apps” dataset: Storage > Pools, and expand jailhouse > apps >nextcloud. To edit the permissions, select the three dots in the rightmost column corresponding to each dataset, and select “Edit Permissions” as shown below:

Now, for each dataset we want to make the following changes:

db dataset:

User: mysql
Group: mysql

config dataset:
Note that the ‘www’ user and group should already exist, there is no need to create them.

User: www
Group: www

themes dataset:

User: www
Group: www

Create an iocage jail:

Now it’s time to create the jail. This can be done with the web UI, however as the 11.2 releases are relatively new, I haven’t had any experience with it. This guide, will therefore present the instructions for the command line interface. First, you’ll need to SSH into your FreeNAS host. Instructions on how to configure SSH are available here. The gist of this is that you’ll need to enable the SSH service in the FreeNAS UI and configure the public/private key pair for your user, and then make a connection. From a unix terminal (macOS, Linux), this will look like the following, assuming a FreeNAS host local IP of 192.168.0.9:

$ ssh root@192.168.0.9

If you’re using Windows, you’ll need to use PuTTy or Cygwin. Refer to the guide linked above for more detail. Once you have established a SSH connection, you’ll need to use the iocage command to create the jail as follows:

$ iocage create -n nextcloud -r 11.2-RELEASE ip4_addr="vnet0|192.168.0.10/24" defaultrouter="192.168.0.1" vnet="on" allow_raw_sockets="1" boot="on"

To provide some insight as to what this is doing; the -n flag allows the specification of the jail name, in this case “nextcloud”, the -r flag specifies the release of FreeBSD to be installed in the jail (Note that this version must be the same or lower than your version of FreeNAS. If you’re still using 11.1, then you’ll need to pass 11.1-RELEASE as a parameter instead; using 11.2-RELEASE will break the jail), ip4_addr is the networking specification – in this case the IP/Mask for the jail (192.168.0.10/24), and the interface to use, vnet0. Set this IP value to something convenient to you on the subnet you wish it to be on – the selection is arbitrary, though if you’re new to this, it is advisable for simplicity that you choose an IP on the same subnet as your router. To illustrate this, if your router is 192.168.0.1, then choose an IP of the form 192.168.0.x, where x is a number between 0 and 254. The defaultrouter parameter specifies the router for your network; typically this will be 192.168.0.1 by default, but if it’s something else put that here. vnet=”on” enables the vnet interface, which is required as we previously specified vnet0 as the interface. allow_raw_sockets=”1″ enables raw sockets, which enables the use of functions such as ping and traceroute within the jail, and enables interaction with various network subsystems. boot=”on” enables the jail to be auto-started at boot time. More detail on all of the parameters that can be used to configure a jail on creation can be found in the man page for iocage. If the jail doesn’t start automatically after issuing this command, start it manually:

$ iocage start nextcloud

Add storage to the iocage jail

As I mentioned previously, it’s possible to mount a device from one file system into another. This is done by creating an entry in the file system table (fstab) of the receiving file system. More information about fstab is available here. In our case, this enables data edited inside the jail to be stored outside the jail, so that if the jail needs to be destroyed or rebuilt, we still have the configuration data we need to get it back to the previous state with minimal effort. This is achieved using the fstab command.

The goal is to mount the datasets you created earlier into the jail, which can be achieved as follows:

$ iocage fstab -a nextcloud /mnt/vault/cloud /mnt/data nullfs rw 0 0
$ iocage fstab -a nextcloud /mnt/jailhouse/apps/nextcloud/db /var/db/mysql nullfs rw 0 0
$ iocage fstab -a nextcloud /mnt/jailhouse/apps/nextcloud/config /usr/local/www/nextcloud/config nullfs rw 0 0
$ iocage fstab -a nextcloud /mnt/jailhouse/apps/nextcloud/themes /usr/local/www/nextcloud/themes nullfs rw 0 0

The format these take are:

$ iocage fstab -a jailname source_location destination_location nullfs (rw/ro) 0 0

where source_location is the dataset location on your freenas host, and destination_location is the mount location within the jail. rw/ro refers to the permissions the jail has for the mounted dataset; rw is read/write and ro is read only. Choose ro if the jail needs to read the data but shouldn’t be able to alter it. Obviously, in the case of Nextcloud, we want to give all of these mounts read write access. The -a flag is to add an item to the jails fstab file. The -e flag can be used to edit an entry once made:

$ iocage fstab -e nextcloud

This will open the fstab file in vi (if you just entered, type :q! enter to quit). If you’re not familiar with vi, or prefer not to use it (the commands take some getting used to), this can be changed by using the setenv command with the EDITOR flag:

$ setenv EDITOR /usr/local/bin/nano

This will change the default editor to use the text editor nano for this session. Other alternatives include ee, emacs, vim. Choose one based on your own preferences and what you have installed. I will be using nano as I find it relatively intuitive.

Set primary cache in FreeNAS UserSpace Shell

$ zfs set primarycache=metadata jailhouse/apps/nextcloud/db

This setting provides some optimisations specific to database storage, and should only be applied to your database directory. Since MariaDB has it’s own internal cache, it would be a waste of memory to cache the same thing in ZFS as well.

Further reading on the impact of tweaking this setting can be found on PatPro[1][2]. TLDR; Only ever set this to ‘metadata’ for database applications, and ‘all’ for everything else, otherwise you’ll have significant performance degradation.

Okay, now on to configuring the jail!

Jail Setup

In order to log in to the jail environment, we need to identify the jail ID (JID). This can be determined by executing one of the following equivelant commands (either is fine):

$ iocage list
$ jls

“iocage list” will present a table that looks like the following:

+-----+--------------+-------+--------------+----------------+
| JID |     NAME     | STATE |   RELEASE    |      IP4       |
+=====+==============+=======+==============+================+
| 1   | nextcloud    | up    | 11.2-RELEASE | 192.168.0.10   |
+-----+--------------+-------+--------------+----------------+

You can see here JID = 1 for the Nextcloud jail. We can use this to enter the jail using the following command:

$ jexec <JID> <SHELL>

For example:

$ jexec 1 tcsh

This will enter jail 1 with the shell tcsh. A range of shell options can be found here. For completeness, the equivelant iocage command would be:

$ iocage console nextcloud

Which may work for you, however at the time of writing I was having issues with the command line text editors with this entry method (they wouldn’t display the file being edited), and isn’t something I can recommend at this point in time.

Excellent, now you should be at the jail terminal, and we can start setting things up:

root@nextcloud:~ $

Okay, so what we’re going to do here is set up what’s known as a FAMP stack. This is a derivation of the LAMP stack, which is a popular web server environment configuration. LAMP is an acronym for Linux Apache MySQL PHP. In this case, we’re obviously not using Linux, so this becomes the FAMP stack; FreeBSD, Apache, MySQL and PHP. Alright, lets get stuck into it!

Change pkg repo to latest branch

This is a step I had to do to fix a bug whose patch had not made it to the quarterly release, however this likely won’t be an issue for you unless you’re installing Nextcloud 14.0.1 as a fresh install (This is the case at the time of writing – 18/12/2018). There was an issue in which the Nextcloud configuration file did not contain the correct “apps_paths” directives, which was resolved in 14.0.1_1. This appears to be an issue with the quarterly branch pkg and has not been rectified with newer versions of Nextcloud. I’ve filed a bug report so hopefully this will be fixed in the future, however it has not been at the time of writing – 21/03/2019. The changes made here will update the repository to the one updated most frequently. This is good for bug fixes and new features, with the added risk of bugs that have not yet been discovered. For most people, the quarterly release will be sufficient (unless previous bugs mentioned here have not been fixed), but if you’re a trailblazer or want the updates soon after they’re released, follow these instructions. Open the FreeBSD configuration file

$ ee /etc/pkg/FreeBSD.conf

Replace the line:

url: "pkg+http://pkg.FreeBSD.org/${ABI}/quarterly"

with:

url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest"

Save and Exit:

Esc
a (leave editor)
a (save changes)

Install required packages

Now that the pkg repository has been updated, we can go ahead and install the necessary packages. The packages we will install are as follows:
– nano: a text editor
– Apache 2.4: the web server to make your next cloud instance visible in the web ui
– MariaDB: The mysql database package
– Nextcloud: the cloud application!
– Redis: caching package

You can install these by running the following commands:

$ pkg update
$ pkg install nano
$ pkg install apache24
$ sysrc apache24_enable=yes
$ service apache24 start

$ pkg install mariadb102-server
$ sysrc mysql_enable=yes
$ service mysql-server start
$ mysql_secure_installation

NOTE: If you get the following error at this point:

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

Follow this procedure:
1. Press Ctrl + C to stop the script
2. Enter the following command to stop the mysql server

    $ /usr/local/etc/rc.d/mysql-server stop

3. Then enter the following command:

    $ mysqld_safe --skip-grant-tables & 
    $ /usr/local/etc/rc.d/mysql-server start 

4. Once again stop the script by pressing Ctrl + C
5. Re-run the wizard script

    $ mysql_secure_installation

This should resolve this issue. Provide the following answers to the prompts:

Enter current password for root (enter for none): 

Press enter as there is no password

Set root password? [Y/n] y
New password: 

Enter a new password of your choice (don’t forget it!)

Re-enter new password: 

Re-enter the password

Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y

MariaDB is now configured. At this stage, the installer should have created a user named ‘mysql’, and a group named ‘mysql’ within the jail, with UID=88 and GID=88 respectively. You’ll recall earlier in the guide, we created a mysql user and group with these UID and GID. It is imperative that the UID and GID of the user and group created earlier on the FreeNAS host, and the user and group created during the mysql installation within the jail match. If they don’t, you will run into permission issues, so go ahead and change the ID of the user and group on the FreeNAS host if this is the case for you. Time to install Nextcloud:

$ pkg install nextcloud-php71

It is important to note that php 7.1 is approaching end of life at the time of writing. It will still work, it will just no longer receive updates after reaching EOL. With this in mind, it may be worth installing the php 7.2 package; nextcloud-php72. I didn’t do extensive testing with this package however, so you may be subject to errors or differences in the setup procedure not addressed in this guide. As a side note, I did also attempt to install the php 7.3 package, which I wasn’t able to get working. This may be due to the fact that php 7.3 is still in beta at the time of writing.

If all of these versions are reasonably old at the time of reading, you can search for the available Nextcloud packages by using the following command:

$ pkg search nextcloud

Install the most relevant version for you. Importantly, this is only a comment on the php version. All of these packages will have the latest version of Nextcloud itself.

Another point of relevance is that here I have chosen to use the package manager “pkg” to install Nextcloud for its simplicity in installation and maintenance. It is important to be aware that the availability of newer releases through the package manager is subject to updates pushed by the packages maintainer, and may lag behind the official releases somewhat (in my experience this has been in the order of a few days to a week). If you’re interested in installing Nextcloud manually, refer to this guide, which uses “wget” to download a zip file from Nextcloud directly. This may have the benefit of allowing you to use the web interface to update your nextcloud installation (I haven’t tried, though). If you do decide to go down this path, you’ll have to install php separately, which is addressed in the guide.

Now install Redis as follows:

$ pkg install redis
$ sysrc redis_enable=yes
$ service redis start

The function of the previous commands should have been relatively self explanatory. To provide a little more detail, “pkg update” downloads the latest list of packages in the repository, “pkg install” installs a package, “sysrc” adds an item to rc.conf, which in this case ensures that these services start on boot, and “service start” starts a given service.

Now that we have everything we need installed, lets get configuring!

Configure MySQL

Login to MySQL to create Nextcloud Database and User

$ mysql -u root -p

Enter the password you made for root during the MariaDB 10.1 Setup. Then enter each of the following commands one by one:

CREATE DATABASE nextcloud;
CREATE USER 'nextcloud_admin'@'localhost' IDENTIFIED BY 'your-password-here';
GRANT ALL ON nextcloud.* TO 'nextcloud_admin'@'localhost';
FLUSH PRIVILEGES;
exit

Where ‘your-password-here’ is the password you just used to log in to mysql. It’s important that you include the semi-colon ‘;’ at the end of each statement. If you don’t it won’t know when to terminate each command.

Configure Apache for PHP 7.1 with php-fpm

Many other guides on this and similar topics suggest the use of mod_php to configure apache to handle php files, however Apache recommends the use of proxy_fcgi and php-fpm above all other recipes. This is due to its ability to enable diagnosis of php problems more quickly, and significantly reduce the memory footprint of the httpd server as it can facilitate more scalable threaded MPM’s such as event or worker. This is in contrast to mod_php, which poses some difficulty in maintaining a thread-safe php library. If this is not done, child processes are prone to memory leaks which are likely to consume large amounts of RAM and deplete the available system resources. Additionally, mod_php has certain vulnerabilities that allow uninitialised memory to be turned into executable code. This vulnerability is mitigated by using FastCGI and php-fpm.

php-fpm should have been installed along with php when you installed Nextcloud, so lets go ahead and add it to the startup script (rc.conf) and start the php-fpm service:

$ sysrc php_fpm_enable=yes
$ service php-fpm start

Now lets enable the proxy_fcgi modules. Open the apache config file:

 $ nano /usr/local/etc/apache24/httpd.conf

Search (Ctrl + W) for and uncomment the following two lines (remove the leading ‘#’) to enable fastCGI:

LoadModule proxy_module libexec/apache24/mod_proxy.so
LoadModule proxy_fcgi_module libexec/apache24/mod_proxy_fcgi.so

Save and quit

Ctrl + X
y
enter

Now reload apache gracefully:

apachectl graceful

This ensures that whenever a php file is loaded, apache will use the php installation to parse the contents (with the appropriate VirtualHost entry, discussed later). Without this, the php file will download without loading – not very useful. For more information and different configuration options available for php-fpm, see the apache documentation.

Create a test Virtual Host File

The virtual host file handles the site specific configuration. This will be discussed in more detail later for the nextcloud specific configuration. For now, lets just create a test vhost configuration so we can test our php configuration. Create a new vhost file:

$ nano /usr/local/etc/apache24/Includes/test.conf

Copy and paste the following

<VirtualHost *:80>
    DocumentRoot "/usr/local/www/apache24/data"
    ServerName 192.168.0.10
    ProxyPassMatch ^/(.*.php(/.*)?)$ fcgi://127.0.0.1:9000/usr/local/www/apache24/data/$1
    DirectoryIndex /index.php index.php
</VirtualHost>

Change the ServerName directive to match the IP you chose for this jail, then Save and Exit (Ctrl + X).

Configure php.ini

$ cd /usr/local/etc

Create php.ini by copying the php.ini-production file (a template with production appropriate security configuration) to a new file named php.ini:

$ cp php.ini-production php.ini

Now, edit php.ini:

$ nano /usr/local/etc/php.ini

Use the search command in nano (Ctrl + W) to uncomment and make sure the following parameters have these values. Comments can be removed by deleting the “;” at the beginning of the line:

cgi.fix_pathinfo=1
date.timezone=Country/City

SEE: http://php.net/manual/en/timezones.php for the timezone relevant to you. an example would be Australia/Sydney

post_max_size = 1999M
upload_max_filesize = 1999M
memory_limit = 512M

Uncomment and update the following values as well, which provide the php configuration for caching data:

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

Save and Exit:

Ctrl + X
Y
ENTER

Restart Apache and php-fpm

$ service php-fpm restart
$ service apache24 restart

Test the php configuration

Navigate to /usr/local/www/apache24/data:

$ cd /usr/local/www/apache24/data
$ nano info.php

Paste the following into info.php

<?php
phpinfo(); //display all info
?>

This is a simple function that will display all php info for testing purposes. Save and exit:

Ctrl + X
Y
ENTER

Now, open a browser and navigate to http://JAIL_IP/info.php, where JAIL_IP is the IP you gave to this jail when you created it using iocage create, for example http://192.168.0.10/info.php. You should see a page displaying information about your PHP installation. If this works, congratulations! If it doesn’t, go back over the previous steps and try to work out where you’ve gone wrong.

Nextcloud configuration

Configure Apache for Nextcloud

Nextcloud will have been installed to /usr/local/www/nextcloud, which is not the default web root for apache (place where apache looks for index.php). This will need to be changed to the Nextcloud directory so that the Nextcloud web UI can be loaded. You can do this by editing apache’s configuration file:

$ nano /usr/local/etc/apache24/httpd.conf

Change the following two lines

DocumentRoot "/usr/local/www/apache24/data"
<Directory "/usr/local/www/apache24/data">

To

DocumentRoot "/usr/local/www/nextcloud"
<Directory "/usr/local/www/nextcloud">

Note that if for whatever reason Nexcloud hasn’t been installed to /usr/local/www/nextcloud, replace this path with the Nextcloud installation directory relevant to you. This part is variable based on how you install Nextcloud (i.e. if you followed an installation process different to this one). This path is the default as installed by pkg, but some guides suggest placing Nextcloud in /usr/local/www/apache24/data/nextcloud, which, if this is the case for you, this is what you’ll have to change the web root to.

Now enable the .htaccess file within this block. The changes you’ve just made should yield a block that looks as follows:

DocumentRoot "/usr/local/www/nextcloud"
<Directory "/usr/local/www/nextcloud">
    #
    # Possible values for the Options directive are "None", "All",
    # or any combination of:
    #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
    #
    # Note that "MultiViews" must be named *explicitly* --- "Options All"
    # doesn't give it to you.
    #
    # The Options directive is both complicated and important.  Please see
    # http://httpd.apache.org/docs/2.4/mod/core.html#options
    # for more information.
    #
    Options Indexes FollowSymLinks

    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   AllowOverride FileInfo AuthConfig Limit
    #
    AllowOverride None

    #
    # Controls who can get stuff from this server.
    #
    Require all granted
</Directory>

To enable the .htaccess file to be used for configuration, change the AllowOverride value to ‘all’:

    AllowOverride all

Save and Exit (Ctrl + X).

Permissions

Ensure the installation folder and data folders have the correct permissions so that you can read and write configuration settings, files, and perform updates.

chown -R www:www /usr/local/www/nextcloud /mnt/data

This command changes the ownership recursively of the specified folder (folder and all sub folders) to user “www” and group “www”. The arguments are:

chown -R user:group /path/to/directory

Create a VirtualHost definition for Nextcloud

A Virtual Host (or vhost) definition determines how a server processes an incoming request. This is where a range of configuration options for a site can be set, depending on both the IP and port which a request comes through on. A Virtual Host definition begins with the directive, which takes both an IP and a port as a parameter. As an example, the following definition processes requests for IP 192.168.0.10 on port 80:

<VirtualHost 192.168.0.10:80>

For our purposes, we will use a wildcard (*) for the IP, which means that our vhost definition will be evaluated for all IPs, but we will specify port 80 specifically, which is the port used for HTTP traffic. There are two types of vhost matching, IP-based matching and Name-based matching. Because we’re accepting all IP addresses in this configuration, we’re relying on the ServerName field for Name-based matching.

For these examples, I’m going to use mydomain.com, and the subdomain cloud.mydomain.com. If for example you’re using a DDNS (more on this later), you might replace all instances of cloud.mydomain.com with something like cloud.no-IP.org. Navigate to the apache Includes directory:

cd /usr/local/etc/apache24/Includes

First, lets remove the configuration file we created earlier; we won’t need it anymore.

$ rm /usr/local/etc/apache24/Includes/test.conf

Now, create the new site configuration file:

$ nano cloud.mydomain.com.conf

Add the following content to the file:

    <VirtualHost *:80>
        DocumentRoot "/usr/local/www/nextcloud"
        ServerName cloud.mydomain.com
        <FilesMatch .php$>
            SetHandler "proxy:fcgi://127.0.0.1:9000/"
        </FilesMatch>
        DirectoryIndex /index.php index.php
    </VirtualHost>

Remember to replace cloud.mydomain.com with the domain relevant to you. Save and Exit (Ctrl + X). Now, lets discuss what’s going on here. The first line, DocumentRoot, defines the “root”, or top level directory from which to serve content. This means that using the URL http://cloud.mydomain.com will direct a user to files contained within this path; in this case /usr/local/www/nextcloud. Additionally, subdirectories within the DocumentRoot will be accessible as a path specification to the URL. As an example, lets assume there is a directory /usr/local/www/nextcloud/data, containing a file test.php. This would be accessible from http://cloud.mydomain.com/data/test.php. It’s important that the DocumentRoot points to the top level of the Nextcloud installation, as this is where index.php lies, which will present the Nextcloud user interface.

The ServerName is relatively self descriptive – this is the domain name of your server. It’s important to note that this name must have a valid DNS entry. This means that either this server is available on the Internet, and can be navigated to, OR there is a host entry in your routers DNS Resolver to direct queries to this URL to your web server IP. Alternatively, if this server is only going to be available on your local network, you can replace this with your servers local IP, i.e.:

ServerName 192.168.0.10

To be clear here:

  1. If your domain is available on the internet, cloud.mydomain.com must resolve to a public IP
  2. If your domain is only available locally, cloud.mydomain.com must resolve to a local IP
  3. OR, it must be a local IP.

The next directive, <FilesMatch>, matches all files containing .php in the title and assigns the fastCGI proxy module we set up earlier as the handler. This allows us to use php files, and serve php content using php-fpm.

More reading on Virtual Host definitions are available in the apache documentation [3] [4] [5].

Test your configuration

Restart apache:

$ service apache24 restart

Now, navigate to http://JAIL_IP/, i.e. http://192.168.0.10/ again to confirm you can see the setup screen for Nextcloud. If you can, well done! We’re most of the way there.

Web Configuration

Set up your admin account with a username and password you choose, then populate the fields as follows:

Data folder = /mnt/data
Database user = nextcloud_admin
Database password = MADEUP_PASSWORD_FROM_BEFORE
Database name = nextcloud
Database host = localhost:/tmp/mysql.sock

Add external domain as a trusted domain

In the terminal, navigate to the Nextcloud config file:

$ nano /usr/local/www/nextcloud/config/config.php

Add your domain name to the trusted domains array. Adding cloud.mydomain.com would look like the following:

<?php
$CONFIG = array (
  'apps_paths' =>
  array (
    0 =>
    array (
      'path' => '/usr/local/www/nextcloud/apps',
      'url' => '/apps',
      'writable' => true,
    ),
    1 =>
    array (
      'path' => '/usr/local/www/nextcloud/apps-pkg',
      'url' => '/apps-pkg',
      'writable' => false,
    ),
  ),
  'logfile' => '/var/log/nextcloud/nextcloud.log',
  'memcache.local' => '\OC\Memcache\APCu',
  'instanceid' => 'ocy4qsadkxhl',
  'passwordsalt' => '44RcdZYDK/TNVGLyCxVPT67M88sjhJ',
  'secret' => 'aCLhfzgCaLGyfVp5upS4mXpP2sduzZw6FGsAZtUwhpduUZji',
  'trusted_domains' =>
  array (
    0 => '192.168.0.10',
    1 => 'cloud.mydomain.com',
  ),
  'datadirectory' => '/mnt/data',
  'dbtype' => 'mysql',
  'version' => '14.0.4.2',
  'overwrite.cli.url' => 'http://192.168.0.10',
  'dbname' => 'nextcloud',
  'dbhost' => 'localhost:/tmp/mysql.sock',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => 'nextcloud_admin',
  'dbpassword' => 'Default123!',
  'installed' => true,
);

The line of interest here is

    1 => 'cloud.mydomain.com',

within the ‘trusted_domains’ block. Replace this with your domain. Save and Exit (Ctrl + X).

Fix the annoying apache errors

To get rid of the following error message when starting and stopping the apache server:

AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
Syntax OK
Stopping apache24.
Waiting for PIDS: 80591.
Performing sanity check on apache24 configuration:
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
Syntax OK
Starting apache24.
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message when stating apache do the following:

Open the apache configuration file:

$ nano /usr/local/etc/apache24/httpd.conf

Search for the phrase “ServerName”, and enter your jails ip and port 80 such that it appears as follows:

ServerName JAIL_IP:80

ie

ServerName 192.168.0.10:80

Uncomment this line, and the message should no longer appear. To test this, restart apache

$ service apache24 restart

This should produce a clean restart message:

Performing sanity check on apache24 configuration:
Syntax OK
Stopping apache24.
Waiting for PIDS: 12933.
Performing sanity check on apache24 configuration:
Syntax OK
Starting apache24.

Configure Cron jobs:

Cron is one of the most useful utilities in FreeBSD. It’s a utility that runs in the background and regularly checks “/etc/crontab” for tasks to execute and searches “/var/cron/tabs” for custom crontab files. These files are used to schedule tasks which cron runs at the specified times. Each entry in a crontab defines a task to run, and is known as a cron job. There are two types of configuration files, the system crontab, and the user crontab.

A crontab can be edited with the command

$ crontab -u <user> -e

In this case, we will configure the crontab of the “www” user, and add an entry to run the nextcloud cron script. Before we do this, lets change the environment editor to nano.

$ setenv EDITOR nano
$ crontab -u www -e

Add the following (assuming it’s blank, if not just add the job). The crontab header describes what each field in the cronjob represents, and is courtesy of squarism.

# minute (0-59),
# |     hour (0-23),
# |     |       day of the month (1-31),
# |     |       |       month of the year (1-12),
# |     |       |       |       day of the week (0-6 with 0=Sunday).
# |     |       |       |       |       commands
  */15      *       *       *       *       /usr/local/bin/php -f /usr/local/www/nextcloud/cron.php

Save and Exit (Ctrl + X), and the www crontab should be configured.

Caching and Redis

Redis is an in-memory data structure store, used as a database, cache and message broker. This will provide performance improvements in terms of accessing your data. To find out more, read the Redis Documentation. Lets update redis.conf to run on the unix socket. Execute the following command:

$ nano /usr/local/etc/redis.conf

Inside this file, find the “port” value and change it from its default value to 0. This will stop Redis from listening on a TCP port so we can configure it to listen on a unix socket.

port 0

Additionally, uncomment the following by removing the “#” in front of each statement:

unixsocket /tmp/redis.sock
unixsocketperm 777

And then confirm that the following statement is uncommented (No leading ‘#’):

bind 127.0.0.1

This ensures that Redis can only operate on the local interface, as a security precaution. Save and Exit (Ctrl + X).

Now, restart the service

$ service redis restart

Now, confirm Redis is in the feedback list by running the following command:

$ ls -al /tmp

You should see redis.sock and mysql.sock in the feedback list as follows:

srwxrwxrwx  1   mysql   wheel   0   MMM     D   HH:MM   mysql.sock
srwxrwxrwx  1   redis   wheel   0   MMM     D   HH:MM   redis.sock

If you run into troubles here, please consult the Nextcloud documentation and the Redis Documentation on configuring Redis.

Now, install the following packages:

$ pkg install php71-pecl-redis
$ pkg install php71-pecl-APCu

These packages are extensions providing an API to allow php to communicate with the Redis database, and also for user caching using APC. Note that if you installed nextcloud-php72, the packages you install here will need to be modified for the correct php version, i.e. php72-pecl-redis. Lets adjust the Redis and caching configuration using the following commands. Note that these are order specific:

$ su -m www -c 'php /usr/local/www/nextcloud/occ config:system:set redis host --value="/tmp/redis.sock"'
$ su -m www -c 'php /usr/local/www/nextcloud/occ config:system:set redis port --value=0 --type=integer'

Now, this is important. If you’re using PHP 7.1 and Nextcloud 14, execute the following command:

$ su -m www -c 'php /usr/local/www/nextcloud/occ config:system:set memcache.local --value="\OC\Memcache\Redis"'

Otherwise, if you’re using PHP 7.1 or higher and Nextcloud 15 or PHP 7.2 or higher and Nextcloud 14, execute this command:

$ su -m www -c 'php /usr/local/www/nextcloud/occ config:system:set memcache.local --value="\OC\Memcache\APCu"'

If you get this wrong, the following command won’t work. Make sure you don’t get this wrong. Now, make the final configuration change:

$ su -m www -c 'php /usr/local/www/nextcloud/occ config:system:set memcache.locking --value="\OC\Memcache\Redis"'

These commands switch user to the user “www”, where the su flag -m leaves the environment unmodified. The -c flag specifies a command to be run within the new user shell. In this case, it runs the program “occ”, and passes some configuration options as a parameter. See the su man page for more information.

$ service apache24 restart

At this stage, your nextcloud server should be ready to go for local network use. There are, however, a range of security considerations that will be dealt with in the remainder of the guide. These are very important, especially if you intend to open the server to the web.

Security

Given that your new private cloud is likely to house a lot of your sensitive data, security is a paramount consideration, especially if you’re planning on making it visible to the internet. Here I will discuss a number of security considerations.

Nextcloud recommends a number of steps be taken to harden your server:
1. Give PHP read access to /dev/urandom
2. Enable hardening modules
3. Place data directory outside of the web root
4. Disable preview image generation
4. Use HTTPS
5. Redirect all unencrypted traffic to HTTPS
6. Enable HTTP Strict Transport Security (HSTS)
7. Use proper SSL configuration
8. Use a dedicateed domain for Nextcloud
9. Ensure that your Nextcloud instance is installed in a DMZ
10. Serve security related headers by the Web server

There are a number of useful sites to help you test the security of your nextcloud instance, here are a few:
Nextclouds own security scanner
SSL Labs
Mozilla Observatory

Make sure you evaluate the security of your site with at least one of these tools after making the changes below; you don’t want all of your data to be vulnerable. nachoparker of Own Your Bits does an excellent breakdown of the results you’re likely to see from these platforms, and offers methods to rectify some of the common issues.

I’ll now discuss each of the above hardening tips and how this has/can be implemented in FreeNAS.

Give PHP read access to /dev/urandom

This should be available by default, but to confirm, enter the following command:

$ ls -l /dev/urandom

This should return the following

lrwxr-xr-x  1 root  wheel  6 Nov 25 10:43 /dev/urandom -> random

The part of interest here is “lrwxr-xr-x”. Ignoring the leftmost “l”, this is a representation of the directory permissions, in three groups of “rwx”; one each for the owner (user), owner (group), and other. In this case, the owning user is root, and the owning group is wheel. Since the nextcloud user, “www”, falls into neither of these groups, it is part of the “other” set of permissions. This means we’re most interested in the rightmost three characters. In this case, these are “r-x”. This means that any user has the permissions to read from this directory, and execute files in this directory, but not to write to this directory. Since “www” can read, this requirement is satisfied.

If this is not the case, however, run the following command:

$ chmod o+r /dev/urandom

chmod changes a files modes. The arguments passed here are o for other users and +r to add read.

If you want more detail on how permissions in unix, or more specifically FreeBSD work, here is some background reading.

Enable hardening modules

Mandatory Access Control (MAC)

The Nextcloud documentation recommends the use of hardening modules such as SELinux. SELinux (Security-Enhanced Linux) is a linux kernel security module, that provides a mechanism for supporting access control security policies, including mandatory access controls. FreeBSD is obviously not linux, and so does not include the SELinux modules. However, it does have it’s own system called Mandatory Access Control. This allows an administrator to ensure that a user will not be permitted to change security attributes at will. All user utilities, programs and scripts are required to work within the constraints of the access rules provided by the selected security policy modules. The Nextcloud Documentation provides some configuration advice for SELinux, namely:

  • Enable updates via the web interface (don’t do this for FreeBSD)
  • Disallow write access to the whole web directory
  • Allow access to a remote database
  • Allow access to LDAP server
  • Allow access to remote network
  • Allow access to network memcache
  • Allow access to SMTP/sendmail

At the time of writing, I’m not certain how to reliably implement this with MAC in FreeBSD, and so is considered beyond the scope of this guide. This may form the content of a future blog post on the topic.

Enable Common Technical Controls

There are a number of system hardening modules that FreeBSD offers at install time. Unfortunately, since this is a jail, we were not presented with these options. The options are as follows:

  1. Hide processes running as other users
  2. Hide processes running as other groups
  3. Disable reading kernel message buffer for unpriveleged users
  4. Disable process debugging facilities for unpriveleged users
  5. Randomize the PID of newly created processes
  6. Insert stack guard page ahead of growable segments
  7. Clean the /tmp filesystem on startup
  8. Disable opening syslogd network socket (disables remote logging)
  9. Disable SendMail service

Andrew Volpe of BSD Adventures suggests that these should all be enabled unless there is a good reason not to. An example of a good reason is that if you have a remote logging server, you would want to disable option 8 (so that opening syslogd network sockets is enabled). We will configure these as follows. First, open the kernel parameter configuration file:

$ nano /etc/sysctl.conf

Paste the following values into the file:

security.bsd.see_other_uids=0
security.bsd.see_other_gids=0
security.bsd.unprivileged_read_msgbuf=0
security.bsd.unprivileged_proc_debug=0
kern.randompid=$(jot -r 1 9999)
security.bsd.stack_guard_page=1

This enables options 1-6. To enable options 7-9, run the following commands:

$ sysrc clear_tmp_enable=YES
$ sysrc sendmail_enable="NONE"
$ sysrc sendmail_submit_enable="NO"
$ sysrc sendmail_outbound_enable="NO"
$ sysrc sendmail_msp_queue_enable="NO"
$ sysrc syslogd_flags="-c -ss"

It’s important to note that the majority of these should have these values set already by default, but this ensures that these settings will have the values we want. Additionally, Nextcloud does not require SendMail to be enabled to send mail; it has its own libraries for this.

Tamper Detection

Andrew Volpe of BSD Adventures also suggests the use of a tamper detection package to keep track of any changes made to configuration files in the event an unauthorised user gains access and tries to change your server configuration, or even just when a valid user makes changes. This can be achieved with the AIDE package:

$ pkg install aide

Then, once installed, the configuration options can be customised using /usr/local/etc/aide.conf. The default options should do a reasonable job of securing the jail. If you want to make modifcations beyond the default, you can learn how to customise the configuration using the official AIDE documentation. Now, to finish the installation/configuration, navigate to the aide database directory and run the following commands:

$ cd /var/db/aide
$ aide --init
$ mv databases/aide.db.new databases/aide.db

To compare the database to the current configuration files, run the following command

$ aide

This will give you an output identifying any differences. If you run this immediately after installing, you should get a statement to the following effect:

AIDE found NO differences between database and filesystem. Looks okay!!

Unfortunately, to reset the recorded differences, you need to create a new database and replace aide.db with it. To simplify this process, it can be automated! To implement this, we’ll need to create a script to create the new database, archive the old database, and replace it with the new one. We can then have the script email you the change log, so you can be notified if someone has tampered with files. The mailing portion is optional, however there would be nothing to stop a malicious actor from altering the aide database if your only copy is stored locally within the jail, so this is recommended. Lets create this script, courtesy of Bob Aiello:

$ mkdir -p /scripts/aide
$ nano /scripts/aide/chkaide.sh

Paste the following:

#! /bin/sh
#chkaide.sh - Bob Aiello, modified for FreeBSD by Samuel Dowling
MYDATE=`date +%Y-%m-%d`
MYFILENAME="Aide-"$MYDATE.txt
UPDATE_NAME="aide_update.txt"
/bin/echo "Aide check !! `date`" > /tmp/$MYFILENAME
/usr/local/bin/aide --check > /tmp/myAide.txt
/bin/cat /tmp/myAide.txt|/usr/bin/grep -v failed >> /tmp/$MYFILENAME
/bin/echo "**************************************" >> /tmp/$MYFILENAME
/usr/bin/tail -20 /tmp/myAide.txt >> /tmp/$MYFILENAME
/bin/echo "****************DONE******************" >> /tmp/$MYFILENAME
/usr/bin/mail -s"$MYFILENAME `date`" john.smith75@gmail.com < /tmp/$MYFILENAME
/usr/local/bin/aide --update >> /tmp/$UPDATE_NAME
mv /var/db/aide/databases/aide.db /var/db/aide/databases/archive/aide-$MYDATE.db
mv /var/db/aide/databases/aide.db.new /var/db/aide/databases/aide.db

Change the email john.smith75@gmail.com to the recipient email you would like these change logs sent to. Save and Exit (Ctrl + X).We need to create a directory for the archived logs, and change the permissions so that it can be executed by the root user:

$ mkdir /var/db/aide/databases/archive
$ chmod 700 /scripts/aide/chkaide.sh
$ chown root:wheel /scripts/aide/chkaide.sh

This script essentially creates a text file containing the output of the “aide –check” command, and emails the contents to you. It then updates the database so that each email will only contain the changes since the last time you received an email. Now lets create a cronjob so that this can be run

$ crontab -e 

Add the following entry:

06 01 * * * /scripts/aide/chkaide.sh

This will set the chkaide script to run at 1:06 AM every day. Now, this won’t work just yet. First we need to ensure a Mail Transfer Agent (MTA) is installed. If you already have one installed, you can skip this step.

Installing a Mail Transfer Agent

One option for an MTA would be to use FreeBSD’s default, SendMail. However, due to security concerns associated with SendMail, we will be using Postfix instead. You’re welcome to use another MTA such as Exim if you would prefer, however Postfix is what this guide will cover.

First, install postfix

$ pkg install postfix-sasl

During the installation, you’ll be prompted with the following:

Would you like to activate Postfix in /usr/local/etc/mail/mailer.conf [n]? y

Make sure you provide ‘y’ as the answer. Now, to make postfix the default mail client, make sure that sendmail has been disabled:

$ sysrc sendmail_enable="NONE"
$ sysrc sendmail_submit_enable="NO"
$ sysrc sendmail_outbound_enable="NO"
$ sysrc sendmail_msp_queue_enable="NO"

This should be the case from an earlier step, but confirm that these are the values. Add postfix to the startup sequence:

$ sysrc postfix_enable="YES"

Stop the sendmail service:

$ service sendmail stop

If it isn’t started, you may get a response similar to the following:

Cannot 'stop' sendmail. Set sendmail_enable to YES in /etc/rc.conf or use 'onestop' instead of 'stop'.
Cannot 'stop' sendmail_msp_queue. Set sendmail_msp_queue_enable to YES in /etc/rc.conf or use 'onestop' instead of 'stop'.

If you do, this means it’s already stopped, and you can move on. Start the postfix service:

$ service postfix start

Some extra configuration is needed as Sendmail is so ubiquitous that some software assumes it is already installed and configured. Check /etc/periodic.conf and make sure that these values are set to NO. If this file does not exist, create it with these entries:

$ nano /etc/periodic.conf
daily_clean_hoststat_enable="NO"
daily_status_mail_rejects_enable="NO"
daily_status_include_submit_mailq="NO"
daily_submit_queuerun="NO"

Save and Exit (Ctrl + X). FreeBSD uses /etc/mail/mailer.conf to map the expected Sendmail binaries to the location of the new binaries, and so we need to update this file to point to the right location. Note that this likely isn’t a necessary step if you deviated from the guide and installed postfix using ports, as this file is updated during the installation process. If you installed using pkg however (as this guide suggested), open the mailer configuration file:

$ nano /etc/mail/mailer.conf

Comment out the current entries, and paste the new binary locations below it. The file should end up looking like this:

# $FreeBSD: releng/11.2/etc/mail/mailer.conf 327765 2018-01-10 09:06:07Z delphij $
#
# Execute the "real" sendmail program, named /usr/libexec/sendmail/sendmail
#
#sendmail       /usr/libexec/sendmail/sendmail
#mailq          /usr/libexec/sendmail/sendmail
#newaliases     /usr/libexec/sendmail/sendmail
#hoststat       /usr/libexec/sendmail/sendmail
#purgestat      /usr/libexec/sendmail/sendmail

#
# Execute the Postfix sendmail program, named /usr/local/sbin/sendmail
#
sendmail        /usr/local/sbin/sendmail
send-mail       /usr/local/sbin/sendmail
mailq           /usr/local/sbin/sendmail
newaliases      /usr/local/sbin/sendmail

Save and exit (Ctrl + X). Navigate the postfix directory /usr/local/etc/postfix:

$ cd /usr/local/etc/postfix

Open the configuration file for editing:

$ nano main.cf

Search for the following phrase:

#alias_maps = hash:/etc/aliases

Uncomment this line by removing the ‘#’ at the beginning. Now scroll to the end of the file (shortcut: Ctrl+_ , then Ctrl + V), and paste the following configuration parameters as suggested by Marin Nikolov:

# Manual configuration for Gmail

## SASL Options
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/usr/local/etc/postfix/sasl_passwd

## TLS Options
smtp_use_tls = yes
smtp_tls_security_level = encrypt
tls_random_source = dev:/dev/urandom

## Relay host
relayhost = [smtp.gmail.com]:587

Save and Exit (Ctrl + X). Note that the email address I’m configuring this email to be sent from will be gmail. If you prefer a different provider, your relayhost and port will change (587 is for TLS, 465 is for SSL), and you’ll have to use values appropriate for you. Now, set the appropriate permissions for the postfix directory:

$ postfix -c /usr/local/etc/postfix set-permissions

Create the alias maps:

$ newaliases
$ postalias /etc/aliases

Now we need to configure the gmail authentication settings. Create a new file for these settings:

$ nano /usr/local/etc/postfix/sasl_passwd

Add the following line:

smtp.gmail.com    <username>:<password>

Replace with your gmail email, i.e. user@gmail.com, and with the password for the account. Save and Exit (Ctrl + X). Now hash the file so postfix can use it:

$ postmap /usr/local/etc/postfix/sasl_passwd

Secure the file so that only the root user can read or edit it:

$ chmod 0600 /usr/local/etc/postfix/sasl_passwd
$ chown root:wheel /usr/local/etc/postfix/sasl_passwd

And finally, you’ll need to enable “Less Secure Apps” in the Gmail application. Refer to the google documentation on allowing less secure apps to achieve this. Now all that’s left to do is confirm that everything works. Send a test email:

$ echo "Test Email Contents" | mail -s "Postfix Test Email" recipient_user@domain.com

Replace recipient_user@domain.com with the email address to receive the test email, and confirm that the email was received. It may also be worth inspecting the logs to ensure that no errors are present:

$ nano /var/log/maillog

Scroll to the end (Ctrl+_ , Ctrl + V) to view the most recent logs. If the test email doesn’t work, this is your first stop to debugging any errors you may have. Unfortunately due to the large variety of error messages, I can’t address them all and you’ll have to debug this yourself. For more information on mail functions, see the mail(1) man page.

Now, confirm that the aide script works by running it:

$ /bin/sh /scripts/aide/chkaide.sh

If you receive an email with the output, you know it’s working!

Postfix hardening

To further improve the security of your postfix configuration, Linux Audit suggests the following changes:

$ postconf -e disable_vrfy_command=yes
$ postconf -e inet_interfaces=loopback-only
$ postconf -e mynetworks="127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128"
$ postconf -e smtpd_helo_required=yes

disable_vrfy_command prevents others from being able to verify whether an email is a valid email on the system. Setting inet_interfaces to loopback-only means that postfix will only listen on the local interface, which is what we want because we are only interested in sending outgoing emails. Changing the mynetworks value to the network address of the local network prevents spammers from leveraging an open relay system in your client. The last configuration setting configures the smtpd daemon to require a “HELO” command, which will prevent communication with other mail servers that have either been improperly configured, or are spammers.

Place data directory outside of the web root

In our case, the web root is:

/usr/local/www/nextcloud

Our data directory is:

/mnt/data

Since data is not within the webroot hierarchy, this requirement is already satisfied.

Disable preview image generation

For high security deployments, Nextcloud recommends the disabling of preview generation for common filetypes. You’ll need to determine your own security requirements to determine whether this is worth enabling for you. Essentially, the risk is that in order to display thumbnails, a directory of these thumbnails needs to be maintained. Typically, these thumbnails don’t have the same permission settings as the files themselves, so it may be possible for a user to determine the contents of a file without having permission to access the file itself.

If this is something that you think might provide benefit to you, you can disable preview image generation as follows. First, open the Nextcloud config file:

$ nano /usr/local/www/nextcloud/config/config.php

Navigate to the end of the file, and right before the

);

statement, add the following:

'enable_previews' => false,

so the end of the config file should be similar to the following:

    ...
    'theme' => '',
    'loglevel' => 2,
    'enable_previews' => false,
);

Preview image generation can be re-enabled by changing the value of ‘enable_previews’ to ‘true’.

SSL

Due to the interrelated nature of items 4-7, they will all be dealt with in this section, where we will discuss the configuration of HTTPS/SSL for your domain. Note that if you only plan on using this locally (not remotely), it is still good practice to use SSL, however it is less necessary as your threat profile is diminished. Configuring SSL for local use is a different process, where you will have to self sign a certificate, and so it won’t be addressed here. This part assumes that you have a public domain pointing at your web server (i.e. you can access cloud.mydomain.com from the internet). This is critical, as certbot will not be able to issue a certificate if your domain is only available on your LAN. Some Dynamic DNS providers will give you a free subdomain, scroll down to the section dealing with DDNS for more information before undertaking this step, if that’s something you’re interested in.

First, open the apache config file and search for “ssl_module”

$ nano /usr/local/etc/apache24/httpd.conf
Ctrl + W
ssl_module

Uncomment the following lines:

 LoadModule ssl_module libexec/apache24/mod_ssl.so
 LoadModule rewrite_module libexec/apache24/mod_rewrite.so

Loading mod_rewrite fulfils the requirements of recommendation number 5 by redirecting http to https. This isn’t all that’s required to achieve this, however the additional requirements have already been implemented by Nextcloud in the .htaccess file. Update the apache server to listen on both ports 80 (HTTP) and 443 (HTTPS) by finding the phrase:

Listen 80

And below it, add:

Listen 443

Now Save and Exit the apache config file (Ctrl + X).

Obtain a certificate

Now it’s time to get a certificate for your domain. Again, we will use cloud.mydomain.com as an example. As a reminder, this domain must be public for this to work. If it’s not, you’ll need to self sign a certificate, which will be a different process. For public domains, we can get a free certificate courtesy of LetsEncrypt using the certbot package. First, download the package:

$ pkg install py27-certbot

Now, try to grab a certificate. It’s important that for this stage to work, LetsEncrypt is able to communicate with your server over port 80. If you’re self hosting this and you haven’t already, create a port forward in your router to forward external port 80 to JAIL_IP:80 to allow this. Now request a certificate:

$ certbot certonly --webroot -w /usr/local/www/nextcloud -d cloud.mydomain.com

Hopefully this works! Unfortunately for me, it did not. I suspect this is due to the way I’ve configured my domain. Certbot’s documentation is available here if you need to do some troubleshooting. If it still doesn’t work, fret not! There are other ways of verifying the server. The way I utilised was DNS verification, which is supported by certbot, however it requires the download of an additional plugin. The Domain Name System that I use is Amazon Web Services’ Route 53. If you have a different Domain Name System, check the list of supported plugins to confirm this is a method available to you. Each of these plugins will have a specific method associated with it, so if you use something other than Route 53, you’ll need to research this process yourself. Since I’m only familiar with Route 53, I’m only going to address the process for this.

First, you’ll need to download the AWS command line tools package:

$ pkg install awscli

Then, create an AWS configuration file using:

$ aws configure

This will prompt you for four pieces of information:
1. AWS Access Key ID – You will need to create a Key Pair – Fill the AWS Access Key ID in here
2. AWS Secret Access Key – The second component of the key pair
3. Default region name – The region closest to you – i.e. us-west-2. This should be available somewhere in your AWS dashboard
4. Default output format: text

For more information about how to set this up, see the AWS Documentation. Now, to install the certbot-dns-route53 plugin! First, install pip:

$ pkg install py27-pip
$ pip install certbot-dns-route53

This list of available dns plugins is available here. Now, running the “certbot certonly” command will run you through the prompts to retrieve/manage your certificates, and is useful to manage your individual environment:

$ certbot certonly

The alternative is to request everything with arguments directly as follows:

$ certbot certonly --dns-route53 -d cloud.mydomain.com

This can also be used to obtain wildcards! If you want a wildcard as well, just append an additional -d flag and domain name:

$ certbot certonly --dns-route53 -d cloud.mydomain.com -d *.mydomain.com

If none of this has worked for you, you may have better luck with acme.sh, or see the letsencrypt IRC channel at the bottom of the article.

Configure certificate automatic renewals

Unfortunately, the LetsEncrypt certificates are designed to expire after 90 days, mostly to ensure that there is some sort of auto-renewal policy in place. Fortunately, the certbot package ships with a renew command. To confirm that this will work without issues, use the dry run command:

$ certbot renew --dry-run

If this runs successfully, you can confidently make a cron job entry to the root users crontab:

$ crontab -e

Add the following line

0 0,12 * * * /usr/local/bin/python2.7 -c 'import random; import time; time.sleep(random.random() * 3600)' && /usr/local/bin/certbot renew --quiet

This attempts a renewal at a random offset from midnight and noon every day.

Update the VirtualHost entries in the site configuration file

Before the site is accessible from a https domain, we also need to update the site configuration file to add a virtual host entry for the SSL connection:

$ nano /usr/local/etc/apache24/Includes/cloud.mydomain.com.conf

Replace the current entry for port 80 with the following:

<VirtualHost *:80>
    ServerName cloud.mydomain.com
    Redirect permanent / https://cloud.mydomain.com/
</VirtualHost>

Below this, add an entry for port 443, as described below

Use the Mozilla SSL Configuration Generator to generate the virtual hosts entry, paying specific attention to the SSLProtocol and SSLCipherSuite fields. This will fulfil the requirements of recommendation number 7 to use a proper SSL configuration. I specified apache version 2.4.34, openssl version 1.0.2o, and opted for a modern configuration. This means that only newer browsers are supported. Two other options for configuration are available; “Intermediate” and “Old”. I recommend against choosing these where possible. They allow for compatability with older browsers, so if you’re running an old environment (and can’t update for whatever reason), then you may not have another choice. But this compatability comes at the expense of security. Replace the fields below as appropriate with the results of the Mozilla SSL Configuration Generator to apply your choices. The section that the SSL Configuration Generator generates is identified by the comment “# modern configuration, tweak to your needs”.

<VirtualHost *:443>
        ServerAdmin john.smith75@gmail.com
        ServerName cloud.mydomain.com
        <FilesMatch .php$>
            SetHandler "proxy:fcgi://127.0.0.1:9000/"
        </FilesMatch>
        DirectoryIndex /index.php index.php
        DocumentRoot /usr/local/www/nextcloud
        SSLCertificateFile /usr/local/etc/letsencrypt/live/cloud.mydomain.com/fullchain.pem
        SSLCertificateKeyFile /usr/local/etc/letsencrypt/live/cloud.mydomain.com/privkey.pem
        SSLEngine on

        # modern configuration, tweak to your needs
        SSLProtocol         all -SSLv3 -TLSv1 -TLSv1.1
        SSLCipherSuite          ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
        SSLHonorCipherOrder     on
        SSLCompression          off
        SSLSessionTickets       off
        SSLOptions          +StrictRequire

        <IfModule mod_headers.c>
            Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
        </IfModule>
</VirtualHost>

As can be seen, the last statement, the requirements of recommendation number 6 is satisfied by enabling HTTP Strict Transport Security (HSTS):

Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"

Again, replace all instances of cloud.mydomain.com with the domain relevant to you, and replace the email for the ServerAdmin entry with your own. Save and exit the file (Ctrl+X).

$ service apache24 restart

Enable SSL Caching

Now, lets enable SSLSessionCache and SSLStaplingCache. SSLSessionCache keeps track of all of the current SSL user sessions, and SSLSessionCacheTimeout ensures that each user is required to renew their session every 10 minutes. SSLStaplingCache keeps track of the revocation status of the certificate, reducing the amount of communication required between the client and the certificate authority. To do this, first open the apache configuration file:

$ nano /usr/local/etc/apache24/httpd.conf

Scroll to the bottom (Ctrl+_, Ctrl+V), and replace this section:

<IfModule ssl_module>
        SSLRandomSeed startup builtin
        SSLRandomSeed connect builtin
</IfModule>

With this section:

<IfModule ssl_module>
        SSLRandomSeed startup builtin
        SSLRandomSeed connect builtin
        SSLSessionCache         "shmcb:/var/log/apache/ssl_gcache_data(512000)"
        SSLSessionCacheTimeout  600
        SSLUseStapling          On
        SSLStaplingCache        "shmcb:/var/log/apache/ssl_stapling(32768)"
</IfModule>

Whilst still in the apache configuration file, search for socache_shmcb_module (Ctrl+W). Uncomment it to enable the shmcb module (Remove the ‘#’ at the beginning of the line).

LoadModule socache_shmcb_module libexec/apache24/mod_socache_shmcb.so

Save and exit (Ctrl + X). Now create the directory for the SSLSessionCache:

$ mkdir /var/log/apache
$ service apache24 restart

Use a dedicated domain for Nextcloud

Using a dedicated domain, such as cloud.domain.com instead of domain.com/nextcloud, offers a number of benefits associated with the Same-Origin-Policy. This is primarily that it preventing clients from reading responses from different domains, which is important in preventing malicious code in other tabs you may have executing on your Nextcloud instance. Hendrik Brummermann illustrated this with a good example in his Stack Overflow answer:

Assume you are logged into Facebook and visit a malicious website in another browser tab. Without the same origin policy JavaScript on that website could do anything to your Facebook account that you are allowed to do. For example read private messages, post status updates, analyse the HTML DOM-tree after you entered your password before submitting the form.

It’s obvious that giving any other tab you have open permission to act as your user is undesireable.

Ensure that your Nextcloud instance is installed in a DMZ

A DMZ, or demilitarized zone, is a physical or logical subnetwork that contains and exposes external facting services to an untrusted network such as the internet. The purpose of this is to add an additional layer of security to a LAN. This is achieved by placing a firewall between the LAN and the DMZ, limiting the exposure to the LAN if the DMZ is compromised. See here for more detail. One possible configuration for this is depicted below:

In essence, this is a process that doesn’t provide any additional security to your Nextcloud instance directly. In general, it would, however, provide a second line of defence to prevent access to the rest of your LAN if the Nextcloud instance is compromised. In the case of running Nextcloud in a FreeNAS jail, the efficacy of this is in question. According to iXsystems, the entire LAN accessible to the FreeNAS host would be routable by a compromised jail, making this segregation of jail from host an exercise in futility.

For these reasons, and due to the uncertainty around the benefit this would actually have to our configuration, we will skip the implementation of a DMZ.

Serve security related headers by the Web server

Nextcloud has been kind enough to ensure a range of basic security headers as part of the default environment, including:
– X-Content-Type-Options: no sniff
– Prevents browsers from interpreting text files as JavaScript
– X-XSS-Protection: 1; mode=block
– Instructs browsers to enable their browser side Cross-Site-Scripting filter
– X-Robots-Tag: none
– Instructs search machines not to index these pages
– X-Frame-Options: SAMEORIGIN
– Prevents Nextcloud from being embedded within an iframe from a different domain
– Referrer-Policy: no-referrer
– Instructs browser not to send referrer information along with requests to any origin

For optimal security, these can be served by the web server to enforce them on response. To do this, open the apache configuration file:

$ nano /usr/local/etc/apache24/httpd.conf

Now, ensure that the following two lines are uncommented (remove the ‘#’ from the beginning of the line as necessary):

LoadModule env_module libexec/apache24/mod_env.so
LoadModule headers_module libexec/apache24/mod_headers.so

Save and Exit (Ctrl + W). Restart the web server to implement these changes:

$ service apache24 restart

It is important to note that at the time of writing and in the current configuration, Nextcloud will fail the Content Security Policy tests on the security testing websites listed earlier. This is due to the fact that it allows ‘unsafe-eval’. Currently, there is not a fix to this that won’t break your Nextcloud server. However, a fix to this has been implemented in Nextcloud 15, so there’s nothing that needs to be done here.

Configure DDNS updates:

Now, if you’re self hosting, and you have a residential internet plan with your ISP, your IP address is likely not static. If it is static, you can disregard this. What this means is that your ISP may periodically change your public IP. This can be problematic if you’re hosting a web server, as the DNS Servers will not update as your IP changes, breaking the link to your web server. To address this, there are two alternatives. The first is to use a Dynamic DNS (DDNS) service and use either the FreeNAS DDNS service or your router to keep it updated, or update the DNS servers directly. Free examples of DDNS providers include No-IP, Free DNS and Easy DNS, which may also provide you with a domain – I know that No-IP does. In lieu of buying domain name, the domain provided by the DDNS provider will be sufficient, and this applies to the entirety of the previous instructions that have dealt with domain names. If you already own a domain name that you want to use, you just need to add a CNAME record for the DDNS domain to the DNS record for your domain. As an example, if your DDNS domain is cloud.no-IP.org, you would add a record pointing from cloud.mydomain.com to cloud.no-IP.org. Since this is very specific to each users configuration and registrar etc., I won’t address any more here.

However, I use Route 53, so I’ll discuss how to manually update the IP in your A record for your cloud domain using Route 53 and the AWS command line interface (CLI) tools. For this, you will need your Hosted Zone ID and the Record Set name. Will Warren provides a great guide and bash script that you can use to achieve this.

First, create a new directory called scripts, and a subdirectory for update-route53 in your root directory, i.e:

$ mkdir -p /scripts/update-route53

The -p flag allows you to create both of these directories at once. Now, create the script:

$ nano /scripts/update-route53/update-route53.sh

Copy the following shell script, courtesy of Will Warren, into the file:

#!/usr/local/bin/bash

# (optional) You might need to set your PATH variable at the top here
# depending on how you run this script
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Hosted Zone ID e.g. BJBK35SKMM9OE
ZONEID="enter zone id here"

# The CNAME you want to update e.g. hello.example.com
RECORDSET="enter cname here"

# More advanced options below
# The Time-To-Live of this recordset
TTL=300
# Change this if you want
COMMENT="Auto updating @ `date`"
# Change to AAAA if using an IPv6 address
TYPE="A"

# Get the external IP address from OpenDNS (more reliable than other providers)
IP=`dig +short myip.opendns.com @resolver1.opendns.com`

# Handle for current date
DATE=`date '+%Y-%m-%d %H:%M:%S'`

function valid_ip()
{
    local  ip=$1
    local  stat=1

    if [[ $ip =~ ^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ ]]; then
        OIFS=$IFS
        IFS='.'
        ip=($ip)
        IFS=$OIFS
        [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 
            && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
        stat=$?
    fi
    return $stat
}

# Get current dir
# (from http://stackoverflow.com/a/246128/920350)
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
LOGFILE="/var/log/update-route53.log"
IPFILE="$DIR/update-route53.ip"

if ! valid_ip $IP; then
    echo "$DATE     Invalid IP address: $IP" >> "$LOGFILE"
    exit 1
fi

# Check if the IP has changed
if [ ! -f "$IPFILE" ]
    then
    touch "$IPFILE"
fi

if grep -Fxq "$IP" "$IPFILE"; then
    # code if found
    echo "$DATE     IP is still $IP. Exiting" >> "$LOGFILE"
    exit 0
else
    echo "$DATE     IP has changed to $IP" >> "$LOGFILE"
    # Fill a temp file with valid JSON
    TMPFILE=$(mktemp /tmp/temporary-file.XXXXXXXX)
    cat > ${TMPFILE} << EOF
    {
      "Comment":"$COMMENT",
      "Changes":[
        {
          "Action":"UPSERT",
          "ResourceRecordSet":{
            "ResourceRecords":[
              {
                "Value":"$IP"
              }
            ],
            "Name":"$RECORDSET",
            "Type":"$TYPE",
            "TTL":$TTL
          }
        }
      ]
    }
EOF

    # Update the Hosted Zone record
    aws route53 change-resource-record-sets 
        --hosted-zone-id $ZONEID 
        --change-batch file://"$TMPFILE" >> "$LOGFILE"
    echo "" >> "$LOGFILE"

    # Clean up
    rm $TMPFILE
fi

# All Done - cache the IP address for next time
echo "$IP" > "$IPFILE"

Replace the ZONEID and RECORDSET values with values relevant to your AWS Hosted Zone. This script essentially uses the “dig” command to identify your current IP address, and update the record set for your domain with the return value of this IP address. For this to work, there are a few requirements. First, you need dig installed. FreeBSD does not ship with dig, so you’ll need to install it using the following command:

$ pkg install bind-tools

Secondly, if, like me you route all of your WAN traffic over a VPN, you’ll need to make sure this jail does not route over the VPN. If you don’t, the script will pull the VPN IP and not your WAN IP, which will not direct to your server (unless your VPN provider supports port forwarding; mine doesn’t). Now, you need to add this script as a cron job so it runs every 30 minutes.

$ crontab -e

Add the following line:

*/30 * * * * /scripts/update-route53/update-route53.sh

You will be able to view all of the changes to your ip in the log file that is created by this script at /var/log/update-route53.log.

How much does it cost?

There are a range of free DDNS providers, and so this may be the cheapest option for you if you don’t already have a Route53 Hosted Zone. The Amazon Route 53 Pricing Page indicates that a new hosted zone will cost you $0.50/month. I already have a Route53 hosted zone associated with my domain, so this was no additional cost to me and makes things simpler by not introducing additional services.

AND THAT’S IT! YOU’RE DONE! If everything works correctly, give yourself a pat on the back because this was a pretty involved process. If you’ve noticed any errors with this guide, or if you think certain steps could be improved with more clarity, or you just have some feedback, please leave a comment to let me know.

Updgrading

To upgrade your Nextcloud server, first navigate to the Nextcloud jail shell. From the nextcloud jail shell, issue the following commands:

$ pkg update
$ pkg upgrade nextcloud-php71
$ cd /usr/local/www/nextcloud
$ su -m www -c "php ./occ upgrade"

It’s important that you upgrade in this manner. As tempting as it might be to upgrade using the web interface, the package information will go out of sync if you do. New patches/versions often take a few days after official release to propogate to the FreeBSD pkg repository, so don’t stress if it’s not immediately available.

Debugging

During this process, you may run into errors that I have not addressed. My suggestion is that for your first port of call, check the logs. Here are the locations of some log files.

  1. Nextcloud logs
    /var/log/nextcloud/nextcloud.log
    
  2. Apache logs
    /var/log/httpd-error.log
    

These are the two most likely places an error will be logged. PHP errors will be logged in the apache error log by default. The level of log detail for PHP can be configured in /usr/local/etc/php.ini. The level of log detail for Apache can be configured in /usr/local/etc/apache24/httpd.conf.

Use these logs to idenitfy what the problem with your configuration is. Then, use some keywords from the error to search google and see if anybody else has found a solution to the problem. If you can’t find a solution, or you’re having trouble interpreting the solutions provided, make reference to the “Support” section at the end of this article and ask for help in one of the suggested locations.

From my experience, most of the errors I ran into were with configuring Redis. This manifested as an “Internal Server Error 500” in both instances. In the first instance, Redis was not running and I had not realised. You can check the status of a service using the following command:

$ service <service> status

This will tell you if it is running or not. The second issue I ran into was a permissions issue. I initially had the unixsocketperm flag in /usr/local/etc/redis.conf set to 775, which was causing a “Permission Denied” error for Redis to show in the logs. I suspect this is due to the fact that the ownership for /tmp/redis.sock was redis:wheel, and since the www user was not a member of wheel, it did not have write access. I took a blunt approach to this and set the unixsocketperm flag to 777, which rectified the issue. I attempted to create a group which would allow these permissions to be restricted to 775, however the socket did not retain the group ownership status through a restart of the Redis service. I’m sure there’s a way to do this, but I couldn’t figure it out quickly. If you have the answer to this, leave a comment down below!

Support

There are a number of places you can seek help regarding any issues you might be having with Nextcloud on FreeNAS:

  1. Nextcloud Forums
  2. FreeNAS Forums
  3. Reddit
    1. r/nextcloud
    2. r/freenas
  4. Freenode IRC – server: irc.freenode.net, and the following channels
    • #nextcloud
    • #freenas
    • ##letsencrypt

I’ve found IRC to be a better platform for issues that need to be discussed in some detail, however the communities on the forums and also reddit are typically larger.

   Send article as PDF   

170 thoughts on “How to install NextCloud 14/15 on FreeNAS 11.2 in an iocage jail with hardened security

    1. Unfortunately the overwhelming amount documentation for Nextcloud is for Apache. I’ll consider this as the topic of a future blog post, however these are the broad strokes of what you’ll need to look for in the mean time:

      • Configure php-fpm for nginx
      • Configure nginx to forward port 80 traffic to port 443 for SSL
      • Configure nginx SSL:
        ** Use a modern SSL Protocol, i.e. TLS v1.2
        ** Use a modern SSL CipherSuite
        ** Configure stock .htaccess options in nginx, such as headers to be passed.

      The last part of this is the most verbose, but Nextcloud do provide some documentation to help configure the configuration files

  1. Many thanks for the tutorial. I managed it until the security section where it reads:
    “At this stage, your nextcloud server should be ready to go for local network use. There are, however, a range of security considerations that will be dealt with in the remainder of the guide. These are very important, especially if you intend to open the server to the web.”

    However by trying to access my local nextcloud-ip I constantly get following error message in firefox (chrome dito):
    “The page isn’t redirecting properly
    Firefox has detected that the server is redirecting the request for this address in a way that will never complete.”

    Where could I look for help, a internet search was not successful?

    1. Hi there! At the bottom of the article I list a number of places for support. This isn’t an error I’ve come across, and without more information it will be difficult to help you debug. As a first step, my suggestion would be to go back through the previous steps to make sure everything is configured as it should be. You mention you run into issues at the “Security” section – did you have any issues configuring NC through the web ui? Or have you not been able to navigate to the nextcloud web ui at all? If not, were you able to see the php test page earlier in the steps? How have you configured the ServerName? Are the php-fpm and apache services running? (service apache24 status, service php-fpm status). Try to locate the specific location in the guide where things stop working. As a second step, if double checking your configuration doesn’t yield a solution, I’d suggest asking in the #nextcloud or #freenas IRC channels; you’ll be able to engage in a dialog with someone to help work through your specific problem. This is where I’ve found the most helpful support in solving problems 🙂

  2. I had the same issue as Astmohn. At the “Web Configuration” section I’m able to get to the NextCloud admin page for the initial setup, put in the correct data and click Finish Setup. However this eventually results in the redirection error Astmohn mentions and any further access to the NextCloud URL gets the same.

    My searches turned up configuration issues that were not present in my http.conf (i.e. your instructions properly sets the values that all my research states are the source of this problem). Eventually I grew tired of trying to fix it and destroyed the jail to some day try again from a fresh start.

    I have no doubt that the problem is related to some small issue with the apache configuration but I don’t have much experience with apache or web apps in general. The things that stuck out in my mind:

    You mention you changed the pkg repo to latest branch (though you state it’s optional) and say that you did so to fix a bug. However you never elaborate on what bug you were resolving in this fashion. I suspect this may be part of the problem and intend to change to the latest branch with my next test to see if that’s the case. Would have been nice for at least some elaboration on the bug you are referring to so your readers could make a more informed decision on this step.
    Domain name vs. IP. This one annoys me greatly with NextCloud because they seem to assume you are going to have a legitimate domain name and access your NC server from outside your network. I use a non-real domain name for my home network (lastname.home) to prevent any possible domain collisions and honestly as long as it resolves internally (which it does) then it shouldn’t matter. However NC config seems to dislike the use of a raw IP (I use a fixed IP for all my always-on services) and I wonder if it’s getting hung up on my non-standard domain name.

    Interestingly when I access the NC web interface using the IP it displayed an initial page but then redirects and immediately dies with the redirect error again.

    I’ll be giving your instructions another go here in the future with the latest pkg repo and see if that makes a difference.

    1. Hmm, interesting! Given two of you have had the same issue, I’m going to give the installation another go myself to make sure the instructions are correct. It’s unlikely to be the issue I referenced; that was related to fresh installations of Nextcloud 14.0.1 not including the appropriate configuration for the ‘apps’ field in the config.php file, which was rectified in 14.0.1_1 iirc. Switching to the “latest” branch allowed me to pull 14.0.1_1 instead of 14.0.1. Since we’re on 14.0.4 now, this shouldn’t be a consideration. However, you make a good point so I’ll revise the post to include some discussion of this for troubleshooting purposes.

      With regards to the domain name and IP, you’re exactly right and I do provide this clarification in the article. You can enter any domain for these settings, including the local IP of the jail, provided that your DNS Server can resolve the jail IP. To use your example, lastname.home should work perfectly well if you have a DNS Resolver entry redirecting lastname.home to your jail IP, i.e. 192.168.0.10. In pfSense this can be configured in Services > DNS Resolver > Host Overrides > Add. If you do intend to access it this way, you would need to add lastname.home to your trusted domains as discussed in the article.

      1. Just got bit with the redirect bug too. Chrome, Firefox, Safari

        Did the the step WEB CONFIGURATION then clicked finished setup and boom. Redirect hell

        1. When I nano /usr/local/www/nextcloud/config/config.php
          It is way different than yours

          <?php
          $CONFIG = array (
          ‘instanceid’ => ‘redacted’,
          ‘passwordsalt’ => ‘redacted’,
          ‘secret’ => ‘redacted/’,
          ‘trusted_domains’ =>
          array (
          0 => ‘redacted’,
          ),
          ‘datadirectory’ => ‘/mnt/data’,
          ‘dbtype’ => ‘mysql’,
          ‘version’ => ‘15.0.0.10’,
          ‘overwrite.cli.url’ => ‘redacted,
          ‘dbname’ => ‘nextcloud’,
          ‘dbhost’ => ‘localhost:/tmp/mysql.sock’,
          ‘dbport’ => ”,
          ‘dbtableprefix’ => ‘oc_’,
          ‘mysql.utf8mb4’ => true,
          ‘dbuser’ => ‘nextcloud_admin’,
          ‘dbpassword’ => ‘redacted’,
          ‘installed’ => true,
          );

          1. Huh. That’s interesting. I’m guessing since you’re using Nextcloud 15.0.0, you’re on the quarterly branch (latest is at 15.0.5), which means that the issues I discuss above with respect to 14.0.1 aren’t fixed by a version upgrade. This must mean that it’s more specific to brnrd’s release than Nextcloud. To fix it, you have two options.

            1. Start the installation again (nuke the jail and remake it), but this time switch to the latest branch (can confirm this has worked for me many times), OR
            2. You could try to repair this installation by adding the following to your config.php file:
              'apps_paths' =>
              array (
                0 =>
                array (
                  'path' => '/usr/local/www/nextcloud/apps',
                  'url' => '/apps',
                  'writable' => true,
                ),
                1 =>
                array (
                  'path' => '/usr/local/www/nextcloud/apps-pkg',
                  'url' => '/apps-pkg',
                  'writable' => false,
                ),
              ),
            

            This should go BELOW

            <?php
             $CONFIG = array (
            

            and ABOVE

            ‘instanceid’ => ‘redacted’,
            

            Once you’ve done this, restart Apache and see if this fixes it (service apache24 restart). If it doesn’t, I’m not sure what the fix is. You could try debugging this yourself (a good place to start would be looking at the revisions to 14.0.1) or asking in the #freebsd (for freebsd pkg’s) or #httpd (for apache server) IRC channels. I’d suggest it might just be simpler to install from the latest branch though, rather than quarterly.

          2. Scratch what I’ve said; It’s not caused by the quarterly branch package. I’ve just been through a fresh install and I haven’t been able to reproduce your issues. I tested with both nextcloud-php71 and nextcloud-php72, both of which worked fine using the steps I’ve provided. Which nextcloud distribution did you install? Did you skip any steps? Also, where are your redirects trying to redirect to? In Firefox right click > Inspect element > Network tab. With this new window open, navigate to your nextcloud jail ip, and observe the file path in the “File” column

          3. Which nextcloud distribution did you install?
            — nextcloud-php72

            Did you skip any steps?
            — No but did have to use mkdir to make the fstab section to work. On a fresh install mnt/data, …/mysql, config, themes, are not created.

            I am going to start over, take everything I learned and try again this afternoon.

            Freenas version FreeNAS-11.2-U2.1

          4. Fresh Start with php 71 same redirect issue after finish setup.

            Redirect file:
            /index.php/apps/files

          5. Yet again I was missing stuff in the config so I did the ” You could try to repair this installation by adding the following to your config.php file:”
            Which fixed the redirect but gave me this error
            Internal Server Error

            The server was unable to complete your request.

            If this happens again, please send the technical details below to the server administrator.

            More details can be found in the server log.Internal Server Error

            The server was unable to complete your request.

            If this happens again, please send the technical details below to the server administrator.

            More details can be found in the server log.

            httpd-error.log
            [Thu Mar 21 12:55:44.801257 2019] [mpm_prefork:notice] [pid 73653] AH00163: Apache/2.4.38 (FreeBSD) configured — resuming normal operations
            [Thu Mar 21 12:55:44.802019 2019] [core:notice] [pid 73653] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’
            [Thu Mar 21 13:15:56.199095 2019] [mpm_prefork:notice] [pid 73653] AH00171: Graceful restart requested, doing restart
            AH00558: httpd: Could not reliably determine the server’s fully qualified domain name, using 127.0.0.1. Set the ‘ServerName’ directive globally to suppress this message
            [Thu Mar 21 13:15:56.207272 2019] [mpm_prefork:notice] [pid 73653] AH00163: Apache/2.4.38 (FreeBSD) configured — resuming normal operations
            [Thu Mar 21 13:15:56.207293 2019] [core:notice] [pid 73653] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’
            [Thu Mar 21 13:27:24.130109 2019] [mpm_prefork:notice] [pid 73653] AH00169: caught SIGTERM, shutting down
            [Thu Mar 21 13:27:24.254491 2019] [mpm_prefork:notice] [pid 80260] AH00163: Apache/2.4.38 (FreeBSD) configured — resuming normal operations
            [Thu Mar 21 13:27:24.254944 2019] [core:notice] [pid 80260] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’
            [Thu Mar 21 13:35:23.695450 2019] [mpm_prefork:notice] [pid 80260] AH00169: caught SIGTERM, shutting down
            [Thu Mar 21 13:35:23.838368 2019] [mpm_prefork:notice] [pid 82076] AH00163: Apache/2.4.38 (FreeBSD) configured — resuming normal operations
            [Thu Mar 21 13:35:23.838802 2019] [core:notice] [pid 82076] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’

          6. The apache log doesn’t show anything of much use. Can you look at the contents of the nextcloud log to see if there’s anything there? it’s at /var/log/nextcloud/nextcloud.log. Also, when posting code, it formats much more nicely if you begin and end it with a triple back tick; ```

          7. /var/log/nextcloud/nextcloud.log.

            No log found in that location

            Should service httpd be running?
            service httpd status
            —httpd does not exist in /etc/rc.d or the local startup
            directories (/usr/local/etc/rc.d), or is not executable

          8. the httpd service is apache24. Try locating the nextcloud log: locate nextcloud.log; this should return the path where this file exists. If it doesn’t exist it will return blank to a new line.

    2. Okay, so I just went through the guide again and surprisingly, it looks like 14.0.1 is still the current version in the quarterly branch so you were right, this was the issue. Switching to the latest branch resolves what you were experiencing. Incidentally, the latest branch is 15.0.0, and so I have made a couple of minor adjustments to ensure compatibility. I’ve tested the guide for 15.0.0, and everything seems to be working as expected. Pay special attention when it comes to configuring the nextcloud config.php file for use with Redis/APCu; this has been the main cause of the issues I’ve run into so far.

  3. First of all I would like to say thank you for creating this details guide !
    I’m very new to all this stuff especially with the all the command. So please help!!
    My question is: in the add storage to iocage jail section. What should I be entering for this specific command line (assuming I adopted the structure you used when creating all the datasets
    iocage fstab -a jailname source_location destination_location nullfs (rw/ro) 0 0
    would it be something like this:
    iocage fstab -a nextcloud mnt/vault/cloud mnt/jailhouse/apps/nextcloud nullfs (rw/ro) 0 0

    Also, is there any way that you could contact you directly because I know for sure I will be needing a lot help in the future. Thank you so much !!!

    1. Hi there! If you’ve adopted the directory structure I use, I provide the exact commands you need to use immediately before the command you’ve just provided me. The commands you need to use are:

      $ iocage fstab -a nextcloud /mnt/vault/cloud /mnt/data nullfs rw 0 0
      $ iocage fstab -a nextcloud /mnt/jailhouse/apps/nextcloud/db /var/db/mysql nullfs rw 0 0
      $ iocage fstab -a nextcloud /mnt/jailhouse/apps/nextcloud/config /usr/local/www/nextcloud/config nullfs rw 0 0
      $ iocage fstab -a nextcloud /mnt/jailhouse/apps/nextcloud/themes /usr/local/www/nextcloud/themes nullfs rw 0 0

      With regards to what you’ve proposed: iocage fstab -a nextcloud mnt/vault/cloud mnt/jailhouse/apps/nextcloud nullfs (rw/ro) 0 0

      You’re almost there, but not quite. With this, you’ve specified:
      – source_location: mnt/vault/cloud
      – destination_location: mnt/jailhouse/apps/nextcloud

      The source location is good, that’s what you would want to specify, but the destination location is wrong. This is because inside the jail, there is no directory /mnt/jailhouse/apps/nextcloud (this is the path on your FreeNAS host! Outside the jail!)

      What we want to do is specify a location within the jail, to make the content inside /mnt/vault/cloud available. In the commands I’ve provided above, this location within the jail would be /mnt/data (this will automatically be created). Hope this helps!

      With regards to direct contact, either here or the corresponding FreeNAS forum post are the best places to contact me for support for this guide. The benefit of using the FreeNAS Forums is that other people also might be able to provide support where I’m slow to reply.

      Hope this helps!

      1. “I’ve provided above, this location within the jail would be /mnt/data (this will automatically be created”

        I have had mostly success starting this guide but I have noticed the /mnt/data on my system was not automatically created. I was wondering how do I create it?

        1. It’s created within your jail environment if you’ve used the fstab entries that I’ve specified. If you’re not within the jail, you won’t see it at /mnt/data. From the host, it would be located at /mnt/iocage/jails/nextcloud/root/mnt/data/

          1. When I run the fstab I get this message “Destination: /mnt/jailhouse/iocage/jails/nextcloud/root/mnt/data does not exist!”

          2. Okay, time to start troubleshooting then. This shouldn’t happen. I suppose an easy fix to that immediate problem would be to create the directory from your host by executing mkdir /mnt/jailhouse/iocage/jails/nextcloud/root/mnt/data, or just mkdir /mnt/data from within the jail. This might fix the issue; if it doesn’t it indicates that something bigger is going on with your fstab entries. Run iocage list to make sure that nextcloud shows up, and that its status is online.

            Following this, it would be prudent to confirm that your fstab entry is actually correct. Run iocage fstab -l nextcloud from your freenas host, and paste the output here. It should look like the following:

            root@freenas:~ # iocage fstab -l nextcloud
            +-------+--------------------------------------------------------------------------------------------------------------------+
            | INDEX |                                                    FSTAB ENTRY                                                     |
            +=======+====================================================================================================================+
            | 0     | /mnt/vault/cloud /mnt/iocage/jails/nextcloud/root/mnt/data nullfs rw 0 0                                           |
            +-------+--------------------------------------------------------------------------------------------------------------------+
            | 1     | /mnt/jailhouse/apps/nextcloud/db /mnt/iocage/jails/nextcloud/root/var/db/mysql nullfs rw 0 0                       |
            +-------+--------------------------------------------------------------------------------------------------------------------+
            | 2     | /mnt/jailhouse/apps/nextcloud/config /mnt/iocage/jails/nextcloud/root/usr/local/www/nextcloud/config nullfs rw 0 0 |
            +-------+--------------------------------------------------------------------------------------------------------------------+
            | 3     | /mnt/jailhouse/apps/nextcloud/themes /mnt/iocage/jails/nextcloud/root/usr/local/www/nextcloud/themes nullfs rw 0 0 |
            +-------+--------------------------------------------------------------------------------------------------------------------+
            
            
          3. The mkdir worked allowed me to finish my fstab
            Thanks !

            +——-+——————————————————————————————————————————+
            | INDEX | FSTAB ENTRY |
            +=======+==============================================================================================================================+
            | 0 | /mnt/jailhouse/apps/nextcloud/db /mnt/jailhouse/iocage/jails/nextcloud/root/var/db/mysql nullfs rw 0 0 |
            +——-+——————————————————————————————————————————+
            | 1 | /mnt/jailhouse/apps/nextcloud/config /mnt/jailhouse/iocage/jails/nextcloud/root/usr/local/www/nextcloud/config nullfs rw 0 0 |
            +——-+——————————————————————————————————————————+
            | 2 | /mnt/jailhouse/apps/nextcloud/themes /mnt/jailhouse/iocage/jails/nextcloud/root/usr/local/www/nextcloud/themes nullfs rw 0 0 |
            +——-+——————————————————————————————————————————+
            | 3 | /mnt/digital-documents/cloud /mnt/jailhouse/iocage/jails/nextcloud/root/mnt/data nullfs rw 0 0 |
            +——-+——————————————————————————————————————————+

  4. Hi,
    I recently upgraded my FreeNAS to 11.2, which broke my Nextcloud so that SMB external storages no longer seem to work. If I follow this guide, will that installation include SMB support?
    If not, do you know of a way to get it working?

    1. Hi Andreas, Unfortunately not. All of my storage is local to my FreeNAS host, so this wasn’t something I had to explore. Having said that, it appears that this is additional configuration after the setup process, not something that needs to be established during the traditional setup procedure. My advice would be to refer to the documentation regarding the configuration; after a brief look, it seems to be relatively descriptive. You can view the documentation here: SMB/CIFS, Configuring External Storage. Good luck!

  5. Thanks for your reply. I just installed NC 15 following your guide. That worked very well, thank you so very much for a well written guide. It´s now among my bookmarks 🙂
    I am having one problem left to solve, and I thought I´d ask you if maybe you have seen it before or can understand what is happening.

    It´s the configuration of postfix. I can´t get it to work. I´ve been over the steps a dozen times, and I can´t find anything wrong.

    I´m trying to send an email from nc@domain.com to user@domain.com using tls and port 587. The only place I´ve entered the sender email address is as username in /usr/local/etc/postfix/sasl_passwd.

    When sending the test email I get this error:
    Username nc@domain.comand sender root@nextcloud.localdomain doesnt match (in reply to MAIL FROM command)).
    Why is it using root@nexcloud.localdomain as sender? Am I supposed to change the sender address somewhere other than /usr/local/etc/postfix/sasl_passwd?

  6. Nevermind. it worked once i set everything up in Settings in the GUI. I was so focused on the terminal it didn´t appear to me until now.
    Thanks again!

  7. THIS is brilliant!
    This is the best guide I have seen on iocage/nextcloud.
    Not only does it work flawlessly (I installed nextcloud 15 using PHP7.2) but the security bit is invaluable.

    Thanks a lot for this!

  8. Hi again.
    I have a new question. Why is it necessary to do upgrades via console instead of the web based one? What will break if I use the web based one instead?
    I never updated pkg to tha latest branch, if that matters…

    1. Hi Andreas,

      It’s more a semantic thing than anything else. If you install with the package manager, you should keep it maintained with the package manager. I have experimented with web updates, and the minor update I tested on appeared to work, but the package manager went out of sync and didn’t receive any new information about the update. You’re welcome to try, but be aware you may run into issues down the road. That’s not to say that upgrading via the console is a walk in the park either; I seem to run into issues every time I do that as well. It doesn’t seem to be a polished process in either case. An alternative to what I’ve presented in this guide is to not use FreeBSD ports, or the package manager pkg, and just download Nextcloud from their website directly. I would imagine that you would use the web updater to stay up to date this way, but it wasn’t the path I took so I can’t provide any specific advice.

      Not switching to the latest branch shouldn’t impact you at all (i.e. staying on quarterly, provided you’re not running 14.0.1 as discussed in the guide) except to say that obviously you’re not going to receive updates as quickly. Quarterly in fact. if you want to switch to the latest branch you can follow the instructions I provide at any stage and then run the upgrade commands. At the moment the pkg repo is at 15.0.0, and I’m expecting 15.0.1 or 15.0.2 in the next few days.

      Cheers.

  9. This has got to be one of the most comprehensive install guide that I have read. Will definitely be giving it a go over the weekend. Thank you for sharing….

  10. I rarely comment on blogs but i wanted to say that i really appreciate the effort and detail you put into this guide! It fit my exact scenario and allowed me to quickly rebuild my Nextcloud instance better than it was before! i especially appreciate the explanations as to why the commands are being ran. A very helpful guide!!

  11. This install guide is by far the best I was able to find to install Nextcloud on FreeNAS in a jail.
    There are only two errors /informations I cannot fix.
    Nextcloud complains that the webserver is not configured correctly to be able to resolve “/.well-known/caldav” and “/.well-known/carddav”.
    I know the document root is not the apache default.
    The documentation I followed is this https://docs.nextcloud.com/server/15/admin_manual/issues/general_troubleshooting.html#service-discovery
    I tried to patch the .htaccess in the nextcloud directory as described but this did not work.

    It would be great if you could help me and maybe you it is woth to extend the guide in this point.

    Many thanks especially for this very helpful guide

    1. Hi Michael, from memory the CalDAV and CardDAV settings to suppress the warnings you’re getting are indeed contained within the .htaccess file that ships with Nextcloud by default. If my recollection is correct, then this means that something you’ve done is interfering with this. In my guide, I specify setting the AllowOverride directive to ‘all’, i.e. “AllowOverride all”, which should allow apache to use the .htaccess file – did you do this? If not, do this and see if that resolves your issue. If it doesn’t, then, did you use a virtual host entry from another site? Some of the examples I’ve seen have “AllowOverride None” in them, which will override the change in httpd.conf. Also, have you made sure that all of the paths are correct and pointing to the Nextcloud webroot (/usr/local/www/nextcloud)? As far as the guide goes, I’ve confirmed that the steps work to enable the .htaccess file a number of times, so I’d suggest you go back through the steps to make sure you haven’t missed anything.

      Cheers

  12. Awesome guide, thanks. I’ve configured postfix per your instructions and rechecked it, however I’m getting the following errors when running # echo “Test Email Contents” | mail -s “Postfix Test Email” johndoe@gmail.com

    Do you have any idea if I’m missing something?

    Jan 29 17:51:22 nextcloud postfix/pickup[34700]: 6BB70221A3: uid=0 from=
    Jan 29 17:51:22 nextcloud postfix/cleanup[39094]: 6BB70221A3: message-id=20190130016722.6BB70221A3@nextcloud.localdomain
    Jan 29 17:51:22 nextcloud postfix/qmgr[34701]: 6BB70221A3: from=root@nextcloud.localdomain, size=362, nrcpt=1 (queue active)
    Jan 29 17:51:22 nextcloud postfix/smtp[39096]: 6BB70221A3: SASL authentication failed; server smtp.gmail.com[74.125.20.109] said: 535-5.7.8 Username and Password not accepted. Le$
    Jan 29 17:51:23 nextcloud postfix/smtp[39096]: 6BB70221A3: to=johndoe@gmail.com, relay=smtp.gmail.com[74.125.20.108]:587, delay=0.86, delays=0.06/0.02/0.78/0, dsn$

    It looks like its trying to send from root@nextcloud.localdomain instead of the user name in /usr/local/etc/postfix/sasl_passwd

    What am I missing

    1. Hi Edmond, reading through the log snippet you’ve posted, it says “SASL authentication failed; server smtp.gmail.com[74.125.20.109] said: 535-5.7.8 Username and Password not accepted”. It seems like you’re getting a response from the gmail smtp server telling you that you’ve put in an incorrect username and password. No need to worry about the root@nextcloud.localdomain, this is just your local user and jail host name. If you enter in a valid username/password combination you should be good to go. Cheers.

      1. Hello Samuel! This is an amazing tutorial. I too am having the same issue with the SASL authentication failed. I’ve doubled checked the username and password. All are good. I’ve tried it with using less secure apps and with an app specific password. Still no luck. How can I troubleshoot?

        1. Hi Phil, honestly I’ve never run into this issue before so I’m not able to provide you with a solution unfortunately. It doesn’t seem to be specific to Nextcloud or FreeBSD, but perhaps it is specific to postfix and gmail. This thread seems to indicate that the log may provide you with a link that provides more detail about the problem with the authentication (I can see that this is present in Edmonds log snippet, but is truncated by the text editor – see the Username and Password not accepted. Le$; here $ means that there’s more to the line). Unfortunately it seems that you’ve tried the solutions presented in the linked thread, but my suggestion would be to have a look through var/log/maillog to see what errors postfix is giving you, and explore solutions to those errors individually. If you can find the Learn more at 530 5.5.1 https://support.google.com/mail/?p=WantAuthError statement, perhaps it would be worth going to this link and seeing what description it gives you of the error messages. At the end of the article, I provide a few places that you can go for more detailed support. As an example, the #postfix IRC channel has a population of 317 at the time of writing; here would be a good place to start asking questions. IRC is where I go for support with issues like these; the people there are typically very knowledgable, and some are willing to help work through a problem.

          Edit: Have you made sure to re-run $ postmap /usr/local/etc/postfix/sasl_passwd after changing your credentials? It’s critical that you do this; it re-creates sasl_passwd.db, which is how the credentials are read by postfix.

          1. Thanks Samuel. Still working on the email piece, but I have everything else working. Fantastic guide! I can’t thank you enough for all of the effort you put into this.

  13. I ran through this tutorial using NextCloud 15 on FreeNAS 11.2-RELEASE-U1. The only things I deviate from were I created the jail using the gui in FreeNAS, I created the storage locations manually via the zfs command, and I used DHCP for the jail IP because I use DHCP reservations on my network instead of static IPs. For DNS, I used ddns.net with a CNAME from my own domain. The letsencrypt test command works if your server is accessible over HTTP first by its DNS name before you try to get the certificate.

    Thanks for a great howt0.

    1. Nice one! I’m glad you could deviate from what I presented, adjust it for your needs and get it working. Cheers 🙂

  14. Thank you very much for this. I went through multiple tutorials and this has been the most educational and least frustrating. You explained everything very clearly.

    Cheers Mate

  15. Excellent post! I used this to migrate my Nextcloud from a Raspberry Pi to a FreeNAS jail.

    Just one question. I found periodic.conf in /etc/defaults/
    Should I modify the one in there?

    1. Hi Andrew, no you don’t want to modify /etc/defaults/periodic.conf. This is the system default as per hier(7) and isn’t intended to be modified. You just want to create a new one in /etc/, i.e. /etc/periodic.conf. Hope this helps.

  16. Been working great. This machine is just a practice run for me to learn on. I don’t have a UPS for this machine. I had a brief power failure. Freenas boots ok, nextcloud wont start up. What steps do i need to take to troubleshoot? This is the error message that popped up when I tried to start nextcloud from the jails interface in Freenas:

    Error: concurrent.futures.process._RemoteTraceback:
    “””
    Traceback (most recent call last):
    File “/usr/local/lib/python3.6/concurrent/futures/process.py”, line 175, in _process_worker
    r = call_item.fn(*call_item.args, **call_item.kwargs)
    File “/usr/local/lib/python3.6/site-packages/middlewared/worker.py”, line 128, in main_worker
    res = loop.run_until_complete(coro)
    File “/usr/local/lib/python3.6/asyncio/base_events.py”, line 468, in run_until_complete
    return future.result()
    File “/usr/local/lib/python3.6/site-packages/middlewared/worker.py”, line 88, in _run
    return await self._call(f'{service_name}.{method}’, serviceobj, methodobj, params=args, job=job)
    File “/usr/local/lib/python3.6/site-packages/middlewared/worker.py”, line 81, in _call
    return methodobj(*params)
    File “/usr/local/lib/python3.6/site-packages/middlewared/worker.py”, line 81, in _call
    return methodobj(*params)
    File “/usr/local/lib/python3.6/site-packages/middlewared/schema.py”, line 668, in nf
    return f(*args, **kwargs)
    File “/usr/local/lib/python3.6/site-packages/middlewared/plugins/jail.py”, line 542, in start
    iocage.start()
    File “/usr/local/lib/python3.6/site-packages/iocage_lib/iocage.py”, line 1654, in start
    callback=self.callback
    File “/usr/local/lib/python3.6/site-packages/iocage_lib/ioc_start.py”, line 66, in __init__
    self.__start_jail__()
    File “/usr/local/lib/python3.6/site-packages/iocage_lib/ioc_start.py”, line 391, in __start_jail__
    silent=self.silent)
    File “/usr/local/lib/python3.6/site-packages/iocage_lib/ioc_common.py”, line 81, in logit
    _callback(content, exception)
    File “/usr/local/lib/python3.6/site-packages/iocage_lib/ioc_common.py”, line 64, in callback
    raise callback_exception(message)
    RuntimeError: mount_nullfs: /mnt/vault: No such file or directory
    jail: /sbin/mount -t nullfs -o rw /mnt/vault/cloud /mnt/Vault/iocage/jails/nextcloud/root/mnt/data: failed

    “””

    The above exception was the direct cause of the following exception:

    Traceback (most recent call last):
    File “/usr/local/lib/python3.6/site-packages/middlewared/main.py”, line 161, in call_method
    result = await self.middleware.call_method(self, message)
    File “/usr/local/lib/python3.6/site-packages/middlewared/main.py”, line 1109, in call_method
    return await self._call(message[‘method’], serviceobj, methodobj, params, app=app, io_thread=False)
    File “/usr/local/lib/python3.6/site-packages/middlewared/main.py”, line 1046, in _call
    return await self._call_worker(serviceobj, name, *args)
    File “/usr/local/lib/python3.6/site-packages/middlewared/main.py”, line 1073, in _call_worker
    job,
    File “/usr/local/lib/python3.6/site-packages/middlewared/main.py”, line 1004, in run_in_proc
    return await self.run_in_executor(self.__procpool, method, *args, **kwargs)
    File “/usr/local/lib/python3.6/site-packages/middlewared/main.py”, line 989, in run_in_executor
    return await loop.run_in_executor(pool, functools.partial(method, *args, **kwargs))
    RuntimeError: mount_nullfs: /mnt/vault: No such file or directory
    jail: /sbin/mount -t nullfs -o rw /mnt/vault/cloud /mnt/Vault/iocage/jails/nextcloud/root/mnt/data: failed

    1. Hi Phil,

      Looking at the Tracebacks you’ve provided it looks like fstab can’t find the dataset’s you’ve specified, so when it tries to mount your host dataset into the jail it’s throwing an error. Specifically, the cause of your issue is the line
      RuntimeError: mount_nullfs: /mnt/vault: No such file or directory.
      I’ve noticed that the last line in each traceback;
      jail: /sbin/mount -t nullfs -o rw /mnt/vault/cloud /mnt/Vault/iocage/jails/nextcloud/root/mnt/data: failed
      has two different dataset names. For the first path specification you’ve used /mnt/vault, and the second you’ve used /mnt/Vault. Is it possible you forgot to capitalise the “V” in “Vault” for the first path in your fstab entry for this mount? You can edit this by running the following commands from your FreeNAS hosts shell:
      $ setenv EDITOR nano
      $ iocage fstab -e nextcloud
      Then make the appropriate changes. My guess (you might have to adapt this for your actual circumstances) is that the entry should look like this:
      /mnt/Vault/cloud /mnt/Vault/iocage/jails/nextcloud/root/mnt/data nullfs rw 0 0
      Hope this helps!

      1. Hello Samuel!
        Thank you for responding and helping. I admit I am a newbie here. I understand very little. I made the changes you mentioned. You are correct. The one mistake I did make is using the capital V when I created the pool. I did make those changes. It looks like I have a deadlock error. What might cause that?

        Error: concurrent.futures.process._RemoteTraceback:
        “””
        Traceback (most recent call last):
        File “/usr/local/lib/python3.6/concurrent/futures/process.py”, line 175, in _process_worker
        r = call_item.fn(*call_item.args, **call_item.kwargs)
        File “/usr/local/lib/python3.6/site-packages/middlewared/worker.py”, line 128, in main_worker
        res = loop.run_until_complete(coro)
        File “/usr/local/lib/python3.6/asyncio/base_events.py”, line 468, in run_until_complete
        return future.result()
        File “/usr/local/lib/python3.6/site-packages/middlewared/worker.py”, line 88, in _run
        return await self._call(f'{service_name}.{method}’, serviceobj, methodobj, params=args, job=job)
        File “/usr/local/lib/python3.6/site-packages/middlewared/worker.py”, line 81, in _call
        return methodobj(*params)
        File “/usr/local/lib/python3.6/site-packages/middlewared/worker.py”, line 81, in _call
        return methodobj(*params)
        File “/usr/local/lib/python3.6/site-packages/middlewared/schema.py”, line 668, in nf
        return f(*args, **kwargs)
        File “/usr/local/lib/python3.6/site-packages/middlewared/plugins/jail.py”, line 542, in start
        iocage.start()
        File “/usr/local/lib/python3.6/site-packages/iocage_lib/iocage.py”, line 1654, in start
        callback=self.callback
        File “/usr/local/lib/python3.6/site-packages/iocage_lib/ioc_start.py”, line 66, in __init__
        self.__start_jail__()
        File “/usr/local/lib/python3.6/site-packages/iocage_lib/ioc_start.py”, line 391, in __start_jail__
        silent=self.silent)
        File “/usr/local/lib/python3.6/site-packages/iocage_lib/ioc_common.py”, line 81, in logit
        _callback(content, exception)
        File “/usr/local/lib/python3.6/site-packages/iocage_lib/ioc_common.py”, line 64, in callback
        raise callback_exception(message)
        RuntimeError: mount_nullfs: /mnt/Vault/iocage/jails/nextcloud/root/mnt/data: Resource deadlock avoided
        jail: /sbin/mount -t nullfs -o rw /mnt/Vault/cloud /mnt/Vault/iocage/jails/nextcloud/root/mnt/data: failed

        “””

        The above exception was the direct cause of the following exception:

        Traceback (most recent call last):
        File “/usr/local/lib/python3.6/site-packages/middlewared/main.py”, line 161, in call_method
        result = await self.middleware.call_method(self, message)
        File “/usr/local/lib/python3.6/site-packages/middlewared/main.py”, line 1109, in call_method
        return await self._call(message[‘method’], serviceobj, methodobj, params, app=app, io_thread=False)
        File “/usr/local/lib/python3.6/site-packages/middlewared/main.py”, line 1046, in _call
        return await self._call_worker(serviceobj, name, *args)
        File “/usr/local/lib/python3.6/site-packages/middlewared/main.py”, line 1073, in _call_worker
        job,
        File “/usr/local/lib/python3.6/site-packages/middlewared/main.py”, line 1004, in run_in_proc
        return await self.run_in_executor(self.__procpool, method, *args, **kwargs)
        File “/usr/local/lib/python3.6/site-packages/middlewared/main.py”, line 989, in run_in_executor
        return await loop.run_in_executor(pool, functools.partial(method, *args, **kwargs))
        RuntimeError: mount_nullfs: /mnt/Vault/iocage/jails/nextcloud/root/mnt/data: Resource deadlock avoided
        jail: /sbin/mount -t nullfs -o rw /mnt/Vault/cloud /mnt/Vault/iocage/jails/nextcloud/root/mnt/data: failed

        1. Phil, this is difficult for me to debug because I don’t have all the details about your system that would require me to help. On the face of it, this error is caused by “nullfs avoiding a deadlock of the system by doing a duplicate mount”. One possible cause for this would be trying to mount the same directory twice; did you replace the existing fstab entry with what I suggested, or just add it to what was already there?

          In tackling these problems in the future, often the easiest way is just to google the error message you’re getting. In this case the error you’re interested in is indicated by the line beginning with RuntimeError. Simply analysing this line and googling “Resource deadlock avoided FreeNAS” provided a number of links that indicated what the problem may be. That’s all I’m doing! Also, as I’ve mentioned in the blog post, the #freenas IRC channel is immensely helpful for these kinds of questions – people are able to help debug in real time, and are much more knowledgeable than I am 🙂

          I suspect that this is an issue with the fstab file, and it’s entries. If worst comes to worst, you could just delete the contents of this file (using iocage fstab -e nextcloud as discussed before), and go over the section of the guide addressing the construction of these mounts again, paying special attention to the differences in naming conventions between your configuration and mine. You may also need to reboot your system to free any locked resources, or manually unmount the rogue entry. I would suggest a reboot is the simpler way to go though.

          1. Hello Samuel! Thank you for all of the help. I ended up doing a clean install of FreeNas and ran through your tutorial again. All is well! Scored well on the test sites. Amazing tutorial! Thank you!

  17. Hi Samuel,

    Fantastic guide and very nice work! I installed on my freenas machine in a jail without problem and got A+ security rating from the nextcloud scan.

    I’m wondering if you have any tips or recommendation on how I can use a reverse proxy jail to put nextcloud behind one. I asking mainly about changing my current configuration of the nextcloud jail so it works with a reverse proxy.

    1. Hi Magnus, Unfortunately, I’ve never set up a reverse proxy jail so no advice to give. I did find this thread on the FreeNAS forums that might be helpful though 🙂 Hope it helps, good luck! Cheers

  18. Hi Samuel. Just a quick question. I’d like to reboot my server, any potential issues I need to look out for while I do this?

    1. Nope! It’s probably a good idea to reboot to identify any misconfigurations you may have (if you have them) anyway 🙂

  19. Hi Samuel

    Great guide by the way. I must have taken forever to write it up. I not sure I would have had the patience, however thanks.

    That said I’d like to touch on a few points since it took me about 2 whole days to set some things up that are a little different than yours. I’m on FreeNAS 11.2

    I installed nextcloud-php72 and can say that everything is working. I didn’t try nextcloud-php73
    I really enjoyed the way you described your dataset layout. In your guide when you mounted the respective directories in the jail, I just wanted to let you know this can be done also within the FreeNAS GUI. I’m not much of a GUI guy however when directories are manually mounted on the command line, they never show within the FreeNAS GUI. It’s helpful months later to go back to the GUI and see what directories are mounted since I usually forget the command line statements. I’m specifically referring to the iocage fstab portion of the guide
    Mysql — arg!!! How many times can I say I messed this portion up after forgetting the passwords. Not to fear however, this process can totally be undone. This isn’t the only command so I would suggest the user may want to google however
    mysql -e “drop database nextcloud” -p
    will drop the entire database table for nextcloud. The following statement will also drop the nextcloud_admin user from the database
    DROP USER ‘nextcloud_admin’@’localhost’
    If you totally forget the root password to the mysql database (yep did that to,) it can be reset as well. I’d refer to the bottom section of this link of google the process. There is a lot of tutorials:
    https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html
    redis — Yikes – Major stumbling block here. I had to chown a few of the files and change attributes. I pick this up through tail -f /var/log/nextcloud
    chown redis:wheel /tmp/redis.sock
    chmod 777 /tmp/redis.sock
    chown redis:wheel /usr/local/etc/redis.conf
    chmod 777 /usr/local/etc/redis.con
    sudo service redis restart
    — Side note to all users. Watching log files are unfortunately a necessary evil when installing these things because things break. What I like to do is pop open at least 2 terminal windows and either use ssh or the jail exec (Jail#) bash to login to the jail. Within one terminal window you can enter the commands as set in this guide. Within either the 1 or 2 additional terminal windows I use the command tail -f which puts the realtime output onto the screen. Its really helpful.
    Note on my directory structure. The guide is written so the principle domain name is linked to nextcloud. In my particular installation, I didn’t want my website to be served like this. Using the domain name mydomain.com as an example, I wanted http://www.mydomain.com and mydomain.com to be linked to the “main” website, and nextcloud.mydomain.com to actually be linked to the nextcloud installation. I took me a while to figure this one out, however its totally possible to do this.
    Within /usr/local/www there is a nextcloud directory which will serve as the DocumentRoot for nextcloud.mydomain.com
    Also within /usr/local/www I created a subdirectory called main which will serve as the DocumentRoot for http://www.mydomain.com (and mydomain.com).
    Within the /usr/local/etc/apache24/Includes directory, I needed to actually create two files nextcloud.mydomain.com.conf and mydomain.com.conf. I pretty much followed all of your statements but had to make the following changes to get things to work:
    Within the mydomain.com.conf – change if to something like this (assuming SSL is installed):

    ServerName http://www.mydomain.com
    ServerAlias mydomain.com

    DocumentRoot “/usr/local/www/main”

    Redirect permanent / https://www.mydomain.com/

    ServerAdmin @.com
    ServerName http://www.mydomain.com
    ServerAlias mydomain.com
    DocumentRoot /usr/local/www/main #<—-Notice the directory — this can be changed to the directory or directory mount that holds the main website files
    …… <—————————- This means include all the other stuff after these statements

    Within the nextcloud.mydomain.com.conf file I did something like:

    ServerName nextcloud.mydomain.com

    DocumentRoot “/usr/local/www/nextcloud”

    Redirect permanent / https://nextcloud.mydomain.com/

    ServerAdmin @.com
    ServerName nextcloud.mydomain.com
    DocumentRoot /usr/local/www/nextcloud #<—–Notice the directory for this subdomain
    …….. <——-Put all other config statements here

    I wanted to touch on the LetsEncrypt section. Another very painful step. I wasn’t using Amazon or any DNS resolver so this section wasn’t working for me. Some tips however. Personally I bought a domain name and have it registered with noip.com. I have the following domains — http://www.mydomain.com, mydomain.com and nextcloud.mydomain.com. The all resolve however to the same IP address since I’m running a home server on FreeNAS. I’m using the FreeNas DynamicDNS client to update these domains. I had a previous old webserver which I set up LetsEncrypt certs and I copied the entire directory to /usr/local/etc/letsencrypt. Just to be sure that within this directory there are subdirectories called accounts, archive, csr, keys, live, renewal, renewal-hooks. Whether you are copying the certs or creating them from scratch you need to also however create a couple of subdirectories for either the activation or renewal process to work. (This is probably why you mentioned the process didn’t work for you).

    Within /usr/local/www/main (If you have this directory structure you have to do this):
    mkdir -p /usr/local/www/main/.well-known
    mkdir -p /usr/local/www/main/.well-known/acme-challenge
    chown -R www:www /usr/local/www/main

    Within /usr/local/www/nextcloud:
    mkdir -p /usr/local/www/nextcloud/.well-known
    mkdir -p /usr/local/www/nextcloud/.well-known/acme-challenge
    chown -R www:www /usr/local/www/nextcloud
    After making these directory structures, you can then either create or renew the letsencrypt certificates.
    Admittedly this isn’t the only way to do this, however what I wanted was for my http://www.mydomain.com and mydomain.com certs to be associated with mydomain .com (which the DocumentRoot for this domain is /usr/local/www/main) and the nextcloud.mydomain.com to be associated with nextcloud.mydomain.com (which the DocumentRoot for this domain is /usr/local/www/nextcloud). What is needed however is for the .well-known/acme-challenge directory structure to be in place for what ever domains and webroots you are associating with you certificates or the process will fail.
    After I copied my letsencrypt directory to the new server, I needed to forward ports 80 and 443 to the router to point at the machine and then reran something similar to the following to allow the certs to be setup for my particular structures:
    certbot certonly –cert-name mydomain.com -d mydomain.com, http://www.mydomain.com, nextcloud.mydomain.com

    I also tested the security of my ssl setup at https://www.ssllabs.com/ssltes. Based on your settings and the link for the Mozilla site I received A+. Thanks for your tips

  20. Thank you very much for this guide, in particular for the stating the reasonings for your configuration steps in detail.
    However, I’m currently quite doubtful which approach I should take for installing Nextcloud on FreeNAS 11.2 for a small private family cloud (eg. syncing contacts, backing up images from the smartphone and so on). Although I have some experience on Linux systems I’m rather new to FreeNAS/BSD. And it seems to me that at the moment the FreeNAS community is missing a real roadmap for Nextcloud. There is the Nextcloud plugin, the danb35 installation script, your excellent guide and the idea of using a Docker VM with a Nextcloud template. All very confusing. Do you know anything about the status of the plugin? Does it include any of your security considerations? Have you ever considered to get involved in the maintenance of the plugin?

    1. Hi Markus,

      As far as installation alternatives you’ve essentially hit the nail on the head; these are the options you have. This isn’t specific to Nextcloud though; you have these options for most programs that you would install on FreeNAS. It comes down to what you’re looking to get out of it I guess; manual installation using the method I’ve presented gives you some confidence about what you’re installing and you’ll know exactly what security precautions have been taken – you can then add or remove from this as you see appropriate for your use case. You’ve correctly identified that this is somewhat less obvious in the case of the plugin. I’ve never used the plugin, so I can’t really comment on it’s current status, but I know that it has previously been subject to a poor maintenance schedule, and has fallen behind the release schedule by quite a margin. By all accounts this isn’t presently the case, but it’s something to consider. If you’re not interested in having the manual control and understanding provided by configuring everything yourself, danb35’s script is a good solution. At least with this script you’ll have much broader support and an ability to fix any configuration issues in a more traditional way (it’s just a FreeBSD jail; you can find support for this in the freebsd community); problems with the plugin can be difficult to identify and fix (at least for me), and are less straight forward to rectify if you’re relying on the plugin maintainer to make changes.

      Plugin maintenance is something I’ve not had any exposure to, so it’s not something I’m presently considering. I am considering adding some of the security configurations to danb35’s script, but I have a lot of other things on my plate to keep me busy at this stage 🙂 Hope this helps.

      1. Hi Samuel,
        Guess what: If followed your guide and it works perfectly. I’m on FreeNAS 11.2 and tried to always use the latest packages: mariadb10.3, php7.3, nextcloud 15 and everything runs fine. I only had problems to get py36-certbot running probably because I just don’t get it how python 3.6 is activated. Nonetheless py27-certbot works.
        Thank you very much, Markus

  21. Hi Sam, one other question I have. You stated, “The second, “jailhouse”, is a 500GB Samsung SSD, and is the pool I store all of my jails on so that they benefit from the faster IO operations an SSD affords.” But later you say, “The remaining dataset is the ‘iocage’ dataset. This is created automatically when you create a jail, so you don’t need to worry about doing anything here, however it is important to note that this is where the local storage for your iocage jails is held.” So I’m a little confused about your configuration. Do you actually store the jails in the “jailhouse” pool or the “iocage” dataset? Thanks!

    1. Hi Andrew, In my configuration the iocage dataset is stored under the jailhouse root dataset of the jailhouse pool. The jailhouse pool is associated with the SSD. Each pool will have a root level dataset associated with it with the same name. You might have to specify the jail root to be the jailhouse pool. Does this clear things up? I’ve realised the directory structure in the post is a bit misleading so I’ve fixed that up. Cheers

  22. I may have missed something, but under the “…” menu for the nextcloud datasets that I’ve created, I do not have “Edit Permissions”. The available choices are, from top to bottom: “Add Dataset”, “Add Zvol”, “Edit Options”, “Delete Dataset”, and “Create Snapshot.” Any ideas?

    1. I’ve answered my own question. If you create the nextcloud datasets within the “iocage” dataset, as I mistakenly did, then apparently there is no “Edit Permissions” option. So, I will delete and recreate these sets outside of “iocage”. I am, however, confused: why wouldn’t we want to create the jail first, then use the directory structure that exists within the jail?

      1. Hi Oscar, as I discuss (perhaps later) in the guide, the reason we use a directory structure outside of the jail is so that the data we’re storing is independent of the jail. If you used the jail directory structure all your data would be erased every time you nuked the jail. This way, if you have to upgrade your jail, or misconfigure it irreparably, it’s trivial to create a new jail and be back up and running relatively quickly. Note that the jail directory structure is deleted when a jail is deleted. Of course, you’re welcome to forge your own path as well; this was just how I preferred to set it up.

  23. Based on recent nextcloud updates, I think you should add also this command to the guide:
    su -m www -c ‘php /usr/local/www/nextcloud/occ db:convert-filecache-bigint’

    The settings page of nextcloud requested it.

    Thanks for the guide!

        1. I don’t think it’s that straight forward. I had to do the same conversion upgrading from 14.0.3 to 15.0.1. I’ll have to do some testing to see when it’s required.

      1. At the end. Once you’ve got everything else set up and working, if you navigate to Settings > Overview in the web browser and see an error message indicating that this command needs to be run (The error message literally has the command you need to run in it), then you’ll need to run this command to upgrade your database schema.

          1. Yes, just as he has it. It runs a command as the www user. The quotes allow you to be explicit about what command to run as www, namely everything contained by the quotes.

  24. Many thanks for this really grat guide!
    I just recently did an upgrade from Freenas 11.0 to 11.2 which sort of broke all of my warden jails so I decided not to maintain these soon to be obsolete ones anymore and jump the iocage train instead.
    This made me switch some of the apps I used to newer/better alternatives (eg. Transmission>qBittorrent) and also set up a Nextcloud from scratch as i want to know what’s happening under the hood especially when things are facing the interwebs.
    Your guide really helped me a lot – mainly the security hardening part which I found very coprehensive and straightforward.
    Can’t see any donation option on your site so as a thank you I’ll post some info on problems I had to deal with during the process and which I think someone may find useful.

    Nextcloud installation breaks after a HTTP 504 “Gateway Timeout” error.

    – Uninstall the nextcloud pkg and remove its configuration
    – In MariaDB execute:
    DROP USER ‘nextcloud_admin’@’localhost’;
    DROP DATABASE nextcloud;
    Then start again from setting up the DB and installing Nextcloud

    Postfix configuration

    – Do not use google aliases like username+alias@gmail.com to log in to gmail account
    – Try to send a test email and look closely at postfix log, If everything is fine with the configuration it should eventually say that you need to issue an application specific password for Nextcloud’s Postfix in your Google Account’s “Security” tab.
    – Update the sasl_passwd file to include google app specific password and re-run postmap /usr/local/etc/postfix/sasl_passwd

    (This one is network setup specific for those who are on the routers without reverse NAT)
    After setting up the SSL certificate and forcing HTTPS connection you will loose possibility to connect to Nextcloud locally via its IP address as when trying to connect you will be redirected to Nextcloud’s HTTPS domain name and the connection will eventually fail.

    – Add another port (eg. 7777) to /usr/local/etc/apache24/httpd.conf on which you will connect to Nextcloud via local IP (eg. 192.168.0.7):

    Listen 80
    Listen 443
    Listen 7777
    ….

    Add a vhost declaration to your domain config in /usr/local/etc/apache24/Includes/your_domain.conf:

    ServerName 192.168.0.7
    DocumentRoot “/usr/local/www/nextcloud”

    SetHandler “proxy:fcgi://127.0.0.1:9000/”

    DirectoryIndex /index.php index.php

    Now you should be able to connect both locally using 192.168.0.7:7777 as well as from the web using Nextcloud’s domain name.

    Bigint conversion the proper way (using occ maintenance mode):
    su -m www -c ‘php /usr/local/www/apache24/data/nextcloud/occ maintenance:mode –on’
    su -m www -c ‘php /usr/local/www/apache24/data/nextcloud/occ db:convert-filecache-bigint’
    su -m www -c ‘php /usr/local/www/apache24/data/nextcloud/occ maintenance:mode –off’
    Watch closely for typos and if you happen to set up Nextcloud using Freenas jails shell and you want to copy some of the code from this guide to text files on Nextcloud storage using Windows PC and then “cat >>” this code to your config files – remeber to clean the text files from Windows specific hidden characters.

    – show hidden chars:
    cat -e /mnt/data/admin/files/file.txt
    – install converter:
    pkg install unix2dos
    – remove hidden chars:
    dos2unix /mnt/data/admin/files/file.txt

    In my case everything else went smooth (even the cert issuing part) on Nextcloud 15 / php 7.2.15 / openssl 1.0.2o / apache 2.4.38 / python 2.7.15
    Thanks again Samuel for your work!

  25. Great guide , I actually had it up and running for a short bit, but when I get to CACHING AND REDIS now the site just comes up with

    Internal Server Error

    The server encountered an internal error and was unable to complete your request.
    Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report.
    More details can be found in the webserver log.

    I’ve looked into the logs and there wasn’t anything in it.

    Apache error

    [proxy_fcgi:error] [pid 54466] [client 192.168.10.254:8673] AH01071: Got error ‘PHP message: PHP Parse error: syntax error, unexpected ‘array’ (T_ARRAY), expecting ‘)’ in /usr/local/www/nextcloud/config/config.php on line 12\n’
    [Tue Mar 05 20:13:30.992060 2019] [proxy_fcgi:error] [pid 54468] [client 192.168.10.254:8675] AH01071: Got error ‘PHP message: PHP Parse error: syntax error, unexpected ‘array’ (T_ARRAY), expecting ‘)’ in /usr/local/www/nextcloud/config/config.php on line 12\n’
    [Tue Mar 05 20:13:31.759532 2019] [proxy_fcgi:error] [pid 54469] [client 192.168.10.254:8676] AH01071: Got error ‘PHP message: PHP Parse error: syntax error, unexpected ‘array’ (T_ARRAY), expecting ‘)’ in /usr/local/www/nextcloud/config/config.php on line 12\n’

    I’m not 100% where I went wrong after the initial configuration and install it was all working I’m sure I stuffed something up somewhere I installed PHP72 on the box left me scratching my head any pointers would be appreciated. Thanks again.

    1. It looks like your config.php file is messed up. Probably missing a semicolon or parentheses. Did you try looking at the file closely?

  26. Hey Kevdog,
    you were totally right my friend, I missed the ‘domain.com’, after 1 => i’m such an idiot, I was in there like 10 times to and just didn’t notice thanks a lot everyone up and running, onto securing it now thanks again.

  27. Fantastic, detailed walkthrough article. It is hard to find how-to articles that go into the how’s and why’s of what given settings are. I’m sure it took you a lot of extra time to include the extra detail, but not only do I now have Nextcloud migrated from being hosted on a Raspberry Pi to my FreeNAS box I understand more of the inner workings as well. A+, thank you very much

  28. I’m sorry to ask a silly question but i get as far as imputing the following code:

    su -m www -c ‘php /usr/local/www/nextcloud/occ config:system:set redis host –value=”/tmp/redis.sock”‘

    but it gives me the error:

    Could not open input file: /usr/local/www/nextcloud/occ

    if i try to move forward with the next step it keeps giving me this error.

    if it helps to solve this, i think a part of my problem is that i imputed the following 2 lines first but forgot to change it to php72.

    $ pkg install php71-pecl-redis
    $ pkg install php71-pecl-APCu

    i went back and changed it to php72 and reimputed the 2 lines but i think the damage has been done. can anyone help me with this.

    1. A couple of things to check:
      1. Are you copying the command directly from the post? You should. In what you’ve posted here, you just have -value, it should be --value
      2. Do you actually have Nextcloud installed? Navigate to /usr/local/www/nextcloud to see if the program occ is actually present, i.e:

      $ cd /usr/local/www/nextcloud
      $ ls -l

      Try to find occ in the resulting list. If nextcloud isn’t installed, nothing will appear at this point. It’s possible that by uninstalling php71-pecl-redis and php71-pecl-APCu, necessary packages to nextcloud were also removed, or nextcloud was removed. It might be worth just starting over again to avoid some of these debugging headaches.

      Cheers.

      1. Thank you for the info Samuel. i copied the command directly from the post but if it needs the — i will insert it when i try it again. Also, when i paste the commands you gave me it does not show the occ, so it looks like i have to start over on this =(. thank you for all your help, you are awesome!

  29. root@bgnas:~ # iocage list
    +—–+———–+——-+————–+————+
    | JID | NAME | STATE | RELEASE | IP4 |
    +=====+===========+=======+==============+============+
    | 2 | nextcloud | up | 11.1-RELEASE | 10.0.0.230 |
    +—–+———–+——-+————–+————+
    root@bgnas:~ # jexec 2 tcsh
    root@nextcloud:/ # ee /etc/pkg/FreeBSD.conf
    ^[ (escape) menu ^y search prompt ^k delete line ^p prev li ^g prev page
    ^o ascii code ^x search ^l undelete line ^n next li ^v next page
    ^u end of file ^a begin of line ^w delete word ^b back 1 char ^z next word
    ^t top of text ^e end of line ^r restore word ^f forward char
    ^c command ^d delete ESC-Enter: exit
    =====line 11 col 48 lines f ===========================

    $FreeBSD: releng/11.1/etc/pkg/FreeBSD.conf 320745 2017-07-06 17:22:33Z gjb $

    #

    To disable this repository, instead of modifying or removing this file,

    create a /usr/local/etc/pkg/repos/FreeBSD.conf file:

    #

    mkdir -p /usr/local/etc/pkg/repos

    echo “FreeBSD: { enabled: no }” > /usr/local/etc/pkg/repos/FreeBSD.conf

    #

    FreeBSD: {
    url: “pkg+http://pkg.FreeBSD.org/${ABI}/latest”,
    mirror_type: “srv”,
    signature_type: “fingerprints”,
    fingerprints: “/usr/share/keys/pkg”,
    enabled: yes
    }

    “/etc/pkg/FreeBSD.conf” 16 lines, 503 characters
    root@nextcloud:/ # pkg update
    The package management tool is not yet installed on your system.
    Do you want to fetch and install it now? [y/N]: y
    Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:11:amd64/latest, please wait…
    pkg: Error fetching http://pkg.FreeBSD.org/FreeBSD:11:amd64/latest/Latest/pkg.txz: No address record
    A pre-built version of pkg could not be found for your system.
    Consider changing PACKAGESITE or installing it from ports: ‘ports-mgmt/pkg’.
    root@nextcloud:/ # pkg: Error fetching http://pkg.FreeBSD.org/FreeBSD:11:amd64/latest/Latest/pkg.txz: No address record
    pkg:: Too many arguments.
    root@nextcloud:/ # A pre-built version of pkg could not be found for your system.
    A: Command not found.
    root@nextcloud:/ # Consider changing PACKAGESITE or installing it from ports: ‘ports-mgmt/pkg’.
    root@nextcloud:/ # pkg install nano
    The package management tool is not yet installed on your system.
    Do you want to fetch and install it now? [y/N]: y
    Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:11:amd64/latest, please wait…
    ^C
    root@nextcloud:/ # ping pkg.FreeBSD.org
    ping: cannot resolve pkg.FreeBSD.org: Host name lookup failure
    root@nextcloud:/ # vi /etc/resolv.conf

    Generated by resolvconf

    search com
    nameserver 10.0.0.201
    nameserver 10.0.0.202
    nameserver 8.8.8.8

    ~
    ~
    ~
    ~
    ~
    ~
    ~
    ~
    ~
    ~
    ~
    ~
    ~
    ~
    ~
    ~
    ~
    :q
    root@nextcloud:/ # ifconfig
    lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
    options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
    inet6 ::1 prefixlen 128
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
    inet 127.0.0.1 netmask 0xff000000
    nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
    groups: lo
    epair0b: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=8
    ether 02:ff:60:ba:b5:82
    hwaddr 02:05:a0:00:06:0b
    inet 10.0.0.230 netmask 0xff000000 broadcast 10.255.255.255
    nd6 options=1
    media: Ethernet 10Gbase-T (10Gbase-T )
    status: active
    groups: epair

    Dear,
    I am new to these iocage configuration but I stuck up here while following ur methed. I feel i am not able to connect internet or Free BSD package repository. somthing wrong while creating VNET.
    please guid. Now I have to install all
    following
    $ pkg update
    $ pkg install nano
    $ pkg install apache24
    $ sysrc apache24_enable=yes
    $ service apache24 start

    $ pkg install mariadb102-server
    $ sysrc mysql_enable=yes
    $ service mysql-server start
    $ mysql_secure_installation

    1. Hi Naufal,

      This isn’t something I can effectively help you debug in this forum. It looks like your analysis of this is right; it looks like your jail doesn’t have internet connectivity. Some steps you can take are to try to ping your name servers, i.e. ping 8.8.8.8 to see if you get a response, and then see if you can contact the freebsd servers: nslookup freebsd.org, and if neither of those work, see if you can ping your Freenas host or router, ping 192.168.0.2 (replace with freenas ip), ping 192.168.0.1 (replace with router ip). It might be worth executing ifconfig on your freenas host to see if the jail vnet interface is present in bridge0 along with your network interface. In my case, my network interface is igb0, yours might be different. If it’s not there, you’ll need to add your network interface to the bridge so your jails have internet access. This is all speculation on my part though, if you want to resolve this I’d really recommend visiting the freenas forums or the #freenas IRC channel.

      Good luck!

  30. Hey Samuel

    I know about the upgrade options however I’m pretty much trying to stick to the freebsd of pkg update cycle and not upgrade through nextcloud itself. I recently saw some my packages for nextcloud were pushed and installed through pkg. I’m now presented with this option through nextcloud — https://imagebin.ca/v/4amQEKNji7Vj

    Is there anything specific I need to do at this point like put occ in maintainence mode or anything prior to proceeding? I’m asking because upgrades have screwed my prior install before in the distant past.

    1. Kevdog,

      My experience with the upgrade procedure is that it hasn’t been smooth, and I think you might have to accept some risk in breaking your installation (hence the advice to back everything up before attempting in the image you linked). Putting your installation in maintenance mode does seem prudent, especially if you have other users using your cloud service. The problems I’ve had in the past have been related to app configuration not updating properly; I’m not sure if this was an issue with the freebsd pkg or Nextcloud itself, though. I wish I had better advice for you, but it’s not a process I’ve had a significant amount of experience with yet 🙂 Good luck!

  31. Question since I can’t seem to find an answer. I upgraded nextcloud and now I’m getting within the apps section – says no apps found for your version. https://pasteboard.co/I6xj80H.png

    I’m not sure what to do. I restarted the apache24, redis, and php-fpm services.

    Personal rant — nextcloud updating sucks!! The system seems very easy to break. Nextcloud not very robust.

    1. I feel you dude. I had issues when I last upgraded to 15.0.0. As far as apps go, prior to updating there is a check done to make sure there is a compatible app version for the proposed upgrade:

      This indicates that all of the apps that I have installed are compatible with 15.0.5, but you probably have a more expansive set of apps installed, which is where the problems are arising. Nextcloud’s robustness seems to be it’s primary disadvantage. It was something that I hadn’t really considered too closely when writing this guide, and so it may in fact be better to install it directly from nextcloud’s distribution rather than from pkg. You could then just use the web updater, which seems like it may provide a better upgrade experience (I have limited experience with this though, and I have heard that it has been not-so-great in the past; it seems like these issues may have been fixed but I’m really not sure).

      Regardless, to help solve your current problem, you can go through the problem apps configuration xml in /usr/local/www/nextcloud/apps-pkg/<name of app here>/appinfo/info.xml. Have a poke around and see if you can identify what’s wrong there. What fixed an issue in the past for me was that this file had a max-version="14" property, which caused errors upgrading to 15. Changing it allowed me to start nextcloud up and get everything working, but it triggered integrity check warnings, as the hashes of these files no longer matched the files because I edited it. I never worked out a solution to this, but I suspect it would have involved installing each app again from source so that the hashes matched what was listed and the integrity checks passed.

      Moving forward though, I strongly suggest checking out the #nextcloud IRC channel on freenode. There are a number of very knowledgable and helpful users you can have a real time dialogue with about problems there; this is usually my first stop for support when things go wrong that I don’t know anything about.

  32. Hi Team, after getting everything working, i did a restart on my Freenas server and now the nextcloud iocage will not start. any ideas why?

    root@freenas:~ # iocage list
    +—–+———–+——-+————–+———–+
    | JID | NAME | STATE | RELEASE | IP4 |
    +=====+===========+=======+==============+===========+
    | – | nextcloud | down | 11.1-RELEASE | 10.0.0.15 |
    +—–+———–+——-+————–+———–+
    root@freenas:~ # iocage start nextcloud
    * Starting nextcloud
    + Start FAILED
    mount_nullfs: /mnt/cloud: No such file or directory
    jail: /sbin/mount -t nullfs -o rw /mnt/cloud /mnt/iocage/jails/nextcloud/root/mnt/data: failed

    root@freenas:~ #

    1. Hi David,

      Head to your terminal and type

      root@freenas:~ # ls /mnt/cloud
      

      I think you’ll find that you don’t have a dataset named this. In the guide I provide, it’s /mnt/vault/cloud, where vault is the name of the pool that the cloud dataset lives on. You can edit the fstab for nextcloud by running:

      
      root@freenas:~ # setenv EDITOR nano
      root@freenas:~ # iocage fstab -e nextcloud
      

      Make the necessary changes, try to restart the jail:

      
      root@freenas:~ # iocage start nextcloud
      

      Then restart your NAS to make sure that these changes will persist moving forward.

        1. So after i updated the fstab i was able to start up the Jail again and i looked like i was able to access nextcloud but after i restarted my freenas server the jail still comes up and its running but i can no longer access my nextcloud. I have tried restarting my Jail and restarting freenas but with no luck.
          I’m stuck in the trouble shooting process and i can use some guidance on this.

          Here is what i have to help with this. please let me know what other info i can provide you.

          root@freenas:~ # iocage list
          +—–+———–+——-+————–+———–+
          | JID | NAME | STATE | RELEASE | IP4 |
          +=====+===========+=======+==============+===========+
          | 4 | nextcloud | up | 11.1-RELEASE | 10.0.0.15 |
          +—–+———–+——-+————–+———–+

          root@nextcloud:/ # service -e
          /etc/rc.d/cleanvar
          /etc/rc.d/netif
          /etc/rc.d/newsyslog
          /etc/rc.d/syslogd
          /etc/rc.d/virecover
          /etc/rc.d/motd
          /usr/local/etc/rc.d/redis
          /usr/local/etc/rc.d/postfix
          /usr/local/etc/rc.d/php-fpm
          /usr/local/etc/rc.d/mysql-server
          /usr/local/etc/rc.d/apache24
          /etc/rc.d/cron

          root@nextcloud:/ # /var/log/nextcloud/nextcloud.log
          /var/log/nextcloud/nextcloud.log: Permission denied.

          root@nextcloud:/ # /var/log/httpd-error.log
          /var/log/httpd-error.log: Permission denied.

          1. Hi David, can you be more explicit about what you mean by “can no longer access my nextcloud”? What’s the nature of your inability to access; authentication? Can’t get the the web ui? You can’t see any files? What are the symptoms.

            Looking through the logs are what you want to do, so good start there. The problem is you’ve just specified a directory without an application, which is why you’re getting Permission denied.. Change you commands to:

            root@nextcloud:/ # nano /var/log/nextcloud/nextcloud.log
            root@nextcloud:/ # nano /var/log/httpd-error.log
            
  33. Sorry for not being specific. i’m not able to access the web ui ether by the HTTPS site or by typing in the Jail IP address.

    thank you for clarifying nano. I was able to pull up both logs but the first one “nextcloud.log” was blank. however this is what the “httpd-error.log” is showing:

    [Sat Mar 23 11:20:15.625039 2019] [mpm_prefork:notice] [pid 57360] AH00163: Apache/2.4.38 (FreeBSD) configured — resuming normal operati$
    [Sat Mar 23 11:20:15.625240 2019] [core:notice] [pid 57360] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’
    [Sat Mar 23 11:32:49.986022 2019] [mpm_prefork:notice] [pid 57360] AH00171: Graceful restart requested, doing restart
    AH00558: httpd: Could not reliably determine the server’s fully qualified domain name, using 127.0.0.1. Set the ‘ServerName’ directive gl$
    [Sat Mar 23 11:32:49.988657 2019] [mpm_prefork:notice] [pid 57360] AH00163: Apache/2.4.38 (FreeBSD) configured — resuming normal operati$
    [Sat Mar 23 11:32:49.988664 2019] [core:notice] [pid 57360] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’
    [Sat Mar 23 11:40:21.506731 2019] [mpm_prefork:notice] [pid 57360] AH00169: caught SIGTERM, shutting down
    [Sat Mar 23 11:40:21.568723 2019] [mpm_prefork:notice] [pid 58895] AH00163: Apache/2.4.38 (FreeBSD) configured — resuming normal operati$
    [Sat Mar 23 11:40:21.568923 2019] [core:notice] [pid 58895] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’
    [Sat Mar 23 11:40:59.954695 2019] [proxy_fcgi:error] [pid 58896] [client 10.0.0.12:63840] AH01071: Got error ‘Primary script unknown\n’
    [Sat Mar 23 11:41:11.834753 2019] [proxy_fcgi:error] [pid 58897] [client 10.0.0.12:63839] AH01071: Got error ‘Primary script unknown\n’
    [Sat Mar 23 11:46:16.582755 2019] [proxy_fcgi:error] [pid 58920] [client 185.235.245.21:33644] AH01071: Got error ‘Primary script unknown$
    [Sat Mar 23 11:54:12.727978 2019] [proxy_fcgi:error] [pid 58921] [client 213.81.189.88:39175] AH01071: Got error ‘Primary script unknown\$
    [Sat Mar 23 11:56:20.608675 2019] [mpm_prefork:notice] [pid 58895] AH00169: caught SIGTERM, shutting down
    [Sat Mar 23 11:56:20.670193 2019] [mpm_prefork:notice] [pid 60338] AH00163: Apache/2.4.38 (FreeBSD) configured — resuming normal operati$
    [Sat Mar 23 11:56:20.670376 2019] [core:notice] [pid 60338] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’
    [Sat Mar 23 12:02:33.831677 2019] [mpm_prefork:notice] [pid 60338] AH00169: caught SIGTERM, shutting down
    [Sat Mar 23 12:02:33.892662 2019] [mpm_prefork:notice] [pid 60731] AH00163: Apache/2.4.38 (FreeBSD) configured — resuming normal operati$
    [Sat Mar 23 12:02:33.892865 2019] [core:notice] [pid 60731] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’
    [Sat Mar 23 12:10:06.097636 2019] [mpm_prefork:notice] [pid 60731] AH00169: caught SIGTERM, shutting down
    [Sat Mar 23 12:10:06.157707 2019] [mpm_prefork:notice] [pid 60949] AH00163: Apache/2.4.38 (FreeBSD) configured — resuming normal operati$
    [Sat Mar 23 12:10:06.157909 2019] [core:notice] [pid 60949] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’
    [Sat Mar 23 13:50:12.089278 2019] [mpm_prefork:notice] [pid 60949] AH00169: caught SIGTERM, shutting down
    [Sat Mar 23 13:50:12.156588 2019] [ssl:warn] [pid 65295] AH01882: Init: this version of mod_ssl was compiled against a newer library (Ope$
    [Sat Mar 23 13:50:12.165242 2019] [ssl:warn] [pid 65296] AH01882: Init: this version of mod_ssl was compiled against a newer library (Ope$
    [Sat Mar 23 13:50:12.165294 2019] [ssl:warn] [pid 65296] AH01873: Init: Session Cache is not configured [hint: SSLSessionCache]
    [Sat Mar 23 13:50:12.167213 2019] [mpm_prefork:notice] [pid 65296] AH00163: Apache/2.4.38 (FreeBSD) OpenSSL/1.0.2k-freebsd configured — $
    [Sat Mar 23 13:50:12.167237 2019] [core:notice] [pid 65296] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’
    [Sat Mar 23 13:53:19.511197 2019] [mpm_prefork:notice] [pid 65296] AH00169: caught SIGTERM, shutting down
    [Sat Mar 23 13:53:19.579399 2019] [ssl:warn] [pid 65389] AH01882: Init: this version of mod_ssl was compiled against a newer library (Ope$
    [Sat Mar 23 13:53:19.588815 2019] [ssl:warn] [pid 65390] AH01882: Init: this version of mod_ssl was compiled against a newer library (Ope$
    [Sat Mar 23 13:53:19.590617 2019] [mpm_prefork:notice] [pid 65390] AH00163: Apache/2.4.38 (FreeBSD) OpenSSL/1.0.2k-freebsd configured — $
    [Sat Mar 23 13:53:19.590639 2019] [core:notice] [pid 65390] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’
    [Sat Mar 23 13:58:59.548214 2019] [mpm_prefork:notice] [pid 65390] AH00169: caught SIGTERM, shutting down
    [Sun Mar 24 12:07:24.685236 2019] [ssl:warn] [pid 53014] AH01882: Init: this version of mod_ssl was compiled against a newer library (Ope$
    [Sun Mar 24 12:07:24.699021 2019] [ssl:warn] [pid 53015] AH01882: Init: this version of mod_ssl was compiled against a newer library (Ope$
    [Sun Mar 24 12:07:24.700922 2019] [mpm_prefork:notice] [pid 53015] AH00163: Apache/2.4.38 (FreeBSD) OpenSSL/1.0.2k-freebsd configured — $
    [Sun Mar 24 12:07:24.700953 2019] [core:notice] [pid 53015] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’
    [Sun Mar 24 12:11:26.157426 2019] [mpm_prefork:notice] [pid 53015] AH00169: caught SIGTERM, shutting down
    [Sun Mar 24 12:13:24.488585 2019] [ssl:warn] [pid 3395] AH01882: Init: this version of mod_ssl was compiled against a newer library (Open$
    [Sun Mar 24 12:13:24.498179 2019] [ssl:warn] [pid 3396] AH01882: Init: this version of mod_ssl was compiled against a newer library (Open$
    [Sun Mar 24 12:13:24.499759 2019] [mpm_prefork:notice] [pid 3396] AH00163: Apache/2.4.38 (FreeBSD) OpenSSL/1.0.2k-freebsd configured — r$
    [Sun Mar 24 12:13:24.499796 2019] [core:notice] [pid 3396] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’
    [Sun Mar 24 12:22:26.381658 2019] [mpm_prefork:notice] [pid 3396] AH00169: caught SIGTERM, shutting down
    [Sun Mar 24 12:22:31.549252 2019] [ssl:warn] [pid 9808] AH01882: Init: this version of mod_ssl was compiled against a newer library (Open$
    [Sun Mar 24 12:22:31.558508 2019] [ssl:warn] [pid 9809] AH01882: Init: this version of mod_ssl was compiled against a newer library (Open$
    [Sun Mar 24 12:22:31.560092 2019] [mpm_prefork:notice] [pid 9809] AH00163: Apache/2.4.38 (FreeBSD) OpenSSL/1.0.2k-freebsd configured — r$
    [Sun Mar 24 12:22:31.560133 2019] [core:notice] [pid 9809] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’

    1. What’s the error message you get when you go to the browser? Internal Server error? Too many redirects? Could not find the web page? Nothing much in the logs is standing out to me – SIGTERM indicates that apache is crashing/restarting but the last log is March 24; 2 days ago. You could try increasing the log verbosity to see if anything extra falls out.

      My suggestion would be to visit the #nextcloud channel in IRC though, some of those guys are likely to be better positioned to help, I can’t see much going on at this point. Can you ping your jail ip from outside? Can you ping your router from the jail? Can you ping google?

      1. March 24 was the last day it worked for me. the error i get when i try to pull up the web page with the IP or the HTTPS is:

        This site can’t be reached 10.0.0.15 took too long to respond.
        Try:

        Checking the connection
        Checking the proxy and the firewall
        Running Windows Network Diagnostics
        ERR_CONNECTION_TIMED_OUT

        When i try to ping the IP address it says the following which is pretty confusing. its like it can ping it, but it pulls a different IP address. here is what the ping shows:

        C:\Users\David>ping 10.0.0.15

        Pinging 10.0.0.15 with 32 bytes of data:
        Reply from 10.0.0.12: Destination host unreachable.
        Reply from 10.0.0.12: Destination host unreachable.
        Reply from 10.0.0.12: Destination host unreachable.
        Reply from 10.0.0.12: Destination host unreachable.

        Ping statistics for 10.0.0.15:
        Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),

        how would i go about increasing the log verbosity to see if anything extra falls out?

        1. This looks like it’s a problem with the networking for the jail, not something specific to nextcloud. Try pinging your router and computer from inside the jail to confirm. I’m guessing that 10.0.0.12 is your router? I think this message means that there’s no route from your router to the jail – strange. I’m not sure how to fix this to be honest; the Freenas forums or #freenas on IRC are your best bets.

          Not that you’ll need it now, but iirc the log verbosity can be changed in php.ini for php related error messages, and httpd.conf for apache related messages.

          1. that is so strange. you are right, i’m not able to ping out of the Jail. i will need to figure this one out. Thank you so much again for your help.

  34. Hey, I have tried to follow your instruction to the point and sadly I ran into any number of issues
    1. Order of creating virtual folders + wont work at the early stage you suggested since nextcloud dont exists yet
    2. Ran into the same issues of not being able to connect to the nextcloud interface once entering the initial details
    ( browser throws unreachable…. same as others brought forward)
    (Somehow I managed to find a workaround, but forgot what I did atm 🙁 )
    3. Biggest headache I had was when installing php71-pecl-redis & php71-pecl-APCu
    Installing these packages blew away my entire nextcloud installation *i.e nextcloud itself
    Only thing remaining what the config and .htaccess
    * I think I understand whats happening, but a bit of warning would have been nice.
    — what happened: 1. I initially opted for php72 and without really thinking I applied 71 resulting in that the entire nextcloud blew away.
    I managed to recover by taking a copy of the config and .htaccess and then reinstalling nextcloud as per your earlier instruction. – That brought nc back but with lost *in particular .htaccess
    So reapplied my backup and everything was back.

    Now stuck on the email sendout using chkaide.sh. It wont work under nc, but do work under root.
    Nothing mentioned who/what should run this so wonder if its meant to be a scheduled job under nc or under root?
    The test “echo “Test Email Contents” | mail -s “Postfix Test Email “xxx@domain.com” dont send out anything under nc *log keep complaining about “Domain of sender address root@nextcloud.localdomain does not exist”
    Doing the same thing ssh into root and it works, but the shell script still wont work under root

    Still trying to work out bigint issues and “/.well-known/caldav” reported in nc – struggling with that
    Doco points to oc command and that throws “not found”

    1. Hi Martin,

      Everything is to be run as root. When you log in via jexec <JID> tcsh, you’re automatically logged in as the root user, so I’m not sure what you’re doing but you should follow the guide exactly to make sure it works. With regards to the chkaide.sh script, what is the error you get? What do you mean when you say it “won’t work”?

      As far as the big int issues, you run the command as specified in the error message, or more verbosely:

      su -m www -c ‘php /usr/local/www/nextcloud/occ maintenance:mode –on’
      su -m www -c ‘php /usr/local/www/nextcloud/occ db:convert-filecache-bigint’
      su -m www -c ‘php /usr/local/www/nextcloud/occ maintenance:mode –off’
      

      The caldav issue is due to apache not using the .htaccess file provided by nextcloud; go back to the section in the guide addressing enabling .htaccess and make sure all the settings are as specified.

      Also, if the occ executable isn’t in your nextcloud directory, i.e. at /usr/local/www/nextcloud/occ, then it sounds like your installation may be broken. If this is the case, I’d suggest starting again.
      Cheers.

      1. thanks for the bigint update = will try that later

        As for the mail sendout…
        1. followed all your instructions within the jail jexec where folder and script got created – Just assumed that would be 100% tied to nextcloud without risking interfering with existing stuff
        So effectively the script and location is within the nc containter
        When I tried to run the echo test and script this is thrown
        Mar 26 13:13:05 nextcloud postfix/postfix-script[94794]: starting the Postfix mail system
        Mar 26 13:13:05 nextcloud postfix/master[94796]: daemon started — version 3.3.3, configuration /usr/local/etc/postfix
        Mar 26 13:17:12 nextcloud postfix/pickup[94797]: 9CBF325B35: uid=0 from=
        Mar 26 13:17:12 nextcloud postfix/cleanup[95248]: 9CBF325B35: message-id=20190326051712.9CBF325B35@nextcloud.localdomain
        Mar 26 13:17:12 nextcloud postfix/qmgr[94798]: 9CBF325B35: from=root@nextcloud.localdomain, size=46479, nrcpt=1 (queue active)
        Mar 26 13:17:12 nextcloud postfix/smtp[95250]: warning: database /usr/local/etc/postfix/sasl_passwd.db is older than source file /usr/local/etc/postfix/sasl_passwd
        Mar 26 13:17:12 nextcloud postfix/smtp[95250]: 9CBF325B35: to=redacted, relay=smtp.iinet.net.au[203.0.178.192]:587, delay=0.17, delays=0.03/0.03/0.09/0.02, dsn=5.0.0, status=bounced (host smtp.iinet.net.au[203.0.178.192] said: 553 #5.1.8 Domain of sender address root@nextcloud.localdomain does not exist (in reply to MAIL FROM command))
        Mar 26 13:17:12 nextcloud postfix/cleanup[95248]: C7F1425B37: message-id=20190326051712.C7F1425B37@nextcloud.localdomain
        Mar 26 13:17:12 nextcloud postfix/bounce[95252]: 9CBF325B35: sender non-delivery notification: C7F1425B37
        Mar 26 13:17:12 nextcloud postfix/qmgr[94798]: C7F1425B37: from=<>, size=48651, nrcpt=1 (queue active)
        Mar 26 13:17:12 nextcloud postfix/qmgr[94798]: 9CBF325B35: removed

        I tried to run it as root outside the jail and the echo command worked fine, but the script obviously required me to qualify inside the nc container – but if, like you suggested this should reside at a root level, then I guess it makes sense – script and folder creations should in effect be /scripts/aide/ vs /mnt/JailSSD/iocage/jails/nextcloud/root/scripts/aide/
        Does the same apply for aide installation or… ? Installed aide within the nc jail

      2. Just posted a reply to this but now its gone???
        Anyways…
        thanks for the hints on sorting the db issues.
        As for the error thrown when running the script, this is what thrown back when issuing the echo and running the script within the nc container

        It works on a root level, but the script wont resolve anything
        cloud postfix/postfix-script[94794]: starting the Postfix mail system
        Mar 26 13:13:05 nextcloud postfix/master[94796]: daemon started — version 3.3.3, configuration /usr/local/etc/postfix
        Mar 26 13:17:12 nextcloud postfix/pickup[94797]: 9CBF325B35: uid=0 from=
        Mar 26 13:17:12 nextcloud postfix/cleanup[95248]: 9CBF325B35: message-id=20190326051712.9CBF325B35@nextcloud.localdomain
        Mar 26 13:17:12 nextcloud postfix/qmgr[94798]: 9CBF325B35: from=root@nextcloud.localdomain, size=46479, nrcpt=1 (queue active)
        Mar 26 13:17:12 nextcloud postfix/smtp[95250]: warning: database /usr/local/etc/postfix/sasl_passwd.db is older than source file /usr/local/etc/postfix/sasl_passwd
        Mar 26 13:17:12 nextcloud postfix/smtp[95250]: 9CBF325B35: to=<[edited]@[edited].com>, relay=smtp.[edited][x.x.x.x]:587, delay=0.17, delays=0.03/0.03/0.09/0.02, dsn=5.0.0, status=bounced (host smtp.[edited].[edited][xxx.x.x.xxx] said: 553 #5.1.8 Domain of sender address root@nextcloud.localdomain does not exist (in reply to MAIL FROM command))
        Mar 26 13:17:12 nextcloud postfix/cleanup[95248]: C7F1425B37: message-id=20190326051712.C7F1425B37@nextcloud.localdomain
        Mar 26 13:17:12 nextcloud postfix/bounce[95252]: 9CBF325B35: sender non-delivery notification: C7F1425B37
        Mar 26 13:17:12 nextcloud postfix/qmgr[94798]: C7F1425B37: from=<>, size=48651, nrcpt=1 (queue active)
        Mar 26 13:17:12 nextcloud postfix/qmgr[94798]: 9CBF325B35: removed

        As per most recent reply, tried to move the script out of the nc container into root level *same directory structure) but that throws this….
        root@freenas[/scripts/aide]# /bin/sh /scripts/aide/chkaide.sh
        /scripts/aide/chkaide.sh: /usr/local/bin/aide: not found
        /scripts/aide/chkaide.sh: /usr/local/bin/aide: not found
        mv: rename /var/db/aide/databases/aide.db to /var/db/aide/databases/archive/aide-2019-03-26.db: No such file or directory
        mv: rename /var/db/aide/databases/aide.db.new to /var/db/aide/databases/aide.db: No such file or directory
        root@freenas[/scripts/aide]#

        1. Okay, to clarify, everything I describe runs as root within the nextcloud jail. aide is installed within the jail, checkaide.sh is at /scripts/aide within the jail (so absolute path is /mnt/JailSSD/iocage/jails/nextcloud/root/scripts/aide/ – but you should not be using this; at no point do I indicate that you should leave the jail). The postfix configuration is undertaken within the nextcloud jail. The issue you’re getting at the end there is that aide is not installed on the freenas host; which makes sense because that’s not where it should be installed.

          Did you configure postfix to use a gmail account?

          1. Installing inside the nc container (jail) is exactly what I did, but like I said the “echo…” test and script throws errors in the log pointing to “root@nextcloud.localdomain does not exist ”
            The script runs, but wont send out the email.

            qmail or not…? No, I did not use qmail – thought I would be able to use my own private mail and provider (which still works performing the “echo…” test outside the jail (root), but again throws the “root@nextcloud.localdomain does not exist ” when running it inside the nc jail.

          2. You probably can use another email provider, but there is likely different configuration required to what I’ve presented. It looks like FreeNAS uses sendmail, so if you set your email up through the GUI it either uses that or their own implementation, which is also possible, and neither of these are postfix like I use in my guide. My advice would be to set up a gmail account specifically for server based notifications, and use that. Or don’t, but I’m afraid I don’t know enough about configuring MTA’s to help you get that working sorry.

            If you do want to go down the rabbit hole and work out how to configure this for your provider, this is where I would start.

            Good luck!

  35. Just moved the script out of the nc container same directory structure, but @ root level
    output:
    root@freenas[/scripts/aide]# /bin/sh /scripts/aide/chkaide.sh
    /scripts/aide/chkaide.sh: /usr/local/bin/aide: not found
    /scripts/aide/chkaide.sh: /usr/local/bin/aide: not found
    mv: rename /var/db/aide/databases/aide.db to /var/db/aide/databases/archive/aide-2019-03-26.db: No such file or directory
    mv: rename /var/db/aide/databases/aide.db.new to /var/db/aide/databases/aide.db: No such file or directory
    root@freenas[/scripts/aide]#

    BTW. sent some stuff across in my previous reply pointing out my email to the world – anyway to edit posts or…?

    1. Reinstalled everything and keep running into issues with mariadb – service refuse to start up now.
      Blown away the jail to start from scratch, but issue persist.
      Right now I decided to blow the jail away and apply my most recent config that dont include nextcloud – started the installation process and same issue
      Just refuse to start and Im buggered if I can figure out why.
      maria error log show…
      2019-03-27 17:22:14 0 [Note] InnoDB: The first innodb_system data file ‘ibdata1’ did not exist. A new tablespace will be created!
      2019-03-27 17:22:14 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
      2019-03-27 17:22:14 0 [Note] InnoDB: Uses event mutexes
      2019-03-27 17:22:14 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
      2019-03-27 17:22:14 0 [Note] InnoDB: Number of pools: 1
      2019-03-27 17:22:14 0 [Note] InnoDB: Using generic crc32 instructions
      2019-03-27 17:22:14 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
      2019-03-27 17:22:14 0 [Note] InnoDB: Completed initialization of buffer pool
      2019-03-27 17:22:14 0 [Note] InnoDB: Setting file ‘./ibdata1’ size to 12 MB. Physically writing the file full; Please wait …
      2019-03-27 17:22:14 0 [Note] InnoDB: File ‘./ibdata1’ size is now 12 MB.
      2019-03-27 17:22:14 0 [Note] InnoDB: Setting log file ./ib_logfile101 size to 50331648 bytes
      2019-03-27 17:22:14 0 [Note] InnoDB: Setting log file ./ib_logfile1 size to 50331648 bytes
      2019-03-27 17:22:14 0 [Note] InnoDB: Renaming log file ./ib_logfile101 to ./ib_logfile0
      2019-03-27 17:22:14 0 [Note] InnoDB: New log files created, LSN=45786
      2019-03-27 17:22:14 0 [Note] InnoDB: Doublewrite buffer not found: creating new
      2019-03-27 17:22:14 0 [Note] InnoDB: Doublewrite buffer created
      2019-03-27 17:22:14 0 [Note] InnoDB: 128 out of 128 rollback segments are active.
      2019-03-27 17:22:14 0 [Note] InnoDB: Creating foreign key constraint system tables.
      2019-03-27 17:22:14 0 [Note] InnoDB: Creating tablespace and datafile system tables.
      2019-03-27 17:22:14 0 [Note] InnoDB: Creating sys_virtual system tables.
      2019-03-27 17:22:14 0 [Note] InnoDB: Creating shared tablespace for temporary tables
      2019-03-27 17:22:14 0 [Note] InnoDB: Setting file ‘./ibtmp1’ size to 12 MB. Physically writing the file full; Please wait …
      2019-03-27 17:22:14 0 [Note] InnoDB: File ‘./ibtmp1’ size is now 12 MB.
      2019-03-27 17:22:14 0 [Note] InnoDB: Waiting for purge to start
      2019-03-27 17:22:14 0 [Note] InnoDB: 10.3.13 started; log sequence number 0; transaction id 7
      2019-03-27 17:22:14 0 [Note] Plugin ‘FEEDBACK’ is disabled.
      2019-03-27 17:22:14 0 [ERROR] Could not open mysql.plugin table. Some plugins may be not loaded
      2019-03-27 17:22:14 0 [ERROR] Can’t open and lock privilege tables: Table ‘mysql.servers’ doesn’t exist
      2019-03-27 17:22:14 0 [Note] Server socket created on IP: ‘::’.
      2019-03-27 17:22:14 0 [ERROR] Fatal error: Can’t open and lock privilege tables: Table ‘mysql.user’ doesn’t exist

      Any assistance sorting this would be highly appreciated – its driving me nuts atm – failing this I will blow the entire nas away and start again – something I dont want 🙁

      1. Are you deleting your datasets and re-creating them when starting again? If not, your db files will be persistent and are probably interfering with the set up of the new database. Until you have something worth restoring, it’s probably best to nuke the datasets you mount into the jail with fstab to get a clean start. I.e: /mnt/vault/cloud, /mnt/jailhouse/apps/nextcloud/db, /mnt/jailhouse/apps/nextcloud/config, /mnt/jailhouse/apps/nextcloud/themes. After you do have something worth restoring, you would have to go through the restoration process: https://docs.nextcloud.com/server/14/admin_manual/maintenance/restore.html

        1. hm, yes, I’ve nuked everything except the directories vault/ (keeping predefined cloud)* jailhouse/apps/nextcloud/* (keeping existing directories *config, themes & db)
          All directories 100% cleaned up – yet service refuse to start
          Tried this like 5 times now, and finally resorted to reverted to a clean config – but same issue persist
          No idea whats going on here – In effect theres nothing left tied to nextcloud jail (starting to think theres something outside affecting this now *but no idea why and have followed these instruction to the letter (over and over again 🙁 )

          1. Im confused, are you saying you have or havent deleted the db dataset? If you havent, you should

          2. Just decided to take u up on the idea of nuking everything *including the apps/config, db and themes.
            No issues deleting the config and themes pool – BUT the db throws “ERROR deleting dataset”
            hm… something is hogging this directory causing issues *like initial post describing my issues starting mariadb
            This error using the web interface dont give me anything but the “Error deleting dataset”
            Moving up one level trying to do the same with the nextcloud pool results in the same error
            Owner of the apps/nextcloud is root
            weirdly enough the owner of the db was “user” = tried to change that to root, but still cant delete either pools

  36. I have * and I did!!!! I left the folders though – now managed to delete the entire apps/nextcloud structure and will try to re-create everything from scratch again – hopefully it sorts itself

    1. once I removed the pools and started again it seem to work *as far as starting the maria service * – trust the rest would work out

      A bit weird that pools empty ones would cause issues, but who knows …. I sure tell tale of something driving someone up the wall throwing things – weird

      1. As mentioned earlier, they werent empty. They contain the files necessary to restore an existing nextcloud installation. Deleting them meant you could start fresh

      2. Ok, Finally back on track – experienced the same issue with redirect issue once entered the cloud initial setup
        Work around was to: su -m www -c “php /usr/local/www/nextcloud/occ app:enable twofactor_backupcodes”
        That fixed the issue and I could proceed with setting things up inside nc

        Another really weird issue I came across is the fstab frequently dropping all its definition
        * Actually what happens is that the fstab gets corrupt where previous definitions ends up in a long string that wont be recognized by the system start
        Common thing seem to be when you add nested folders and/or decide to edit a mount point – Had this happening like 10 times now where I had to re-create most mount points.
        Usually one or two def still linger where the rest end up in a loooooong string inside the fstab
        * possible a bug
        Simple test:
        1. create a folder inside the jail and create a mount point using iocage
        2a. add another nested folder and point that to a different location and add the mount point
        *Disaster!!!!
        1. create a folder inside the jail and create a mount point using iocage
        2. enter the web interface for the jail and bring up the mount points – then edit one of them by renaming the jail folder
        * Disaster!!!!
        Results in fstab entries being screwed up

  37. @Martin
    I’m glad you got the nextcloud issue resolved. Just a few things — the directory structure under /usr/local/www/nextcloud should always be www:www. Sometimes if you edit files as a different user, your editor will save the file under a different user — for example su will save the files as root:root or root:wheel. You need to make sure if youre having issues the file permissions and ownerships are correct

    In terms of the mount point disaster. I can’t say for certain what your issue is. I can only offfer something else you may want to try. I created all my datasets within the FreeNAS gui itself, and not on the command line. By creating all the mount points within the FreeNAS gui and then sharing the selected datasets with the jail as configured through the gui, I never actually had to edit any fstab files. In my limited experience, jails can be kind of tricky to use. Although the iocage fstab commands should always technically “work”, if things are done manually on the command line, they don’t always show up within the freenas gui. I’ve found by doing mounting most of the datasets using the FreeNas gui, the mountpoints seem more robust. I have no explanation why using the GUI is more robust since behind the scenes I believe it is using the same fstab commands, other than it just seems to be more reliable in my experience.

    If you are having issues with fstab mount points becoming corrupted, why don’t you try sharing the dataset (or mountpoint) using the GUI rather then using the iocage fstab commands. After you try this, I’m OK if you tell me my idea is full of s**t.

    1. Its actually the gui that is corrupting t he fstab – NOT the iocage command itself.

      Still have some issues to sass out though.
      Like putting nc in maintenance mode.
      When I run the command: su -m www -c ‘php /usr/local/www/nextcloud/occ maintenance:mode –on’
      It throws back an error: Too many arguments, expected arguments “command”.

      I also struggle with how I could mount pools that in effect should be owned by individual users *accessible from both local file systems and nextcloud.
      Adding a mount point and then map it to a group tied to a user makes it visible to user logged on to nc. But its only READ ONLY access.
      The other way around would be to copy old shared content across to the users container inside nc i.e vault/cloud//files/
      That would make the content fully accessible by the user logged on to nc.
      Problem with this approach is that any content created from within nc ends up with www:www (owner/group) that prevent the user from modifying any of the files from outside nc
      I would also need to create a SMB share to the folder structure vault/cloud//files/
      But permission would be a major issue
      In effect I want a private user shares to be fully manageable by set users from within nc and outside where content created from with nc should have the user and owner (not www:www as it is now)

      1. Ok, Think I worked the shares out – simply need to enforce the ownership as part of the SMB share creation under the aux (force user = www) – Then I can set the ownership to the user in question with a group of www as part of the pool creation – works! – happy with that – Now both the user using the nc cloud app as well as user switching to their smb share over the local network can work freely with whats there

        My next challenge is to secure the nc and change it to use https (not familar with apache when it comes to this – quite simple setting it up on lighttpd that I used in the past – but now theres new challenges with different ways of doing things – never ends does it 😉

  38. yea – all hm most actually good
    One small issue that screws with my head

    When logging on using my public ip i.e https://xxx.xxx.xxx.xxx:port and I want to recover a lost password, no email is sent through to the user.
    Doing the same via my local ip works perfectly

    Sending a test email as admin from the public gateway works as well

    What is going on with that????

    User have valid email registered and nothing ends up in a spam folder *dont think the email is being sent at all
    Checked the nc logs and nothing indicating any errors or issues

    suggestions…?

    Sort of become an important feature for users to recover/reset lost passwords using the public gateway

    1. Sorry mate, looks like you’ve hit a point beyond my expertise. I’d recommend heading over to the Nextcloud forums or #nextcloud in IRC.

  39. I have only had to run this installation once and everything works like a charm. It is the best instruction I have read so far in the internet. On everything. Hands down.

    Only thing missing is that I now get two notifications:

    This instance is missing some recommended PHP modules. For improved performance and better compatibility it is highly recommended to install them.
    imagick

    Some columns in the database are missing a conversion to big int. Due to the fact that changing column types on big tables could take some time they were not changed automatically. By running ‘occ db:convert-filecache-bigint’ those pending changes could be applied manually. This operation needs to be made while the instance is offline. For further details read the documentation page about this.
    filecache.mtime
    filecache.storage_mtime

    If these could be fixed…I’ll get a whole keg not just a beer 🙂

    1. Hi Alpha, to resolve the bigint conversion issue, execute the following commands:

      su -m www -c 'php /usr/local/www/nextcloud/occ maintenance:mode –on'
      su -m www -c 'php /usr/local/www/nextcloud/occ db:convert-filecache-bigint'
      su -m www -c 'php /usr/local/www/nextcloud/occ maintenance:mode –off'
      

      To resolve the imagick issue, I’m pretty sure you just install the imagick php package for the php version you chose, i.e. pkg install php72-pecl-imagick, changing php72 for whatever is relevant for you (make sure you’re inside the jail). I’m pretty sure this was the solution when I resolved it for myself; these are things on my backlog to add to the guide when I get time, but I’ve been pretty swamped recently so I just haven’t had a chance.

    2. Hi together, regarding the imagick issue I suggest to wait for another nextcloud update. Imagick has some security issues and the developers want to remove the hint in the Info page of NC. ->Google

  40. Good evening !

    Thank you for your post, it’s actually very helpful, can’t find better.

    Everything is very well explicated…but…yes there is a but (unfornately just for me I guess).

    I try to find a solution by myself but I can’t find anything on the Web, hope you’ll could help me.

    So, I followed all your instructions and I cannot reach my NextCloud page by HTTPS on my domain. Everything worked fine in local at the beginning but I can’t even connect to my page locally.

    Here is my httpd-error.log :
    [Sat Mar 30 23:43:01.640184 2019] [core:info] [pid 91289] AH00096: removed PID file /var/run/httpd.pid (pid=91289)
    [Sat Mar 30 23:43:01.640234 2019] [mpm_prefork:notice] [pid 91289] AH00169: caught SIGTERM, shutting down
    [Sat Mar 30 23:43:01.791370 2019] [ssl:info] [pid 91550] AH01887: Init: Initializing (virtual) servers for SSL
    [Sat Mar 30 23:43:01.791666 2019] [ssl:info] [pid 91550] AH01914: Configuring server subdomain.mydomain.com:443 for SSL protocol
    [Sat Mar 30 23:43:01.791683 2019] [ssl:debug] [pid 91550] ssl_engine_init.c(1748): AH10083: Init: (subdomain.mydomain.com:443) mod_md support is unavailable.
    [Sat Mar 30 23:43:01.791848 2019] [ssl:debug] [pid 91550] ssl_engine_init.c(478): AH01893: Configuring TLS extension handling
    [Sat Mar 30 23:43:01.792007 2019] [ssl:debug] [pid 91550] ssl_util_stapling.c(868): AH01960: OCSP stapling initialized
    [Sat Mar 30 23:43:01.792415 2019] [ssl:debug] [pid 91550] ssl_util_ssl.c(476): AH02412: [subdomain.mydomain.com:443] Cert matches for name ‘subdomain.mydomain.com’ [subject: CN=subdomain.mydomain.com / issuer: CN=Let’s Encrypt Authority X3,O=Let’s Encrypt,C=US / serial: 0323374E984CE4C11536F2B0F3115BCAC378 / notbefore: Mar 30 17:24:12 2019 GMT / notafter: Jun 28 17:24:12 2019 GMT]
    [Sat Mar 30 23:43:01.792435 2019] [ssl:info] [pid 91550] AH02568: Certificate and private key subdomain.mydomain.com:443:0 configured from /usr/local/etc/letsencrypt/live/subdomain.mydomain.com/fullchain.pem and /usr/local/etc/letsencrypt/live/subdomain.mydomain.com/privkey.pem
    [Sat Mar 30 23:43:01.792755 2019] [ssl:info] [pid 91550] AH01876: mod_ssl/2.4.38 compiled against Server: Apache/2.4.38, Library: OpenSSL/1.0.2o-freebsd
    [Sat Mar 30 23:43:01.812073 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(398): AH00821: shmcb_init allocated 32768 bytes of shared memory
    [Sat Mar 30 23:43:01.812101 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(412): AH00822: for 32680 bytes (32768 including header), recommending 2 subcaches, 10 indexes each
    [Sat Mar 30 23:43:01.812117 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(449): AH00824: shmcb_init_memory choices follow
    [Sat Mar 30 23:43:01.812131 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(451): AH00825: subcache_num = 2
    [Sat Mar 30 23:43:01.812145 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(453): AH00826: subcache_size = 16336
    [Sat Mar 30 23:43:01.812159 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(455): AH00827: subcache_data_offset = 256
    [Sat Mar 30 23:43:01.812173 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(457): AH00828: subcache_data_size = 16080
    [Sat Mar 30 23:43:01.812187 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(459): AH00829: index_num = 10
    [Sat Mar 30 23:43:01.812205 2019] [socache_shmcb:info] [pid 91551] AH00830: Shared memory socache initialised
    [Sat Mar 30 23:43:01.812226 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(398): AH00821: shmcb_init allocated 512000 bytes of shared memory
    [Sat Mar 30 23:43:01.812240 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(412): AH00822: for 511912 bytes (512000 including header), recommending 32 subcaches, 88 indexes each
    [Sat Mar 30 23:43:01.812255 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(449): AH00824: shmcb_init_memory choices follow
    [Sat Mar 30 23:43:01.812269 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(451): AH00825: subcache_num = 32
    [Sat Mar 30 23:43:01.812282 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(453): AH00826: subcache_size = 15992
    [Sat Mar 30 23:43:01.812296 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(455): AH00827: subcache_data_offset = 2128
    [Sat Mar 30 23:43:01.812310 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(457): AH00828: subcache_data_size = 13864
    [Sat Mar 30 23:43:01.812324 2019] [socache_shmcb:debug] [pid 91551] mod_socache_shmcb.c(459): AH00829: index_num = 88
    [Sat Mar 30 23:43:01.812407 2019] [socache_shmcb:info] [pid 91551] AH00830: Shared memory socache initialised
    [Sat Mar 30 23:43:01.812423 2019] [ssl:info] [pid 91551] AH01887: Init: Initializing (virtual) servers for SSL
    [Sat Mar 30 23:43:01.812437 2019] [ssl:info] [pid 91551] AH01914: Configuring server subdomain.mydomain.com:443 for SSL protocol
    [Sat Mar 30 23:43:01.812452 2019] [ssl:debug] [pid 91551] ssl_engine_init.c(1748): AH10083: Init: (subdomain.mydomain.com:443) mod_md support is unavailable.
    [Sat Mar 30 23:43:01.812633 2019] [ssl:debug] [pid 91551] ssl_engine_init.c(478): AH01893: Configuring TLS extension handling
    [Sat Mar 30 23:43:01.812652 2019] [ssl:debug] [pid 91551] ssl_util_stapling.c(868): AH01960: OCSP stapling initialized
    [Sat Mar 30 23:43:01.813067 2019] [ssl:debug] [pid 91551] ssl_util_ssl.c(476): AH02412: [subdomain.mydomain.com:443] Cert matches for name ‘subdomain.mydomain.com’ [subject: CN=subdomain.mydomain.com / issuer: CN=Let’s Encrypt Authority X3,O=Let’s Encrypt,C=US / serial: 0323374E984CE4C11536F2B0F3115BCAC378 / notbefore: Mar 30 17:24:12 2019 GMT / notafter: Jun 28 17:24:12 2019 GMT]
    [Sat Mar 30 23:43:01.813087 2019] [ssl:info] [pid 91551] AH02568: Certificate and private key subdomain.mydomain.com:443:0 configured from /usr/local/etc/letsencrypt/live/subdomain.mydomain.com/fullchain.pem and /usr/local/etc/letsencrypt/live/subdomain.mydomain.com/privkey.pem
    [Sat Mar 30 23:43:01.813413 2019] [ssl:info] [pid 91551] AH01876: mod_ssl/2.4.38 compiled against Server: Apache/2.4.38, Library: OpenSSL/1.0.2o-freebsd
    [Sat Mar 30 23:43:01.815156 2019] [proxy:debug] [pid 91552] proxy_util.c(1925): AH00925: initializing worker proxy:reverse shared
    [Sat Mar 30 23:43:01.815192 2019] [proxy:debug] [pid 91552] proxy_util.c(1982): AH00927: initializing worker proxy:reverse local
    [Sat Mar 30 23:43:01.815247 2019] [proxy:debug] [pid 91552] proxy_util.c(2033): AH00931: initialized single connection worker in child 91552 for ()
    [Sat Mar 30 23:43:01.815428 2019] [proxy:debug] [pid 91553] proxy_util.c(1925): AH00925: initializing worker proxy:reverse shared
    [Sat Mar 30 23:43:01.815458 2019] [proxy:debug] [pid 91553] proxy_util.c(1982): AH00927: initializing worker proxy:reverse local
    [Sat Mar 30 23:43:01.815507 2019] [proxy:debug] [pid 91553] proxy_util.c(2033): AH00931: initialized single connection worker in child 91553 for (
    )
    [Sat Mar 30 23:43:01.815777 2019] [mpm_prefork:notice] [pid 91551] AH00163: Apache/2.4.38 (FreeBSD) OpenSSL/1.0.2o-freebsd configured — resuming normal operations
    [Sat Mar 30 23:43:01.815807 2019] [mpm_prefork:info] [pid 91551] AH00164: Server built: unknown
    [Sat Mar 30 23:43:01.815849 2019] [core:notice] [pid 91551] AH00094: Command line: ‘/usr/local/sbin/httpd -D NOHTTPACCEPT’
    [Sat Mar 30 23:43:01.815865 2019] [core:debug] [pid 91551] log.c(1568): AH02639: Using SO_REUSEPORT: no (1)
    [Sat Mar 30 23:43:01.815881 2019] [mpm_prefork:debug] [pid 91551] prefork.c(918): AH00165: Accept mutex: flock (default: flock)
    [Sat Mar 30 23:43:01.816043 2019] [proxy:debug] [pid 91554] proxy_util.c(1925): AH00925: initializing worker proxy:reverse shared
    [Sat Mar 30 23:43:01.816069 2019] [proxy:debug] [pid 91554] proxy_util.c(1982): AH00927: initializing worker proxy:reverse local
    [Sat Mar 30 23:43:01.816115 2019] [proxy:debug] [pid 91554] proxy_util.c(2033): AH00931: initialized single connection worker in child 91554 for ()
    [Sat Mar 30 23:43:01.816275 2019] [proxy:debug] [pid 91555] proxy_util.c(1925): AH00925: initializing worker proxy:reverse shared
    [Sat Mar 30 23:43:01.816301 2019] [proxy:debug] [pid 91555] proxy_util.c(1982): AH00927: initializing worker proxy:reverse local
    [Sat Mar 30 23:43:01.816348 2019] [proxy:debug] [pid 91555] proxy_util.c(2033): AH00931: initialized single connection worker in child 91555 for (
    )
    [Sat Mar 30 23:43:01.816663 2019] [proxy:debug] [pid 91556] proxy_util.c(1925): AH00925: initializing worker proxy:reverse shared
    [Sat Mar 30 23:43:01.816689 2019] [proxy:debug] [pid 91556] proxy_util.c(1982): AH00927: initializing worker proxy:reverse local
    [Sat Mar 30 23:43:01.816733 2019] [proxy:debug] [pid 91556] proxy_util.c(2033): AH00931: initialized single connection worker in child 91556 for ()
    [Sat Mar 30 23:43:06.560526 2019] [ssl:info] [pid 91552] [client 81.49.167.221:57804] AH01964: Connection to child 0 established (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:43:06.596909 2019] [ssl:info] [pid 91553] [client 81.49.167.221:57805] AH01964: Connection to child 1 established (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:43:07.006621 2019] [proxy:debug] [pid 91557] proxy_util.c(1925): AH00925: initializing worker proxy:reverse shared
    [Sat Mar 30 23:43:07.006685 2019] [proxy:debug] [pid 91557] proxy_util.c(1982): AH00927: initializing worker proxy:reverse local
    [Sat Mar 30 23:43:07.006737 2019] [proxy:debug] [pid 91557] proxy_util.c(2033): AH00931: initialized single connection worker in child 91557 for (
    )
    [Sat Mar 30 23:43:08.068583 2019] [proxy:debug] [pid 91558] proxy_util.c(1925): AH00925: initializing worker proxy:reverse shared
    [Sat Mar 30 23:43:08.068642 2019] [proxy:debug] [pid 91558] proxy_util.c(1982): AH00927: initializing worker proxy:reverse local
    [Sat Mar 30 23:43:08.068694 2019] [proxy:debug] [pid 91558] proxy_util.c(2033): AH00931: initialized single connection worker in child 91558 for ()
    [Sat Mar 30 23:43:08.068825 2019] [proxy:debug] [pid 91559] proxy_util.c(1925): AH00925: initializing worker proxy:reverse shared
    [Sat Mar 30 23:43:08.068883 2019] [proxy:debug] [pid 91559] proxy_util.c(1982): AH00927: initializing worker proxy:reverse local
    [Sat Mar 30 23:43:08.068927 2019] [proxy:debug] [pid 91559] proxy_util.c(2033): AH00931: initialized single connection worker in child 91559 for (
    )
    [Sat Mar 30 23:43:25.501091 2019] [ssl:info] [pid 91554] [client 81.49.167.221:57806] AH01964: Connection to child 2 established (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:43:44.406529 2019] [ssl:info] [pid 91555] [client 81.49.167.221:57807] AH01964: Connection to child 3 established (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:43:45.229783 2019] [proxy:debug] [pid 91560] proxy_util.c(1925): AH00925: initializing worker proxy:reverse shared
    [Sat Mar 30 23:43:45.229842 2019] [proxy:debug] [pid 91560] proxy_util.c(1982): AH00927: initializing worker proxy:reverse local
    [Sat Mar 30 23:43:45.229894 2019] [proxy:debug] [pid 91560] proxy_util.c(2033): AH00931: initialized single connection worker in child 91560 for ()
    [Sat Mar 30 23:44:03.310910 2019] [ssl:info] [pid 91556] [client 81.49.167.221:57808] AH01964: Connection to child 4 established (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:44:03.901537 2019] [proxy:debug] [pid 91744] proxy_util.c(1925): AH00925: initializing worker proxy:reverse shared
    [Sat Mar 30 23:44:03.901611 2019] [proxy:debug] [pid 91744] proxy_util.c(1982): AH00927: initializing worker proxy:reverse local
    [Sat Mar 30 23:44:03.901666 2019] [proxy:debug] [pid 91744] proxy_util.c(2033): AH00931: initialized single connection worker in child 91744 for (
    )
    [Sat Mar 30 23:44:06.587670 2019] [ssl:debug] [pid 91552] ssl_engine_io.c(1370): (70007)The timeout specified has expired: [client 81.49.167.221:57804] AH02007: SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
    [Sat Mar 30 23:44:06.587740 2019] [ssl:info] [pid 91552] [client 81.49.167.221:57804] AH01998: Connection closed to child 0 with abortive shutdown (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:44:06.694884 2019] [ssl:debug] [pid 91553] ssl_engine_io.c(1370): (70007)The timeout specified has expired: [client 81.49.167.221:57805] AH02007: SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
    [Sat Mar 30 23:44:06.694942 2019] [ssl:info] [pid 91553] [client 81.49.167.221:57805] AH01998: Connection closed to child 1 with abortive shutdown (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:44:22.215315 2019] [ssl:info] [pid 91557] [client 81.49.167.221:57810] AH01964: Connection to child 5 established (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:44:25.509141 2019] [ssl:debug] [pid 91554] ssl_engine_io.c(1370): (70007)The timeout specified has expired: [client 81.49.167.221:57806] AH02007: SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
    [Sat Mar 30 23:44:25.509238 2019] [ssl:info] [pid 91554] [client 81.49.167.221:57806] AH01998: Connection closed to child 2 with abortive shutdown (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:44:41.120410 2019] [ssl:info] [pid 91558] [client 81.49.167.221:57815] AH01964: Connection to child 6 established (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:44:44.416981 2019] [ssl:debug] [pid 91555] ssl_engine_io.c(1370): (70007)The timeout specified has expired: [client 81.49.167.221:57807] AH02007: SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
    [Sat Mar 30 23:44:44.417080 2019] [ssl:info] [pid 91555] [client 81.49.167.221:57807] AH01998: Connection closed to child 3 with abortive shutdown (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:45:00.022003 2019] [ssl:info] [pid 91559] [client 81.49.167.221:57833] AH01964: Connection to child 7 established (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:45:03.349918 2019] [ssl:debug] [pid 91556] ssl_engine_io.c(1370): (70007)The timeout specified has expired: [client 81.49.167.221:57808] AH02007: SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
    [Sat Mar 30 23:45:03.349995 2019] [ssl:info] [pid 91556] [client 81.49.167.221:57808] AH01998: Connection closed to child 4 with abortive shutdown (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:45:18.926668 2019] [ssl:info] [pid 91560] [client 81.49.167.221:57838] AH01964: Connection to child 8 established (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:45:22.307392 2019] [ssl:debug] [pid 91557] ssl_engine_io.c(1370): (70007)The timeout specified has expired: [client 81.49.167.221:57810] AH02007: SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
    [Sat Mar 30 23:45:22.307513 2019] [ssl:info] [pid 91557] [client 81.49.167.221:57810] AH01998: Connection closed to child 5 with abortive shutdown (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:45:37.831702 2019] [ssl:info] [pid 91744] [client 81.49.167.221:57855] AH01964: Connection to child 9 established (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:45:41.154260 2019] [ssl:debug] [pid 91558] ssl_engine_io.c(1370): (70007)The timeout specified has expired: [client 81.49.167.221:57815] AH02007: SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
    [Sat Mar 30 23:45:41.154365 2019] [ssl:info] [pid 91558] [client 81.49.167.221:57815] AH01998: Connection closed to child 6 with abortive shutdown (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:45:56.737935 2019] [ssl:info] [pid 91552] [client 81.49.167.221:57858] AH01964: Connection to child 0 established (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:46:00.030865 2019] [ssl:debug] [pid 91559] ssl_engine_io.c(1370): (70007)The timeout specified has expired: [client 81.49.167.221:57833] AH02007: SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
    [Sat Mar 30 23:46:00.030970 2019] [ssl:info] [pid 91559] [client 81.49.167.221:57833] AH01998: Connection closed to child 7 with abortive shutdown (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:46:18.987485 2019] [ssl:debug] [pid 91560] ssl_engine_io.c(1370): (70007)The timeout specified has expired: [client 81.49.167.221:57838] AH02007: SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
    [Sat Mar 30 23:46:18.987583 2019] [ssl:info] [pid 91560] [client 81.49.167.221:57838] AH01998: Connection closed to child 8 with abortive shutdown (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:46:37.834633 2019] [ssl:debug] [pid 91744] ssl_engine_io.c(1370): (70007)The timeout specified has expired: [client 81.49.167.221:57855] AH02007: SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
    [Sat Mar 30 23:46:37.834725 2019] [ssl:info] [pid 91744] [client 81.49.167.221:57855] AH01998: Connection closed to child 9 with abortive shutdown (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:46:41.111877 2019] [ssl:info] [pid 91553] [client 81.49.167.221:57862] AH01964: Connection to child 1 established (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:46:56.856564 2019] [ssl:debug] [pid 91552] ssl_engine_io.c(1370): (70007)The timeout specified has expired: [client 81.49.167.221:57858] AH02007: SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
    [Sat Mar 30 23:46:56.856687 2019] [ssl:info] [pid 91552] [client 81.49.167.221:57858] AH01998: Connection closed to child 0 with abortive shutdown (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:47:00.017634 2019] [ssl:info] [pid 91554] [client 81.49.167.221:57864] AH01964: Connection to child 2 established (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:47:41.194563 2019] [ssl:debug] [pid 91553] ssl_engine_io.c(1370): (70007)The timeout specified has expired: [client 81.49.167.221:57862] AH02007: SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
    [Sat Mar 30 23:47:41.194668 2019] [ssl:info] [pid 91553] [client 81.49.167.221:57862] AH01998: Connection closed to child 1 with abortive shutdown (server subdomain.mydomain.com:443)
    [Sat Mar 30 23:48:00.039653 2019] [ssl:debug] [pid 91554] ssl_engine_io.c(1370): (70007)The timeout specified has expired: [client 81.49.167.221:57864] AH02007: SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
    [Sat Mar 30 23:48:00.039755 2019] [ssl:info] [pid 91554] [client 81.49.167.221:57864] AH01998: Connection closed to child 2 with abortive shutdown (server subdomain.mydomain.com:443)

    It seems that my problem is linked to my SSL, I can’t figure how. Let’s Encrypt seems working perfectly.

    Hope someone could help me, thank you !

    P.S : Sorry for my poor english. Be french and be stuck on this problem for hours don’t help for this 😀

    1. Hi Maxime, I’m not sure what’s causing your problem unfortunately, nothing really stands out in your logs aside from perhaps:

      [Sat Mar 30 23:47:41.194563 2019] [ssl:debug] [pid 91553] ssl_engine_io.c(1370): (70007)The timeout specified has expired: [client 81.49.167.221:57862] AH02007: SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]
      

      or perhaps

      [Sat Mar 30 23:43:01.791683 2019] [ssl:debug] [pid 91550] ssl_engine_init.c(1748): AH10083: Init: (subdomain.mydomain.com:443) mod_md support is unavailable.
      [Sat Mar 30 23:43:01.791848 2019] [ssl:debug] [pid 91550] 
      

      I’ve never run into either of these issues though so I’m not going to be much help. I’d advise heading over to the #httpd channel on IRC; they’ll be able to help you work through it.

      Cheers

      1. Good morning !

        I found the solution during this week. It’s not link to NextCloud at all, it was an hairpinning.

        If you meet the same problem as me, try to connect to your subdomain.domain.com from Tor or your cellphone in 4G. If it’s working on it but not on your local network, you have an hairpin problem.

        To solve this, I had to change my router, hope you will not have to do this.

        Thank you very much for your help anyway

  41. Any ideas on what’s causing this error?

    mount_nullfs: /mnt/jailhouse: No such file or directory
    jail: /sbin/mount -t nullfs -o rw /mnt/jailhouse/apps/nextcloud/db /mnt/BigDrive1/iocage/jails/nextcloud/root/var/db/mysql: failed

    1. Sure, it doesn’t look like you have a dataset named jailhouse; did you set up your directory structure the same way I described? It looks like you need to replace the instances of jailhouse with BigDrive1

      1. I see the mistake now. I changed jailhouse to BigDrive1 all the way through but a made the mistake of doing the first mount point like the example, so I had 5 mount points instead 4. Everything was working until I installed the last freenas update then it broke. Now I can’t delete the mount point using the GUI. The error I get is “name ‘collections’ is not defined”. It looks like I’m stuck until the next update comes out.

        https://www.ixsystems.com/community/threads/nameerror-name-collections-is-not-defined-after-update.74058/

  42. Good afternoon,

    I can use some help with my current problem with this install. I have eavrything working great and all is well except when i try to up load a file that is 35 gigabytes nextcloud. i have tried uploading via a WebDAV mapped drive and the web interface but it keeps telling me that the file is too large. the steps i took to resolve this is to update the $ nano /usr/local/etc/php.ini and change the size values below to 50G

    post_max_size = 50G
    upload_max_filesize = 50G

    then i restart Apache and php-fpm

    $ service php-fpm restart
    $ service apache24 restart

    but it still will not take the 35 gb file. any advice on this would be greatly appreciated.

    Thank you.

    1. David, I suspect that because we enabled the use of .htaccess files, the default values in the nextcloud .htaccess is overriding what’s in php.ini. Try opening /usr/local/www/nextcloud/.htaccess and adjust the same parameters you need to here, reload the server and see if there are any changes. I also remember reading somewhere that changes may take up to 5 mins to propagate.

      Cheers

      1. Thank you Samual for info on the .htaccess file. i did the changes you suggested reset the server and waiting 10 min but it still is not letting me upload large files. can you take a look at the file below and see if there is anythign else i can cange on it that would posably make this work? Does it have anything to do with the Memory_limit 512M?

        Let browsers cache WOFF files for a week

        Header set Cache-Control “max-age=604800”

        php_value upload_max_filesize 50G
        php_value post_max_size 50G
        php_value memory_limit 512M
        php_value mbstring.func_overload 0
        php_value always_populate_raw_post_data -1
        php_value default_charset ‘UTF-8’
        php_value output_buffering 0

        SetEnv htaccessWorking true

        php_value upload_max_filesize 50G
        php_value post_max_size 50G
        php_value memory_limit 512M
        php_value mbstring.func_overload 0
        php_value default_charset ‘UTF-8’
        php_value output_buffering 0

        SetEnv htaccessWorking true

  43. Hello Samuel,
    This is by far the best Guide to install Nextcloud on freenas.

    Actually everything worked very well until the end.

    But after the login on the GUI I get a forwarding error.

    The GUI redirects me to http://www.mydomain.com/Apps/files/ and I get the error message of the redirection error.

    What could be the reason?

    Thomas

    1. Thomas, can you post the contents of your config.php file? I suspect it’s missing the appropriate apps-pkg redirects. Explicitly, make sure it contains this at the top:

       'apps_paths' =>
        array (
          0 =>
          array (
            'path' => '/usr/local/www/nextcloud/apps',
            'url' => '/apps',
            'writable' => true,
          ),
          1 =>
          array (
            'path' => '/usr/local/www/nextcloud/apps-pkg',
            'url' => '/apps-pkg',
            'writable' => false,
          ),
        ),
      

      This should go BELOW

      <?php
       $CONFIG = array (
      

      and ABOVE

      ‘instanceid’ => ‘redacted’,
      

      Also, can you share the details of your installation method? I.e., did you install from the quarterly or latest branch? Did you install nextcloud-php71, nextcloud-php72, or nextcloud-php73? Any other information that would describe some of the choices you made when installing would also be appreciated.

      Cheers

      1. Hi Samuel,
        at first, thanks for your help.
        I’ve installed nextcloud-php71-

        I’ve forget to paste the following part in config.php.
        ‘apps_paths’ =>
        array (
        0 =>
        array (
        ‘path’ => ‘/usr/local/www/nextcloud/apps’,
        ‘url’ => ‘/apps’,
        ‘writable’ => true,
        ),
        1 =>
        array (
        ‘path’ => ‘/usr/local/www/nextcloud/apps-pkg’,
        ‘url’ => ‘/apps-pkg’,
        ‘writable’ => false,
        ),

        After I’ve added this I get an “Internal Server Error” Message from my Nextcloud GUI.
        No Login possible anymore.

        Here is my config.php:
        I’ve removed the passwords and domain.

        <?php
        $CONFIG = array (
        ‘apps_paths’ =>
        array (
        0 =>
        array (
        ‘path’ => ‘/usr/local/www/nextcloud/apps’,
        ‘url’ => ‘/apps’,
        ‘writable’ => true,
        ),
        1 =>
        array (
        ‘path’ => ‘/usr/local/www/nextcloud/apps-pkg’,
        ‘url’ => ‘/apps-pkg’,
        ‘writable’ => false,
        ),
        ),
        ‘logfile’ => ‘/var/log/nextcloud/nextcloud.log’,
        ‘memcache.local’ => ‘\OC\Memcache\APCu’,
        ‘instanceid’ => ‘oc7a4ybhff7f’,
        ‘passwordsalt’ => ‘xxx’,
        ‘secret’ => ‘xxx’,
        ‘trusted_domains’ =>
        array (
        0 => ‘192.168.1.10’,
        1 => ‘mydomain.com’,
        ),
        ‘datadirectory’ => ‘/mnt/data’,
        ‘dbtype’ => ‘mysql’,
        ‘version’ => ‘15.0.5.3’,
        ‘overwrite.cli.url’ => ‘http://192.168.1.10’,
        ‘dbname’ => ‘nextcloud’,
        ‘dbhost’ => ‘localhost:/tmp/mysql.sock’,
        ‘dbport’ => ”,
        ‘dbtableprefix’ => ‘oc_’,
        ‘mysql.utf8mb4’ => true,
        ‘dbuser’ => ‘nextcloud_admin’,
        ‘dbpassword’ => ‘xxx’,
        ‘installed’ => true,
        ‘redis’ =>
        array (
        ‘host’ => ‘/tmp/redis.sock’,
        ‘port’ => 0,
        ),
        ‘memcache.local’ => ‘\OC\Memcache\APCu’,
        ‘memcache.locking’ => ‘\OC\Memcache\Redis’,
        ‘enable_previews’ => false,
        );

        1. Thomas,

          That’s progress. I’d suggest looking in the nextcloud log to see if anything stands out. Everything in your config.php file looks okay, though you might have some luck changing the instances of APCu to Redis. The log should indicate if there are any errors with caching though.

          Cheers

  44. Hello,

    Many thanks for this tuto that was very helpful!!
    I’ve just got one question/problem : with certbot, it appears that if you do a permanent redirect with the http (:80) on the VirtualHost to HTTPS, certbot cannot renew the certificate (“failed authorization procedure” error). Is there a way to let the certificate renew without having to desactivate temporarily SSL?

    Thanks again!

    1. Not to my (limited) knowledge Adrien. This sounds like a good question for the ##letsencrypt IRC channel though. As mentioned in the blog, I renew via DNS so this isn’t a problem that I’ve had to tackle.

  45. Hi, Samuel!

    EXCELLENT guide – I found it incredibly helpful!

    I’m running into just one small issue that I cannot figure out, despite a couple of hours of trial-and-error and experimenting.

    Here’s a quick rundown of my setup:
    NextCloud 15
    Running on FreeBSD 11.2-RELEASE-p9
    Duck DNS DynDNS Service with Port Forwarding Working

    I have two Apache rules in a configuration file:

    ServerName DuckDNS_address
    Redirect permanent / https://DuckDNS_address
    and

    ServerAdmin me@here.com
    ServerName server_name

    SetHandler “proxy:fcgi://127.0.0.1:9000/”

    DirectoryIndex /index.php index.php
    DocumentRoot “/usr/local/www/nextcloud”
    SSLCertificateFile correct_path
    SSLCertificateKeyFile correct_path
    SSLEngine on

    Header always set Strict-Transport-Security “max-age=15552000; >

    When I first start apache, and I use either http://DuckDNS_address or https://DuckDNS_address, it works (always directing to https://DuckDNS_address) from either within my network or from outside of it. However, after about 20 seconds, the UI will no longer resolve from within my network, but it continues to work fine from outside my network.

    If I add an additional directive in the CONF file, matching the local IP address of the NextCloud instance (and port 80), I can get it to work internally. However, this causes a problem with mobile devices: I either have to use the local address and not have the instance work outside my network) or the DuckDNS address (and not have the instance work while I’m connected to my local network).

    I can reliably reproduce this behavior, but cannot for the life of me figure out what might be failing. I’d be grateful for any help or guidance!

    1. It seems like the issue is that you can only have one specification of server address for your server. The way I dealt with this was to, instead of using the IP address of the external server, use the DNS name. i.e. cloud.ddns.net (or whatever it is). This should resolve correctly when you’re outside of your home network. To make it accessible from within your home network as well, add a DNS Resolver entry to your router (assuming you use pfSense!) such that any internal dns query to cloud.ddns.net returns your servers internal address, i.e. 192.168.0.10. This just means that your router intercepts your DNS request and provides you with the preferred internal IP rather than the external IP.

      Hope this helps.

      Cheers.

  46. Hi Samuel,

    Thank you for putting in the effort to write this excellent guide. I got everything installed and configured but once I got to the Nextcloud setup screen on my browser, entered all the credentials and tried to ‘Finish Setup’ I received a ‘Can’t create or write into the data directory /mnt/data ‘ error. I triple checked the entire setup and can’t find my mistake. I entered the ‘chown -R www:www /usr/local/www/nextcloud /mnt/data’ command to set permissions but I wonder if maybe there is there another directory that needs permissions?

    I’d be very grateful for any insights you could provide.

    1. Hi Parrish, you can list the permissions associated with all directories in mnt by passing the -l flag to ls, i.e: ls -l /mnt/. This should show you all of the rwx permissions for each directory inside /mnt. Ideally, you want /mnt/data to have at least rwx------ permissions (first three listed is owner, second three is group, third three is other), or some variation thereof where either the www user OR the www group has write permission, so rwxrwxr-- or something similar. It’s hard for me to explain how the permissions work in this format, so it might be easier if you just read the documentation on FreeBSD permissions. If the www user doesn’t have rw permissions on the folder, you can use the chmod command to edit these. For your data directory I’d suggest 770 (rwxrwx---) would probably be appropriate (this means that anyone in the www user or group is able to read, write or execute, but users outside of this group can’t read, write or execute anything), so you can execute chmod -R 770 /mnt/data, and this will apply these permissions recursively to all files in the /mnt/data directory.

      This shouldn’t have been required if you followed the way I set the datasets up, but if you had existing datasets you wanted to use then its possible you may not have had the correct permissions already on the dataset. If this doesn’t solve your issue, I’d suggest heading to the #freenas, #freebsd or #nextcloud channels in IRC for support, as it won’t be easy for me to help troubleshoot in this format.

      Cheers.

  47. Hello Samuell,

    I am following your guide and until now it is working like a charm! I am at the point of configuring the 15Min Cron Job for the www user. You are describing the configuration direct in the shell. Would there be any differences planing the same Cron Job through the FreeNAS-GUI, or even just ticking the dialog-box in the Preferences of the Nextcloud-GUI?

    Many regards

    Costis

    1. Hi Costis, I’m not sure! I’ve never set it using either of these methods, but I’d be keen to hear what you find out if you give it a go 🙂 Let me know!

      Cheers

      1. Hi Samuel,

        I tried both methods, through the FreeNAS GUI and through Shell (as you describe on this page). In the first case I kept getting the warning from nextcloud, that no cronjob was recorded for over 24Std. With the shell configuration there are no warnings anymore.

        Meanwhile Nextcloud ist configured and running with letsencrypt certificate according to your guide (I could skip the Route 53 part), although at the beginning I lost access to nextcloud over the local IP and “cloud.mydomain.com”. It worked after changing port forwarding in the router from 80->80 which, as you said was needed for certbot, to 80->443 for SSL. This I don’t understand completely. I thought the following lines in the cloud.medomain.com.config file should take care of that(?) Am I doing something wrong?

        DocumentRoot “/usr/local/www/nextcloud”
        ServerName cloud.mydomain.com
        Redirect permanent / https://cloud.mydomain.com/

        …(rest configuration)…

        Many Greetings

        1. Hi Costis,

          Perhaps I’m not understanding you properly – I don’t talk about a GUI configuration at all, but I’m glad it’s working after configuring it using the shell. With regards to the port forwarding, what I advocate is WAN:80 -> LAN:80 and WAN:443 -> LAN:443, not WAN:80 -> LAN:443. You’re correct, the redirect in the vhost is sufficient to direct the user to an SSL socket, but when your router receives a request for the site over port 443, you need to make sure that the request is directed to the correct host, over port 443 as well.

          Hope this helps.

          Cheers

  48. When I execute the command…

    certbot certonly –webroot -w /usr/local/www/nextcloud -d cloud.mydomain.com
    .
    ..I receive the error…

    certbot: Command not found.

    I am attempting this on Freenas 11.2 with your instructions amended only to use PHP 7.2 instead of 7.1 from the guide. I have removed the certbot package and reinstalled, as well as restarted the entire jail, but I receive the same error when I execute above command. Any help/ideas?

    1. Hi Tony,

      This means that Certbot isn’t installed. Try running the installation command again: pkg install py27-certbot. Pay special attention to any messages you’re given during the installation process. I just spun up a new jail and confirmed that the package isn’t broken or anything, so all you should have to do is install it and the certbot command should be available.

      If this still doesn’t work, run ls -l /usr/local/bin/*certbot*. This should list all installed programs containing ‘certbot’ in the name. Doing this on my system shows:

      lrwxr-xr-x  1 root  wheel   11 Apr  3 10:31 /usr/local/bin/certbot -> certbot-2.7
      -rwxr-xr-x  1 root  wheel  393 Apr  3 10:31 /usr/local/bin/certbot-2.7
      

      This means that what pkg install py27-certbot is actually installing is certbot-2.7. It then creates a symbolic link to certbot. Perhaps this symbolic link creation is failing in your installation, so you might be able to try replacing certbot with certbot-2.7, i.e. certbot-2.7 certonly ....

      Hope this helps.

      Cheers.

      1. Thanks so much. That was exactly the problem.

        BTW, I was able to use an A name on Cloudflare for DynDNS with the script found here…

        https://github.com/jonegerton/cloudflare-ddns/blob/master/cf-ddns.sh

        …with the thing to note about the script being that the cfhost entry has to be in the subdomain.domain.com format and not just the entry name. Then add it to crontab with the line…

        */5 * * * * bash {set file location here}/cf-ddns.sh >/dev/null 2>&1

        …to update every 5 minutes. If there’s no change in public IP (it’s cached), no requests are sent.

        Also, I was finally able to get certbot and LetsEncrypt to succeed by manually creating the <.well-known> folder in the webroot (…/www/nextcloud/.well-known) and manually setting the ownership to www:www

        Thanks for the help and I hope this extra info helps someone else, if you want to add it to the guide.

      2. Yea certbot is now installed on freebsd versions as certbot-2.7. I suppose there is a certbot-3.5 but I haven’t checked (2.7 refers to python version (2.7 or 3.5 respectively)). I had to create a symbolic link since at least with my install certbot was not linked to certbot-2.7. The question was answered above so I guess I’m late to the game.

        1. Strange that you had to do this manually – as I said, I spun up a new jail to test installation of the certbot package and the symbolic link was created automatically. To anybody struggling with this, you can create the symbolic link for python 2.7 with the following command (replace 2.7 with 3.x as required):

          ln -s /usr/local/bin/certbot /usr/local/bin/certbot-2.7
          
  49. Hello i followed your steps with php7.2 and worked perfectly. now i have 2 questions if you are able to help me with.
    1. when i open the jail i get you have mail how can i view that mail ?
    2. i only have 1 jail in DMZ im able to push publicly how can i have other virtual hosts ? i downloaded wordpress in /www/wp and created wp.domain.com.conf with the same code you have for nextcloud but changed the diricitory but i got “You don’t have permission to access / on this server.”

    1. Hi Sulayman,

      1. type mail at the terminal prompt within the jail
      2. My setup doesn’t tell you to put your jail in a DMZ, and in fact suggests that this may be a futile effort to begin with. If you want to use multiple web servers within the same jail, there are a number of ways to achieve this. First is by name or port virtual host entries. Refer to the documentation on how to achieve this. The second (perhaps better?) way to do this would be to set up a reverse proxy. Have a read of the documentation and see how you go. I’ve never done either though, so I’m not an expert on this. I run all of my web servers in separate jails, and my only publicly facing one is nextcloud.
  50. Hey everyone, i’ve got all the way to the last part of the install go to the local ip to continue the setup of nextclould but get this not sure where i have gone wrong.
    <?php
    /**
    *
    * Your webserver seems to be not configured to use PHP or PHP is not installed.
    * Please contact your administrator or follow our documentation:
    * https://docs.nextcloud.com/server/13/admin_manual/installation/source_installation.html
    *
    * @copyright Copyright (c) 2016, ownCloud, Inc.
    *
    * @author Georg Ehrke oc.list@georgehrke.com
    * @author Joas Schilling coding@schilljs.com
    * @author Jörn Friedrich Dreyer jfd@butonic.de
    * @author Lukas Reschke lukas@statuscode.ch
    * @author Morris Jobke hey@morrisjobke.de
    * @author Robin Appelman robin@icewind.nl
    * @author Sergio Bertolín sbertolin@solidgear.es
    * @author Thomas MÃŒller thomas.mueller@tmit.eu
    * @author Vincent Petry pvince81@owncloud.com
    *
    * @license AGPL-3.0
    *
    * This code is free software: you can redistribute it and/or modify
    * it under the terms of the GNU Affero General Public License, version 3,
    * as published by the Free Software Foundation.
    *
    * This program is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    * GNU Affero General Public License for more details.
    *
    * You should have received a copy of the GNU Affero General Public License, version 3,
    * along with this program. If not, see http://www.gnu.org/licenses/
    *
    */

    require_once DIR . ‘/lib/versioncheck.php’;

    try {

    require_once __DIR__ . '/lib/base.php';

    OC::handleRequest();

    } catch(\OC\ServiceUnavailableException $ex) {
    \OC::$server->getLogger()->logException($ex, array(‘app’ => ‘index’));

    //show the user a detailed error page
    OC_Template::printExceptionErrorPage($ex, 503);

    } catch (\OC\HintException $ex) {
    try {
    OC_Template::printErrorPage($ex->getMessage(), $ex->getHint(), 503);
    } catch (Exception $ex2) {
    try {
    \OC::$server->getLogger()->logException($ex, array(‘app’ => ‘index’));
    \OC::$server->getLogger()->logException($ex2, array(‘app’ => ‘index’));
    } catch (Throwable $e) {
    // no way to log it properly – but to avoid a white page of death we try harder and ignore this one here
    }

    //show the user a detailed error page
    OC_Template::printExceptionErrorPage($ex, 500);
    }

    } catch (\OC\User\LoginException $ex) {
    OC_Template::printErrorPage($ex->getMessage(), $ex->getMessage(), 403);
    } catch (Exception $ex) {
    \OC::$server->getLogger()->logException($ex, array(‘app’ => ‘index’));

    //show the user a detailed error page
    OC_Template::printExceptionErrorPage($ex, 500);

    } catch (Error $ex) {
    try {
    \OC::$server->getLogger()->logException($ex, array(‘app’ => ‘index’));
    } catch (Error $e) {
    http_response_code(500);
    header(‘Content-Type: text/plain; charset=utf-8’);
    print(“Internal Server Error\n\n”);
    print(“The server encountered an internal error and was unable to complete your request.\n”);
    print(“Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report.\n”);
    print(“More details can be found in the webserver log.\n”);

    throw $ex;
    }
    OC_Template::printExceptionErrorPage($ex, 500);

    }
    should i just delete the jail and start again as i’ve retraced my steps everything is running i can get the php info up left me scratching my head a bit

    1. Hi Mike, I’ve never seen this error before unfortunately. I’d recommend starting again, and if it persists, seek help in #nextcloud or #php channels on IRC. This isn’t an easy forum to help you debug the issues you’re having. One thing you could check is the apache error log, and make sure the config.php file for nextcloud matches what I’ve detailed.

      Cheers.

  51. Has anyone had problems upgrading to Version 16 of nextcloud? I see it’s available, but I am a bit reluctant to take the plunge…

    1. I haven’t yet, but It’s probably prudent to wait until 16.0.1 is released, .0 versions are risky because the bugs haven’t been discovered and patched yet. Also, I haven’t had great experiences upgrading nextcloud. My last upgrade broke a couple of apps, and getting it working again resulted in an integrity error because the app hashes didn’t match. Proceed with caution!

  52. Hi Martinus,

    I installed Version 16 fresh (no upgrade) with Samuel’s guide for 14/15 without problems.

  53. Hello Samuel. This has been working great for months. I moved into a new house over the weekend and now have a new internet provider. I have my DNS updated to my new external ip.

    My question is how do i go about updating my nextcloud internal ip? Do I use the FreeNas Gui or do I need to SSH?

    1. Hi Phil,

      I’m not sure what you mean by updating the ‘nextcloud internal IP’; Are you talking about the LAN IP of your FreeNAS host or your jail? The jail should have a static IP as per the first steps in the guide when we created it, specifically this command:

      iocage create -n nextcloud -r 11.2-RELEASE ip4_addr="vnet0|192.168.0.10/24" defaultrouter="192.168.0.1" vnet="on" allow_raw_sockets="1" boot="on"
      

      This would have set the jail to have the IP 192.168.0.10. If you’re talking about your FreeNAS host, then you may need to make a static DHCP entry in your router.

      Cheers,

      Sam

      1. Sam,
        Yes correct. I didn’t explain it well. I’m talking about the the LAN IP of the nextcloud jail itself . I used the command you listed above when I first set everything up so it worked well, but I moved into a new house with a different internet provider so my LAN IP number format changed from 10.0.0.x (Comcast) to 192.168.1.x (WOW). So I wanted to change my Jail IP from the 10.0.0.x format to the 192.168.1.x format if possible.

        Hopefully that makes sense.

        1. Phil, as per the iocage documentation, the command you need is:

          root@freenas:~ # iocage set ip4_addr="vnet0|192.168.1.10/24" nextcloud
          

          Replace the IP with the IP you wish the jail to have. Also note that this is issued from the FreeNAS host, not inside the jail. I’ve never used this before though, so I hope it works 🙂

  54. Hi Samuel,

    An awesome guide. I’m grateful. I’m going through it, and got the point where I found an issue, not with your instructions, but my setup. The /vault/cloud/ share I want to be able to use with NextCloud, seats on a FreeNAS server and it’s mirrored (read only) from a DROBO NAS via Resilio Sync. The files are owned by the rslsync user and group (rslsync:rslsync) which presents a problem, because if I change user and group ownership to www, as your guide suggests, it would effectively break write access to Resilio Sync replication. I haven’t spent too long thinking about a work around,and I was curious as to your approach to such a problem. Regards, Angelo C.

    1. Angelo, it should be fine if you just add the www user to your rslsync group and give the group the same permissions as the user (774 or something). I wouldn’t advise keeping the permissions as read only though, this will probably present issues or significantly diminish the functionality you get out of nextcloud.

      Another alternative if you need rslsync to have read only privileges, would be to make www the owning user and group, and just let rslsync be a member of the other group, and give it read only privileges (i.e. www:www 774).

Leave a Reply

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