The Power of SED


I use pydio on a few of my servers for sharing files.  Recently, on one of them, I decided it would be good to move the document root for the site.  Everything seemed really great, until I started getting reports of files that were shared earlier were no longer working.

Seems that when you share a file, pydio creates a tiny php file that gets stored in /your_doc_root/data/public

Inside that php file, onf of the things that you find is a line that says,

require_once(“/your_doc_root/data/publicLet.inc.php”);

So, when I changed my doc root from /usr/local/www/apache24/data/admins/ to /usr/local/www/apache24/data/, things stopped working.

If you only had one or two files shared, you could just go in and edit each of them.  I had hundreds to deal with.  Luckily for me, my google-foo was excellent today and I came across an excellent post about using sed to replace text within files.

Long story short, for me to get rid of the offending “admins” in all of the shared files, I just needed one tiny sed command.

sed -i '' -- 's/admins\///g' *.php

You would want to cd to the data/public folder, then issue that command.  Doing so will look in all files in that directory ending in .php and replace anything that is “admins/” with nothing.

Happy day!  Thank you internet!

Baikal Server – Your very own CardDAV / CalDAV server


Hi all!  Sorry for the lack in new posts.  I’ve had a busy past several months.  We sold and bought houses, moved, did multiple projects at the new house and had an accident at work that left me with 6 broken ribs, 4 fractured vertebrae and a concussion to top it all off.

All that said, I have been tinkering a little on some computer geekery.

This really has very little to do with FreeNAS, but I ran across a great little project for running your own CalDAV / CardDAV server.  The project is called Baikal and can be found here http://baikal-server.com/ .   I’ve been looking for something like this to share contacts with my wife for a long time.  I first tried OwnCloud, but the way it integrates with Apple’s AddressBook is clunky, with many card imports getting missed and even a few crashes of the AddressBook App.  I’ve had Baikal up and running for a few days now, and so far, it has been working great.  What I haven’t exactly figured out yet, maybe because it isn’t an option yet, is how to share contacts between users.  So for the time being, both my wife and I are using the same login.

So, now for the FreeNAS part of this.  I am running the Baikal server on my FreeNAS box in a jail.   Install was really easy, especially because I already had a jail up and running with a webserver installed.

Part I

Get the software

1. Open a terminal either through the GUI or ssh and connect to the server.

2. Switch user to root.

 su
 enter root password

3. Jexec into your jail

jls

JID   IP Address    Hostname    Path
1     192.168.0.44  Services2   /mnt/Files/jails/Services

You’ll want to replace 1 in the next line with the corresponding JID for the jail you want from the above output.

jexec 1 csh

4. Update the ports tree.

portsnap fetch
portsnap update

5. Install the package for Baikal

pkg install baikal

6. Change the ownership on the baikal directory…this will depend a little on your setup, apache defaults to using www. Then move it somewhere a little more useful.

chown -R www:www /usr/local/www/baikal
mv /usr/local/www/baikal /usr/local/www/apache24/data/.

7. Setup the webserver for baikal.  I use apache, so that’s what I’ll show you.  Edit the httpd.conf file and add the following towards the bottom.  ServerName can be either an IP or a URL

vi /usr/local/etc/apache24/httpd.conf

<VirtualHost *:80>

DocumentRoot /usr/local/www/apache24/data/baikal/html

ServerName xxx.xxxxxxxxx.xxx

<Directory “/usr/local/www/apache24/data/baikal/html”>

Options None

Options +FollowSymlinks

AllowOverride All

</Directory>

</VirtualHost>

 8. Restart apache and see if it works.

service apache24 restart

9. Test to see if things are running right.  Go to the URL you used in the above apache config.  You should see the following if everything is working.

Screen Shot 2014-12-10 at 9.01.27 PM

10. Log into the web setup utility for Baikal.  Add a /admin after the URL from above.  Now you should be greeted witha nice little setup page.  After setup is done, you end up here:

Screen Shot 2014-12-10 at 9.03.29 PM

Log in with the admin credentials you just created, then create at least one user.

11. Now, the cool part is linking your address book to it.  The tricky thing about that is getting the URL right.  For AddressBook, it is:  http://server.ip.address/card.php/principals/username/

There is a really good description of various  setups for clients over at the GitHub page for the project. https://github.com/netgusto/Baikal/blob/master/INSTALL.md

Some closing notes, there are multiple ways to setup the webserver to make this go.  I’d recommend setting it up with ssl enabled.  That is a more complicated process and I haven’t the time nor desire to outline it here. Also, it seems that Baikal really doesn’t like being setup in a way where it is not the docroot.  So for instance, it is happy to be at http://somewebsite.com , but it will break when connecting your addressbook to it if it is located at http://somewebsite.com/cards.  Maybe it just doesn’t like being aliased, not sure exactly, but it sure wasn’t happy with me for a while.

Hope you all enjoy.

Enable Multi-Factor Authentication for OpenVPN


Google Authenticator and OpenVPN

Google Authenticator and OpenVPN

In my previous post, we went over how to get Google Authenticator installed on FreeNAS.  Then we setup SSH to use it.  In this guide, we’ll get Multi-Factor Authentication working for OpenVPN.  This guide will be specific to FreeNAS, but should be applicable to FreeBSD as well.

Part I

Get Google Authenticator installed and setup for users

Go see my previous guide on getting Google Authenticator installed.

Part II

Configure OpenVPN to use both certificates and an OTP (one time password) provided by Google Authenticator.

1. Open a terminal either through the GUI or ssh.

2. Switch user to root.

 su
 enter root password

3. Mount the file system and make it writeable

 mount -uw /

4. First we need to create an entry for openvpn under /etc/pam.d This will tell OpenVPN that authentication with the pam_google_authenticator.so module is required.  Also need to remember to copy this file to /conf/base/etc/pam.d so that our change will survive a reboot.

touch /etc/pam.d/openvpn

printf "auth required /usr/local/lib/pam_google_authenticator.so" >> /etc/pam.d/openvpn

cp /etc/pam.d/openvpn /conf/base/etc/pam.d/openvpn

5. Check to make sure the permissions are correct on the pam_google_authenticator.so module.  sshd doesn’t seem to care, but OpenVPN does seem to care.  Side note, there are several guides written for Linux that say you have to modify the MakeFile with LDFLAGS=”-lpam” when building the pam_google_authenticator.so module.  That is NOT the case in FreeNAS / FreeBSD as the port takes care of that.

chmod 555 /usr/local/lib/pam_google_authenticator.so

6. Now we need to add a few settings to our OpenVPN server config.  If you followed my guide on setting up OpenVPN on FreeNAS, your server config is on your data drive.  Change the part after the “>>” to match your setup.

printf "\n#Enable Multi-Factor Authentication\n" >> /mnt/Files/openvpn/openvpn.conf

printf "plugin /usr/local/lib/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn\n\n" >> /mnt/Files/openvpn/openvpn.conf

printf "#Prevent re-authorization every 3600 seconds\n" >> /mnt/Files/openvpn/openvpn.conf

printf "reneg-sec 0\n\n" >> /mnt/Files/openvpn/openvpn.conf

7. Now, on your client computers, you need to add the following to your openvpn-client config.  You can just add it at the bottom.

#Add this to the client config to enable Multi-Factor Authentication
auth-user-pass

#Prevent the password file from being cached
auth-nocache

8. Now restart openvpn on your FreeNAS box.

service openvpn restart

Your output should look like this:

Stopping openvpn.
Waiting for PIDS: 494.
Starting openvpn.
AUTH-PAM: BACKGROUND: INIT service='openvpn'
add net 10.8.0.0: gateway 10.8.0.2

9. Make the filesystem read only again.

mount -ur /

10. Fire up your VPN connection on a client computer and you should get a field that asks for a username and password in order to connect.

Tunnelblick

 

You will put in your user name for one of the accounts you set up using the google-authenticator command on your FreeNAS server.  The password will just be the 6 digit OTP you get from the Google Authenticator App on your smart phone.  Don’t bother saving it in the keychain.  If everything goes right, you will connect and then see this in your terminal session:

AUTH-PAM: BACKGROUND: received command code: 0
AUTH-PAM: BACKGROUND: USER: joe
AUTH-PAM: BACKGROUND: my_conv[0] query='Verification code: ' style=1

Part III

Questions and such…

We’ve done it.  We now have multi-factor authentication setup for our VPN.  I’m left wondering though.  Many of the guides I looked at related to this subject said that /etc/pam.d/openvpn needed a lot more in it that what I have used.  For instance, one guide over at askubuntu.com says to use this:

account [success=2 new_authtok_reqd=done default=ignore] pam_unix.so
account [success=1 new_authtok_reqd=done default=ignore] pam_winbind.so
account requisite pam_deny.so
account required pam_permit.so
auth required pam_google_authenticator.so

Is all of that account stuff really needed?  My hunch is that it is not.  If you have any insight, please share it in the comments section.

Google Authenticator on FreeNas


Google Authenticator

Multi Factor Authentication is a useful way to tighten the security of your system.  Having it in place means that attackers can’t simply brute force your password, they need to steal your Hardware Authentication device as well.  In the case of Google Authenticator, that means stealing your phone.

Part I Get Google Authenticator installed and setup for users

1. Open a terminal either through the GUI or ssh. 2. Switch user to root.

 su
 enter root password

3. Mount the file system and make it writeable

 mount -uw /

4. Install the libqrencode. This is optional, but is a nice feature as it allows you to “scan” a QR code from the terminal with your smart phone.

pkg_add -r libqrencode

5. Install the Google-Authenticator PAM module

pkg_add -r pam_google_authenticator
chmod 555 /usr/local/lib/pam_google_authenticator.so

6. Install the Google Authenticator App on your smartphone. Google Play Store  Apple App Store Windows Phone – not sure if this works

7. Switch your user to the user you want to have two factor authentication. Then run google-authenticator. If you want to be all fancy, add the -l option and then a quoted string. Without that, when you scan the QR code into your Google Authenticator app it will display with an email@host description.  You can also add the user name at the end if you like.

su joe
google-authenticator -l "JoePaetzel.com:joe"

Output: Do you want authentication tokens to be time-based (y/n) y https://www.google.com/chart?chs=some_long_URL

Screen Shot 2014-05-13 at 9.40.26 AM

Your new secret key is: E3W7AB2KXXXXXX Your verification code is 78XXXX Your emergency scratch codes are: 7967XXXX 1820XXXX 1659XXXX 3623XXXX 3140XXXX Do you want me to update your "/home/joe/.google_authenticator" file (y/n) y

Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) y

By default, tokens are good for 30 seconds and in order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time. If you experience problems with poor time synchronization, you can increase the window from its default size of 1:30min to about 4min. Do you want to do so (y/n) n

If the computer that you are logging into isn't hardened against brute-force login attempts, you can enable rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login attempts every 30s. Do you want to enable rate-limiting (y/n) y

8. Scan the QR code that was generated into your Google Authenticator app on your smart phone.

9. Repeat steps 7 & 8 for all the users you need to set up.

Part II. Doing something useful with Google Authenticator.

Let’s go ahead and add two factor authentication to SSH. There are several things we need to do to get that accomplished. The quick overview: 1. Make some config changes to sshd_config, some easy, some not so much 2. Tell PAM about the Google Authenticator module and how we want to use it. 3. Your homework is applying the concepts from my post on getting hacks to survive upgrades. Before we do any of that, we need to decide how we want to implement this. In my mind, it makes sense to initially allow users to login to ssh with a public key and either a Google Authenticator code or their user password. This will allow some time for everyone to get set up without any of them getting locked out. Eventually, I’ll probably switch it to require a public key and just the Google Authenticator code. The decision we make here affects how we set the sshd_config parameter AuthenticationMethods, as well as how we configure /etc/pam.d/sshd. For a more in-depth explanation of the options that AuthenticationMethods offers, please see: http://lwn.net/Articles/544640/ For a full explanation of setting up the PAM module in /etc/pm.d/sshd, please see: FreeBSD Man Pages I’ll show you how I have mine set up.

10. We need to make some configuration changes to sshd. One we can make in the terminal, the other we need to do in the FreeNAS gui.

a. Now go back to the terminal, make sure you are root. We need to change the sshd_config file in three places.

/etc/ssh/sshd_config   /etc/ix.rc.d/ix-sshd and /conf/base/etc/ix.rc.d/ix-sshd

We are making the same change in all three places.

The quick way:

sed -i -e 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ssh/sshd_config
sed -i -e 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ix.rc.d/ix-sshd
sed -i -e 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /conf/base/etc/ix.rc.d/ix-sshd

The long way (do in each of the three locations):

vi /etc/ssh/sshd_config

Scroll down to: ChallengeResponseAuthentication no

Change the no to yes. To do that in vi, put the cursor over the n in no. Hit “x” twice. Now hit “a” then type “yes”. Hit the esc key to exit insert mode. type “:wq” to write it and quit. Do not type any of the quotes.

*Feature Request*

There is a chance that in future releases all of that will become an option in the gui.

b. Open the FreeNAS gui and go to the Services tab. Click on SSH. Click on Advanced Mode button. In the extra Options Field, type:

AuthenticationMethods publickey,keyboard-interactive

c. Under Services, click on Control Services. Then turn ssh off and then back on. If we did everything right, it should start right up.

11. Now we need to edit the /etc/pam.d/sshd file so that pam knows to use Google Authenticator.  There a couple of options you have for this…like required, requisite or sufficient.  We’ll use sufficient for now so that we have the option of using the Google code or a password.  Later on we will change it to required so that there is no longer the password option.  Here’s what it looks like to start with:

# # $FreeBSD: src/etc/pam.d/sshd,v 1.18 2009/10/05 09:28:54 des Exp $ # # PAM configuration for the "sshd" service #

# auth auth sufficient pam_opie.so no_warn no_fake_prompts auth requisite pam_opieaccess.so no_warn allow_local #auth sufficient krb5.so no_warn try_first_pass #auth sufficient pam_ssh.so no_warn try_first_pass auth required pam_unix.so no_warn try_first_pass

# account account required pam_nologin.so account required pam_login_access.so account required pam_unix.so

# session #session optional pam_ssh.so want_agent session required pam_permit.so

# password password required pam_unix.so no_warn try_first_pass

What we want to do is add “auth sufficient /usr/local/lib/pam_google_authenticator.so” after “#auth sufficient pam_ssh.so no_warn try_first_pass” and before “auth required pam_unix.so no_warn try_first_pass” You can either do it the long way with vi or the quick way with awk

awk '{ print $0; if(NR == 11) printf("auth            sufficient      '/usr/local/lib/pam_google_authenticator.so'\n"); }' /etc/pam.d/sshd > /etc/pam.d/sshd-temp && mv /etc/pam.d/sshd-temp /etc/pam.d/sshd

We should run cat on the file to make sure it turned out the way we want it.

cat /etc/pam.d/sshd

Output should be:

# # $FreeBSD: src/etc/pam.d/sshd,v 1.18 2009/10/05 09:28:54 des Exp $ # # PAM configuration for the "sshd" service #

# auth auth sufficient pam_opie.so no_warn no_fake_prompts auth requisite pam_opieaccess.so no_warn allow_local #auth sufficient krb5.so no_warn try_first_pass #auth sufficient pam_ssh.so no_warn try_first_pass auth sufficient /usr/local/lib/pam_google_authenticator.so auth required pam_unix.so no_warn try_first_pass

# account account required pam_nologin.so account required pam_login_access.so account required pam_unix.so

# session #session optional pam_ssh.so want_agent session required pam_permit.so

# password password required pam_unix.so no_warn try_first_pass

Also need to do the same with /conf/base/etc/pam.d/sshd and /conf/base/etc/ix/templates/pam.d/sshd

awk '{ print $0; if(NR == 11) printf("auth            sufficient      '/usr/local/lib/pam_google_authenticator.so'\n"); }' /conf/base/etc/pam.d/sshd > /conf/base/etc/pam.d/sshd-temp && mv /conf/base/etc/pam.d/sshd-temp /conf/base/etc/pam.d/sshd

awk '{ print $0; if(NR == 11) printf("auth            sufficient      '/usr/local/lib/pam_google_authenticator.so'\n"); }' /conf/base/etc/ix/templates/pam.d/sshd > /conf/base/etc/ix/templates/pam.d/sshd-temp && mv /conf/base/etc/ix/templates/pam.d/sshd-temp /conf/base/etc/ix/templates/pam.d/sshd

12. Now go read my article about getting hacks to stick and survive upgrades.  Apply that logic to this hack and enjoy Multi-Factor Authentication even after system upgrades. 13. Change the root folder back to read only.

mount -ur /

Final Thoughts

That should be everything.  Try logging in over ssh and you should get a prompt for your Verification Code

Seven:~ joe$ ssh 192.168.0.122 Authenticated with partial success. Verification code:

I need to give credit to Randy who wrote the foundation for much of this guide over at http://www.nytechgroup.com

http://www.nytechgroup.com/2011/10/05/two-factor-authentication-freebsd/

Make sure to also check out my guide on getting OpenVPN working with Google Authenticator.

OS X Mail in Mavericks not deleting Mailboxes


Note to self: Finally figured out how to get Mail.app on OS X Mavericks to behave when I am trying to delete or move mailboxes that are “On My Mac”. The Secret is there was an ACL set that was preventing the everyone group from deleting anything.

ls -le
total 0
drwxrwxr--  16 joe  staff  578 Feb 27 08:56 V2
0: group:everyone deny delete

There may be undesired consequences from doing this…proceed at your own risk.

To fix this:

1. Quit out of Mail.app

2. Open terminal, and do the following.

cd ~/Library/mail
chmod -R -a "everyone deny delete" V2

That will remove the ACL from all of the mailboxes and folders.  As I said, might have a negative side effect.

I’d like to thank Vincent Danen for the article he wrote at TechRepublic.com that pointed me in the right direction.

FreeNAS – getting hacks to survive an upgrade Part 2


***WARNING***

THIS DOES NOT MEAN YOU GET TO SHUT YOUR BRAIN OFF.  UPGRADING FREENAS COULD STILL RENDER YOUR CHANGES NULL AND VOID.  AFTER ANY FREENAS UPGRADE, VERIFY THAT YOUR CHANGES ARE STILL IN EFFECT EVEN WITH THIS STICKY HACK IN PLACE.

Part 1 of trying to get hacks to FreeNAS to survive an upgrade was a failure.  But never fear, I went back to the drawing board and had great success tonight. Basically I changed my approach slightly,  Instead of trying to make changes to /conf/base/etc/rc.conf , what ended up working was just making the changes to /etc/rc.conf on every boot.

This will have the added benefit of working even if the FreeNAS developers change their naming scheme again for things in /conf/base/etc.

Write our hacks.sh script

1. I have OpenVPN and pf Firewall enabled, neither of which are stock to FreeNAS.  You’ll need to adjust this script to meet your needs.  Open up your favorite text editor and save your hacks.sh file somewhere on your data drive on the FreeNAS box.

First thing is lets search /etc/rc.conf to see if our hacks are in place.  If they are, we exit.

#!/bin/sh
if grep "pf_enable" /etc/rc.conf
then
echo "Hacks in Place"
else

Now, the else section is where we add our hacks back in to /etc/rc.conf when they are not there.  I’m just using a simple echo command to write the line I want to add to the shell and then am adding it to the end of /etc/rc.conf.  I’m adding a blank line before my hacks, some notes about the hacks I’m adding and the config changes.  You will need to change the paths to pf_rules, openvpn_configfile and openvpn_dir to match your setup.

echo "" >> /etc/rc.conf
echo "#Turn on PF Firewall" >> /etc/rc.conf
echo "pf_enable='YES'" >> /etc/rc.conf
echo "pf_rules='/mnt/Files/joe/hacks/pf.conf'" >> /etc/rc.conf
echo "gateway_enable='YES'" >> /etc/rc.conf
echo "" >> /etc/rc.conf
echo "#Turn on OpenVPN" >> /etc/rc.conf
echo "openvpn_enable='YES'" >> /etc/rc.conf
echo "openvpn_if='tun'" >> /etc/rc.conf
echo "openvpn_configfile='/mnt/Files/openvpn/openvpn.conf'" >> /etc/rc.conf
echo "openvpn_dir='/mnt/Files/openvpn'" >> /etc/rc.conf

Next we want to start the services that we have added as hacks to FreeNAS.  For me that is pf and openVPN.  Last thing is to close out the if statement with fi.

service pf start
service openvpn start
fi

Here’s the full script.

#!/bin/sh
if grep "pf_enable" /etc/rc.conf
then
echo "Hacks in Place"
else
echo "" >> /etc/rc.conf
echo "#Turn on PF Firewall" >> /etc/rc.conf
echo "pf_enable='YES'" >> /etc/rc.conf
echo "pf_rules='/mnt/Files/joe/hacks/pf.conf'" >> /etc/rc.conf
echo "gateway_enable='YES'" >> /etc/rc.conf
echo "" >> /etc/rc.conf
echo "#Turn on OpenVPN" >> /etc/rc.conf
echo "openvpn_enable='YES'" >> /etc/rc.conf
echo "openvpn_if='tun'" >> /etc/rc.conf
echo "openvpn_configfile='/mnt/Files/openvpn/openvpn.conf'" >> /etc/rc.conf
echo "openvpn_dir='/mnt/Files/openvpn'" >> /etc/rc.conf
service pf start
service openvpn start
fi

Save it and exit.

2. Now we need to make our hacks.sh script executable and make it owned by root for good measure.  Make sure to change the path below to match your setup.

chmod 700 /mnt/Files/joe/hacks/hacks.sh
chown root /mnt/Files/joe/hacks/hacks.sh

Set up the FreeNAS GUI to run hacks.sh as an init script.

3. Log into the FreeNAS gui and go to System > Init/Shutdown Scripts.  Then click add Init/Shutdown Script

Screen Shot 2014-03-09 at 10.30.47 PM

You want to select script in the first field.  Browse to your hacks.sh script and select it in the second field and select Post Init in the third field.

Screen Shot 2014-03-09 at 10.31.06 PM

Hit OK.

4. Reboot and watch the magic.

Verification

5. After you’ve rebooted, check the status of your hacks.

service openvpn status

You should get this if you are running openVPN

openvpn is running as pid 17535.

service pf status

You should get this if you are running pf.  Notice that is says enabled.

No ALTQ support in kernel
ALTQ related functions disabled
Status: Enabled for 5 days 00:16:00           Debug: Urgent

State Table                          Total             Rate
current entries                       21
searches                      1236116133         2855.0/s
inserts                            75627            0.2/s
removals                           75649            0.2/s
Counters
match                            2299524            5.3/s
bad-offset                             0            0.0/s
fragment                               0            0.0/s
short                                  0            0.0/s
normalize                              0            0.0/s
memory                                 0            0.0/s
bad-timestamp                          0            0.0/s
congestion                             0            0.0/s
ip-option                          28950            0.1/s
proto-cksum                            0            0.0/s
state-mismatch                     94319            0.2/s
state-insert                           0            0.0/s
state-limit                            0            0.0/s
src-limit                             15            0.0/s
synproxy                               0            0.0/s

Final Thoughts

I set this up and tested it in a VM that started out as FreeNAS 9.2.0.  After setting this all up, I did a system upgrade using the GUI and upgraded to 9.2.1.2.  After rebooting, I checked /etc/rc.conf and my changes were in fact still there.  I then checked to see if pf and openVPN were running and they were.  SUCCESS!!!

I hope you all enjoy this.  Let me know of all the great ways you find to use this.

FreeNAS – getting hacks to survive an upgrade


Update:

The first attempt at getting this to work failed miserably. Not only did the shell script mangle the additions to rc.conf, but the script created a reboot loop that was pretty much impossible to break.  THIS NEEDS MORE WORK! 

GOT IT WORKING!!!  CHECK IT OUT HERE!

I’ve been customizing FreeNAS to do more than it is meant to do out of the box.  I want to run OpenVPN on it.  I want it to have a firewall enabled on it.  I’ve got those things working, but the issue I have is after every OS upgrade, I have to remember to go back in and re-enable all of them.

What we really need is a way to make modifications to FreeNAS sticky.  So, I was thinking, why not write a script that will launch when the system is initializing and check to see if the modifications are in place or not.  The FreeNAS developers are pretty good about keeping things that are configured in the GUI and moving them forward with the OS upgrades.

Here are the basic steps involved:

  1. Write a shell script that checks /conf/base/etc/rc.conf for our customizations
  2. If they are not present, add them to the end of /conf/base/etc/rc.conf, then reboot
  3. If they are there, boot normally
  4. Run the script at startup by creating an init script in the GUI

I am not much of a code writer…and honestly this is my first shell script….so it isn’t going to be pretty.  So far here is what I have.

#!/bin/sh
if grep ‘pf_enable’ /conf/base/etc/rc.conf
then
echo “Hacks in Place”
else
mount -uw /
echo ‘#Turn on pf firewall’ >> /conf/base/etc/rc.conf
echo ‘pf_enable=”YES”‘ >> /conf/base/etc/rc.conf
echo ‘pf_rules=”/mnt/Files/joe/hacks/pf.conf”‘ >> /conf/base/etc/rc.conf
echo ‘gateway_enable=”YES”‘ >> /conf/base/etc/rc.conf
echo ‘ ‘ >> /conf/base/etc/rc.conf
echo ‘#Turn on OpenVPN’ >> /conf/base/etc/rc.conf
echo ‘openvpn_enable=”YES”‘ >> /conf/base/etc/rc.conf
echo ‘openvpn_if=”tun”‘ >> /conf/base/etc/rc.conf
echo ‘openvpn_configfile=”/mnt/Files/openvpn/openvpn.conf”‘ >> /conf/base/etc/rc.conf
echo ‘openvpn_dir=”/mnt/Files/openvpn”‘ >> /conf/base/etc/rc.conf
fi

So, that’s where I am on this so far.  Next step will be to test it out in a vm and see what it does.  Hopefully it does what I expect and then it is just a matter of setting it up in the GUI under Init Scripts.

More to come, so stay tuned.

Secure FreeNAS 9.2.1.2 with a Firewall


The recent NTP reflection incident I was a victim of woke me up to the need for securing my FreeNAS boxes from outside connections.  Luckily, FreeNAS 9.2.1.2 comes shipped with the kernel extension for pf, so getting it working is pretty easy.

If you are going to do this on your FreeNAS box, please also check out my guide on getting hacks to FreeNAS to survive system upgrades.

DISCLAIMER – I AM NOT A SECURITY EXPERT, FOLLOW THIS GUIDE AT YOUR OWN RISK

I’ve been told that pf does not play nice with vimage jails.  It tends to cause kernel panics.

Get the basics done

1. Mount the filesystem so we can make some changes.

su
enter your root password
mount -uw /

2. Figure out what interfaces you have active so we can add them to the firewall rules.

ifconfig

Your output should look something like this:

re0: flags=8943<up,broadcast,running,promisc,simplex,multicast> metric 0 mtu 1500
options=82099<RXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
ether f4:6d:04:db:21:ba
inet 192.168.0.10 netmask 0xffffff00 broadcast 192.168.0.255
inet6 xxxx::xxxx:xxxx:xxxx:xxxx%re0 prefixlen 64 scopeid 0x6
inet xxx.xxx.xxx.xxx netmask 0xfffffff8 broadcast 50.241.46.71
nd6 options=23<performnud,accept_rtadv,auto_linklocal>
media: Ethernet autoselect (1000baseT )
status: active

ipfw0: flags=8801<up,simplex,multicast> metric 0 mtu 65536
nd6 options=9<performnud,ifdisabled>

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 0xa
inet 127.0.0.1 netmask 0xff000000
nd6 options=21<performnud,auto_linklocal>

bridge0: flags=8843<up,broadcast,running,simplex,multicast> metric 0 mtu 1500
ether 02:df:7f:1c:ff:00
nd6 options=1
id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
member: epair0a flags=143<learning,discover,autoedge,autoptp>
ifmaxaddr 0 port 12 priority 128 path cost 2000
member: re0 flags=143<learning,discover,autoedge,autoptp>
ifmaxaddr 0 port 6 priority 128 path cost 20000

epair0a: flags=8943<up,broadcast,running,promisc,simplex,multicast> metric 0 mtu 1500
options=8<VLAN_MTU>
ether 02:09:09:00:0c:0a
nd6 options=1
media: Ethernet 10Gbase-T (10Gbase-T )
status: active

tun0: flags=8051<up,pointopoint,running,multicast> metric 0 mtu 1500
options=80000<LINKSTATE>
inet 10.8.0.1 –> 10.8.0.2 netmask 0xffffffff nd6 options=1
Opened by PID 17528

What we want to note are all the interface names.  Mine are re0, ipfw0, lo0, bridge0, epair0a and tun0

Create the firewall rules

3. Create the pf.conf file and edit it to your needs.  We are going to put it on our data drive so future FreeNAS upgrades don’t wipe it out. Adjust the path to match your setup.

mkdir /mnt/Files/hacks
vi /mnt/Files/hacks/pf.conf

Side note, vi has lots of commands, we just need to know a few:

x will delete the character your cursor is over, i will insert, esc will exit insert mode and to save and quit we use :wq

Here are the rules I am running.

#change this to match your primary ethernet interface, re0 or em0 are common, but there are others
ext_if="re0"
vpn_if="tun0"
table <bruteforce> persist
#These are all of the other interfaces we discovered in step 2
set skip on lo0
set skip on bridge0
set skip on ipfw0
set skip on epair0a
set skip on tun0
set block-policy return
scrub in all
#change xxx.xxx.xxx.xxx to the external IP of your FreeNAS box
nat on $ext_if from 10.8.0.0/24 to any -> xxx.xxx.xxx.xxx
#Lock it down
block in all
block out all
#Allow VPN traffic
pass on tun0 keep state
block quick from <bruteforce>
#Allow traffic in for ssh
pass in on $ext_if proto tcp from any to any port 22 flags S/SA keep state (max-src-conn 10, max-src-conn-rate 5/5, overload <bruteforce> flush global)
#Allow traffic in for web - delete or comment out if you don't want web traffic
pass in on $ext_if proto tcp from any to any port 80 flags S/SA keep state
pass in on $ext_if proto tcp from any to any port 443 flags S/SA keep state
#Allow traffic in for OpenVPN
pass in on $ext_if proto udp from any to any port 1194 keep state label "openvpn"
#Allow LAN traffic to connect to FreeNAS - change xxx.xxx.xxx.0 to match your network, ie 192.168.0.0 or 10.0.0.0
pass in on $ext_if from xxx.xxx.xxx.0/24 to any keep state
#Allow traffic out from the LAN
pass out on $ext_if from any to any keep state

Enable the Firewall

4. Edit /etc/rc.conf and add the following.

vi /etc/rc.conf

pf_enable="YES"
pf_rules="/mnt/Files/hacks/pf.conf"
gateway_enable="YES"

5. Start up the firewall and see if it works

service pf start

Your should get this as your output:

Enabling pf
No ALTQ support in kernel
ALTQ related functions disabled

Now check to make sure it is working:

service pf status

Your output should be something like this:

No ALTQ support in kernel
ALTQ related functions disabled
Status: Enabled for 0 days 00:04:55           Debug: Urgent

State Table                          Total             Rate
current entries                       29
searches                         1040038         3525.6/s
inserts                               95            0.3/s
removals                             109            0.4/s
Counters
match                               1093            3.7/s
bad-offset                             0            0.0/s
fragment                               0            0.0/s
short                                  0            0.0/s
normalize                              0            0.0/s
memory                                 0            0.0/s
bad-timestamp                          0            0.0/s
congestion                             0            0.0/s
ip-option                             22            0.1/s
proto-cksum                            0            0.0/s
state-mismatch                         0            0.0/s
state-insert                           0            0.0/s
state-limit                            0            0.0/s
src-limit                              0            0.0/s
synproxy                               0            0.0/s

6. Start IP Forwarding without restarting your server

sysctl net.inet.ip.forwarding=1

Then make sure to go into the FreeNAS gui, click on System, Click on Sysctls.  Then add that same value so it survives reboots.

Screen Shot 2014-05-14 at 10.43.22 AM

Make your changes stick

7.  Add your rc.conf changes to /conf/base/etc/rc.conf

vi /conf/base/etc/rc.conf

pf_enable="YES"
pf_rules="/mnt/Files/hacks/pf.conf"
gateway_enable="YES"

To really make these changes stick, follow my guide on the subject.

Clean Up

8. Make the filesystem read only again

mount -ur /

Final Thoughts

An added benefit of setting up a firewall this way is that it will let you route to other computers on your LAN over your VPN.  Hope you all enjoy this and let me know how things work out for you.

FreeNas Naughty NTP


Seems like FreeNas 9.2.0 and earlier shipped with ntpd enabled and listening for monitoring requests.  Recently got a notice that one of my machines was part of a DDoS attack on port 123 (NTP).  It was a NTP reflection attack and my freenas box was responding to the requests.

I should say, this will only affect you if your FreeNas box is internet facing or if you have port 123 forwarded to it.

So for a fix, ssh’d in and edited /etc/ntp.conf

Added:

disable monitor

Then stopped and restarted ntpd

service ntpd stop

service ntpd start

To verify that the problem is fixed,

ntpdc -n -c monlist 127.0.0.1

You should get a no connection error…or something like that.

Then, we want to:

mount -uw /

vi /conf/base/etc/ix.rc.d/ix-ntpd

scroll down to where you see EOF and right before that insert (i in vi):

disable monitor

Hit esc to exist insert mode and type :wq enter to save and quit

Make the file system read only again

mount -ur /

That should do it.  Your other option is to upgrade to 9.2.1 or higher.

Contemplating the next writeup.


Wondering if there is more interest in a writeup on setting up owncloud on FreeNAS 9.2.1 or if you’d rather have a writeup on setting up CrashPlan on FreeNAS 9.2.1?  I have owncloud working, so that would be the easier one.  CrashPlan is a difficult little bugger, so that will take some more work.  Or maybe there is something else entirely.  Vote it up and we’ll see what happens.