ITA - debian installazione headless
June 2021 (2812 Words, 16 Minutes)
Introduzione
Negli ultimi giorni mi è capitato di acquistare un server remoto e di doverlo installare senza l’uso della console di amministrazione.
Di seguito racconto il percorso che ho seguito.
Processo di installazione
Passo 1 - avvio del sistema
Per poter procedere è necessario avviare il server in modalità rescue ( in altre parole usando una live image messa a disposizione del fornitore ) via ssh; in questa maniera saremo completamente liberi di operare senza nessun impaccio.
Passo 2 - partizionamento dei dischi
schema di partizionamento1
Per garantire mia privacy e la sicurezza del sistema su una piattaforma remota ho deciso di criptare l’intero sistema; il server dispone di un unico disco rigido che verrà formattato cosi:
partizione | mount | fs | note |
---|---|---|---|
sda2 | /boot | ext4 | partizione di boot |
sda1 | |||
/dev/mapper/sys_crypt | cryopto | partizione cryptata | |
/dev/mapper/sys_lvm/root | ext4 | lvm | |
/dev/mapper/sys_lvm/swap | lvm | ||
/dev/mapper/sys_lvm/data | ext4 | lvm |
In parole: ci saranno due partizioni fisiche: la prima conterrà le informazioni di boot, la seconda sarà cryptata con LUKS e conterrà un array lvm con il resto delle partizioni.
In questa maniera configurando correttamente dropbear ( vedi passo 5 ) quando il server si avvia sarà possibile connettersi via ssh e inserire la password per decriptare le partizioni di sistema e sbloccare il processo di avvio.
Procedura
Lanciamo il tool di partizionamento:
root@rescue:~# cfdisk /dev/sda
fino ad ottenere:
Controlliamo il risultato con il comando:
root@rescue:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 1.8T 0 disk
├─sda2 8:2 0 512M 0 part
├─sda3 8:3 0 2M 0 part
└─sda1 8:1 0 1.8T 0 part
root@rescue:~#
Preparazione della partizione di boot
Formatto la partizione in ext4:
root@rescue:~# mkfs.ext4 /dev/sda2
mke2fs 1.42.12 (29-Aug-2014)
/dev/sda2 contains a swap file system labelled 'swap-sda2'
Proceed anyway? (y,n) y
Creating filesystem with 131072 4k blocks and 32768 inodes
Filesystem UUID: e1abb7d2-f112-4a39-aa85-171cccda3d47
Superblock backups stored on blocks:
32768, 98304
Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
root@rescue:~#
Preparazione delle partizioni di sistema
Per questa fase ho fatto riferimento alla bellissima documentazione da archwiki:
Inizio con il creare la partizione cryptata:
root@rescue:~# cryptsetup luksFormat /dev/sda1
WARNING!
========
This will overwrite data on /dev/sda1 irrevocably.
Are you sure? (Type uppercase yes): YES
Enter passphrase:
Verify passphrase:
root@rescue:~# cryptsetup luksOpen /dev/sda1 sys_crypt
Enter passphrase for /dev/sda1:
root@rescue:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 1.8T 0 disk
├─sda2 8:2 0 512M 0 part
├─sda3 8:3 0 2M 0 part
└─sda1 8:1 0 1.8T 0 part
└─sys_crypt 251:0 0 1.8T 0 crypt
root@rescue:~#
Quando il sistema chiede la password :
Enter passphrase
Ho inserito la chiave di decriptazione generata con il comando pwgen
, questa stringa va conservata con cura.
Il passo successivo consiste nella creazione dei volumi lvm:
Volume fisico
root@rescue:~# pvcreate /dev/mapper/sys_crypt
Physical volume "/dev/mapper/sys_crypt" successfully created
root@rescue:~# pvdisplay -v -m
DEGRADED MODE. Incomplete RAID LVs will be processed.
Scanning for physical volume names
"/dev/mapper/sys_crypt" is a new physical volume of "1.82 TiB"
--- NEW Physical volume ---
PV Name /dev/mapper/sys_crypt
VG Name
PV Size 1.82 TiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID hUuzwh-Jrmz-ymLi-celV-HE2k-8324-bjPfk9
Gruppo di volumi fisici
root@rescue:~# vgcreate syslvm /dev/mapper/sys_crypt
Volume group "syslvm" successfully created
root@rescue:~# vgdisplay
--- Volume group ---
VG Name syslvm
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 1
Act PV 1
VG Size 1.82 TiB
PE Size 4.00 MiB
Total PE 476802
Alloc PE / Size 0 / 0
Free PE / Size 476802 / 1.82 TiB
VG UUID sDXdXw-sK3W-ffH3-U0i0-6D2u-r0GV-czDRt4
Volumi logici
root@rescue:~# lvcreate -L 50G syslvm -n root
Logical volume "root" created
root@rescue:~# lvcreate -L 4G syslvm -n swapp
Logical volume "swapp" created
root@rescue:~# lvcreate -l 100%FREE syslvm -n data
Logical volume "data" created
root@rescue:~# lvdisplay
--- Logical volume ---
LV Path /dev/syslvm/root
LV Name root
VG Name syslvm
LV UUID AVQOKX-2N4B-iz5P-QIUp-OJOI-zwEl-bjj91j
LV Write Access read/write
LV Creation host, time rescue.ovh.net, 2021-06-02 10:17:11 +0200
LV Status available
# open 0
LV Size 50.00 GiB
Current LE 12800
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 251:1
--- Logical volume ---
LV Path /dev/syslvm/swapp
LV Name swapp
VG Name syslvm
LV UUID S99dgF-ly5i-PbQN-iPZQ-Gmbc-oCHV-TW3e22
LV Write Access read/write
LV Creation host, time rescue.ovh.net, 2021-06-02 10:17:22 +0200
LV Status available
# open 0
LV Size 4.00 GiB
Current LE 1024
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 251:2
--- Logical volume ---
LV Path /dev/syslvm/data
LV Name data
VG Name syslvm
LV UUID pOn7MH-u0zB-09bD-wtsK-qgdU-1HZh-E3dYOy
LV Write Access read/write
LV Creation host, time rescue.ovh.net, 2021-06-02 10:17:42 +0200
LV Status available
# open 0
LV Size 1.77 TiB
Current LE 462978
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 251:3
root@rescue:~#
Al termine di questi passaggi ho ottenuto una struttura simile:
root@rescue:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 1.8T 0 disk
├─sda2 8:2 0 512M 0 part
├─sda3 8:3 0 2M 0 part
└─sda1 8:1 0 1.8T 0 part
└─sys_crypt 251:0 0 1.8T 0 crypt
├─syslvm-root 251:1 0 50G 0 lvm
├─syslvm-swapp 251:2 0 4G 0 lvm
└─syslvm-data 251:3 0 1.8T 0 lvm
root@rescue:~#
Poi procedo con la formattazione:
root@rescue:~# mkfs.ext4 /dev/mapper/syslvm-root
mke2fs 1.42.12 (29-Aug-2014)
Creating filesystem with 13107200 4k blocks and 3276800 inodes
Filesystem UUID: 6d3601f8-67c8-493a-8808-3b78f3edd398
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
root@rescue:~# mkfs.ext4 /dev/mapper/syslvm-data
mke2fs 1.42.12 (29-Aug-2014)
Creating filesystem with 474089472 4k blocks and 118530048 inodes
Filesystem UUID: c548c7aa-dea2-437d-bb8f-66da7e4db447
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
102400000, 214990848
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
root@rescue:~# mkswap /dev/mapper/syslvm-swapp
Setting up swapspace version 1, size = 4194300 KiB
no label, UUID=96730e50-2d3e-45c2-912a-556ef9d121af
root@rescue:~#
Passo 3 - Installazione del sistema base
Una volta partizionato il disco si deve procedere al montaggio ordinato delle partizioni e all’installazione del sistema base; i passi che seguono sono tratti da questa pagina della documentazione di debian e richiedono un po di tempo.
Il prossimo step consiste nel montare le partizioni nel modo giusto
root@rescue:~# ls /mnt/
root@rescue:~# mount /dev/mapper/syslvm-root /mnt/
root@rescue:~# mkdir /mnt/boot
root@rescue:~# mkdir /mnt/media/data -p
root@rescue:~# mount /dev/sda2 /mnt/boot/
root@rescue:~# mount /dev/mapper/syslvm-data /mnt/media/data/
root@rescue:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 1.8T 0 disk
├─sda2 8:2 0 512M 0 part /mnt/boot
├─sda3 8:3 0 2M 0 part
└─sda1 8:1 0 1.8T 0 part
└─sys_crypt 251:0 0 1.8T 0 crypt
├─syslvm-root 251:1 0 50G 0 lvm /mnt
├─syslvm-swapp 251:2 0 4G 0 lvm
└─syslvm-data 251:3 0 1.8T 0 lvm /mnt/media/data
root@rescue:~#
Successivamente eseguo il debootstrap del sistema base:
root@rescue:~# debootstrap --arch amd64 buster /mnt
Il passo successivo serve a creare il contenuto della cartella /dev
nel nuovo sistema, quindi procedo con chroot:
LANG=C.UTF-8 chroot /mnt/ /bin/bash
export TERM=xterm-color
apt install makedev
root@rescue:/# mount none /proc -t proc
root@rescue:/# cd /dev
root@rescue:/dev# MAKEDEV generic
Una volta che questo comando è termino è necessario uscire dal chroot e montare in bind le seguenti partizioni
root@rescue:~# mount --bind /dev/ /mnt/dev/
root@rescue:~# mount -t proc proc /mnt/proc
root@rescue:~# mount --bind /sys/ /mnt/sys/
Da questo momento in avanti tutte le operazioni sono eseguite all’interno del chroot con i bind attivi
Generare il file fstab
Uso le informazioni di questi due comandi per generare il vile /etc/fstab
manualmente:
root@rescue:/# blkid
/dev/sda1: UUID="e3942b82-cbc4-46e9-9d27-0da8076a7d3d" TYPE="crypto_LUKS" PARTUUID="8453be7e-01"
/dev/sda2: UUID="e1abb7d2-f112-4a39-aa85-171cccda3d47" TYPE="ext4" PARTUUID="8453be7e-02"
/dev/sda3: UUID="2021-05-31-22-54-46-00" LABEL="config-2" TYPE="iso9660" PARTUUID="8453be7e-03"
/dev/mapper/sys_crypt: UUID="hUuzwh-Jrmz-ymLi-celV-HE2k-8324-bjPfk9" TYPE="LVM2_member"
/dev/mapper/syslvm-root: UUID="6d3601f8-67c8-493a-8808-3b78f3edd398" TYPE="ext4"
/dev/mapper/syslvm-swapp: UUID="96730e50-2d3e-45c2-912a-556ef9d121af" TYPE="swap"
/dev/mapper/syslvm-data: UUID="c548c7aa-dea2-437d-bb8f-66da7e4db447" TYPE="ext4"
root@rescue:/# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 1.8T 0 disk
|-sda1 8:1 0 1.8T 0 part
| `-sys_crypt 251:0 0 1.8T 0 crypt
| |-syslvm-root 251:1 0 50G 0 lvm /
| |-syslvm-swapp 251:2 0 4G 0 lvm
| `-syslvm-data 251:3 0 1.8T 0 lvm /media/data
|-sda2 8:2 0 512M 0 part /boot
`-sda3 8:3 0 2M 0 part
root@rescue:/#
Il risultato dovrebbe essere:
root@rescue:/# cat /etc/fstab
# <file system> <dir> <type> <options> <dump> <pass>
UUID=6d3601f8-67c8-493a-8808-3b78f3edd398 / ext4 defaults 1 1
UUID=e1abb7d2-f112-4a39-aa85-171cccda3d47 /boot ext4 defaults 0 0
UUID=c548c7aa-dea2-437d-bb8f-66da7e4db447 /media/data ext4 defaults 0 0
UUID=96730e50-2d3e-45c2-912a-556ef9d121af none swap defaults 0 0
Per maggiori info su questo file vedere qui
Generare il file crypttab
Il secondo file importante da configurare /etc/crypttab
con il seguente contenuto :
sys_crypt UUID=e3942b82-cbc4-46e9-9d27-0da8076a7d3d none discard
Dove l’UUID specificato è quello del device TYPE="crypto_LUKS"
che nel mio caso è /dev/sda1
.
Riconfigurare la timezone
Per configurare la timezone e l’ora riconfiguro il pacchetto tzdata
:
root@rescue:/# dpkg-reconfigure tzdata
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = "en_US:en",
LC_ALL = "en_US.UTF-8",
LANG = "C.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to a fallback locale ("C.UTF-8").
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
/usr/bin/locale: Cannot set LC_CTYPE to default locale: No such file or directory
/usr/bin/locale: Cannot set LC_MESSAGES to default locale: No such file or directory
/usr/bin/locale: Cannot set LC_ALL to default locale: No such file or directory
Current default time zone: 'Europe/Rome'
Local time is now: Wed Jun 2 11:15:55 CEST 2021.
Universal Time is now: Wed Jun 2 09:15:55 UTC 2021.
Configurazione di apt
Nel file /etc/apt/sources.list
inserisco il seguente contenuto :
deb http://deb.debian.org/debian buster main contrib non-free
deb-src http://deb.debian.org/debian buster main contrib non-free
deb http://deb.debian.org/debian-security/ buster/updates main contrib non-free
deb-src http://deb.debian.org/debian-security/ buster/updates main contrib non-free
deb http://deb.debian.org/debian buster-updates main contrib non-free
deb-src http://deb.debian.org/debian buster-updates main contrib non-free
Come descritto qui
Configurare locale e tastiera
Per rigenerare il locale:
root@rescue:/# apt install locales
A me piace avere il locale in inglese americano sulle macchine, ma se volessi riconfigurarlo, dovrei usare il comando:
dpkg-reconfigure locales
Per aggiornare la configurazione della tastiera:
root@rescue:/# apt install console-setup
Installare il kernel
Per installare il kernel sul host è necessario installare il pacchetto linux-image-amd64
:
root@rescue:/# apt install linux-image-amd64/stable
Passo 4 - Configurazione di rete
Questo è un passaggio veramente delicato, sbagliando qualcosa non sarà possibile accedere al sistema remoto.
Viviamo sereni il server di solito può essere riavviato in modalità rescue in qualsiasi momento, il debug di un problema può essere affrontato riavviando il server in modalità rescue, decriptando i di dischi, montare le partizioni come ho fatto precedentemente e aprendo una chroot per correggere eventuali errori
Configurare hostname
Scelgo il nome host :
echo DebianHostName > /etc/hostname
Configurare file hosts
Creo il file /etc/hosts
e aggiungere le seguenti linee:
127.0.0.1 localhost
127.0.1.1 DebianHostName
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
Configurare udev
Questo passo è importante per semplificarsi la vita negli step successivi (configurazione di dropbear e grub).
Raccolgo le informazioni con il seguente comando:
root@rescue:~# ip link show eth0
6: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 00:22:4d:ad:bc:4b brd ff:ff:ff:ff:ff:ff
Ed edito il file ` /etc/udev/rules.d/70-persistent-net.rules` in questa maniera:
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:22:4d:ad:bc:4b", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
Riporto correttamente il mac adr dell’interfaccia.
Configurare le interfaccie
Raccolgo le informazioni utili dal sistema di rescue:
root@rescue:~# ip addr show eth0
eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:22:4d:ad:bc:4b brd ff:ff:ff:ff:ff:ff
inet 37.187.121.17/24 brd 37.187.121.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 2001:41d0:a:f211::1/128 scope global
valid_lft forever preferred_lft forever
inet6 fe80::222:4dff:fead:bc4b/64 scope link
valid_lft forever preferred_lft forever
root@rescue:~# ip route
default via 37.187.121.254 dev eth0
37.187.121.0/24 dev eth0 proto kernel scope link src 37.187.121.17
root@rescue:~#
Configuro di conseguenza il file /etc/network/interfaces
root@rescue:/# cat /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)
# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 37.187.121.17
network 37.187.121.0
netmask 255.255.255.0
broadcast 37.187.121.255
gateway 37.187.121.254
Configurare i DNS
Edito il file /etc/resolv.conf
e aggiungo le linee contenenti i server dns:
nameserver 208.67.222.222
nameserver 208.67.220.220
Io personalmente uso i server forniti da opendns
Passo 5 - Configurazione di drop bear e GRUB
grub
Prima di installare il boot loader devo installare i pacchetti necessari per supportare lo schema di partizionamento utilizzato:
root@rescue:~# apt install cryptsetup lvm2
Questi due pacchetti andranno a installare degli hook nelle cartelle di configurazione per initarm-fs permettendo di sbloccare il server da remoto.
Adesso posso installare grub usiamo il seguente comando:
root@rescue:~# apt install grub-pc
Installo il boot loader sul disco:
root@rescue:~# grub-install /dev/sda
dropbear Questo tool è un server ssh leggero da includere dentro l’initramfs e che permette di collegarsi da remoto e sbloccare manualemnte i dischi criptati.
root@rescue:~# apt install dropbear-initramfs
Edito /etc/dropbear-initramfs/config
aggiungendo i parametri con cui lanciare dropbear :
root@rescue:~# cat /etc/dropbear-initramfs/config
#
# Configuration options for the dropbear-initramfs boot scripts.
# You must run update-initramfs(8) to effect changes to this file (like
# for other files under the '/etc/dropbear-initramfs' directory).
#
# Command line options to pass to dropbear(8)
#
DROPBEAR_OPTIONS="-I 180 -j -k -p 2222 -s"
#
# On local (non-NFS) mounts, interfaces matching this pattern are
# brought down before exiting the ramdisk to avoid dirty network
# configuration in the normal kernel.
# The special value 'none' keeps all interfaces up and preserves routing
# tables and addresses.
#
#IFDOWN=*
Edito il file /etc/initramfs-tools/initramfs.conf
aggiungendo questa linea:
IP=37.187.121.17::37.187.121.254:255.255.255.0:kenningar
Questa linea serve per abilitare la rete.
Edito il file /etc/dropbear-initramfs/authorized_keys
per aggiungere la mia chiave pubblica al server ssh, ciò mi permettarà di loggarmi senza password sul server.
Come ultimo passo aggiorno l’immagine dell’init con il comando :
root@rescue:~# update-initramfs -u
Mi assicuro che dropbear non sia abibilitato all’avvio del sistema:
root@rescue:~# systemctl disable dropbear
Questo passo ci assicura che dropbear non parta prima del server ssh (che andrò ad installare nel passo successivo) evitando conflitti.
Passo 6 - Configurazione di ssh
Installo il server open ssh con il seguente comando :
root@rescue:~# apt install ssh
Mi assicuro che il servizio sia abilitato al’avvio:
root@rescue:~# systemctl enable ssh
NB: non lo faccio ora, ma dopo il primo riavvio installerò fail2ban e proteggendo il server ssh dagli attacchi brute-force.
NB: non lo faccio ora, ma dopo il primo riavvio disabiliterò la possibilità di loggarsi con l’utente root via ssh
Passo 8 - Configurazione degli utenti
Come ultimo passo non mi rimane che configurare gli utenti remoti.
NB: le password usate nei passi successivi sono state generate con il comando pwgen
Utente non privilegiato
Creoo l’utente myadmin
root@rescue:~# adduser myadmin
Imposto la password per questo utente:
root@rescue:~# passwd myadmin
Password utente root
Imposto la password dell’utente root con il comando:
root@rescue:~# passwd
Passo 9 - Riavvio
Dopo aver riavviato il server dovrei potermi loggare dentro il server drop bear con in comando:
ssh root@37.187.121.17 -p 2222
Sbloccare i dischi criptati uso il comando cryptroot-unlock
:
BusyBox v1.30.1 (Debian 1:1.30.1-4) built-in shell (ash)
Enter 'help' for a list of built-in commands.
~ # cryptroot-unlock
Please unlock disk sys_crypt:
cryptsetup: sys_crypt set up successfully
~ # Connection to 37.187.121.17 closed by remote host.
Connection to 37.187.121.17 closed.
A questo punto vengo scollegato e il server riprende la normale procedura di boot, al termine del quale sarà possibile collegarsi normalmente.
Conclusione
Questa è una procedura lunga e in certi casi può richiedere alcuni tentativi prima di imbroccare la configurazione corretta e la uso solamente se in fase di installazione non si ha accesso diretto alla macchina, ovviamente nel caso si abbia accesso alla console al momento dell’esecuzione dell’installer di una distribuzione linux consiglio di usare l’installer di default.
Riferimenti
- https://www.debian.org/releases/stable/i386/apds03.en.html
- https://wiki.archlinux.org/title/LVM
- https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS
- https://wiki.debian.org/it/fstab
- https://wiki.debian.org/it/SourcesList
- https://www.cyberciti.biz/faq/howto-linux-rename-ethernet-devices-named-using-udev/
- https://www.cyberciti.biz/security/how-to-unlock-luks-using-dropbear-ssh-keys-remotely-in-linux/
- https://git.kernel.org/pub/scm/libs/klibc/klibc.git/tree/usr/kinit/ipconfig/README.ipconfig
Quest'opera è distribuita con Licenza Creative Commons Attribuzione - Condividi allo stesso modo 4.0 Internazionale Theme Moonwalk