7 June 2016

OpenVPN in FreeNAS jail

Goal

Since I've thrown Windows out of the window and got FreeBSD running on my computer, I don't have any possibility of remotely accessing my FreeNAS server. For this reason, I made myself install and configure OpenVPN in a FreeNAS jail to allow myself to access my home network.

This post is written with the intention of setting up an OpenVPN instance, called opepnvpn_priv. If you would want to have a second instance, for example if you want to tighten up the allowed traffic for a specific set of users, you will want to set up a second openvpn instance, which in this post will be named openvpn_pub. At the end of this post, the additional steps will be written down and explained to have the second instance running, I'll try to not make this to confusing for you guys who only want 1 instance running.

This post is written based on the information which are found on the following 2 links:
OpenVPN howto: https://openvpn.net/howto.html
Guide on FreeNAS forums, written by the user 'Robles': https://forums.freenas.org/index.php?threads/how-to-install-openvpn-inside-a-jail-in-freenas-9-2-1-6-with-access-to-remote-hosts-via-nat.22873/

Approach

So after reading the FreeNAS forums, somebody already did the effort to write a guide on how to setup OpenVPN in a FreeNAS jail, though it isn't up to date anymore. (at some point in the future this article won't be either probably). After some reading and testing, it also seems possible to allow the connecting clients to use the public IP address of the location of the OpenVPN server. Because I'll allow friends to use the VPN server as well so that they can reach my FreeNAS box, I'll be creating 2 instances of OpenVPN. 1 instance will be used by myself, in this guide it will be named openvpn_priv. The other instance, which can be used by friends (and in essence, less trusted) will be connecting to the other instance, which will be named openvpn_pub. The access on the network will be filtered by ipfw on the OpenVPN server.

Network information

propertyvalue
JailnameOpenVPN-ACC
IPv4 address192.168.1.180

LAN subnet: 192.168.1.0/24
LAN gateway + DNS : 192.168.1.1

Subnet for openvpn_priv instance clients: 10.66.66.0/24
Subnet for openvpn_pub instance clients: 10.77.77.0/24

Useful information before getting started

In the OpenVPN howto are quite some important things to read before getting started. They give you an better understanding of how the certificates work, and also some recommendations regarding the subnets to be used are given.

Numbering private subnets

It is also recommended to use an uncommon subnet for the VPN clients so that it will be unlikely that there will be routing conflicts during the VPN session of a client. An example subnet could be: 10.66.66.0/24

Setting up your own Certificate Authority (CA) generating certificates and keys for an OpenVPN server and multiple clients

It is necessary to build your own PKI infrastructure. The PKI consists of:
  • 1 public key and 1 private key for each server.
  • 1 public key and 1 private key for each client that will be connecting.
  • A master Certificate Authority (CA) public and private key which will be used to sign each public keys of the server(s) and client(s).

OpenVPN supports bidirectional authentication based on certificates. Before mutual trust is established, the following actions must have been completed:
  • The client must verify the server certificate.
  • The server must verify the client certificate.

Generating and managing the PKI is done using the easy-rsa command.

Installation

Open a root shell inside the jail and issue the following commands:

pkg update
pkg upgrade
pkg install openvpn


After the installation of openvpn is done, the following file location is shown: /usr/local/etc/rc.d/openvpn. This file is the rc script and contains the instructions to be run during the initialization of the openvpn instance.

Setup PKI infrastructure & generating the CA and certificates

In order to set up the PKI and generate the CA and server and client certificates, it is advised to review the initial settings in the /usr/local/share/easy-rsa/vars. You might want to change the duration of the validity of the generated CA and server/client certificates, which will be 10 years by default. In case you would want to modify this, you would want to do that in this file as shown below:

ee /usr/local/share/easy-rsa/vars


The above configuration will set the generated CA and certificate to be valid for 3 years.

Once you feel comfortable about the settings in your vars file, go on and initialise the PKI:
easyrsa init-pki.

Generate CA

Once the PKI is initialized, the CA can be generated.
easyrsa build-ca

When it asks for the PEM pass to be entered, choose a very strong password. This password is very crucial for your PKI security and should be kept very secret! this password will prevent malicious people to generate a server or client certificate in case your CA would be stolen.


The generated CA will be saved to /usr/local/share/easy-rsa/pki/ca.crt

Generate server certificate and key

It is advised to build the server certificate and key without a password. This will allow the instance to be started unattended. Execute the following command to do so:
easyrsa build-server-full OpenVPN-ACC nopass

When the command asks for the PEM pass phrase, enter the password which you choose for the CA.


The following 2 files will be created:
  • Server certificate (public key): /usr/local/share/easy-rsa/pki/issued/OpenVPN-ACC
  • Server private key: /usr/local/share/easy-rsa/pki/private/OpenVPN-ACC

Generate client certificate and key

Below will be shown how to generate the key for a client. The command should be executed for every single client that should have access to the VPN service. This step should thus be repeated for as many clients that will be connecting to your server. It is advised to generate this certificate and private key with a password, so that the end user must use a password before the certificate can be used to authenticate against the server.
easyrsa build-client-full gertwintop
When the command asks for the PEM pass phrase, enter the password which you choose for the CA.

Generate Diffie-Hellman

openssl dhparam -out /usr/local/share/easy-rsa/pki/dh2048.pem 2048

Generate HMAC

This part is optional, but is strongly advised to do so to help block DoS attacks and UDP port flooding attacks. In case you will be having multiple instances running, this key will help you protect unwanted users from connecting as this file is also used before setting up the connection.

openvpn --genkey --secret /usr/local/share/easy-rsa/pki/ta_priv.key

Create openvpn_priv rc script

Inside the /usr/local/etc/rc.d directory, there is already an openvpn rc script present. In order to make it possible for openvpn to have another instance running (openvpn_priv), execute the following set of commands:
cd /usr/local/etc/rc.d
ln -s openvpn openvpn_priv
When the openvpn_priv instance is started, it will automatically look for the corresponding configfile named 'openvpn_priv.conf' in the /usr/local/etc/openvpn/ directory.

Create config script for server

So in this part, the configuration script for the OpenVPN server will be created and edited.
As 2 instances of OpenVPN will be run (1 will be named openvpn_priv, the other one wille be named openvpn_pub). Each instance of OpenVPN will use it's own pool of IP addresses to assign to connect clients. This will allow us to specify rules in the firewall so allow or deny access for a subnet. The openvpn_priv will have full access to the local LAN, whereas the openvpn_pub will only be allowed to access the FreeNAS shares (no HTTP or SSH access).

In order to get started, create the /usr/local/etc/openvpn directory and copy the example server config script to that folder.
mkdir -p /usr/local/etc/openvpn
cp /usr/local/share/examples/openvpn/sample-config-files/server.conf /usr/local/etc/openvpn/openvpn_priv.conf

Edit config openvpn_priv.conf

Edit the /usr/local/etc/openvpn/openvpn_priv.conf file so that it will suit your environment:
ee /usr/local/etc/openvpn/openvpn_priv.conf

The following fields should be set uncommented and configured conform your environment:

Setting nameinitial value (in sample config)example valuesome extra information regarding this setting
locala.b.c.d192.168.1.180This should be the local LAN ip of the jail in which you installed OpenVPN.
port11941195This should be the port you want the openvpn_priv instance to be listening on.
protoudpudpIn the OpenVPN HOWTO
devtuntun
caca.crt/usr/local/share/easy-rsa/pki/ca.crtThis setting should contain the path of the CA created earlier.
certserver.crt/usr/local/share/easy-rsa/pki/issued/OpenVPN-ACC.crtThis setting should contain the path of the server certificate created earlier
keyserver.key/usr/local/share/easy-rsa/pki/private/OpenVPN-ACC.keyThis setting should contain the path of the server key created earlier
dhdh2048.pem/usr/local/share/easy-rsa/pki/dh2048.pemDiffie Hellman parameters which are used during the exchange of keys between server and client
topologysubnetsubnet
server10.8.0.0 255.255.255.010.66.66.0 255.255.255.0This will be the subnet each client connected to the openvpn_priv instance will get an IP address from.
ifconfig-pool-persistipp.txtipp_priv.txtThis file will maintain the associations of assigned IP addresses and clients.
push"route 192.168.1.10 255.255.255.0""route 192.168.1.0 255.255.255.0"This will advertise the route 192.168.1.0/24 to the connected clients
route192.168.40.128 255.255.255.248192.168.1.180 255.255.255.0 10.66.66.1This will route the traffic from the local LAN back into the VPN subnet
client-to-clientIf this setting is uncommented, clients can see eachother, and not only the server.
tls-authta.key 0/usr/local/share/easy-rsa/pki/ta_priv.key 0This should only be set if the step Generate HMAC was executed
usernodobyThis should be uncommented if the OpenVPN server is set up on a FreeBSD based system so that the daemon privileges are reduced after initialization
groupnobodyThis should be uncommented if the OpenVPN server is set up on a FreeBSD based system so that the daemon privileges are reduced after initialization
statusopenvpn-status.logopenvpn_priv-status.log
log-appendopenvpn.log/var/log/openvpn_priv.log

After all modifications are done, save the file.

Firewall settings

In this part the firewall configuration will be shown. The firewall will contain the set of rules to allow or deny IP packets from the VPN to the local LAN. This can be done based on source IP, destination IP, portnumbers,...

Create the file which will contain the ipfw configuration:
ee /usr/local/etc/ipfw.rules

Please note that copy pasting the text might give some errors, in case you would get errors regarding the ipfw settings you might want to write the following manually.

#!/bin/sh

# General config
EPAIR=$(/sbin/ifconfig -l | tr " " "\n" | /usr/bin/grep epair)
ipfw -q -f flush
ipfw -q nat 1 config if ${EPAIR}

#Config for openvpn_priv instance
ipfw -q add nat 1 all from 10.66.66.0/24 to any out via ${EPAIR}
ipfw -q add nat 1 all from any to any in via ${EPAIR}

# Ensure the tun interface is named "tun0" after each jail restart
TUN=$(/sbin/ifconfig -l | tr " " "\n" | /usr/bin/grep tun)
ifconfig ${TUN} name tun0

/etc/rc.conf configuration

In order to have the openvpn_priv instance start automatically at each restart of the jail (and also FreeNAS box), add the following lines into /etc/rc.conf
openvpn_priv_enable="YES"
openvpn_priv_if="tun"

Also the following lines must be added so that the firewall initialization is done at each restart of the jail:
cloned_interfaces="tun"
gateway_enable="YES"
firewall_enable="YES"
firewall_script="/usr/local/etc/ipfw.rules"

Now restart the jail. This can be done either via the WebUI in FreeNAS, or by opening an ssh session to your FreeNAS box and using the warden command. use the command warden list to see the list of jails on the server.

In my case the following command would stop the OpenVPN-ACC server and start it again:
warden stop OpenVPN-ACC && warden start OpenVPN-ACC

Verifying the configuration

ipfw settings

Verify the ipfw settings by executing the following command:
ipfw list

This should give the following output:

If this doesn't look the same on your end, it is most likely that there is some type in the /usr/local/etc/ipfw.rules file, or the /etc/rc.conf file regarding the settings relevant with ipfw. Review it and execute service ipfw restart && ipfw list to redo the verification.

openvpn_priv settings

Verify the openend sockets inside the jail. This will show us what application is listening on what protocol (UDP or TCP), on what local IP address, and on what portnumber. Depending on the portnumber and protocol defined in /usr/local/etc/openvpn/openvpn_priv.conf the output should look like below:

If the settings don't seem OK, or you would want to use another port for the openvpn_priv instance, edit /usr/local/etc/openvpn/openvpn_priv.conf file, save it and restart the openvpn_priv instance with service openvpn_priv restart

Router portforwarding

The last step necessary to have the openvpn_priv instance being reachable via the internet, is to do portforwarding on the router/firewall on the local LAN end where the server is located.
This setting is very specific on router/firewall you are using, but in this case, keeping the IPs in mind i've been using throughout this post, you would do the following:
Allow port external port 1195, and route the packets to 192.168.1.180 to port 1195.

Client configuration

Software installation

On the client device, you'll need to install the OpenVPN client software.
For windows, the install can be downloaded from the following URL: https://openvpn.net/index.php/download/community-downloads.html
For android, you should find the app easily in the play store.

I'll be explaining the steps on how to get the VPN client working on your Windows machine. The installation itself will not be covered.

So after the installation is completed, the installation folder of OpenVPN can be found on one of the following locations, depending on your Windows bit architecture and the installer. (32-bit vs 64-bit):
C:\Program Files\OpenVPN\
C:\Program Files (x86)\OpenVPN\

Now, it is necessary to copy the generated certificates for this specific client into the config directory inside the OpenVPN installation folder. This should be done via a secure channel, like USB stick, or over the local LAN. It's advised not to send the certificate and keys over an unsecure channel, like mail, skype, or other untrusted connections/platforms.

In this case, we generated a client certificate and key for our client 'gertwintop'. Also the ca.crt and the ta_priv.key should be copied to the client device as well.

The necessary files are still located on the OpenVPN server on the following locations:
  • ca.crt /usr/local/share/easy-rsa/pki/ca.crt
  • gertwintop.crt /usr/local/share/easy-rsa/pki/issued/gertwintop.crt
  • gertwintop.key /usr/local/share/easy-rsa/pki/private/gertwintop.key
  • ta.key /usr/local/share/easy-rsa/pki/ta_priv.key

Client configuration file

The client configuration file should also be located in the C:\Program Files\OpenVPN ( or C:\Program Files (x86)\OpenVPN in case you installed the 32 bit client). Copy the following text in a new textfile and save the file as openvpn_priv.ovpn:

# Specify that we are a client and that we
# will be pulling certain config file directives client

# Use the same settings as used on the server
dev tun
proto udp

# The hostname/IP and port of the server
# replace DNSNAME with your public IP or DNSname
remote DNSNAME 1195

# redirect local traffic to the remote OpenVPN server Also set
# DNS server if redirect-gateway option is set.
# redirect-gateway def1
# dhcp-option DNS 8.8.8.8

# Keep trying indefinitely to resolve the hostname
# of the OpenVPN server
resolv-retry infinite

# Most clients don't need to bind to a specific local port number
nobind

# Try to preserve some state across restarts.
persist-key
persist-tun

# SSL/TLS parms.
ca ca.crt
cert gertwintop.crt
key gertwintop.key

# tls-auth should only be set if Generate HMAC was done
# otherwise comment the tls-auth setting
tls-auth ta_priv.key 1

# Prevent MitM attacks, let client verify the server certificate
remote-cert-tls server

#Enable compression on the VPN link.
comp-lzo

# Set log file verbosity.
verb 3

With the above client configuration, the VPN session allows the client to access the local LAN of the VPN server, the public IP of the client would still be the one it would have without having an active VPN session.

Though, Note the 2 following lines:
# redirect-gateway def1
# dhcp-option DNS 8.8.8.8

If those were uncommented, all internet traffic would be passed via the WAN connection of the VPN server. This will result in a slower performance, but it might give you other opportunities, like bypassing regional limitations.

At this point, you should be able to succesfully connect to your OpenVPN instance. In case you would want a second OpenVPN instance, continu to follow this post!

Setting up a second OpenVPN instance

Generate HMAC

This part is highly recommended in case a second instance is to be configured as this will help you protect users which should be using the openvpn_pub instance to connect to the openvpn_priv instance and vice versa. It should also help to protect from Dos attacks and UDP port flooding attacks.

openvpn --genkey --secret /usr/local/share/easy-rsa/pki/ta_pub.key

create openvpn_pub rc script

Inside the /usr/local/etc/rc.d directory, there is already an openvpn rc script present. In order to make it possible for openvpn to have another instance running (openvpn_pub- execute the following set of commands:
cd /usr/local/etc/rc.d
ln -s openvpn openvpn_pub

When the openvpn_pub instance is started, it will automatically look for the config named 'openvpn_pub.conf' in the /usr/local/etc/openvpn/ directory.

Create config script for server

The easiest way to create a config script for the openvpn_pub instance is to copy the already existing config script of the openvpn_priv instance:
cd /usr/local/etc/openvpn
cp openvpn_priv.conf openvpn_pub.conf

Edit openvpn_pub.conf

Now modify the openvpn_pub.conf file:
ee /usr/local/etc/openvpn/openvpn_pub.conf
Only the following parameters should be modified;

Setting nameinitial value (in openvpn_priv.conf)value to be set in openvpn_pub.confsome extra information regarding this setting
port11951196This should be the port you want the openvpn_pub instance to be listening on. Each instance must have its own unique port number.
server10.66.66.0 255.255.255.010.77.77.0 255.255.255.0This will be the subnet eachclient connected to the openvpn_pub instance will get an IP address from. This should be different then the subnet specified in the config file of the first instance.
ifconfig-pool-persistipp_priv.txtipp_pub.txtThis file will maintain the associations of assigned IP addresses and clients.
route192.168.1.180 255.255.255.0 10.66.66.1192.168.1.180 255.255.255.0 10.77.77.1This will route the traffic from the local LAN back into the VPN subnet
client-to-clientIf this setting is uncommented, clients can see eachother, and not only the server.
tls-auth/usr/local/share/easy-rsa/pki/ta_priv.key 0/usr/local/share/easy-rsa/pki/ta_pub.key 0This should only be set if the step Generate HMAC was executed
statusopenvpn_priv-status.logopenvpn_pub-status.log
log-appendopenvpn_priv.log/var/log/openvpn_pub.log

Save the file after all modifications are done.

Firewall settings

Because we specified a new subnet in the openvpn_pub configuration, the firewall must also be configured so that it will allow specific traffic from the 10.77.77.0/24 subnet to the server. As this instance will be used by friends, and I don't want them to be using internet via my public IP address, I also added some configuration to prevent them from doing that.
ee /usr/local/etc/ipfw.rules

Please note that copy pasting the text might give some errors, in case you would get errors regarding the ipfw settings you might want to write the following manually.

Add the following text so your /usr/local/etc/ipfw.rules file looks like this:

#!/bin/sh

# General config
EPAIR=$(/sbin/ifconfig -l | tr " " "\n" | /usr/bin/grep epair)
ipfw -q -f flush
ipfw -q nat 1 config if ${EPAIR}

#Config for openvpn_priv instance
ipfw -q add nat 1 all from 10.66.66.0/24 to any out via ${EPAIR}
ipfw -q add nat 1 all from any to any in via ${EPAIR}

#Config for openvpn_pub instance
#Prevent access to the FreeNAS webUI
ipfw -q add deny tcp from 10.77.77.0/24 to 192.168.1.10 80
#Prevent SSH access to the FreeNAS server
ipfw -q add deny tcp from 10.77.77.0/24 to 192.168.1.10 22
ipfw -q add nat 1 all from 10.77.77.0/24 to 192.168.1.10 out via ${EPAIR}
ipfw -q add nat 1 all from 192.168.1.10 to 10.77.77.0/24 in via ${EPAIR}

# Ensure the tun interface is named "tun0" after each jail restart
TUN=$(/sbin/ifconfig -l | tr " " "\n" | /usr/bin/grep tun)
ifconfig ${TUN} name tun0

/etc/rc.conf configuration

In order to have the openvpn_pub instance start automatically at each restart of the jail (and also FreeNAS box), add the following lines into /etc/rc.conf
openvpn_pub_enable="YES"
openvpn_pub_if="tun"

Now issue the following commands to start the openvpn_pub instance and to restart the ipfw service so that the settings which are configured in /etc/rc.conf are applied.

service openvpn_pub start
service ipfw restart

Verifying the configuration

Ipfw settings

Verify the ipfw settings by executing the following command ipfw list.
This should give the following output:
If this doesn't look the same on your end, it is most likely that there is some type in the /usr/local/etc/ipfw.rules file, or the /etc/rc.conf file regarding the settings relevant with ipfw. Review it and execute service ipfw restart && ipfw list to redo the verification.

Openvpn_pub settings

Verify the opened sockets inside the jail. This will show us what application is listening on what protocol (UDP or TCP), on what local IP address, and on what portnumber. Depending on the portnumber and protocol specified in /usr/local/etc/openvpn/openvpn_pub.conf the output should look like below:

If the settings don't seem ok, or you would want to use another port for the openvpn_pub instance, edit /usr/local/etc/openvpn/openvpn_pub.conf file, save it and restart the openvpn_pub instance with service openvpn_pub restart

Router portforwarding

Because of the new openvpn instance, which will be listening on port 1196, it should be made available from the internet. Go back into your router settings and forward port 1196 to the internal IP of the jail (192.168.1.180).

Copy the necessary certificates to client

It is assumed that at this point, the OpenVPN client software is already installed on the client device.

Now, it is necessary to copy the generated certificates for this specific client into the config directory inside the OpenVPN installation folder. This should be done via a secure channel, like USB stick, or over the local LAN. It's advised not to send the certificate and keys over an unsecure channel, like mail, skype, or other untrusted connections/platforms.

In this case, we generated a client certificate and key for our client 'gertwintop'. Also the ca.crt and the ta_pub.key should be copied to the client device as well.

The necessary files are still located on the OpenVPN server on the following locations:
  • ca.crt /usr/local/share/easy-rsa/pki/ca.crt
  • gertwintop.crt /usr/local/share/easy-rsa/pki/issued/gertwintop.crt
  • gertwintop.key /usr/local/share/easy-rsa/pki/private/gertwintop.key
  • ta.key /usr/local/share/easy-rsa/pki/ta_pub.key

Client configuration file

The client configuration file should also be located in the C:\Program Files\OpenVPN ( or C:\Program Files (x86)\OpenVPN in case you installed the 32 bit client). Copy the following text in a new textfile and save the file as openvpn_pub.ovpn:

# Specify that we are a client and that we
# will be pulling certain config file directives client

# Use the same settings as used on the server
dev tun
proto udp

# The hostname/IP and port of the server
# replace DNSNAME with your public IP or DNSname
remote DNSNAME 1196

# Keep trying indefinitely to resolve the hostname
# of the OpenVPN server
resolv-retry infinite

# Most clients don't need to bind to a specific local port number
nobind
# Try to preserve some state across restarts.
persist-key
persist-tun

# SSL/TLS parms.
ca ca.crt
cert gertwintop.crt
key gertwintop.key

# tls-auth should only be set if Generate HMAC was done
# otherwise comment the tls-auth setting
tls-auth ta_pub.key 1

# Prevent MitM attacks, let client verify the server certificate
remote-cert-tls server

#Enable compression on the VPN link.
comp-lzo

# Set log file verbosity.
verb 3

With the above client configuration, the VPN session allows the client to access the local LAN of the VPN server, the public IP of the client would still be the one it would have without having an active VPN session.

This should be enough for clients to connect to the openvpn_pub instance.

3 April 2016

Plex media server

The next service I wanted to add to my server was a possibility to stream media to other devices. Plex Media Server is capable of doing this. In this post will be explained how to install Plex Media Server on a FreeNAS jail (it should work on any installation of FreeBSD though).

Jail information

Here you can see the jail information I used to create the jail via the FreeNAS web interface
propertyvalue
JailnamePMS-PRD
IPv4 address192.168.1.101
typestandard
vanillaFALSE (unchecked)

Installing Plex Media Server

Start by SSHing into the FreeNAS server and open a shell into the PMS-PRD jail: jexec PMS-PRD csh.
Get the portstree inside the jail: portsnap fetch extract After the portstree is extracted inside the jail, navigate to the Plex media server port and initiate the installation: cd /usr/ports/multimedia/plexmediaserver-plexpass && make install clean
Note: If you don't own a plex account with an active plexpass, you should not use the plexmediaserver-plexpass port but the plexmediaserver port. After the port is installed, the following information is shown:
user: plex with user ID 972
group: plex with group ID 972
startupscript: /usr/local/etc/rc.d/plexmediaserver_plexpass
In order to have Plex Media Server running after each reboot, add the following line in /etc/rc.conf:
plexmediaserver_plexpass_enable="YES"
Start the service by executing the following command: service plexmediaserver_plexpass start At this point the plex media server should be accessible by opening a web browser and navigating to http://192.168.1.101:32400/web

Mount dataset inside jail

Plex Media Server will be streaming music, series and movies. For those 3 types of media, I created 3 datasets on my FreeNAS box, with the permissions set so that everyone can read and execute. Just mounting the dataset inside the jail should be sufficient as the permissions configured on the dataset are fine. Before configuring the Plex Media Server, restart the service so the mounted storage inside the jail is recognised: service plexmediaserver_plexpass restart

Plexpy monitoring tool

Another nice piece of software to install is Plexpy. It provides functionality to monitor your server and send notifications on events (ex. when a stream is started).

Preparations

Before the application can be used, additional software should be installed; pkg install python2 databases/py-sqlite3 security/py-openssl security/ca_root_nss git Then move into the directory where a clone of the plexpy git repository will be created: cd /usr/local/share/ Now clone the plexpy git repository: git clone https://github.com/drzoidberg33/plexpy.git It is also advised to have a dedicated user to execute the plexpy application. In order to do this, use the useradd command. The user name given 'plexpy'. Modify the permissions on the plexpy folder: chmod -R 770 plexpy Modify the owner and groupowner on the plexpy folder: chown -R plexpy:plexpy plexpy Now log in to a shell as the plexpy user created earlier so that the application can be tested: su plexpy cd /usr/local/share/plexpy python2 PlexPy.py From here, the plex application should be running and accessible via http://192.168.1.101:8181

Start plexpy automatically at boot

The next steps will allow the plexpy application to start automatically at boot or restart of the jail. Copy the sample initscript inside the /etc/rc.d/ folder and modify the permissions so that user, group and other can read and execute.
cp /usr/local/share/plexpy/init-scripts/init.freenas /etc/rc.d/plexpy
chmod 555 /etc/rc.d/plexpy

Then, modify the startup script so that the 'plexpy' user will be used to start the plexpy application:
ee /etc/rc.d/plexpy
: ${plexpy_user:="plexpy"}

Lastly, add the following line
plexpy_enable="YES"
inside the /etc/rc.conf file. If the jail would now be restarted, plex media server and plexpy should be automatically started.

27 March 2016

Transmission in FreeBSD jail

So as mentioned in the blogpost on how to install sabnzbd in a FreeBSD jail here is a blog post which will show how to install the transmission torrent client in a FreeBSD jail.

Goal

So during the selection of the torrent client which I would be installing in a jail, I decided the following requirements should be met:
  • A webinterface to operate the application
  • The possibility to place .torrent files in a shared folder so that the client will import these automatically.
Transmission has all that!

Jail information

Here you can see the jail information I used to create the jail via the FreeNAS web interface
propertyvalue
Jailnametorrent-PRD
IPv4 address192.168.1.104
typestandard
vanillaFALSE (unchecked)

Installation

Transmission will be installed via ports. For this reason it is necessary to get the portstree in the jail. Execute the following command to do so: portsnap fetch extract.
After this is done, switch to the transmission folder in de portstree and initiate the compilation of Transmission:cd /usr/ports/net-p2p/transmission-daemon
make install clean

Configuration

After the software is compiled, the following information was shown on the screen:
"Transmission group and user created; uid = 921, gid = 921"
binary = /usr/local/bin/transmission-remote
binary = /usr/local/bin/transmission-daemon
startupscript = /usr/local/etc/rc.d/transmission
Reading the startupscript provides us more information about what paths are used for configuration. Let's just go with the defaults to get a basic setup running. Later on, watchdir should be configured, download dir should also be modified.
Defaults:
Config dir => /usr/local/etc/transmission/home
Default port the webinterface will be available on : 9091
Download dir => /usr/local/etc/transmission/home/Downloads
Add the following line to /etc/rc.conf
transmission_enable="YES"
Now start the transmission daemon by executing service transmission start. This will also create the initial configuration files in the configuration directory ( /usr/local/etc/transmission/home ). NOTE: stop the transmission daemon by executing service transmission stop prior to editing the config file, as the transmission daemon will always overwrite the config file which was used to start the daemon. Once the /usr/local/etc/transmission/home/settings.json file is modified and saved, the transmission daemon can be started again by executing service transmission start
So the initial configuration files are created, as the above note mentions the transmission service should be stopped prior to editing the configuration file, do so:
service transmission stop
cd /usr/local/etc/transmission/home
ee settings.json
Modify the following line to allow access from any computer on your LAN to access the transmission WEB UI:
"rpc-whitelist":"127.0.0.1", to
"rpc-whitelist":"127.0.0.1,192.168.1.*",
After transmission is started again (service transmission start), you should already have a working torrent server which would allow you to use the webinterface from any computer on your LAN.

Storage for downloads

If no dedicated dataset is created for the torrents downloads, this should be done first so that it later on can be attached to the jail.

Creating a dataset in FreeNAS

So in order to create a dataset, which will be intended to store the downloaded torrents on, log in to the FreeNAS web interface, move to the storage tab section, select the zpool (Fritketel in my case) and click on the Create ZFS Dataset button.


Dataset permissions

After the dataset is created, modify the permissions so that they look like the following:

Mounting the storage inside the jail

Now this dataset can be mounted inside the jail. In order to do this, navigate to the jails tab, select the newly created jail and click on the Add storage button.
Then, point the source to the newly created dataset 'Download'.


Now, inside the jail a new group called 'media' should be created with groupID 816 and the transmission user should be added to that group. This will allow the local transmission user to actually make use of the mounted dataset inside the jail. In order to create a new group 'media' with groupID 816, and the transmission user as member of the new group, execute the following inside the jail:
pw add group -n media -g 816 -M transmission

Folder structure and permissions

The last part to do is to set up a working folder structure on the dataset. I do this to logically separate all usenet and torrent downloads:
mkdir -p /media/transmission/to\ download mkdir -p /media/transmission/downloaded
Apply the appropriate user and owner on the transmission folder and its subfolders:
chown -R transmission:media /media/transmission
Apply the correct permissions on the transmission folder and its subfolders:
chmod -R 775 /media/transmission

Modifying jail bootscript

Now that transmission is configured succesfully, the dataset is created and mounted inside the jail, and a folder structure is in place it is also necessary to instruct transmission to use the new folder structure as download location. This should be done inside /etc/rc.conf. edit this file (ee /etc/rc.conf) and the following lines: transmission_watch_dir="/media/transmission/to\ download" transmission_download_dir="/media/transmission/downloaded" transmission_chown="NO" #this will prevent the downloaded files to be chown'd to transmission:transmission, but remain as how the /media/transmission/downloaded user and group owners is configured (transmission:media in this case)

Torrents can now be added via the Web UI, or by plaving the torrent file in the transmission/to download folder on the download dataset.

27 December 2015

SABnzbd in FreeBSD Jail

So today I installed and configured a usenet client, named SABnzbd. This software is perfect for downloading usenet binaries. For more information about the software, you'd better check out http://sabnzbd.org for a better understand about the features of SABnzbd. I'll start off with giving the information I used to create my jail:

Jail information

propertyvalue
Jailnamesabnzbdplus-prd
IPv4 address192.168.1.102
typestandard
vanillaFALSE (unchecked)

Getting shell access to the jail

First of all, ssh access should already be configured on the FreeNAS machine. If this is already the case, start an ssh session to the FreeNAS machine. on FreeBSD or Linux, this can be done via a terminal, on windows you will need something like putty.

Once the session is established, run jls to get a list of all the jails present on the server.


In order to get into the sabnzbdplus-PRD jail, you would want to run jexec 9 csh.

Installing the software

The software can be easily installed via the portstree. As this is a new jail, the portstree should first be fetched and extracted into the jail: portsnap fetch extract will do that for us. After the portstree is extracted, sabnzbd can be installed by navigating to the /usr/ports/news/sabnzbdplus folder and executing make install clean. The default config should be OK.

After the installation is finnished, the following will be displayed:



It is important to note the changes which are done by the port:
  • group '_sabnzbd' with gid '350'.
  • user '_sabnzbd' with uid '350'
  • rc script is located in /usr/local/etc/rc.d/sabnzbd (this script will be executed each time the jail boots up)
  • default port sabnzbd will listen on: '8080'
By having a quick look at the sabnzbd startup script ( cat /usr/local/etc/rc.d/sabnzbd ) we also get the following information:
  • default config dir = /usr/local/sabnzbd
  • default user sabnzbd will run as = '_sabnzbd'
  • default group sabnzbd will run as = '_sabnzbd'
  • python script which is the actual program = /usr/local/bin/SABnzbd.py

Config sabnzbd to start at boot

Add the following line into /etc/rc.conf:
enable_sabnzbd="YES"

Start the sabnzbd daemon

The software is installed, the configuration is done so that sabnzbd will start automatically at boot time. For now, sabnzbd should be started manually. To do this, execute service sabnzbd start.

Allowing other devices to have access to the Web UI

This shouldn't give any problems, Though, it is still necessary to modify the sabnzbd config file in order to allow other machines on the network to have access to the web interface as well. As said earlier, the config file is located in /usr/local/sabnzbd'.

cd /usr/local/sabnzbd
ee sabnzbd.ini

In this file search for "host = localhost" and modify that line so that it becomes "host = 0.0.0.0". Save the changes and restart the sabnzbd service: service sabnzbd restart. This will allow any device on the same subnet as the sabnzbd server to actually access the sabnzbd web UI, The sabnzbd quick-start will help you set up SABnzbd, like adding a usenet server, adding a username and password to prevent everyone on your LAN to access the web UI,...

Storage

All downloads (usenet as well as torrents) will be placed on a dedicated dataset.

All steps done to have this working setup will be shown here. In a future post on setting up transmission (torrent client), the very same dataset will be used for storing the completed downloads.

Creating a dataset

So first of all, a dataset should be created. This is done via the FreeNAS Web UI. Navigate to the storage tab, and select the zpool where the new dataset should be created and click on the create ZFS Datasetbutton:


After the dataset is created, modify the permissions to that they look like the following:


Now this dataset can be mounted inside the jail. To do this, open up the FreeNAS web UI and navigate to the jails tab. Select the sabnzbdplus jail and click on the 'Add storage' button.
Then, point the source to the newly created dataset 'Download'


Note: the value behind 'Source' is as how the FreeNAS box would see it in its filesystem. The value behind 'Destination' is path how the jail would see it!

Additionally, the permissions should also be set so that the _sabnzbd user (from inside the jail) actually has permissions on the mounted folder inside the jail. Since the dataset (in the FreeNAS web UI) has the user 'media' set as owner, and the group 'media' set as group owner, the _sabnzbd user should be added to the group 'media' inside the jail. In order to get to know the user ID and group ID of the media user in FreeNAS, check the 'Account' section in the FreeNAS web UI. In my case, those are '816'.

Now, inside the jail a new group called 'media' should be created with groupID '816' and the _sabnzbd user should be added to that group. This will allow the local _sabnzbd user to actually make use of the mounted dataset inside the jail:
pw add group -n media -g 816 -M _sabnzbd

Folder layout

In order to keep the downloads a little bit organised, the following commands were executed to create a simple folder layout:
mkdir -p /media/sabnzbd/to\ download
mkdir -p /media/sabnzbd/to\ download/nzedb
mkdir -p /media/sabnzbd/to\ download/couchpotato
mkdir -p /media/sabnzbd/to\ download/sickrage
mkdir -p /media/sabnzbd/to\ download/headphones

This should give the following structure (ignore the folder about transmission, they are used by the transmission jail):

Now, the correct permissions on the created folders should be applied so that the '_sabnzbd' user and 'media' group are owners on the folders and both have permission to read, write and execute:

chown -R _sabnzbd:media /media/sabnzbd
chmod -R 775 /media/sabnzbd

Verifying permissions

In order to see if the chown and chmod commands are applied well, a quick ls -alR /media/sabnzbd could be run:

SABnzbd configuration

Now that al permissions are set, the last step is to configure SABnzbd. Open up a webbrowser and navigate to http://192.168.1.102:8080/sabnzbd and click on Config (top right corner of the page). From here, the configuration can be done. It is advised to check all properties on the SABnzbd wiki as the information is very good in line with how the configuration appears in SABnzbd.

NOTE: Beware that all passwords are saved in plaintext in the SABnzbd config file located in /usr/local/sabnzbd/sabnzbd.ini

The most important thing to configure is the "Completed Download folder", "Permissions for completed downloads" and the "Watched Folder" (both can be found in the config > Folders > User Folders).
They should be set to /media/sabnzbd/downloaded, 775 and /media/sabnzbd/to download

Save the configuration and restart sabnzbd.

Final test

Now all configuration is done, SABnzbd should work:
  • It watches the folder /media/sabnzbd/to download, so if an .nzb file is placed on the dataset Download/sabnzbd/to download SABnzbd should notice this and import the nzb to be downloaded.
  • After the download is finished, SABnzbd will check the files with quickpar. If necessary, the damaged/corrupted files will be fixed automatically if sufficient par blocks are available.
  • The archives will also be extracted into the given "Completed Download folder", /media/sabnzbd/downloaded.
NOTE: The following commands should all be executing in the FreeNAS shell, and not inside the SABnzbd jail.

cp /mnt/testfile.nzb /mnt/Fritketel/Download/sabnzbd/to\ download


As shown above, after the copy of the nzb file, sabnzbd automatically started downloading.


And after the download is completed, it is placed nicely into /mnt/Fritketel/Download/sabnzbd/downloaded folder on FreeNAS.

Lock SABnzbd configuration

To prevent that others can read or modify the SABnzbd configuration via the web UI, modify the file located in /usr/local/sabnzbd/sabnzbd.ini and alter the following line: "config_lock = 0" to "config_lock = 1"

10 December 2015

TransIP DynamicDNS

A few weeks ago I spotted an interesting deal to have my own domain name (fritvet.be). I decided to register it and forward it to my external IP address.

Now the problem was that my isp doesn't assign static IP addresses, so I had to update my domain DNS settings regulary to keep it forwarded to my actual external IP address.

In order to do this, my DNS registrar ( TransIP ) provides an API built in PHP which allows to update the DNS settings for my domain.

Though my knowledge of PHP is next to nonexisting, I managed to get a setup running in a FreeNAS jail which will be explained in this blogpost.

Overview

  1. Creating a FreeNAS jail + general configuration
  2. install php & php-extensions
  3. script for execution + crontab
Maybe some additional information about my setup which might be relevant:
- This installation was done on FreeNAS 9.2.1.3-RELEAS-x64
- forumpost on transip which contains a working php script: click!

1. Creating a FreeNAS jail + general configuration

Start off by logging into the FreeNAS webinterface and navigate to jails and choose to add a jail.
Enter a suitable jailname, make sure to select standardjail as type, and fill in an IP address in the same range as the subnet where the FreeNAS server is located in.

property value
Jailname TransIP-PRD
IPv4 address 192.168.1.110
type standard
vanilla FALSE (unchecked)

Once the jail is created, open a terminal session on the newly created jail via the FreeNAS web interface so that SSH can be enabled.

Configure root password

The root password can be set by executing the following command
passwd root

Create technical user account

The technical user account will be used to run the script.
run the adduser command to create a new user:

Note that the user is also added to the group wheel so that during a session, the user can switch user as root if necessary. At the end of the configuration, the account will be removed from the group so that root access will be denied.

Enable SSH

modify the file /etc/rc.conf so that sshd_enable="NO" becomes sshd_enable="YES". This will make sure the sshd daemon will be start when the jail is started:
ee /etc/rc.conf

Now, the SSH daemon isn't running yet, execute the following command to start the sshd daemon:
service sshd start

Setting the hostname

Setting the hostname for the jail should be done so that it gets a nice name, issue this by executing the following command
hostname transip-prd.local

Portstree

Now that ssh is set up and a technical user account (transip) is created, further configuration can be done via a SSH session. Once logged in via ssh, run the following commands to pull and extract the portstree in the jail :
portsnap fetch extract



Note: Only the first time portsnap fetch extract should be used. If the portstree is already extracted, it can be updated in the future by executing portsnap fetch update

2. Install php and php-extensions

After the portstree is available inside the jail (default location is /usr/ports), the necessary software can be installed.
Since  the API is written in php, the php port should be installed inside the jail, this is done by executing the following commands as root:
cd /usr/ports/lang/php56
make install clean

After the sourcecode is downloaded and compiled, the program will be available: man php

The API also requires some php-extensions to be installed:
cd /usr/ports/lang/php56-extensions
make config


php56-extensions to be installed (1)
php56-extensions to be installed (2)

Moving the API to the jail

The API should be placed inside the jail so that it can actually be used. There are different ways of doing this, depending on your setup. I did this myself by downloading the API to my PC-BSD machine and with the help of the scp command the file could be copied to the jail (ssh should be running on the server for this method to work!)
Notice that the scp command was run on my PC-BSD machine.
scp transip.tar transip@192.168.1.110:/home/transip


after the file  was copied to the jail, it can be extracted with the following command:
tar -xf transip.tar

PHP script

In order to have a working php script, follow the instructions provided in the commented section of the php script - TransIP-updateDNS

3. script for execution + crontab

Fix group membership

Earlier on in this blog, the transip user was created and added to the wheel group, which allows the user to switch user to root. Now all configuration is done, the user can be removed from the 'wheel' group to improve the security
pw groupmod wheel -d transip

Shell script

A shell script provides the possibility of having multiple commands being run sequential. The following code will check if there is a directory called 'log'. If not, it will be created in /home/transip/updateDNS. Then, the current date and timestamp will be shown, and the actual php script which handles the DNS update is launched.
#!/bin/sh
cd /home/transip/updateDNS
if [ ! -d log ]; then
echo "creating log folder"
mkdir log
fi
date "+%d/%m/%Y - %H:%M"
/usr/local/bin/php /home/transip/updateDNS/update.php
printf "\n"
Make the script executable by executing chmod o+x shell.sh
If the script runs fine, you will see the following output (make sure to run this command as the transip to verify permissions are OK):


The shell script runs just fine, without any errors (permissions, php plugins missing,... ). The script should now be run on a fixed interval to keep the domain forwarded to my actual external IP.

Crontab

The crontab file allows us to configure scheduled tasks. In my case, I'll be running the 'update.sh' script each 15 minutes. The script should be run as the transip user, so make sure the following command is ran as the transip user.

crontab -e
and add the following line
*/15 * * * * /bin/sh /home/transip/updateDNS/update.sh >> /home/transip/updateDNS/log/updateDNS.log

11 October 2015

PCBSD - installation problems and solution

Hi there

After some time spending little spare time on computer related stuff (except gaming, if you would consider this related to computerstuff ;-) ) I feel somewhat the urge to get to know how FreeBSD works, how things are done in FreeBSD from administrator perspective. The interest has arisen after installing some plugins (plex media server, sabnzbd, sickrage,...) on my FreeNAS box.

For those reasons, I decided to wipe Fedora Linux from my HP ProBook 6560b and install PCBSD instead. PCBSD is a desktop operating system based on FreeBSD.

The installation itself is quite straightforward. FreeBSD, and thus PCBSD as well, provide the great ZFS filesystem. ZFS has many advantages like automatic snapshotting, ZFS Replication,...

So after the installation was completed, I restarted the laptop just to see the "Missing Operating System" error message on my screen.

After some Googling about "FreeBSD No Operating System" I found my solution on the following link: http://unix.stackexchange.com/questions/125608/freebsd-10-does-not-boot-after-clean-install

It seems the bios-boot partition still has to be set active and flagged as boot partition. By following the next instructions my laptop was able to boot PCBSD:

So after the PCBSD installation is actually finished, open a shell and run
gpart show

This should list all hard disk drives with all its partitions. As you can see on the picture taken below on my PCBSD machine, there are 2 drives (ada0 and ada1). Write down the number in front and also take note on what hard drive the bios-boot partition is found. In my case, will need ada0 and partition 1 for the next few commands.

Once the information is gather, the partition must be set active and the bootflag must be set on the partition. This can be achieved by executing the following commands:
gpart set -a active /dev/ada0
gpart set -a bootme -i 1 /dev/ada0

I wrote ada0 and 1 in bold because those values might be different on each system!

After a reboot was initiated, my laptop succesfuly booted into PCBSD, which looked like this:


On to the next issue!

3 April 2014

Assembling the hardware

So last monday all my hardware arrived!
Only the RAM memory isn't the one i described in my previous post. I decided to go for the Kingston ValueRAM running at 1333 MHz.

4U  case
Case front view


All hardware together

So assembling the hardware went without too much trouble.
First, i had to temporary remove the 2 fans which are mounted at the back of the case (left on the picture): 

Once those were removed, all hardware could be placed easily in the case:


Important note, by using the Xeon E3-1230 v2, which has no integrated gpu, it seems to be impossible to use the onboard VGA output. This can be easily resolved by placing a dedicated GFX card in the pci-E slot. Since it'll become a server, there is no need to have a GFX card in it once it is fully configured.

Ofcourse, some cable management is also needed, but for now i'm way to excited about getting started with FreeNAS!