FreeB­SD Ser­vice Jails – anoth­er lay­er in the secu­ri­ty onion

In May I com­mit­ted a new fea­ture to FreeBSD-current (it will be in the FreeB­SD 15 release, I have no plans to merge this to 14). This fea­ture is called “Ser­vice Jails”. When you enable it, it takes a ser­vice (some­thing which is start­ed by an rc-script at boot or by hand via service(8)) and starts it in a jail(8). It can do this with any ser­vice, and with no more than 2 lines of configuration.

For those which don’t know, a jail is some kind of con­tain­er tech­nol­o­gy. We have this tech­nol­o­gy since 1999 (so it pre-dates Dock­er by 14 years). It served as an inspi­ra­tion for Solaris zones.

Too good to be true?

Con­tainer­iz­ing some soft­ware with only 2 lines of code (if a ser­vice is “Ser­vice Jail ready”, only one line) sounds amaz­ing, and is in no way com­pa­ra­ble to a dock­er file or a nor­mal jail con­fig. This sounds a bit too good to be true. And that is cor­rect. The ser­vice Jails frame­work is some­where between a ful­ly iso­lat­ed con­tain­er, and no con­tainer­iza­tion at all.

The biggest dif­fer­ence is that a Ser­vice Jail has full access to the entire filesys­tem of the host (or par­ent jail), except for chflags(1). This means if your ser­vice runs as root in the Ser­vice Jail, and it is com­pro­mised, the attack­er is able to read your pass­word data­base, and mod­i­fy near­ly any file con­tent (and as such on next boot any­thing can hap­pen). The only excep­tion to this is, if this ser­vice already has pro­vi­sions to run in a chroot and this is enabled. In that case only files in the chroot can be mod­i­fied by an attacker.

What are the benefits?

Com­pared to run­ning a ser­vice on the host itself with­out putting it into a jail you have cre­at­ed your­self and tai­lored to only the soft­ware you need, you have the ben­e­fit of lim­it­ing what the soft­ware (or an intrud­er) is able to do, but not the ben­e­fit of a min­i­mal soft­ware install.

When you enable a Ser­vice Jail for a par­tic­u­lar ser­vice which is not Ser­vice Jail ready and you do not pro­vide a Ser­vice Jail con­fig, the ser­vice is start­ed inside a jail with­out any net­work access and full access to the filesys­tem. A Ser­vice Jail ready ser­vice which nor­mal­ly needs net­work access, can be lim­it­ed by a cus­tom con­fig to not have any net­work access at all (or only to IPv6 and not IPv4, or vice ver­sa). This means you can lim­it this soft­ware to not access the net­work despite not hav­ing it inside a VM.

The Ser­vice Jail also does­n’t allow to:

  • mount filesys­tems (and on pur­pose there is no pro­vi­sion so far to option­al­ly allow this),
  • open raw sock­ets (can be enabled),
  • open sock­ets of pro­to­col stacks that have not had jail func­tion­al­i­ty added (IPv4, IPv6, local UNIX sock­ets and rout­ing stuff are jail-aware) to them (can be enabled),
  • lock/unlock phys­i­cal pages in mem­o­ry (can be enabled),
  • use Sys­tem V IPC facil­i­ties (can be enabled),
  • use debug­ging facil­i­ties for unpriv­i­leged processes,
  • see process­es from the host or oth­er jails,

and all the oth­er stuff which is pro­hib­it­ed in jails by default.

When you enable net­work access (IPv4 and/or IPv6) for a par­tic­u­lar ser­vice, the Ser­vice Jail inher­its all the IPs of the host (or par­ent jail). This means you can not run two ser­vices which want to lis­ten on the same port by this. But as you can lim­it it to get only access to IPv4 and not IPv6 (and vice ver­sa), it means you could run two dif­fer­ent ser­vices for IPv4 and IPv6, or you can test sce­nar­ios where only one IP stack is avail­able but have the host itself con­fig­ured for dual-stack net­work access.

How to get most out of Ser­vice Jails?

With the pos­si­bil­i­ty to allow unpriv­i­leged users to open priv­i­leged ports (sysctl net.inet.ip.portrange.reservedhigh=0) and hav­ing the ser­vice start­ed as non-root (sysrc servicename_user=MyServiceUser), a Ser­vice Jail pro­vides a very good ben­e­fit for a sim­ple one-line con­fig change (sysrc servicename_svcj=YES).

In this case filesys­tem access is restrict­ed to what this par­tic­u­lar user is able to read / write, only process­es start­ed by the ser­vice are vis­i­ble to the ser­vice, and all the oth­er jail-restrictions apply. An intrud­er may as such do bad things to this par­tic­u­lar ser­vice, but not to oth­er ser­vices on the system.

For a read-only web­serv­er this may mean an attack­er may be able to mod­i­fy some log files, but can not see oth­er process­es run­ning on the sys­tem and deduct­ing from them what is the most valu­able next step in the attack.

For a read-only php-fpm ser­vice it may mean that the attack­er can run some in-memory code to spawn a bot­net, but not com­pro­mise oth­er parts of the host or access Sys­tem V mem­o­ry loca­tions of a data­base (if the php-fpm ser­vice is not con­fig­ured to allow access to Sys­tem V resources).

Fur­ther reading

The rc.conf(8) man page con­tains more info about what can be enabled for Ser­vice Jails (search for “svcj” and “SERVICE JAILS”). The rc script­ing arti­cle explains how to make a ser­vice Ser­vice Jails ready, and the FreeB­SD hand­book con­tains a sec­tion how to enable and con­fig­ure Ser­vice Jails.

What’s next?

The base sys­tem ser­vices are either made Ser­vice Jails aware, or con­fig­ured to not run inside a ser­vice jail (e.g. a fsck does­n’t make sense to run in a jail). Not all of the ser­vices are test­ed with Ser­vice Jails. Give them a try and send a bug report in case some­thing does­n’t work.

The FreeB­SD ports col­lec­tion has about 1500 ser­vices. I’ve either com­mit­ted already some patch­es or send patch­es to the main­tain­ers for some of the high pro­file ports (like web­servers, data­bas­es, DNS servers, …) to make some of them Ser­vice Jails ready, but there are too much ser­vices to do that all myself. Feel free to sub­mit some patch­es for them.

Win­dows: remove one item from filesys­tem ACL

Pow­er­Shell snip­pets to remove a group/user from a filesys­tem ACL in Win­dows (and com­pare how to do it in Linux/FreeBSD/Solaris).

Prob­lem

There may be a fold­er (with bro­ken inher­i­tance) with files / direc­to­ries where you want to make sure that there is no spe­cif­ic group / item included.

Solu­tion

Here are some Pow­er­Shell snip­pets to solve this.

Pop­u­late $fold­ers with all direc­to­ries in the cur­rent directory:

$folders =  get-childitem . -directory

To test with one folder:

$folders = "X:\path\to\folder"

Pow­er­Shell to list fold­ers with BUILTIN\Users in the ACL (to see which item will be affected):

foreach ($dir in $folders) { $value = get-acl $dir | Select-object -ExpandProperty Access | where { $_.IdentityReference -eq "BUILTIN\Users"} | Select -Expand IdentityReference; if ($value) {echo $dir} }

Print ACL of before and “to be” after removal (but not remov­ing anything):

foreach ($item in $folders) { $value = get-acl $item | Select-object -ExpandProperty Access | where { $_.IdentityReference -eq "BUILTIN\Users"} | Select -Expand IdentityReference; if ($value) {echo $item; $ACL = (get-item $item).getAccessControl('Access'); $ACL.SetAccessRuleProtection($true, $true); echo $ACL |Select-object -ExpandProperty Access; $ACL = (get-item $item).getAccessControl('Access'); $ACL.Access | where {$_.IdentityReference -eq "BUILTIN\Users"} |%{$acl.RemoveAccessRule($_)}; echo $ACL |Select-object -ExpandProperty Access } }

Set the ACL (dis­able inher­i­tance (con­vert cur­rent set­tings to explic­it ACL) and remove BUILTIN\Users):

foreach ($item in $folders) { $value = get-acl $item | Select-object -ExpandProperty Access | where { $_.IdentityReference -eq "BUILTIN\Users"} | Select -Expand IdentityReference; if ($value) {echo $item; $ACL = (get-item $item).getAccessControl('Access'); $ACL.SetAccessRuleProtection($true, $true); Set-Acl -Path $item -AclObject $ACL; $ACL = (get-item $item).getAccessControl('Access'); $ACL.Access | where {$_.IdentityReference -eq "BUILTIN\Users"} |%{$acl.RemoveAccessRule($_)}; Set-Acl -Path $item -AclObject $ACL } }

How would this be solved in Solaris?

setfacl -d <entry> *

How would this be solved in FreeBSD/Linux?

setfacl -x <entry> *

Sta­tus cryp­to cards HOWTO: prob­lems with the card read­er (sup­port could be better)

After hours (spread over weeks) I come to the con­clu­sion that there is a lot of poten­tial to improve the doc­u­men­ta­tion of card read­ers (but I doubt the card read­er ven­dors will do it) and of the pcsc doc­u­men­ta­tion. It is not easy to arrive at a point where you under­stand every­thing. The com­pat­i­bil­i­ty list does not help much, as the card read­ers are part­ly past their end of life and the mod­els which replace them are not list­ed. Respec­tive­ly the one I bought does not sup­port all the fea­tures I need. I even port­ed the dri­ver to FreeB­SD (not com­mit­ted, I want­ed to test every­thing first) and a lot of stuff works, but one crit­i­cal part is that I can not store a cer­tifi­cate on the cryp­to card as the card read­er or the dri­ver  does not sup­port extend­ed APDUs (need­ed to trans­fer more than 255 bytes to the card reader).

Well, the sta­tus so far:

  • I have a HOWTO what to install to use cryp­to cards in FreeBSD
  • I have a HOWOT what to install / con­fig­ure in Windows
  • I have a HOWTO regard­ing cre­at­ing keys on a openpgp v2 card and how to use this key with ssh on FreeB­SD (or any oth­er unix-like OS which can run pcsc)
  • I have a card read­er which does not sup­port extend­ed APDUs
  • I want to make sure what I write in the HOW­TOs is also suit­able for the use with Win­dows / PuTTY
  • it seems Win­dows needs a cer­tifi­cate and not only a key when using the Win­dows CAPI (using the ven­dor sup­plied card read­er dri­ver) in PuTTY-CSC (works at work with a USB token)
  • the pcsc pkcs11 Win­dows DLL is not suit­able yet for use on Win­dows 8 64bit
  • I con­tact­ed the card read­er ven­dor if the card read­er or the dri­ver is the prob­lem regard­ing the extend­ed APDUs
  • I found prob­lems in gpg4win / pcsc on Win­dows 8
  • I have send some mon­ey to the devel­op­ers of gpg4win to sup­port their work (if you use gnupg on Win­dows, try to send a few units of mon­ey to them, the work stag­nat­ed as they need to spend their time for paid work)

So either I need a new card read­er, or have to wait for an update of the lin­ux dri­ver of the ven­dor… which prob­a­bly means it may be a lot faster to buy a new card read­er. When look­ing for one with at least a PIN pad, I either do not find any­thing which is list­ed as sup­port­ed by pcsc on the ven­dor pages (it is incred­i­ble how hard it is to nav­i­gate the web­sites of some com­pa­nies… a lot of buzz­words but no way to get to the real prod­ucts), or they only list updat­ed mod­els where I do not know if they will work.

When I have some­thing which works with FreeB­SD and Win­dows, I will pub­lish all the HOW­TOs here at once.

OpenPGP cryp­to cards ordered

I wrote in a pre­vi­ous blog post that I want to switch to cryp­to cards for use with ssh and GnuPG. After some research I set­tled on the OpenPGP cry­to cards. I ordered them from ker­nel­con­cepts. As soon as they arrive (and I have some free time), I will start to use them and write down how to work with them with FreeBSD.

Which cryp­to card to use with FreeB­SD (ssh/gpg)

The recent secu­ri­ty inci­dent trig­gered a dis­cus­sion how to secure ssh/gpg keys.

One way I want to focus on here (because it is the way I want to use at home), is to store the keys on a cryp­to card. I did some research for suit­able cryp­to cards and found one which is called Feit­ian PKI Smart­card, and one which is called OpenPGP card. The OpenPGP card also exists in a USB ver­sion (basi­cal­ly a small ver­sion of the card is already inte­grat­ed into a small USB card reader).

The Feit­ian card is report­ed to be able to han­dle RSA keys upto 2048 bits. They do not seem to han­dle DSA (or ECDSA) keys. The smart­card quick starter guide they have  (the Tun­ing smart­card file sys­tem part) tells how to change the para­me­ters of the card to store upto 9 keys on it.

The spec of the OpenPGP card tells that it sup­ports RSA keys upto 3072 bits, but there are reports that it is able to han­dle RSA keys upto 4096 bits (you need to have at least GPG 2.0.18 to han­dle that big keys on the cryp­to card). It looks to me like the card is not han­dle DSA (or ECDSA) cards. There are only slots for upto 3 keys on it.

If I go this way, I would also need a card read­er. It seems a class 3 one (hard­ware PIN pad and dis­play) would be the most “future-proof” way to go ahead. I found a Rein­er SCT cyber­Jack sec­oder card read­er, which is believed to be sup­port­ed by Open­SC and seems to be a good bal­ance between cost and fea­tures of the Rein­er SCT card readers.

If any­one read­ing this can sug­gest a bet­ter cryp­to card (keys upto 4096 bits, more than 3 slots, and/or DSA/ECDSA  sup­port), or a bet­ter card read­er, or has any prac­ti­cal expe­ri­ence with any of those com­po­nents on FreeB­SD, please add a comment.