Introduction
This guide covers the initial setup and configuration needed to build a new Debian system. Some of the commands may assume a specific device name and should be changed to match the device name of your hardware.
Prerequisites
- A CPU compatible with the "amd64" builds of Debian.
- One or more storage devices (SAS, SATA, NVMe) for Debian.
- A CD or USB drive with the Debian 9 install DVD, or the Debian 9 Live DVD for ZFS Root.
- An Internet connection attached to the primary network interface.
- Optionally, a FAT-formatted USB drive with
shellx64.eficopied to the/EFI/BOOT/folder. (For hardware without a working EFI shell. Some systems require this file to be renamed tobootx64.efito actually boot from it.)
Basic Install on a Single Disk
Boot from the Debian 9 install image and select "Install" to begin the text-based installer. Use the default language and keyboard layouts: Language: English, Country: United States, Keymap: American English. Set the hostname and domain name. (It is not recommended to use .local as the domain name.) Do not set a root password, instead create a default administrator account. Use "mars" for the user name with the typical password when applicable. Select "Pacific" for the time zone.
Select "Manual" at the "Partition disks" screen and then create a new blank GPT partition table on your boot volume by highlighting it and pressing the return key. (If your computer does not support UEFI booting, Reboot, use "Expert Install" under "Advanced Options", and then go through the prompts to create a GPT partition on the boot volume. Select "Configure Software RAID" to cause the empty partition table to be written, and finally reboot again and go through the setup prompts.) You should now see a "FREE SPACE" section under your boot disk.
Highlight the "FREE SPACE" below your boot volume and create a firmware partition. Create a 500M partition at the beginning of the disk with a type "EFI System Partition" for UEFI-based systems, or a "FAT32 file system" mounted at /boot/dos for BIOS-based systems. Leave the other options at their defaults.
Highlight the "FREE SPACE" below the firmware partition and create a 1G root partition at the beginning of the free space. Leave all of the defaults, this is a placeholder to reserve the second partition number.
Highlight the "FREE SPACE" below the placeholder root partition and create a "swap area" at the end of the free space, use the following table as a guide to size the swap partition:
Amount of RAM Amount of Swap
Less than 16GB 16G
16GB to 128GB 32G
More than 128GB 64G
Finally, delete the placeholder root partition and create a new partition that fills up the free space between the firmware partition and the swap area. If your root filesystem is larger than 2TB or if it exists on a hardware RAID controller then XFS is recommended. In all other cases ext4 is recommended. (Note that there are special considerations to keep in mind when creating NFS exports directly from an XFS-formatted partition, consider using a ZFS or ext4 partition instead.)
You should now have three partitions defined on your boot volume, numbered in the correct order (1,2,3) with some free space padding the beginning and end of the volume. If everything looks correct select "Finish partitioning and write changes to the disk" to continue with the installation. Proceed through the prompts, accepting the defaults as appropriate, until you reach the "Software Selection" screen. At this point you can select the package groups to install. For servers I only install "SSH Server" and "Standard System Utilities" and for desktops I also install "Debian Desktop Environment" and "GNOME".
At this point the install should finish and reboot into your new Debian system. Proceed to the "Initial Configuration" section below, or go down to the Troubleshooting section for solutions to common problems with the setup process.
ZFS Root Install
Boot from the Debian 9 live image and log in with the default username "user" and password "live" and then become root using the sudo su - command. Since the initial setup of a ZFS root involves a lot of commands you may find it beneficial to configure ssh on the live image so you can run the commands remotely. To enable ssh login from a live image start by editing the /etc/ssh/sshd_config file, change the PasswordAuthentication line to "yes", and then restart the sshd service. If the ssh server package is not installed on your live image you can use apt-get update && apt-get install openssh-server && service sshd start as root to install and start it. The command ip addr will show you which IP address was picked up by the live image.
Run the following commands to configure apt and install the ZFS packages in the live environment:
echo -e '# debian-stretch'\\n\
'deb http://ftp.us.debian.org/debian/ stretch main contrib non-free'\\n\
'deb-src http://ftp.us.debian.org/debian/ stretch main contrib non-free'\\n\
> /etc/apt/sources.list
apt-get update
apt-get install -y debootstrap gdisk parted \
linux-headers-$(uname -r|sed 's,[^-]*-[^-]*-,,') \
zfs-dkms zfs-initramfs
Now that ZFS is installed you'll need to create your root pool. Any underlying ZFS volume can be used for booting beyond the two examples below. First you'll need to create ZFS partitions on your storage media. Use lsblk to list available storage devices and edit the commands below as necessary. Items in red should be customized for your installation.
For a single disk with the firmware partition on the same disk use the following commands:
parted -a optimal /dev/sda mklabel gpt
parted -a optimal /dev/sda mkpart ESP fat32 1MB 500M
parted -a optimal /dev/sda set 1 boot on
parted -a optimal /dev/sda mkpart ZFS zfs 500M 100%
partprobe
/sbin/modprobe zfs
zpool create -f -o ashift=12 -o altroot=/mnt \
-m none -O atime=off -O relatime=on -O dedup=off \
rpool \
ata-SATA_Hard_Drive_00000000000000000001-part2
For multiple disks with a separate boot device (typically a small Flash Disk or SATA DOM) and use the following commands:
parted -a optimal /dev/sda mklabel gpt
parted -a optimal /dev/sda mkpart ESP fat32 1MB 500M
parted -a optimal /dev/sda set 1 boot on
parted -a optimal /dev/sdb mklabel gpt
parted -a optimal /dev/sdb mkpart ZFS zfs 1MB 100%
parted -a optimal /dev/sdc mklabel gpt
parted -a optimal /dev/sdc mkpart ZFS zfs 1MB 100%
parted -a optimal /dev/sdd mklabel gpt
parted -a optimal /dev/sdd mkpart ZFS zfs 1MB 100%
partprobe
/sbin/modprobe zfs
zpool create -f -o ashift=12 -o altroot=/mnt \
-m none -O atime=off -O relatime=on -O dedup=off \
rpool raidz \
ata-SATA_Hard_Drive_00000000000000000001-part1 \
ata-SATA_Hard_Drive_00000000000000000002-part1 \
ata-SATA_Hard_Drive_00000000000000000003-part1
Run zpool list and zpool status to verify that you've created a root pool with the correct volumes that is the size you expect.
Now, create a swap area within ZFS.
zfs create -V 64G -b $(getconf PAGESIZE) -o compression=zle \
-o logbias=throughput -o sync=always \
-o primarycache=metadata -o secondarycache=none \
-o com.sun:auto-snapshot=false rpool/swap
mkswap -L swap /dev/zvol/rpool/swap
Next, prepare the ZFS pool for the installation of Debian 9.
zfs create -o mountpoint=none rpool/ROOT
zfs create -o mountpoint=/ rpool/ROOT/debian
zpool set bootfs=rpool/ROOT/debian rpool
zpool export rpool
zpool import -d /dev/disk/by-id -R /mnt rpool
mkdir -p /mnt/etc/zfs
zpool set cachefile=/mnt/etc/zfs/zpool.cache rpool
Next, install Debian 9 and create some basic configuration files. Items in red should be customized for your installation.
debootstrap --arch=amd64 stretch /mnt http://httpredir.debian.org/debian/
echo MyHostname > /mnt/etc/hostname
sed -i -Ee "s#(127.+)#\1 MyHostname.domain.com MyHostname#" /mnt/etc/hosts
cat /mnt/etc/hosts
echo /dev/zvol/rpool/swap \
none swap defaults 0 0 > /mnt/etc/fstab
cat /mnt/etc/fstab
For this section, you can use ip addr to discover the name of your network interface.
echo -e \
'# This file describes the network interfaces available on your system'\\n\
'# and how to activate them. For more information, see interfaces(5).'\\n\
''\\n\
'source /etc/network/interfaces.d/*'\\n\
''\\n\
'# The loopback network interface'\\n\
'auto lo'\\n\
'iface lo inet loopback'\\n\
''\\n\
'# The primary network interface'\\n\
'allow-hotplug eno1'\\n\
'iface eno1 inet dhcp'\
> /mnt/etc/network/interfaces
for f in dev dev/pts proc sys; do mount -v --bind {,/mnt}/$f; done
chroot /mnt /bin/bash --login
echo -e '# stretch-main'\\n\
'deb http://ftp.us.debian.org/debian/ stretch main contrib non-free'\\n\
'deb-src http://ftp.us.debian.org/debian/ stretch main contrib non-free'\\n\
\\n\
'# stretch-security'\\n\
'deb http://security.debian.org/ stretch/updates main contrib'\\n\
'deb-src http://security.debian.org/ stretch/updates main contrib'\\n\
\\n\
'# stretch-updates'\\n\
'deb http://ftp.us.debian.org/debian/ stretch-updates main contrib'\\n\
'deb-src http://ftp.us.debian.org/debian/ stretch-updates main contrib'\\n\
\\n\
'# stretch-backports'\\n\
'deb http://ftp.us.debian.org/debian/ stretch-backports main contrib non-free'\\n\
'deb-src http://ftp.us.debian.org/debian/ stretch-backports main contrib non-free'\
> /etc/apt/sources.list
apt-get update
apt-get install -y locales
sed -i -Ee 's/# (en_US.UTF+)/\1/' /etc/locale.gen
locale-gen
This next command will prompt you to select the package groups for installation. For servers I only install "SSH Server" and "Standard System Utilities" and for desktops I also install "Debian Desktop Environment" and "GNOME".
tasksel --new-install
apt-get install -y debootstrap gdisk parted dosfstools \
linux-headers-$(uname -r|sed 's,[^-]*-[^-]*-,,') sudo \
linux-image-amd64 zfs-dkms zfs-initramfs
Now you can set up grub-efi. Verify your storage devices using lsblk and change the commands below as necessary.
mkdir /boot/efi
mkdosfs -F 32 -n EFI /dev/sda1
echo UUID=$(blkid -s UUID -o value /dev/sda1) \
/boot/efi vfat defaults 0 1 >> /etc/fstab
mount /boot/efi
apt-get install -y grub-efi-amd64
grub-probe /boot/efi/
grub-probe /
update-initramfs -u -k all
update-grub
grub-install --target=x86_64-efi --efi-directory=/boot/efi \
--bootloader-id=debian --recheck --no-floppy
ls /boot/grub/*/zfs.mod
find /boot/efi -type f
Add a local user account and reboot into the new Debian installation.
For myself:
groupadd -g 1000 user
useradd -g user -G 24,25,27,29,30,44,46,108 \
-u 1000 user -d /home/user -m -s /bin/bash -c "First Lastname"
passwd user
For Mars:
groupadd -g 1000 mars
useradd -g mars -G 24,25,27,29,30,44,46,108 \
-u 1000 mars -d /home/mars -m -s /bin/bash -c "Mars"
passwd mars
For both:
exit
mount | grep -v zfs | tac | awk '/\/mnt/ {print $3}' | xargs -i{} umount -lf {}
zpool export rpool
reboot
At this point you should be booted into your new Debian system. Proceed to the "Initial Configuration" section below, or go down to the Troubleshooting section for solutions to common problems with the setup process.
Base Configuration
These commands will consolidate the differences between the two installation methods outlined above as well as install some sensible default packages. Start by logging into your new install and use sudo su - to become root.
cp -p /etc/apt/sources.list /etc/apt/sources.original
echo -e '# stretch-main'\\n\
'deb http://ftp.us.debian.org/debian/ stretch main contrib non-free'\\n\
'deb-src http://ftp.us.debian.org/debian/ stretch main contrib non-free'\\n\
\\n\
'# stretch-security'\\n\
'deb http://security.debian.org/ stretch/updates main contrib'\\n\
'deb-src http://security.debian.org/ stretch/updates main contrib'\\n\
\\n\
'# stretch-updates'\\n\
'deb http://ftp.us.debian.org/debian/ stretch-updates main contrib'\\n\
'deb-src http://ftp.us.debian.org/debian/ stretch-updates main contrib'\\n\
\\n\
'# stretch-backports'\\n\
'deb http://ftp.us.debian.org/debian/ stretch-backports main contrib non-free'\\n\
'deb-src http://ftp.us.debian.org/debian/ stretch-backports main contrib non-free'\
> /etc/apt/sources.list
echo -e 'apt-get update'\\n\
'apt-get upgrade'\\n\
'apt-get clean'\\n\
'apt-get --purge dist-upgrade'\\n\
'apt-get clean'\\n\
'apt-get --purge autoremove'\\n\
'apt-get autoclean'\\n\
'aptitude forget-new'\\n\
'aptitude keep-all'\\n\
'aptitude purge ~c'\
> /opt/update_debian.sh
chmod 700 /opt/update_debian.sh
apt-get update
apt-get --purge -y autoremove exim4*
userdel Debian-exim
groupdel Debian-exim
apt-get install -y aptitude autofs bsd-mailx build-essential console-setup \
console-setup-linux cpp debootstrap discover discover-data dkms dmidecode \
dnsutils dosfstools eject fakeroot firmware-linux firmware-linux-free \
firmware-linux-nonfree gcc gdisk git guile-2.0-libs:amd64 hdparm htop \
haveged installation-report inxi iotop irqbalance keyboard-configuration \
kbd laptop-detect libdiscover2 libfakeroot:amd64 libfribidi0:amd64 \
libgc1c2:amd64 libglib2.0-0:amd64 libglib2.0-data libgsasl7 \
libkyotocabinet16v5:amd64 liblockfile1:amd64 libltdl7:amd64 \
liblzo2-2:amd64 libmailutils5:amd64 libmariadbclient18:amd64 \
libntlm0:amd64 libnuma1:amd64 libnvpair1linux libpython2.7:amd64 \
libusb-0.1-4:amd64 libusb-1.0-0:amd64 libuutil1linux curl wget \
linux-headers-$(uname -r|sed 's,[^-]*-[^-]*-,,') linux-image-amd64 \
locales lsb-release lsscsi mailutils mailutils-common make memtester \
mysql-common ntp parted patch postfix pv rsync screen shared-mime-info \
smartmontools sudo sysbench sysstat tcsh usbutils xdg-user-dirs xkb-data
For postfix select "Satellite System" and enter the computer's FQDN for "System Mail Name" when prompted. The SMTP Relay Host is the local mail server. The "root and postmaster" recipient is a group notification account for shared systems or your own e-mail address for personal systems. Use the defaults for the rest of the postfix configuration prompts. Mail settings can be tested using mailx -s subject email_address after the installation. You can also reconfigure postfix by running dpkg-reconfigure postfix if needed.
Select the defaults for the keyboard layout if prompted.
Install any missing firmware packages now, then continue with the rest of the commands below.
ls /boot/dos && apt-get install -y grub-pc grub-pc-bin
ls /boot/dos && wget -O /tmp/dos.tar.gz \
http://www.irix7.com/osdist/boot_dos_fs.tar.gz \
&& tar -zxf /tmp/dos.tar.gz --no-same-permissions -C /boot/dos/
ls /boot/efi && apt-get install -y efibootmgr grub-efi-amd64-bin
ls /dev/ipmi* && apt-get install -y ipmitool
For systems with nvidia cards also install the proprietary drivers.
apt-get install -y -t stretch-backports nvidia-cuda-toolkit nvidia-detect \
nvidia-kernel-dkms nvidia-smi nvidia-driver nvidia-settings
Select America/Los_Angeles as the new time zone when prompted.
dpkg-reconfigure tzdata
echo -e '/net'\\t'/etc/auto.net' >> /etc/auto.master
mkdir /net
update-pciids
update-usbids
fstrim -v /
ls /home/user && touch /home/user/.hushlogin
ls /home/user && echo -e 'if ($?prompt) then'\\n\
' set path=( $path /sbin .)'\\n\
' alias mv '"'"'mv -i'"'"''\\n\
' alias ls '"'"'ls -Clas'"'"''\\n\
' alias cd '"'"'chdir \\!* ; set prompt="[%m] $cwd% "'"'"''\\n\
' setenv TERM xterm'\\n\
' cd .'\\n\
'endif'\
> /home/user/.cshrc
ls /home/user && \
echo -e 'user ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers.d/local
ls /home/user && chmod 0440 /etc/sudoers.d/local
sed -i 's/user:x:1000/user:x:6201/g' /etc/passwd
sed -i 's/user:\/bin\/bash/user:\/bin\/tcsh/g' /etc/passwd
ls /home/user && chown -R 6201:1000 /home/user
ls /home/mars && touch /home/mars/.hushlogin
ls /home/mars && cp -pr /home/mars /.
sed -i 's/:\/home\/mars/:\/mars/g' /etc/passwd
ls /mars && rm -rf /home/mars
Standardize the /etc/fstab file and update grub configuration. Configure or import any other local filesystems before running these commands.
cp /etc/fstab /tmp/fstab.old
grep "^[UP]" /tmp/fstab.old > /etc/fstab
sed -i 's/ */ /g' /etc/fstab
ls /dev/zvol/rpool/swap && \
echo -e '/dev/zvol/rpool/swap none swap defaults 0 0' >> /etc/fstab
ls /dev/sr0 && \
echo -e '/dev/sr0 /media/cdrom0 udf,iso9660 user,noauto 0 0' >> /etc/fstab
ls /dev/sr1 && \
echo -e '/dev/sr1 /media/cdrom1 udf,iso9660 user,noauto 0 0' >> /etc/fstab
ls /dev/zvol/rpool/swap \
&& sed -i 's/UX_DEFAULT="quiet"/UX_DEFAULT="quiet noresume"/g' /etc/default/grub
ls /dev/sr0 && mkdir /media/cdrom0
ls /dev/sr0 && ln -s /media/cdrom0 /media/cdrom
ls /dev/sr1 && mkdir /media/cdrom1
update-initramfs -u -k all
grub-mkconfig
update-grub
Base Configuration is complete. Follow the rest of the sections as needed.
mDNS with NetATalk 3.x
The following commands will set up mDNS and NetATalk for use when sharing to Apple computers via AFP.
sudo su -
apt-get install -y autofs avahi-daemon avahi-utils
echo -e '<?xml version="1.0" standalone='"'"'no'"'"'?><!--*-nxml-*-->'\\n\
'<!DOCTYPE service-group SYSTEM "avahi-service.dtd">'\\n\
'<service-group>'\\n\
'<name replace-wildcards="yes">%h</name>'\\n\
'<service>'\\n\
' <type>_ssh._tcp</type>'\\n\
' <port>22</port>'\\n\
'</service>'\\n\
'<service>'\\n\
' <type>_sftp-ssh._tcp</type>'\\n\
' <port>22</port>'\\n\
'</service>'\\n\
'<service>'\\n\
' <type>_afpovertcp._tcp</type>'\\n\
' <port>548</port>'\\n\
'</service>'\\n\
'<service>'\\n\
' <type>_device-info._tcp</type>'\\n\
' <port>0</port>'\\n\
' <txt-record>model=RackMac</txt-record>'\\n\
'</service>'\\n\
'</service-group>'\
> /etc/avahi/services/apple.service
apt-get install -y autotools-dev cdbs d-shlibs debhelper devscripts \
dh-buildinfo dh-systemd libacl1-dev libavahi-client-dev libcrack2-dev \
libcups2-dev libdb-dev libevent-dev libgcrypt11-dev libkrb5-dev \
libldap2-dev libltdl3-dev libpam0g-dev libwrap0-dev
mkdir /root/inst
rm -rf /root/inst/libatalk*.deb /root/inst/netatalk*.deb
ls /etc/netatalk/afp.conf && cp -p /etc/netatalk/afp.conf /tmp/afp.conf.bak
cd /root/inst/
git clone https://github.com/adiknoth/netatalk-debian
cd /root/inst/netatalk-debian/
debuild -b -uc -us
ls -las /root/inst/*.deb
dpkg -i /root/inst/libatalk*.deb /root/inst/netatalk*.deb
echo -e ';'\\n\
'; Netatalk 3.x configuration file'\\n\
';'\\n\
'; Edited to serve as example for Debian/Ubuntu by'\\n\
'; Martin Loschwitz <madkiss@debian.org>'\\n\
';'\\n\
''\\n\
'[Global]'\\n\
'; Global server settings'\\n\
'vol preset = default_for_all'\\n\
'log file = /var/log/netatalk.log'\\n\
'uam list = uams_dhx2.so,uams_clrtxt.so'\\n\
'save password = no'\\n\
' '\\n\
'[default_for_all]'\\n\
'file perm = 0664'\\n\
'directory perm = 0774'\\n\
'cnid scheme = dbd'\\n\
'; Uncomment the following line to restrict access to specific users'\\n\
'; valid users = someuser'\\n\
' '\\n\
'; [Homes]'\\n\
'; basedir regex = /home'\\n\
''\\n\
'; The following is an example for a TimeMachine compatible volume,'\\n\
'; limited to a size of round about 1.5 Terabyte.'\\n\
'; [TimeMachine]'\\n\
'; path = /mnt/backup/someuser'\\n\
'; time machine = yes'\\n\
'; vol size limit = 1500000'\\n\
> /etc/netatalk/afp.conf
ls /home/user && \
echo -e '[user]'\\n'path = /home/user'\\n'valid users = user'\
>> /etc/netatalk/afp.conf
ls /mars && \
echo -e '; [mars]'\\n'; path = /mars'\\n'; valid users = mars'\
>> /etc/netatalk/afp.conf
ls /tmp/afp.conf.bak && cp -p /tmp/afp.conf.bak /etc/netatalk/afp.conf
chmod 644 /etc/netatalk/afp.conf
chown root:root /etc/netatalk/afp.conf
Troubleshooting