Annotation of wikisrc/security/cgdroot.mdwn, revision 1.11

1.1       khorben     1: Root filesystem encryption
                      2: ==========================
                      3: 
1.8       khorben     4: It is possible to run NetBSD with [complete root filesystem encryption][1], thanks to the `cgdroot.kmod` kernel module. It really is a memory disk (also knows as RAM disk) that is expected to be loaded in the kernel while booting. It is named after CGD, the "cryptographic device driver", which implements encryption for storage in the NetBSD kernel.
1.1       khorben     5: 
1.9       khorben     6: The mechanism described here still requires one unencrypted partition to boot from (typically `wd0a`). Full disk encryption would make it more difficult for an attacker to modify the unencrypted part of the disk to plant a backdoor. With only partial encryption, the original [[!template id=man name="cgdconfig" section="8"]] binary may be modified to send the passphrase away, allowing an attacker with a disk dump to recover the data.
1.1       khorben     7: 
1.10      khorben     8: The NetBSD Guide contains [an entire section about CGD][2].
                      9: 
1.1       khorben    10: The boot process
                     11: ----------------
                     12: 
1.9       khorben    13: Instead of booting the GENERIC kernel normally and using the root filesystem directly as usual, a special kernel module containing a memory disk is loaded at boot-time. This minimal filesystem image will then be the actual root filesystem, where the decryption process takes place.
1.1       khorben    14: 
1.9       khorben    15: The boot partition on disk needs to contain:
1.4       leot       16: 
1.3       leot       17: * [[!template id=man name="boot" section="8"]], the second-stage bootloader
                     18: * [[!template id=man name="boot.cfg" section="5"]], the configuration file for the bootloader (optional)
1.1       khorben    19: * a GENERIC kernel
                     20: * the `cgdroot.kmod` kernel module
1.8       khorben    21: * the configuration file for CGD, `cgd.conf`
                     22: * the encryption key for the volume to start from, named after its partition (like `wd0f`)
1.1       khorben    23: 
1.3       leot       24: Once loaded the memory disk mounts the `wd0a` partition onto `/etc/cgd`, and asks for the encryption passphrase as usual (with [[!template id=man name="cgdconfig" section="8"]]). If successful, the `cgd0a` volume configured is mounted on `/altroot`, and [[!template id=man name="init" section="8"]] is told via [[!template id=man name="sysctl" section="7"]] to chroot into this volume before actually booting. The system then starts normally.
1.1       khorben    25: 
                     26: In practice the memory disk remains the real root, and the regular system is
                     27: really ran from a chroot in `/altroot`.
                     28: 
                     29: Obtaining the kernel module
                     30: ---------------------------
                     31: 
1.11    ! khorben    32: The `cgdroot.kmod` kernel module is part of the regular NetBSD releases since NetBSD 7.0. It can be found in the `<arch>/installation/miniroot` folder from the release. For instance, for the amd64 architecture on the German mirror for the 7.0.1 release, download it at [ftp.de.netbsd.org/pub/NetBSD/NetBSD-7.0.1/amd64/installation/miniroot/cgdroot.kmod](ftp://ftp.de.netbsd.org/pub/NetBSD/NetBSD-7.0.1/amd64/installation/miniroot/cgdroot.kmod).
1.1       khorben    33: 
                     34: Configuring the kernel module
                     35: -----------------------------
                     36: 
                     37: The kernel module needs to be available in the boot partition, alongside the desired kernel. The bootloader configuration in `/boot.cfg` should be modified to load the module, as in this example:
1.3       leot       38: 
                     39: [[!template id=filecontent name="/boot.cfg" text="""
1.1       khorben    40: menu=Boot normally:rndseed /etc/entropy-file;load /cgdroot.kmod;boot /netbsd.gz -z
1.3       leot       41: """]]
1.1       khorben    42: 
                     43: Building the kernel module
                     44: --------------------------
                     45: 
                     46: The kernel module can be compiled in two steps from within the source tree for the NetBSD base system, once the distribution has been built. Change to the `distrib/<arch>/ramdisks/ramdisk-cgdroot` and use `nbmake-<arch>` to build:
                     47: 
1.3       leot       48: [[!template id=programlisting text="""
1.2       khorben    49: src/distrib/amd64/ramdisks/ramdisk-cgdroot$ /path/to/tooldir/bin/nbmake-amd64
1.1       khorben    50: [...]
                     51:      create  ramdisk-cgdroot/ramdisk-cgdroot.fs
                     52: Calculated size of `ramdisk-cgdroot.fs.tmp': 5120000 bytes, 85 inodes
                     53: Extent size set to 4096
                     54: ramdisk-cgdroot.fs.tmp: 4.9MB (10000 sectors) block size 4096, fragment size 512
                     55:         using 1 cylinder groups of 4.88MB, 1250 blks, 96 inodes.
                     56: super-block backups (for fsck -b #) at:
                     57:  32,
                     58: Populating `ramdisk-cgdroot.fs.tmp'
                     59: Image `ramdisk-cgdroot.fs.tmp' complete
1.3       leot       60: """]]
1.1       khorben    61: 
                     62: Then the kernel module can be built:
                     63: 
1.3       leot       64: [[!template id=programlisting text="""
1.2       khorben    65: src/distrib/amd64/kmod-cgdroot$ /path/to/tooldir/bin/nbmake-amd64
1.3       leot       66: """]]
1.1       khorben    67: 
                     68: Caveats
                     69: -------
                     70: 
1.5       khorben    71: The biggest (known) issue with this setup occurs when firmware needs to be loaded early in the boot process (such as graphics drivers for the console). At the moment they need to be provided as part of the memory disk. Some network interfaces, of which some wireless devices in particular, also require loading firmware to work properly.
1.1       khorben    72: 
1.5       khorben    73: This setup is not entirely safe against physical attacks. An attacker can modify the boot process to store the passphrase for later retrieval, or insert a backdoor while booting. To defend against such attacks, the bootloader, kernel and ramdisk all need to be signed and their integrity checked before booting (eg with [[!template id=man name="tpm" section="4"]]). Alternatively, it is possible to boot from a removable medium (eg USB stick), which can be protected against tampering attacks (eg secure storage, read-only volume...).
1.1       khorben    74: 
1.6       khorben    75: It is also possible to boot a Xen DOM0 system with root filesystem encryption. However, Xen-enabled NetBSD kernels currently do not support loading modules at boot-time. The memory disk has to be placed directly inside the kernel instead (with [[!template id=man name="mdconfig" section="8"]] or a new kernel configuration).
                     76: 
1.1       khorben    77: References
                     78: ----------
                     79: 
1.4       leot       80: * [Full Disk Encryption with cgd (well, almost)][1]
1.10      khorben    81: * [The cryptographic device driver (CGD)][2]
1.4       leot       82: 
1.3       leot       83: [1]: https://mail-index.netbsd.org/current-users/2013/03/21/msg022311.html "Full Disk Encryption with cgd (well, almost)"
1.10      khorben    84: [2]: http://www.netbsd.org/docs/guide/en/chap-cgd.html "The cryptographic device driver (CGD)"

CVSweb for NetBSD wikisrc <wikimaster@NetBSD.org> software: FreeBSD-CVSweb