Tuesday, January 12, 2016

Solaris 11.2: ZFS Encryption

Oracle Solaris 11 supports encryption on ZFS in a native way to protect critical data without depending on external programs, and it is integrated with the Oracle Solaris Cryptographic Framework, which in turn makes encryption easier and faster by providing several symmetric and asymmetric algorithms for encrypting files and entire file systems. Moreover, when ZFS encryption is enabled on a newly created file system, encryption is automatically inherited by any descendant file systems, for added flexibility, encrypted file systems can live with unencrypted file systems in the same pool.
The following are the supported symmetric algorithms and their respective mechanisms:
root@solaris11-1:~# encrypt -l
Algorithm       Keysize:  Min   Max (bits)
------------------------------------------
aes                       128   256
arcfour                     8  2048
des                        64    64
3des                      128   192

root@solaris11-1:~# cryptoadm list -m
provider=aes
aes: CKM_AES_ECB,CKM_AES_CBC,CKM_AES_CTR,CKM_AES_CCM,CKM_AES_GCM,CKM_AES_GMAC,CKM_AES_CFB128,CKM_AES_XTS,CKM_AES_XCBC_MAC
root@solaris11-1:~#

From the available options, the 128-bit AES CCM mode is the
default. In case we are using deduplication on some
file systems, be aware that a CCM mode is required when combining both
encryption and deduplication.
There are several ways to use ZFS encryption on a system running
Oracle Solaris 11. Let's explore them.
First Way
We can encrypt a single file or a whole file system using the same
algorithms. The following shows an example for a single file:
root@solaris11-2:/tmpcp /etc/hosts /tmp/
root@solaris11-2:/tmp# cd /tmp/
root@solaris11-2:/tmp# encrypt -a aes -i /tmp/hosts -o /tmp/hosts.aes
Enter passphrase:
Re-enter passphrase:

root@solaris11-2:/tmp# file hosts*
hosts:     ascii text
hosts.aes: data

I entered the password oracle123! and everything worked fine. As we can see, the file was encrypted.
If we want to decrypt the file, we can use the following command:
root@solaris11-2:/tmp# decrypt -a aes -i
/tmp/hosts.aes -o /tmp/hosts.decrypted
Enter passphrase:

root@solaris11-2:/tmp# file hosts*
hosts:           ascii text
hosts.aes:       data
hosts.decryptedascii text

root@solaris11-2:/tmp# more hosts.decrypted
#
# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
# Internet host table
#
::1 solaris11-1 localhost
127.0.0.1 solaris11-1 solaris11.example.com localhost loghost
192.168.1.105 solaris11-1.example.com solaris11-1
192.168.1.102 solaris11-2.example.com solaris11-2
192.168.1.250 freenas.example.com freenas
root@solaris11-1:/tmp#

That was easy. We could do something similar to the following to encrypt the entire file system:
root@solaris11-2:~# zpool create pool_encr c8t3d0
root@solaris11-2:~# zfs create -o encryption=on pool_encr/fs_encr_1
Enter passphrase for 'pool_encr/fs_encr_1':
Enter again:
root@solaris11-2:~#
 
The default form of ZFS encryption is to prompt for a passphrase, as indicated in the example above.
I entered the same passphrase (oracle123!). If we create a new descendant file system, the passphrase is inherited from the parent file system.
The first thing we must be aware of is that it's not possible to decrypt a file system as we did for a single file. Another difference is we had to enter the passphrase in an interactive way. There's no problem doing that for some file systems, but entering the passphrase interactively can be real problem when deploying in big environments.
A better alternative would be to store the passphrase outside of our computer:
root@solaris11-1:/# zpool destroy pool_encr         
root@solaris11-1:/# zpool create pool_encr c8t3d0
root@solaris11-1:/# echo "oracle123" >
/media/ORA_PENDRIV/oracle_encryption_key
root@solaris11-1:/# more /media/ORA_PENDRIV/oracle_encryption_key oracle123
root@solaris11-1:/# zfs create -o encryption=on \
-o keysource=passphrase,file:///media/ORA_PENDRIV/oracle_encryption_key pool_encr/fs_encr_2
 
In this case, we also need to protect our removable device (pen drive), because the passphrase is there. Note that the file system is mounted during booting only if the system has access to the removable device, but the lack of any encryption key does not prevent the system from booting.
Important: As a last reminder, Oracle Solaris 11 cannot decrypt an encrypted file system the way it can decrypt an encrypted single file.

Second Way
As an alternative, we can use a wrapping key. A wrapping key is used to encrypt the real (symmetric) key that we would use to perform the encryption. In other words, when using a wrapping key, we store the symmetric key in the keystore, encrypt it using the wrapping key and then—when we need the symmetric key for encrypting a file system—the key is accessed and decrypted by using the wrapping key in a noninteractive mode.
The wrapping key could be a passphrase (which is similar to a password) or a raw key, and it's necessary only when the file system is initially mounted.
Different from the first method, for providing further protection, we could store the wrapping key inside the Oracle Solaris Cryptographic Framework, which is a kind of keystore encrypted by a softtoken. This keystore is protected by an initial passphrase (changeme) that we have to alter:

root@solaris11-2:/# pktool setpin
Enter token passphrase: changeme
Create new passphrase: borges123
Re-enter new passphrase: borges123
Passphrase changed.
root@solaris11-2:/#
The available tokens can be viewed by executing the following command: 
root@solaris11-2:~# pktool tokens
Flags: L=Login required  I=Initialized  X=User PIN expired  S=SO PIN expired
Slot ID
Slot
 Name
Token Name                        Flags    
-------  ---------                    ----------                        -----    
1        Sun Crypto Softtoken         Sun
Software PKCS#11 softtoken    LI
 
 
Let's create and then list some keys:
root@solaris11-2:~# pktool genkey keytype=aes keylen=192 label=otn1
Enter PIN for Sun Software PKCS#11 softtoken: borges123

root@solaris11-2:~# pktool genkey keytype=aes keylen=256 label=otn2
Enter PIN for Sun Software PKCS#11 softtoken:

root@solaris11-2:~# pktool list objtype=key
Enter PIN for Sun Software PKCS#11 softtoken:
Found 2 symmetric keys.
Key #1 - AES:  otn1 (192 bits)
Key #2 - AES:  otn2 (256 bits)

As you can see, the first pktool genkey command created a new key named otn1 using
the AES algorithm with 192 bits, and the second 
pktool genkey command created a key named otn2 using the AES algorithm with 256 bits.
We can repeat the same procedure to encrypt a file, but using the Oracle Solaris Cryptographic Framework this time:
root@solaris11-2:~# cp /etc/hosts /tmp/
root@solaris11-2:~# cd /tmp/
root@solaris11-2:/tmp# encrypt -a aes -K otn2 -i /tmp/hosts -o /tmp/hosts.aes256
Enter PIN for Sun Software PKCS#11 softtoken: borges123


root@solaris11-2:/tmp# file /tmp/hosts*
/tmp/hosts:         ascii text
/tmp/hosts.aes256:  data
 
We've done it! Nobody knows what the real password is, only that it's stored in the Oracle Solaris 11 keystore. Encrypting the example file (a copy of /etc/hosts) was done using the passphrase (borges123).
That's the nice thing: we don’t know the symmetric key itself because we need to enter only the PIN (passphrase) of the keystore.
   
From here, we could decrypt the file using the same method:
root@solaris11-2:/tmp# decrypt -a aes -K otn2 -i /tmp/hosts.aes256 \
-o /tmp/hosts.decrypted
Enter PIN for Sun Software PKCS#11 softtoken:

root@solaris11-2:/tmp# file /tmp/host*
/tmp/hosts:            ascii text
/tmp/hosts.aes256:     data
/tmp/hosts.decrypted:  ascii text
 
 
Before proceeding with file system encryption, it's important to say that the key could be stored outside of the keystore.
In this case, the key administration is our responsibility:
root@solaris11-2:/tmppktool genkey keystore=file
outkey=/mykeys/otn3 \
keytype=aes keylen=256
root@solaris11-2:/tmpls -al /mykeys/otn3
-r--------   1 root     root          32 Dec  9 19:14 /mykeys/otn3
root@solaris11-2:/tmp# file /mykeys/otn3
/mykeys/otn3:    data
root@solaris11-2:/tmppktool list objtype=key
Enter PIN for Sun Software PKCS#11 softtoken: borges123
Found 2 symmetric keys.
Key #1 - AES:  otn1 (192 bits)
Key #2 - AES:  otn2 (256 bits)
root@solaris11-2:/tmp#
 
As we can see from the output, the key isn't stored in the Oracle Solaris 11 keystore (softtoken).
To encrypt an entire file system using the PKCS#11 method (softtoken), do the following:
root@solaris11-2:~# zpool create softtoken_pool c8t4d0

root@solaris11-2:~# zfs create -o encryption=aes-256-ccm \
-o keysource=raw,pkcs11:object=otn2 softtoken_pool/fs_softtoken_1
Enter PKCS#11 token PIN for 'softtoken_pool/fs_softtoken_1':
borges123

root@solaris11-2:~# zfs list -r softtoken_pool
NAME USED  AVAIL  REFER MOUNTPOINT
softtoken_pool                 140K  3.91G
32K  /softtoken_pool 
softtoken_pool/fs_softtoken_1 33K  3.91G    33K /softtoken_pool/fs_softtoken_1
Cool. The symmetric key is stored inside the PKCS#11 keystore. Then, the zfs create command used it to create and encrypt thesofttoken_pool/fs_softtoken_1 filesystem.
It's a nice exercise to collect further information about the file system encryption:
root@solaris11-2:~# zfs get encryption softtoken_pool/fs_softtoken_1
NAME PROPERTY   VALUE        SOURCE
softtoken_pool/fs_softtoken_1  encryption  aes-256-ccm local

root@solaris11-2:~# zfs get keysource softtoken_pool/fs_softtoken_1
NAME PROPERTY  VALUE                   SOURCE
softtoken_pool/fs_softtoken_1  keysource  raw,pkcs11:object=otn2  local

To make a new file system, but using another key, is
straightforward:
root@solaris11-2:~# zfs create -o encryption=aes-192-ccm \
-o keysource=raw,pkcs11:object=otn1
softtoken_pool/fs_softtoken_2
Enter PKCS#11 token PIN for 'softtoken_pool/fs_softtoken_2':
borges123

root@solaris11-2:~# zfs get encryption softtoken_pool/fs_softtoken_2
NAME      PROPERTY   VALUE        SOURCE
softtoken_pool/fs_softtoken_2  encryption  aes-192-ccm local

root@solaris11-2:~# zfs get keysource softtoken_pool/fs_softtoken_2
NAME      PROPERTY  VALUE                   SOURCE
softtoken_pool/fs_softtoken_2  keysource raw,pkcs11:object=otn1  local

root@solaris11-2:~# zfs list -r softtoken_pool
NAME USED  AVAIL  REFER MOUNTPOINT
softtoken_pool 194K  3.91G 33K  /softtoken_pool
softtoken_pool/fs_softtoken_1
33K  3.91G    33K /softtoken_pool/fs_softtoken_1
softtoken_pool/fs_softtoken_2
33K  3.91G    33K /softtoken_pool/fs_softtoken_2

Finally, it's possible to encrypt the entire pool (not just some of the file systems):
root@solaris11-2:~# zpool create -o encryption=on \
-o keysource=raw,pkcs11:object=otn1 softtoken_pool_2 c8t5d0
Enter PKCS#11 token PIN for 'softtoken_pool_2': borges123

root@solaris11-2:~# zfs create softtoken_pool_2/fs_softtoken_3
root@solaris11-2:~# zfs create softtoken_pool_2/fs_softtoken_4

This is very interesting: the encrypted pool was created and the pin number (that is, the passphrase for the keystore) was required, but when we created the descendant
file systems (
fs_softtoken_3 and fs_softtoken_4) no passphrase is prompted for because descendant file systems inherit the parent file system’s encryption key. To verify this, run the following command:

root@solaris11-2:~# zfs get encryption,keysource softtoken_pool_2/fs_softtoken_3 softtoken_pool_2/fs_softtoken_3
NAME PROPERTY    VALUE                   SOURCE
softtoken_pool_2/fs_softtoken_3  encryption on             inherited from softtoken_pool_2
softtoken_pool_2/fs_softtoken_3  keysource   raw,pkcs11:object=otn1  inherited from softtoken_pool_2
softtoken_pool_2/fs_softtoken_3  encryption on                inherited from softtoken_pool_2
softtoken_pool_2/fs_softtoken_3  keysource   raw,pkcs11:object=otn1  inherited from softtoken_pool_2

Amazing. Exactly as we had predicted.

OEL - Yum & CVE info

Having meta data available changes a lot because it makes life for admins easier. Compared to CentOS, which does not provide any meta data
information or Redhat where you need to buy a subscription, Oracle now gives you security information for free! And as far as I know they might integrate bugfixes and enhancements too!
updateinfo.xml.gz file is there, which is very nice. Lets do some tests on a freshly installed oel6.3:
[root@oel6.3~]# yum list-security
CVE-2012-3817 security bind-libs-32:9.8.2-0.10.rc1.el6_3.2.x86_64
CVE-2012-4244 security bind-libs-32:9.8.2-0.10.rc1.el6_3.3.x86_64
CVE-2012-3817 security bind-utils-32:9.8.2-0.10.rc1.el6_3.2.x86_64
CVE-2012-4244 security bind-utils-32:9.8.2-0.10.rc1.el6_3.3.x86_64
CVE-2012-3524 security dbus-1:1.2.24-7.0.1.el6_3.x86_64
CVE-2012-3524 security dbus-libs-1:1.2.24-7.0.1.el6_3.x86_64
CVE-2012-3954 security dhclient-12:4.1.1-31.P1.0.1.el6_3.1.x86_64
CVE-2012-3571 security dhclient-12:4.1.1-31.P1.0.1.el6_3.1.x86_64
CVE-2012-3571 security dhcp-common-12:4.1.1-31.P1.0.1.el6_3.1.x86_64
CVE-2012-3954 security dhcp-common-12:4.1.1-31.P1.0.1.el6_3.1.x86_64
CVE-2012-4405 security ghostscript-8.70-14.el6_3.1.x86_64
CVE-2012-3405 security glibc-2.12-1.80.el6_3.3.x86_64
CVE-2012-3406 security glibc-2.12-1.80.el6_3.3.x86_64
Nice, having the CVE information is very important. This allows us to see if we have any security related updates. The good thing about having this information is that CVE can be queried and specific security updates can be made.
Let’s query a CVE information:
[root@oel63~]# yum info-security CVE-2012-2390
Loaded plugins: security
==============================================================
Update ID : CVE-2012-2390
Release :
Type : security
Status : final
Issued : 2012-05-17
CVEs : CVE-2012-2390
Description : Memory leak in mm/hugetlb.c in the
Linux kernel before 3.4.2
: allows local users to cause a denial of service
: (memory consumption or system crash) via invalid
: MAP_HUGETLB mmap operations.
updateinfo info done
Howto update a specific CVE:
[root@oel63~]# yum update –cve CVE-2012-2337
Loaded plugins: security
Setting up Update Process
Resolving Dependencies
Limiting packages to security relevant ones
1 package(s) needed (+0 related) for security, out of 50 available
–> Running transaction check
—> Package sudo.x86_64 0:1.7.4p5-11.el6 will be updated
—> Package sudo.x86_64 0:1.7.4p5-13.el6_3 will be an update
–> Finished Dependency Resolution
Dependencies Resolved
To update all security related problems you can execute:
[root@oel63 ~]# yum update –security
Loaded plugins: security
Setting up Update Process
Resolving Dependencies
Limiting packages to security relevant ones
29 package(s) needed (+0 related) for security, out of 50 available
–> Running transaction check
As you can see it would only update the packages which have security related issues.
Conclusion:
The fact that Oracle has meta data for their repository and gives it away for free puts them, from a business perspective, clearly ahead of CentOS. It is very important for admins to have the CVE information. Some people will now say, but I can have that too with spacewalk and even get the bugfixes and feature enhancement information. Yes you’re right, but its another component which you’ll have to administrate and maintain. Having the ability to check security updates and maybe in the future bugfixes and enhancements  with yum is just so much easier and nicer.  So Thanks Oracle for giving us CVE meta data information!