Skip to content

Instantly share code, notes, and snippets.

@gaikokujinch
Forked from jacobblock/FreeNAS.md
Last active January 13, 2017 21:01
Show Gist options
  • Save gaikokujinch/2eb3f89170c94935a4e8165f07125e2b to your computer and use it in GitHub Desktop.
Save gaikokujinch/2eb3f89170c94935a4e8165f07125e2b to your computer and use it in GitHub Desktop.
Ultimate FreeNAS Setup

FreeNAS

ToC

Notes

  • nas: My zpool
  • 10.0.0.11: My static FreeNAS ip
  • 192.168.1.3: My static media jail ip
  • 192.168.1.4: My static backup jail ip

Along with that be sure to keep paths consistent between your builds. It is easy to forget if you SSH'd into FreeNAS or into the jail.

Additionally, do not copy/paste entire chunks of commands. I often skip over different yes/no options for brevity in this guide. Read what the prompt says and feel free to drop a comment if answers seem ambiguous.

Setting up the jail

Create a jail using the FreeNAS web UI

Jail name: media_jail
IPv4 address: 192.168.1.3/24
autostart: checked
type: pluginjail
VIMAGE: unchecked
vanilla: checked
sysctls: allow.raw_sockets=true,allow.sysvipc=true

Ports and dependencies

ssh root@10.0.0.11
jls
jexec 17 tcsh
passwd
portsnap fetch extract
portsnap fetch update
sysrc sshd_enable=YES
sysrc ftpd_enable=YES
cd /usr/ports/ports-mgmt/pkg/ && make deinstall
cd /usr/ports/ports-mgmt/pkg/ && make install clean
pkg2ng
cd /usr/ports/ports-mgmt/portmaster && make config-recursive install clean
cd /usr/ports/devel/git && make config-recursive install clean
cd /usr/ports/devel/py-cheetah && make config-recursive install clean

Create a 'media' user and create media directory

mkdir /mnt/media
adduser
Username   : media
Password   : <blank>
Full Name  : Media
Uid        : 1001
Class      : 
Groups     : media 
Home       : /home/media
Home Mode  : 
Shell      : /bin/tcsh
Locked     : no
id media

Create this user in your FreeNAS with the same uid and gid (typically 1001 if you haven't made a custom account yet).

Add mounts for media + crashplan backups inside the jail (/mnt//media to /mnt/media).

Software

Plex

cd /usr/ports/multimedia/plexmediaserver && make config-recursive install clean
cd /usr/local && mkdir plexdata
chown -R media:media plexdata
sysrc plexmediaserver_enable=YES
sysrc plexmediaserver_user=media
sysrc plexmediaserver_group=media

There has been new security settings added and there was a problem with the plex scanner making a request to a local agent. To fix it you should add 192.168.1.0/24 to Settings -> Server -> Network -> Enabled Advanced -> "List of IP Address and networks that are allowed without auth" add 192.168.1.0/24. After that, click refresh all and the scanner should be able to connect to the local agent.

PlexPy

cd /usr/local && git clone https://github.com/JonnyWong16/plexpy.git
chown -R media:media plexpy
cp /usr/local/plexpy/init-scripts/init.freebsd /usr/local/etc/rc.d/plexpy
chmod +x /usr/local/etc/rc.d/plexpy
sysrc plexpy_enable=YES
sysrc plexpy_user=media
sysrc plexpy_dir=/usr/local/plexpy
sysrc plexpy_port=8083

Testing

service sshd start
service couchpotato start
service sickrage start
service headphones start
service sabnzbd start
service plexmediaserver start
service deluge start
service nginx start
service php-fpm start
service postgres start
service calibre start
service madsonic start
service plexpy start

Now check to make sure everything is running fine (192.168.1.3). Then shut down the plugin server and start it up again. Everything should still be working fine.

Backups

Important files Sickbeard replacement: sickbeard.db and config.ini Sabnzbd replacement: sabnzbd.ini Couch potato replacement: Plex: not worth it

Moving over databases and config files from plugins Log into FreeNAS

cp /mnt/tetra/plugins_1/usr/pbi/sickbeard-amd64/data/config.ini /mnt/tetra/media_jail/usr/local/sickbeard
cp /mnt/tetra/plugins_1/usr/pbi/sickbeard-amd64/data/sickbeard.db /mnt/tetra/media_jail/usr/local/sickbeard
cp /mnt/tetra/plugins_1/usr/pbi/sabnzbdplus-amd64/sabnzbd/sabnzbd.ini /mnt/tetra/media_jail/usr/local/sabnzbd
cp /mnt/tetra/plugins_1/usr/pbi/headphones-amd64/data/config.ini /mnt/tetra/media_jail/usr/local/headphones/
cp /mnt/tetra/plugins_1/usr/pbi/headphones-amd64/data/headphones.db /mnt/tetra/media_jail/usr/local/headphones/
cp /mnt/tetra/plugins_1/usr/local/CouchPotatoServer/data/settings.conf /mnt/tetra/media_jail/usr/local/CouchPotatoServer/data
cp /mnt/tetra/plugins_1/usr/local/CouchPotatoServer/data/couchpotato.db /mnt/tetra/media_jail/usr/local/CouchPotatoServer/data

Make sure your settings move across the boundary. Daemons might not start up if ip's, filepaths, etc. are different.

Crashplan

Create a jail using the FreeNAS web UI

Jail name: backup_jail
IPv4 address: 192.168.1./24
autostart: checked
type: portjail
VIMAGE: unchecked
vanilla: checked

Now add the directories you want to backup and where the backups should go.

Ports and dependencies

ssh root@10.0.0.11
jls
jexec 5 tcsh
passwd
portsnap fetch && portsnap extract && portsnap update
sysrc sshd_enable=YES
vi /etc/ssh/sshd_config
# add the following to the end of the file
Match User crasheva
    AllowTcpForwarding yes

adduser # backup with Uid 1002

Download the java runtime in order to please the CrashPlan overlords (or alternatively, modify the crashplan port scripts): http://www.oracle.com/technetwork/java/javase/downloads/index.html Scroll down to Java SE 8u111/112 and click JRE Download (third button). Accept the license


mkdir /usr/ports/distfiles/
cd usr/ports/distfiles/

fetch http://download.oracle.com/otn-pub/java/jdk/8u112-b15/jre-8u112-linux-i586.tar.gz
fetch http://download.oracle.com/otn-pub/java/jdk/8u112-b15/jdk-8u112-linux-i586.tar.gz
fetch http://download.oracle.com/otn-pub/java/jdk/8u112-b15-demos/jdk-8u112-linux-i586-demos.tar.gz


This is just to appease the makefile, and instead we will use OpenJDK's JRE anyways. The following takes quite a while to install.

Install java and crashplan


jexec crasheva tcsh
cd /usr/ports/java/openjdk8-jre/ && make install clean BATCH=yes
# have all options at the beginning cd /usr/ports/java/openjdk8-jre/ && make config-recursive && make install clean


cd /usr/ports/sysutils/linux-crashplan/ && make config-recursive && make install clean

 BATCH=yes
sysrc crashplan_enable=YES

Now change the default Java binary path:

vi /usr/local/share/crashplan/install.vars
  JAVACOMMON=/usr/local/bin/java

Restart the jail. Now follow this guide to modify your current crashplan install to work on the remote machine. You will need to create a port bridge over ssh, which you can do with the following command (before starting up crashplan locally):

ssh -L 4200:localhost:4243 backup@192.168.1.4

And grab the file /var/lib/crashplan/.ui_info from the server and bring it to your local host where you will run the crashplan desktop client.

Helpful codes

Mounting USB drive:

kldload fuse
mkdir /mnt/usb
ntfs-3g /dev/da1s1 /mnt/usb
ntfs-3g -o permissions /dev/da1s1 /mnt/usb

Upgrading

Upgrading can be a royal pain... but fear not. Typically you can just run a portmaster -ad, and if it says "conflict... blah blah" just run "pkg delete -f " then re-run the portmaster command. Eventually everything should be updated! Many times the update process comes to a grinding halt because of dependency issues. You can kick off a single app to be updated similar below. You will also want to review /usr/ports/UPDATING if you run into trouble to see if a port has changed. There is usually a command to migrate a package such as a portmaster -o oldpackage newpackage.

less /usr/ports/UPDATING
portsnap fetch update
cd /usrports/ports-mgmt/pkg && make install clean
cd /usr/ports/ports-mgmt/portmaster && make install clean
pkg version -l '<'
portmaster -Rafd
portmaster -fd news/sabnzbdplus

Rsync files

&rsync --progress --stats --recursive --times --perms --links --dry-run /mnt/tetra /mnt/usb/tetra
nohup foo &

rsync -az -H --delete --numeric-ids --stats --progress -e ssh root@10.0.0.11:/mnt/tetra/family /media/jacob/usb/tetra
rsync -az -H --delete --numeric-ids --stats --progress -e ssh root@10.0.0.11:/mnt/tetra/media_jail/usr/local/sickbeard/data/config.ini /media/jacob/usb/tetra/backup

cp 

Copy server and daemon config files and databases

mkdir /mnt/tetra/backup/server_configs
cd /mnt/tetra/backup/server_configs
rsync -aqz /mnt/tetra/media_jail/usr/local/sickbeard/config.ini /mnt/tetra/media_jail/usr/local/sickbeard/sickbeard.db sickbeard/
rsync -aqz /mnt/tetra/media_jail/usr/local/sabnzbd/sabnzbd.ini sabnzbd/
rsync -aqz /mnt/tetra/media_jail/usr/local/headphones/config.ini /mnt/tetra/media_jail/usr/local/headphones/headphones.db headphones/
rsync -aqz /mnt/tetra/media_jail/usr/local/CouchPotatoServer/data/settings.conf /mnt/tetra/media_jail/usr/local/CouchPotatoServer/data/couchpotato.db couchpotato/
rsync -aqz /mnt/tetra/media_jail/usr/local/etc/nginx/nginx.conf /mnt/tetra/media_jail/usr/local/www/home/index.html nginx/
cd /mnt/tetra/backup/server_configs
rsync -aqz sabnzbd/sabnzbd.ini /mnt/tetra/media_jail/usr/local/sabnzbd/
rsync -aqz sickbeard/config.ini sickbeard/sickbeard.db /mnt/tetra/media_jail/usr/local/sickbeard/
rsync -aqz headphones/config.ini headphones/headphones.db /mnt/tetra/media_jail/usr/local/headphones/
rsync -aqz couchpotato/settings.conf couchpotato/couchpotato.db /mnt/tetra/media_jail/usr/local/CouchPotatoServer/data/

cd /usr/local && chmod -R media:media sabnzbd sickbeard headphones CouchPotatoServer

Appendix

<html>
<head>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<style>
.fluid-container {
padding-left: 15px;
padding-right: 15px;
margin-left: auto;
margin-right: auto;
}
iframe {
width: 100%;
height: 100%;
}
.nav-tabs>li>a.sabnzbd_logo {
background: url("http://192.168.1.3:8080/static/images/logo.png") no-repeat top right;
background-position: 0 0px;
float: left;
height: 40px;
padding-left: 50px;
padding-right: 50px;
}
.nav-tabs>li>a.headphones_logo {
background: url("http://192.168.1.3:8181/images/headphoneslogo.png") no-repeat top right;
background-size: contain;
float: left;
width: 40px;
height: 40px;
}
.nav-tabs>li>a.plex_logo {
background: url("http://192.168.1.3:32400/web/img/base/plex-logo.96faf245690b14fdd33eccd3294ac57f.svg") no-repeat top right;
background-color: #1f1f1f;
background-size: contain;
float: left;
width: 80px;
height: 40px;
}
.nav-tabs>li>a.plexpy_logo {
background: url("http://192.168.1.3:32400/web/img/base/plex-logo.96faf245690b14fdd33eccd3294ac57f.svg") no-repeat top right;
background-color: #1f1f1f;
background-size: contain;
float: left;
width: 80px;
height: 40px;
}
.nav-tabs>li>a.calibre_logo {
background: url("http://192.168.1.3:8082/static/calibre_banner.png") no-repeat top right;
background-size: contain;
height: 40px;
width: 150px;
}
.nav-tabs>li>a.madsonic_logo {
background: url("http://192.168.1.3:4040/icons/madsonic_sunny/logo.png") no-repeat top right;
background-size: contain;
height: 40px;
width: 160px;
}
.nav-tabs>li>a.freenas_logo {
background: url("http://192.168.1.2/static/images/ui/freenas-logo.png") no-repeat top right;
background-size: cover;
height: 40px;
width: 150px;
}
</style>
<title>Home Media</title>
</head>
<body>
<div>
<ul class="nav nav-tabs" id="myTabs">
<li class="active"><a href="#home" data-toggle="tab">Home</a></li>
<li><a href="#freenas" data-toggle="tab" class="freenas_logo"></a></li>
<li><a href="#freenasftp" data-toggle="tab">NAS FTP</a></li>
<li><a href="#plex" data-toggle="tab" class="plex_logo" alt="Plex">Plex</a></li>
<li><a href="#plexpy" data-toggle="tab" class="plexpy_logo" alt="PlexPy">PlexPy</a></li>
<li><a href="#sabnzbd" data-toggle="tab" class="sabnzbd_logo" alt="Sabnzbd"></a></li>
<li><a href="#sickrage" data-toggle="tab">Sickrage</a></li>
<li><a href="#sonarr" data-toggle="tab">Sonarr</a></li>
<li><a href="#couchpotato" data-toggle="tab">Couch Potato</a></li>
<li><a href="#headphones" data-toggle="tab" class="headphones_logo" alt="Headphones"></a></li>
<li><a href="#deluge" data-toggle="tab">Deluge</a></li>
<li><a href="#calibre" data-toggle="tab" class="calibre_logo"></a></li>
<li><a href="#ttrss" data-toggle="tab">TT-RSS</a></li>
<li><a href="#madsonic" data-toggle="tab" class="madsonic_logo"></a></li>
</ul>
</div>
<div>
<div class="tab-content">
<div class="tab-pane active" id="home">
<p>Home!</p>
</div>
<div class="tab-pane" id="freenas" data-src="http://192.168.1.2"><iframe src="" allowfullscreen></iframe></div>
<div class="tab-pane" id="freenasftp" data-src="ftp://192.168.1.3"><iframe src="" allowfullscreen></iframe></div>
<div class="tab-pane" id="sabnzbd" data-src="http://192.168.1.3:8080"><iframe src="" allowfullscreen></iframe></div>
<div class="tab-pane" id="sickrage" data-src="http://192.168.1.3:8081"><iframe src="" allowfullscreen></iframe></div>
<div class="tab-pane" id="sonarr" data-src="http://192.168.1.3:8989"><iframe src="" allowfullscreen></iframe></div>
<div class="tab-pane" id="couchpotato" data-src="http://192.168.1.3:5050"><iframe src="" allowfullscreen></iframe></div>
<div class="tab-pane" id="headphones" data-src="http://192.168.1.3:8181"><iframe src="" allowfullscreen></iframe></div>
<div class="tab-pane" id="plex" data-src="http://192.168.1.3:32400/web/"><iframe src="" allowfullscreen></iframe></div>
<div class="tab-pane" id="plexpy" data-src="http://192.168.1.3:8083"><iframe src="" allowfullscreen></iframe></div>
<div class="tab-pane" id="deluge" data-src="http://192.168.1.3:8112"><iframe src="" allowfullscreen></iframe></div>
<div class="tab-pane" id="calibre" data-src="http://192.168.1.3:8082"><iframe src="" allowfullscreen></iframe></div>
<div class="tab-pane" id="ttrss" data-src="http://192.168.1.3/tt-rss/"><iframe src="" allowfullscreen></iframe></div>
<div class="tab-pane" id="madsonic" data-src="http://192.168.1.3:4040"><iframe src="" allowfullscreen></iframe></div>
</div>
</div>
<script>
$(document).ready(function() {
$('#myTabs').on('show.bs.tab', function(e) {
var paneId = $(e.target).attr('href');
var src = $(paneId).attr('data-src');
if ($(paneId+" iframe").attr("src")=="") {
$(paneId+" iframe").attr("src", src);
}
});
});
</script>
</body>
</html>
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
index index.php index.htm index.html;
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
root /usr/local/www;
listen 80;
server_name localhost;
location / {
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/www/nginx-dist;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
# The following 2 rules are only needed for the user_webfinger app.
# Uncomment it if you're planning to use this app.
# rewrite ^/.well-known/host-meta /nextcloud/public.php?service=host-meta
# last;
#rewrite ^/.well-known/host-meta.json
# /nextcloud/public.php?service=host-meta-json last;
location = /.well-known/carddav {
return 301 $scheme://$host/nextcloud/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/nextcloud/remote.php/dav;
}
location /.well-known/acme-challenge { }
location ^~ /nextcloud {
# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;
# Disable gzip to avoid the removal of the ETag header
gzip off;
# Uncomment if your server is build with the ngx_pagespeed module
# This module is currently not supported.
#pagespeed off;
error_page 403 /nextcloud/core/templates/403.php;
error_page 404 /nextcloud/core/templates/404.php;
location /nextcloud {
rewrite ^ /nextcloud/index.php$uri;
}
location ~ ^/nextcloud/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/nextcloud/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^/nextcloud/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
include fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS off;
#Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass 127.0.0.1:9000;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^/nextcloud/(?:updater|ocs-provider)(?:$|/) {
try_files $uri/ =404;
index index.php;
}
# Adding the cache control header for js and css files
# Make sure it is BELOW the PHP block
location ~* \.(?:css|js)$ {
try_files $uri /nextcloud/index.php$uri$is_args$args;
add_header Cache-Control "public, max-age=7200";
# Add headers to serve security related headers (It is intended
# to have those duplicated to the ones above)
# Before enabling Strict-Transport-Security headers please read
# into this topic first.
# add_header Strict-Transport-Security "max-age=15768000;
# includeSubDomains; preload;";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
# Optional: Don't log access to assets
access_log off;
}
location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
try_files $uri /nextcloud/index.php$uri$is_args$args;
# Optional: Don't log access to other assets
access_log off;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment