This post explains how to make a media management jail in FreeBSD/FreeNAS that includes:

  • Plex media server
  • Sonarr
  • Radarr
  • SABnzbd
  • Transmission
  • nginx as a reverse proxy for the above

Creating the jail

If you are running FreeNAS, simply create a new jail from the jail template. If you are on FreeBSD, follow the instructions below.

  1. Enable jails on the host machine
1
sysrc jail_enable="YES"
  1. Create a dataset for the jail. Replace the paths with paths that are appropriate for your system.
1
2
zfs create -o mountpoint=/usr/local/jails zroot/jails
zfs create zroot/jails/mediajail
  1. Install FreeBSD in to the jail
1
bsdinstall jail /usr/local/jails/mediajail
  1. Copy DNS settings and time to the new jail
1
2
cp /etc/resolv.conf /usr/local/jails/mediajail/etc/resolv.conf
cp /etc/localtime /usr/local/jails/mediajail/etc/localtime
  1. Create /etc/jail.conf and enter the appropriate configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface = "igb0";
host.hostname = "$name.domain.local";
path = "/usr/local/jails/$name";
ip4.addr = 10.0.0.$ip;
mount.fstab = "/usr/local/jails/$name.fstab";
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
exec.clean;
mount.devfs;
mediajail {
$ip = 40;
}
  1. Create the fstab file
1
touch /usr/local/jails/mediajail.fstab
  1. Enter the paths you wish to present to the jail in to the fstab
1
2
3
/media/tank/tv /usr/local/jails/mediajail/media/tv nullfs rw 0 0
/media/tank/movies /usr/local/jails/mediajail/media/movies nullfs rw 0 0
/media/tank/downloads /usr/local/jails/mediajail/media/downloads nullfs rw 0 0
  1. Create the folder that will be mounted
1
2
3
4
5
mkdir /usr/local/jails/mediajail/media/tv
mkdir /usr/local/jails/mediajail/media/movies
mkdir /usr/local/jails/mediajail/media/downloads
mkdir /usr/local/jails/mediajail/media/downloads/incomplete
mkdir /usr/local/jails/mediajail/media/downloads/complete
  1. Create and start the new jail
1
jail -c mediajail

Creating the mediagroup group on the host system, and assigning permissions

  1. Create a group on the host system with the name being mediagroup and the group ID being 816. For FreeNAS this can be done through the GUI, for FreeBSD run:
1
sudo pw groupadd -n mediagroup -g 816
  1. Next, change the owner and permissions of the folders so that the jail can read and write through the shared mediagroup
1
2
3
4
5
6
chown -R root:mediagroup /media/tank/tv
chown -R root:mediagroup /media/tank/movies
chown -R root:mediagroup /media/tank/downloads
chmod -R 6775 /media/tank/tv
chmod -R 6775 /media/tank/movies
chmod -R 6775 /media/tank/downloads

Installing the apps

  1. Enter the new jail. In FreeNAS you can click the terminal window. In FreeBSD, run jexec mediajail /bin/sh

  2. If the jail is in an unsupported version of FreeBSD (looking at you FreeNAS), an unsupported version of sqlite3 is needed. Run the following, accepting all defaults

1
2
3
4
portsnap fetch
portsnap extract
cd /usr/ports/databases/sqlite3
make install clean ALLOW_UNSUPPORTED_SYSTEM=true
  1. Run pkg install with the application names. If you do not have Plex Pass, replace plexmediaserver-plexpass with plexmediaserver
1
pkg install plexmediaserver-plexpass sonarr radarr sabnzbdplus nginx transmission-daemon py27-certbot
  1. Enable all the applications to start on bootup of the jail. Again, if you do not have Plex Pass, replace plexmediaserver_plexpass_enable=YES with plexmediaserver_enable=YES
1
2
3
4
5
6
sysrc plexmediaserver_plexpass_enable=YES
sysrc sonarr_enable=YES
sysrc radarr_enable=YES
sysrc sabnzbd_enable=YES
sysrc nginx_enable=YES
sysrc transmission_enable=YES
  1. Create the mediagroup group in the jail and add all the appliation accounts needed
1
2
3
4
5
pw groupadd -n mediagroup -g 816
pw groupmod mediagroup -m sabnzbd
pw groupmod mediagroup -m sonarr
pw groupmod mediagroup -m radarr
pw groupmod mediagroup -m transmission
  1. Start the applications
1
2
3
4
5
6
service plexmediaserver_plexpass start
service sonarr start
service radarr start
service sabnzbd start
service nginx start
service transmission start

Configuring SABnzbd

  1. SABnzbd only allows connections from localhost initially. First, stop sabnzbd
1
service stop sabnzbd
  1. Replace the host line in the config
1
sed -i -e 's/host = 127.0.0.1/host = 0.0.0.0/g' /usr/local/etc/sabnzbd/sabnzbd.ini
  1. Start sabnzbd
1
service start sabnzbd
  1. Log in to SABnzbd in your browser at:
1
http://<mediajailip>:8080
  1. Run through the initial setup of SABnzbd, inputting the language and news server details.

  2. Once in SABnzbd, click on the cog in the top right corner to get to the settings.Click on the cog on the top to get to “General” settings.

  3. Set up a username and password, then click “Save Changes”.

  4. Go to the “Folders” settings and click “Advanced Settings”. Set the “Temporary Download Folder” to:

1
/media/downloads/incomplete
  1. Set the “Completed Download Folder” to:
1
/media/downloads/complete
  1. Set the “Permissions for completed downloads” to 775 then press “Save Changes”.

Configuring Transmission

  1. Transmission only allows connections from localhost initially, same as SABnzbd. First, stop transmission
1
service stop transmission
  1. Open settings.json and edit the following lines:
1
2
3
4
5
6
7
8
9
rpc-enabled -> change to true
rpc-password -> change to the password you want. This will be hashed upon restarting the service
rpc-username -> change to the username you want
rpc-whitelist -> set to your IP range, ie. 10.1.1.*
rpc-whitelist-enabled -> change to true
download-dir -> /media/downloads/complete
incomplete-dir -> /media/downloads/incomplete
incomlete-dir-enabled -> set to true
umask -> set to 0
  1. Sometimes the download directory set does not stick. Change this with a variable
1
sysrc transmission_download_dir=/media/downloads/complete
  1. Start transmission
1
service start transmission
  1. Log in to Transmission in your browser at:
1
http://<mediajailip>:9191

Configuring Sonarr

  1. Log in to Sonarr in your browser at:
1
http://<mediajailip>:8989
  1. Go to “Settings” and then “General”

  2. Change the “URL Base” to:

1
/sonarr
  1. Set the “Authentication” to Forms and enter a Username and Password. Click “Save”.

Configuring Radarr

  1. Log in to Radarr in your browser at:
1
http://<mediajailip>:7878
  1. Go to “Settings” and then “General”

  2. Change the “URL Base” to:

1
/radarr
  1. Set the “Authentication” to Forms and enter a Username and Password. Click “Save”.

Configuring nginx

  1. Stop the nginx service
1
service stop nginx
  1. Open /usr/local/etc/nginx/nginx.conf in an editor and change to the following, changing when needed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name <hostname>;
location ^~ /.well-known/acme-challenge/ {
alias /usr/local/www/nginx/.well-known/acme-challenge/;
}
location / {
return 301 https://<hostname>$request_uri;
}
}
server {
listen 443 default_server ssl;
server_name <hostname> <jail ip address>;
ssl_certificate /usr/local/etc/letsencrypt/live/<hostname>/fullchain.pem;
ssl_certificate_key /usr/local/etc/letsencrypt/live/<hostname>/privkey.pem;
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
location /sonarr {
proxy_pass http://localhost:8989;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
location /radarr {
proxy_pass http://localhost:7878;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
location /sabnzbd {
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
location /transmission {
proxy_pass http://localhost:9091;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $server_name;
proxy_redirect off;
}
access_log /var/log/nginx/<hostname>.log;
}
}
  1. Start nginx
1
service start nginx
  1. Tell Certbot to generate a new SSL certificate
1
certbot certonly --webroot -w /usr/local/www/nginx -d <hostname>
  1. Reload nginx for the certificate to take effect
1
service reload nginx
  1. Set up a new cron schedule with visudo
1
37 2,15 * * * root /usr/local/bin/certbot renew --post-hook "service nginx reload"

Finishing up

You can now access services through the following:

  • Sonarr - https://<hostname>/sonarr
  • Radarr - https://<hostname>/radarr
  • SABnzbd - https://<hostname>/sabnzbd
  • Transmission - https://<hostname>/transmission

Comment and share

SSL/TLS: A Primer

We all use SSL or TLS every day. But how does it work and what infrastructure is involved? For the rest of the article, I will be referencing both SSL and TLS but will be using the blanket term “TLS” to refer to both.

Continue reading

Recently I built up a new storage server running FreeBSD. Initially I was going to go with FreeNAS like my old storage server, however the FreeNAS project is in a bit of flux at the moment and I thought this would be a good way to learn about the inner workings of FreeBSD. Part of this is segregating the applications running on the server in to “jails”. They are a form of OS-level virtualization, where each jail has its own files, processes and user accounts.

Continue reading

Foglight for Virtualization 7.0 Standard uses Tomcat under the covers to serve the web interface. To replace the SSL certificate, follow the instructions below. I started with a password-protected PFX file that had the password foglight.

  1. Copy the PFX file to the server to the /usr/local/tomcat/conf directory
  2. Run the following to convert the PFX in to a Java keystore file, entering foglight for all password prompts: /usr/local/jre1.6.0_43/bin/keytool -importkeystore -srckeystore /usr/local/tomcat/conf/foglight.pfx -srcstoretype pkcs12 -destkeystore /usr/local/tomcat/conf/foglight.jks -deststoretype JKS
  3. Open /usr/local/tomcat/conf/server.xml in your favourite editor
  4. Replace the Connector section with SSL with the following:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <Connector server="VKernel" port="443" maxHttpHeaderSize="8192"
    maxThreads="150" minSpareThreads="25"
    enableLookups="false" disableUploadTimeout="true"
    acceptCount="100" scheme="https" secure="true"
    SSLEnabled="true" keystoreFile="conf/foglight.jks"
    keystorePass="foglight" clientAuth="false" sslProtocol="TLS"
    ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
    TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,
    TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA" />
  5. Restart Tomcat with service tomcat restart

After a restart, the web interface will now be using the new certificate.

For reference, the username and password for the appliance is vkernel/vkernel and the su password is password.

Comment and share

Password policies are a good thing, however as users aren’t chained to their desks anymore they might not realize that their AD password is expiring. Here’s a script that you can run as a scheduled task that will notify users that their password is expiring.

It was roughly copied from a Reddit thread (link) however it had a few bugs relating to fine-grained password policies and was using .NET methods for a few things instead of Powershell cmdlets.

Hope it comes in useful for someone.

Comment and share

It turns out there’s a lot to getting Powershell to connect to FTP servers. Here’s two functions I’ve written that can list FTP contents and download files. Enjoy.

Comment and share

Set-Permissions

Hee’s a basic script I created recently to set permissions on a file/folder. This can be integrated with other scripts quite nicely.

Enjoy!

Comment and share

As of v45, Chrome is now blocking HTTPS sites with weak Diffie-Hellman public keys. Whilst this is good for everyone, it does cause certain things to stop working. Our Foglight for Virtualization Standard instance stopped working with Chrome and had to be fixed. Although this applies for Foglight, it can be used for any Tomcat 7 instance.

  1. SSH in to the Foglight virtual machine. Default username is vkernel and password is vkernel also.
  2. Change to root by typing su -. Default password is password.
  3. Type nano /usr/local/tomcat/conf/server.xml to edit the Tomcat config file.
  4. Under the HTTPS config section (starts with <Connector server="VKernel" port="443" maxHttpHeaderSize="8192" ....), you will find a cipher list like ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ....". Replace this with: ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA"
  5. Press Ctrl + X and then y to save the file.
  6. Type service tomcat stop then service tomcat start to reload the config file

You should now be able to access the site properly with Chrome v45+.

Comment and share

Jacob Ludriks

author.bio


author.job