Xifrat complet de disc Debian

Aquests dies he aprofitat per xifrar el disc del meu portàtil, inclosa la partició d’arrencada (/boot). L’esquema de particionat que segueixo és:

Device Start End Sectors Size Type
/dev/nvme0n1p1 2048 1050623 1048576 512M EFI System
/dev/nvme0n1p2 1050624 1460223 409600 200M Linux filesystem
/dev/nvme0n1p3 1460224 500118158 498657935 237.8G Linux filesystem

On la 2a i 3a partició estan xifrades amb LUKS i la 3a té a sobre un sistema LVM.

Instal·lar Debian

El primer pas és instal·lar Debian amb normalitat fins que ens demani el particionat de discos. Allà hem de fer una partició d’uns 512M (o menys) per EFI, una de 200M pel /boot (ext4) i una amb la resta d’espai que sigui del tipus crypt-luks. Dins d’aquesta també hem d’implementar volums LVM, cosa que podem fer des del mateix particionador de Debian.

Xifrar /boot

Un cop tinguem Debian instal·lat i funcionant (i haguem fet un backup del /boot) arrenquem amb una Live de, per exemple, Arch Linux, per poder xifrar la partició /boot.

Tenint en compte que ja tenim un backup de /boot, la formatem com a volum luks:

# cryptsetup luksFormat /dev/nvm0n1p2

Muntem les particions i fem chroot:

# cryptsetup open /dev/nvme0n1p3 cryptroot
# cryptsetup open /dev/nvme0n1p2 cryptboot
# mkfs.ext4 /dev/mapper/cryptboot
# mount /dev/ziggy/root /mnt
# mount /dev/mapper/cryptboot /mnt/boot
# mount /dev/nvme0n1p1 /mnt/boot/efi
# arch-chroot /mnt

A partir d’aquí les ordres s’estan executant dins del chroot.

Carreguem el PATH:

# source /etc/profile

Activem el suport xifrat al GRUB editant /etc/default/grub:

GRUB_CMDLINE_LINUX="cryptdevice=/dev/nvme0n1p3:lvm"
GRUB_ENABLE_CRYPTODISK=y

Modifiquem /etc/crypttab:

cryptboot UUID=<uuid-particio-boot> none luks
cryptroot UUID=<uuid-particio-lvm>  none luks

Modifiquem /etc/fstab:

Comentem la línia que munta el boot i afegim:

/dev/mapper/cryptboot    /boot    ext4    errors=remount-ro    0    1

Reecrem el /boot:

# apt install --reinstall linux-image-4.9.0-6-amd64
# mkdir /boot/grub
# grub-mkconfig -o /boot/grub/grub.cfg
# grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=debian --recheck

Amb això ja et queda el boot xifrat. Només cal sortir del chroot, desmuntar les particions i reiniciar el sistema.

Bonus: Evitar posar la contrasenya 4 cops

En haver realitzat aquests passos em trobo que he de posar 4 cops la clau de pas. Dos cops al GRUB (un per cada partició xifrada) i dos cops per arrencar el kernel (també un per cada partició).

Kernel:

A nivell de Kernel, podem utilitzar un keyfile.

El podem generar amb dd:

# dd if=/dev/random of=/crypto_keyfile.bin bs=1 count=4096
# cryptsetup luksAddKey /dev/nvme0n1p2 /crypto_keyfile.bin
# cryptsetup luksAddKey /dev/nvme0n1p3 /crypto_keyfile.bin
# chmod 000 /crypto_keyfile.bin
# chmod -R g-rwx,o-rwx /boot

Editem el fitxer /etc/crypttab:

cryptboot UUID=<uuid-particio-boot> /crypto_keyfile.bin luks,keyscript=/bin/cat
cryptroot UUID=<uuid-particio-lvm>  /crypto_keyfile.bin luks,keyscript=/bin/cat

Creem el fitxer /etc/initramfs-tools/hooks/crypto_keyfile:

#!/bin/sh
cp /crypto_keyfile.bin "${DESTDIR}"

Li donem permisos d’execució i actualitzem l’initramfs:

# chmod +x /etc/initramfs-tools/hooks/crypto_keyfile
# update-initramfs -u

Amb això, si reiniciem, només ens hauria de demanar la passphrase el GRUB.

GRUB:

El GRUB ens demana desxifrar les dues particions per carregar la imatge de fons, entre altres coses. Com que personalment el GRUB és una pantalla que veig menys de 5 segons m’és ben igual la seva aparença i prefereixo haver d’escriure la contrasenya només un cop.

Retirem els permisos d’execució:

# chmod -x /etc/grub.d/05_debian_theme

Actualitzem el GRUB:

# update-grub

I llestos. Al fitxer /boot/grub/grub.cfg ja no consta que s’hagi de muntar l’LVM en aquell moment.

Altre enllaços:

Evitar parar el PC en fallar la passphrase (salta un grub rescue): https://blog.stigok.com/post/decrypt-and-mount-luks-disk-from-grub-rescue-mode

Solucionar error “volume not found”: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=671037

Fonts:

https://wiki.archlinux.org/index.php/Dm-crypt/Encrypting_an_entire_system

http://www.pavelkogan.com/2014/05/23/luks-full-disk-encryption/

 

Apunts Yubikey

Clau SSH

A Debian per poder utitlizar la clau GPG d’autenticació com a clau SSH cal:

Editar el fitxer ~/.gnupg/gpg-agent.conf :

enable-ssh-support

Editar el fitxer ~/.bashrc:

# Set SSH to use gpg-agent
unset SSH_AGENT_PID
if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
 export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
fi

# Set GPG TTY
export GPG_TTY=$(tty)

# Refresh gpg-agent tty in case user switches into an X session
gpg-connect-agent updatestartuptty /bye >/dev/null

Per comprovar que funcioni:

$ ssh-add -L
ssh-rsa AAAAB3NzaC ... pdqtlwX6m1 cardno:000123457915

Let’s Encrypt proxy invers

Apunts breus sobre els problemes que he tingut configurant Let’s Encrypt amb un proxy invers i diferents màquines.

Els fitxers de renovació es troben a: /etc/letsencrypt/renewal

Virtualhosts a la mateixa màquina

No s’ha de fer res especial, que el Certbot renovi per Webroot i prou.

Un exemple de fitxer de renovació:

# renew_before_expiry = 30 days
version = 0.10.2
archive_dir = /etc/letsencrypt/archive/lanpartyripoll.cat
cert = /etc/letsencrypt/live/lanpartyripoll.cat/cert.pem
privkey = /etc/letsencrypt/live/lanpartyripoll.cat/privkey.pem
chain = /etc/letsencrypt/live/lanpartyripoll.cat/chain.pem
fullchain = /etc/letsencrypt/live/lanpartyripoll.cat/fullchain.pem

# Options used in the renewal process
[renewalparams]
authenticator = webroot
installer = None
account = XXXXXXXXXXXXXXXXXXXXXXXXXX
[[webroot_map]]
www.lanpartyripoll.cat = /var/www/lanpartyripoll.cat
lanpartyripoll.cat = /var/www/lanpartyripoll.cat

 

Virtualhosts a diferent màquina

Primer de tot he definit un subdomini apuntant a la màquina que conté el proxy invers. Li he “assignat” els sites default i default-ssl. Aquests sites tenen com a root configurat /var/www/quill. Partint d’aquí, el fitxer de renovació:

# renew_before_expiry = 30 days
version = 0.10.2
archive_dir = /etc/letsencrypt/archive/aniolmarti.cat
cert = /etc/letsencrypt/live/aniolmarti.cat/cert.pem
privkey = /etc/letsencrypt/live/aniolmarti.cat/privkey.pem
chain = /etc/letsencrypt/live/aniolmarti.cat/chain.pem
fullchain = /etc/letsencrypt/live/aniolmarti.cat/fullchain.pem

# Options used in the renewal process
[renewalparams]
authenticator = webroot
installer = None
account = XXXXXXXXXXXXXXXXXXXXXX
[[webroot_map]]
www.aniolmarti.cat = /var/www/quill
blog.aniolmarti.cat = /var/www/quill
aniolmarti.cat = /var/www/quill
quill.aniolmarti.cat = /var/www/quill

A la màquina on hi ha allotjada la web cal modificar l’.htaccess:

Redirect 301 /.well-known http://quill.aniolmarti.cat/.well-known

 

Casos especials

En un subdomini hi tinc un Trac protegit per autenticació HTTP, això provoca que el client d’ACME no pugui accedir-hi i per tant no ho pugui verificar. Això em passa amb el domini xarxacatala.cat.

Primer de tot cal modificar el site del nginx:

 location ^~ /.well-known/acme-challenge/ {
     root /var/www/xarxacatala.cat;
 }

Amb això canviem l’arrel del directori de verificació del subdomini a la del domini principal, que no està protegit per autenticació HTTP.

El fitxer de renovació:

# renew_before_expiry = 30 days
version = 0.10.2
archive_dir = /etc/letsencrypt/archive/xarxacatala.cat
cert = /etc/letsencrypt/live/xarxacatala.cat/cert.pem
privkey = /etc/letsencrypt/live/xarxacatala.cat/privkey.pem
chain = /etc/letsencrypt/live/xarxacatala.cat/chain.pem
fullchain = /etc/letsencrypt/live/xarxacatala.cat/fullchain.pem

# Options used in the renewal process
[renewalparams]
authenticator = webroot
installer = None
account = XXXXXXXXXXXXXXXXXXXXXX
[[webroot_map]]
www.xarxacatala.cat = /var/www/xarxacatala.cat
xarxacatala.cat = /var/www/xarxacatala.cat
gestio.xarxacatala.cat = /var/www/xarxacatala.cat

Pegat proxy invers amb WordPress

Avui he estat mirant de canviar algunes configuracions del servidor i em trobava que amb un nginx (HTTPS) fent de proxy invers cap a un Apache servint un WordPress el navegador responia amb un error de problema de redirecció. Per arreglar-ho només cal afegir unes línies al fitxer wp-config.php.

Busquem la línia define('WP_DEBUG', false); i just després afegim:

// Codi pel proxy invers
if ( $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) {
 $_SERVER['HTTPS'] = 'on';
 $_SERVER['SERVER_PORT'] = 443;
}