Installing Cobbler under Debian 10

Preliminary preparation

There are two options for network implementation:

  1. Server Cobbler, servers deployed via Cobbler and the gateway are in the same local network (in the same vlan);
  2. Cobbler server is the gateway for servers deployed with Cobbler.

Both options are equivalent, but the second option allows you to have independent DNS and DHCP on the network for Cobbler slave servers that do not conflict with the rest of the network. This option requires two network interfaces, either physical or virtual, to implement the VLAN.

Let’s consider the second option.

Install the operating system Debian 10 (Buster) on the server Cobbler in any way convenient for you. Set up the network in the file /etc/network/interfaces:

source /etc/network/interfaces.d/*

auto lo
iface lo inet loopback

allow-hotplug enp1s0
iface enp1s0 inet dhcp

auto enp2s0
iface enp2s0 inet static
    address 192.168.1.1
    netmask 255.255.255.0
    dns-nameservers 192.168.1.2

Software installation

Installation is performed by the command:

apt-get install -y make gcc python3-dev python3-pip python3-future python3-distro python3-sphinx python3-coverage \
     python3-dnspython apache2 libapache2-mod-wsgi-py3 python3-netaddr python3-simplejson python3-yaml python3-cheetah \
     tftpd-hpa ipxe rsync syslinux isolinux pxelinux syslinux-efi syslinux-utils python3-django isc-dhcp-server debmirror \
     fence-agents xorriso bind9 bind9utils dnsutils ipmitool

By default, TFTPD uses the directory /srv/tftp, Cobbler uses the directory /var/lib/tftpboot.

On the one side, you can reconfigure both the first and second services to any directory, but in order to avoid possible problems during updates, we will connect both directories with a symlink:

mkdir -pv /srv/tftp
ln -s /srv/tftp /var/lib/tftpboot

Setting up DHCP server

Installed DHCP server will manage Cobbler directly, but we need to specify the interfaces that it will serve in the file /etc/default/isc-dhcp-server:

INTERFACESv4="enp2s0"

Replace enp2s0 with the network interface you are using. Then check if the service is running:

systemctl enable isc-dhcp-server
systemctl restart isc-dhcp-server

Installing and configuring Cobbler

Installing Cobbler

At the time of this writing, the current version is 3.1.1. Install using command:

wget https://github.com/cobbler/cobbler/archive/v3.1.1.tar.gz
tar -xf v3.1.1.tar.gz
cd cobbler-3.1.1
make install

Used directories

Python libraries will be installed in /usr/local/lib/python3.7/dist-packages/cobbler.

Web office code: /usr/local/share/cobbler.

Executable files will be placed ins /usr/local/bin.

Configuration files are /etc/cobbler and /etc/apache2.

Directory /var/lib/cobbler will be created for internal data.

Files that will need access via the http protocol are /var/www/cobbler and /var/www/cobbler_webui_content and file /var/lib/tftpboot to manage server load.

Cobbler setup

Setting up interaction with Apache

Initially, Cobbler implies access to the control panel via HTTPS. For HTTP access, you need to add permission to /etc/apache2/conf-available/cobbler_web.conf:

echo "
<Location /cobbler_web>
    Require all granted
</Location>
" >> /etc/apache2/conf-available/cobbler_web.conf

Correcting access rights for the control panel data directory:

chown www-data /var/lib/cobbler/webui_sessions

Enable the modules and Apache configurations necessary for work:

a2enmod ssl
a2enmod proxy
a2enmod rewrite
a2enmod proxy_http
a2enconf cobbler
a2enconf cobbler_web

Change in the /etc/systemd/system/cobblerd.service file ExecStart=/usr/bin/cobblerd -F to ExecStart=/usr/local/bin/cobblerd -F.

Check the correctness of the settings in the files according to the directories used:

/etc/apache2/conf-enabled/cobbler.conf
/etc/apache2/conf-enabled/cobbler_web.conf

Create a directory /var/www/cobbler/pub, create symlinks in this folder:

- images -> /var/www/cobbler/images
- pxelinux.cfg -> /srv/tftp/pxelinux.cfg

Restarting Apache with new configuration:

systemctl restart apache2

Configuration setup Cobbler

Copy the service file Cobbler to the systemd service directory, correct it and allow automatic start:

cp -f /etc/cobbler/cobblerd.service /etc/systemd/system/
sed -i 's/httpd.service/apache2.service/g' /etc/systemd/system/cobblerd.service
systemctl enable cobblerd

For Django to work correctly, we adjust some parameters in the Cobbler code:

SECRET_KEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
sed -i "s/SECRET_KEY =.*/SECRET_KEY = '$SECRET_KEY'/" /usr/local/share/cobbler/web/settings.py
sed -i "s/TIME_ZONE =.*/SECRET_KEY = 'Europe\/Moscow'/" /usr/local/share/cobbler/web/settings.py
sed -i "s/\/usr\/share\/cobbler\/web\/templates/\/usr\/local\/share\/cobbler\/web\/templates/" /usr/local/share/cobbler/web/settings.py

In the Cobbler settings file /etc/cobbler/settings, it is need to adjust some values according to the settings of the server itself.

Cobbler Server IP Address:

server: 192.168.1.1

IP address of TFTPD server:

next_server: 192.168.1.1

Allow Cobbler manage DHCP and DNS:

manage_dhcp: 1
manage_dns: 1

Allow download control via TFTPD:

pxe_just_once: 1

Create list of forward and reverse DNS zones:

manage_forward_zones: [test.loc]
manage_reverse_zones: [192.168.1]

Check the correctness of specifying the directory for TFTP-loading servers:

tftpboot_location: /var/lib/tftpboot

Create a root password for newly installed servers, for this use a previously generated random string:

PASSWORD=’password_for_root’
CRYPTED_PASSWORD=$(openssl passwd -1 -salt $SECRET_KEY $PASSWORD)
sed -i "s/^default_password_crypted:.*/default_password_crypted: $CRYPTED_PASSWORD/" /etc/cobbler/settings

Setting up interaction with the bind9 DNS server

Correct the template /etc/cobbler/named.template for the DNS server, namely, prescribe the IP address (s) of the DNS server and the network that this server will serve. It is also need to adjust the directories according to the hosted operating system:

options {
      listen-on port 53 { 127.0.0.1; 192.168.1.1; };
      directory       "/etc/bind";
      dump-file       "/etc/bind/cache_dump.db";
      statistics-file "/etc/bind/named_stats.txt";
      memstatistics-file "/etc/bind/named_mem_stats.txt";
      allow-query     { localhost; 192.168.0.0/16; 172.16.0.0/12; 10.0.0.0/8; };
      recursion yes;
      max-cache-size 256M;
      max-acache-size 256M;
};

logging {
    channel default_debug {
            file "/var/cache/bind/named.run";
            severity dynamic;
    };
};

#for $zone in $forward_zones
    zone "${zone}." {
    type master;
    file "$zone";
};

#end for
#for $zone, $arpa in $reverse_zones
zone "${arpa}." {
   type master;
   file "$zone";
};

#end for

Important

Everything below the logging section is not changed!

Correct the rights to the directory for /etc/bind. This item is required if dynamic zones are used:

chown bind:bind /etc/bind

In case of using dynamic zones, it is need to activate the Cobbler module to work with nsupdate in the file:

/etc/cobbler/settings.d/nsupdate.settings

nsupdate_enabled: 1

Create a key to update DNS:

dnssec-keygen -a HMAC-SHA512 -b 512 -n USER cobbler_update_key

Write this key in /etc/cobbler/settings.d/nsupdate.settings:

nsupdate_tsig_algorithm: "hmac-sha512"
nsupdate_tsig_key: [ "cobbler_update_key.", "hvnK54HFJXFasHjzjEn09ASIkCOGYSnofRq4ejsiBHz3udVyGiuebFGAswSjKUxNuhmllPrkI0HRSSmM2qvZug==" ]

And also add after the logging section in the template /etc/cobbler/named.template:

key cobbler_update_key {
    algorithm hmac-sha512;
    secret "hvnK54HFJXFasHjzjEn09ASIkCOGYSnofRq4ejsiBHz3udVyGiuebFGAswSjKUxNuhmllPrkI0HRSSmM2qvZug==";
};

Configuring communication with DHCP server

Correcting the DHCP Server Template /etc/cobbler/dhcp.template.

For each network used, it must register a section:

subnet 192.168.1.0 netmask 255.255.255.0 {
    option routers             192.168.1.1;
    option domain-name-servers 192.168.1.1;
    option subnet-mask         255.255.255.0;
    range dynamic-bootp        192.168.1.100 192.168.1.254;
    default-lease-time         21600;
    max-lease-time             43200;
    next-server                $next_server;
    class "pxeclients" {
         match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";

         # Legacy
         if option system-arch = 00:00 {
             filename "pxelinux.0";
         }
         # UEFI-32-1
         if option system-arch = 00:06 {
              # Not supported, no 32 bit UEFI grub executable
             filename "unsupported";
         }
         # UEFI-32-2
         if option system-arch = 00:02 {
             # Not supported, no 32 bit UEFI grub executable
             filename "unsupported";
         }
         # UEFI-64-1
         else if option system-arch = 00:07 {
             filename "grub/grubx64.efi";
         }
         # UEFI-64-2
         else if option system-arch = 00:08 {
             filename "grub/grubx64.efi";
         }
         # UEFI-64-3
         else if option system-arch = 00:09 {
             filename "grub/grubx64.efi";
         }
         # armv7   (aka arm 32 bit)
         else if option system-arch = 00:0a {
             filename "grub/armv7.efi";
         }
         # aarch64 (aka arm 64 bit)
         else if option system-arch = 00:0b {
             filename "grub/grubaa64.efi";
         }
         # RiskV 32 bit
         else if option system-arch = 00:25 {
             #ToDo petitboot loader
             filename "unsupported";
         }
         #RiskV 32 bit
         else if option system-arch = 00:27 {
             #ToDo petitboot loader
             filename "unsupported";
         }
         else if option system-arch = 00:0e {
             filename "grub/grub.ppc64le";
         }
         else
         {
             filename "pxelinux.0";
         }
        }
}

Thus, prescribe the network template, addresses of routers and the download server, and also specify the downloadable client pxelinux.0. You don’t need to make any changes to the rest of the files!

First run and configuration check Cobbler

After making all the changes, start the service cobblerd:

systemctl start cobblerd

Loading bootloaders:

cobbler get-loaders

Checking:

cobbler check

Carry out all the recommendations offered by the configuration check.

Carry out synchronization:

cobbler sync

Cobbler setup completed.

Importing Debian 10 distribution

Downloading the distribution kit for network installation:

wget -q -O /tmp/debian-10.2.0-amd64-netinst.iso https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-10.2.0-amd64-netinst.iso

Mount the distribution to a local directory:

mkdir -pv /mnt/debian
mount /tmp/debian-10.2.0-amd64-netinst.iso /mnt/debian

Importing distribution:

cobbler import --name=debian-10.2.0-amd64 --arch=x86_64 --path=/mnt/debian
umount /mnt/debian

The distribution itself does not contain any software, it contains only the Linux kernel and the environment for the installer of three configurations:

cobbler distro list
   debian-10.2.0-gtk-x86_64
   debian-10.2.0-x86_64
   debian-10.2.0-xen-x86_64

Delete the “unnecessary” configurations for us:

cobbler profile remove --name=debian-10.2.0-gtk-x86_64
cobbler profile remove --name=debian-10.2.0-xen-x86_64
cobbler distro remove --name=debian-10.2.0-gtk-x86_64
cobbler distro remove --name=debian-10.2.0-xen-x86_64

But that’s not all, the bootloader from the disk is designed to use cdrom and does not raise the network interface at the beginning of the installation, so it will not be possible to install the distribution kit on the server using it, the installer will require the installation of a cd-disk. To fix the situation, download the installer for network installation and replace the installer files in the Cobbler directories:

mkdir -pv /tmp/netboot
wget -q -O /tmp/netboot/netboot.tar.gz https://mirror.yandex.ru/debian/dists/buster/main/installer-amd64/current/images/netboot/netboot.tar.gz
cd /tmp/netboot
tar -xf /tmp/netboot/netboot.tar.gz

cp -fv /tmp/netboot/debian-installer/amd64/linux /var/www/cobbler/distro_mirror/debian-10.2.0-amd64-x86_64/install.amd
cp -fv /tmp/netboot/debian-installer/amd64/initrd.gz /var/www/cobbler/distro_mirror/debian-10.2.0-amd64-x86_64/install.amd

Carry out synchronization:

cobbler sync

The distribution package from the netboot.tar.gz archive was not installed right away, since Cobbler, when importing the distribution package, checks the signature of the distribution package and installs only those known to it, so initially it is need the original iso-image.

Creating response file for installing Debian

After importing the distribution, have an installer that can access any Debian mirror to install the desired configuration. It remains to create a response file for installing the distribution kit in non-interactive mode.

Following response file was created based on /var/lib/cobbler/templates/sample.seed and saved as /var/lib/cobbler/templates/debian_buster.seed:

# Mostly based on the Ubuntu installation guide
# https://help.ubuntu.com/18.04/installation-guide/
# Debian sample
# https://www.debian.org/releases/stable/example-preseed.txt

# Preseeding only locale sets language, country and locale.
d-i debian-installer/locale string ru_RU

# Keyboard selection.
# Disable automatic (interactive) keymap detection.
d-i console-setup/ask_detect boolean false
d-i keyboard-configuration/xkb-keymap select us
d-i keyboard-configuration/toggle select No toggling
d-i keyboard-configuration/layoutcode string us
d-i keyboard-configuration/variantcode string

# netcfg will choose an interface that has link if possible. This makes it
# skip displaying a list if there is more than one interface.
set $myhostname = $getVar('hostname',$getVar('name','cobbler')).replace("_","-")
d-i netcfg/choose_interface select auto
#d-i netcfg/choose_interface select eth0
#d-i netcfg/dhcp_timeout string 60
#d-i netcfg/dhcpv6_timeout string 60
d-i netcfg/get_hostname string $myhostname

# If non-free firmware is needed for the network or other hardware, you can
# configure the installer to always try to load it, without prompting. Or
# change to false to disable asking.
# d-i hw-detect/load_firmware boolean true

# NTP/Time Setup
d-i time/zone string Europe/Moscow
d-i clock-setup/utc boolean false
d-i clock-setup/ntp boolean true
d-i clock-setup/ntp-server  string ntp.ubuntu.com

# Setup the installation source
d-i mirror/country string manual
d-i mirror/http/hostname string http.mirror.yandex.ru
d-i mirror/http/directory string /debian
#d-i mirror/http/hostname string $http_server
#d-i mirror/http/directory string $install_source_directory
d-i mirror/http/proxy string

#set $os_v = $getVar('os_version','')
#if $breed == "ubuntu" and $os_v and $os_v.lower() != 'precise'
# Required at least for ubuntu 12.10+ , so test os_v is not precise. Olders versions are not supported anymore
d-i live-installer/net-image string http://$http_server/cobbler/links/$distro_name/install/filesystem.squashfs
#end if

# Suite to install.
d-i mirror/suite string buster
d-i mirror/udeb/suite string buster
# d-i mirror/suite string precise
# d-i mirror/udeb/suite string precise

# Components to use for loading installer components (optional).
#d-i mirror/udeb/components multiselect main, restricted

# Disk Partitioning
# Use LVM, and wipe out anything that already exists
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
d-i partman-auto/method string lvm
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-lvm/confirm boolean true
d-i partman-lvm/confirm_nooverwrite boolean true
d-i partman-md/device_remove_md boolean true
d-i partman-partitioning/confirm_write_new_label boolean true

# You can choose one of the three predefined partitioning recipes:
# - atomic: all files in one partition
# - home:   separate /home partition
# - multi:  separate /home, /usr, /var, and /tmp partitions
d-i partman-auto/choose_recipe select atomic

# If you just want to change the default filesystem from ext3 to something
# else, you can do that without providing a full recipe.
# d-i partman/default_filesystem string ext4

# root account and password
d-i passwd/root-login boolean true
d-i passwd/root-password-crypted password $default_password_crypted

# skip creation of a normal user account.
d-i passwd/make-user boolean false

# You can choose to install restricted and universe software, or to install
# software from the backports repository.
d-i apt-setup/restricted boolean true
d-i apt-setup/universe boolean true
d-i apt-setup/backports boolean true

# Uncomment this if you don't want to use a network mirror.
# d-i apt-setup/use_mirror boolean false

# Select which update services to use; define the mirrors to be used.
# Values shown below are the normal defaults.
d-i apt-setup/services-select multiselect security
d-i apt-setup/security_host string security.debian.org
d-i apt-setup/security_path string /debian

$SNIPPET('preseed_apt_repo_config')

# Enable deb-src lines
# d-i apt-setup/local0/source boolean true

# URL to the public key of the local repository; you must provide a key or
# apt will complain about the unauthenticated repository and so the
# sources.list line will be left commented out
# d-i apt-setup/local0/key string http://local.server/key

# By default the installer requires that repositories be authenticated
# using a known gpg key. This setting can be used to disable that
# authentication. Warning: Insecure, not recommended.
# d-i debian-installer/allow_unauthenticated boolean true

# Package selection
# Default for minimal
tasksel tasksel/first multiselect standard
# Default for server
# tasksel tasksel/first multiselect standard, web-server
# Default for gnome-desktop
# tasksel tasksel/first multiselect standard, gnome-desktop

# Individual additional packages to install
# wget is REQUIRED otherwise quite a few things won't work
# later in the build (like late-command scripts)
d-i pkgsel/include string ntp ssh wget

# Debian needs this for the installer to avoid any question for grub
# Please verify that it suit your needs as it may overwrite any usb stick
#if $breed == "debian"
d-i grub-installer/grub2_instead_of_grub_legacy boolean true
d-i grub-installer/bootdev string default
#end if

# Use the following option to add additional boot parameters for the
# installed system (if supported by the bootloader installer).
# Note: options passed to the installer will be added automatically.
d-i debian-installer/add-kernel-opts string $kernel_options_post

# Avoid that last message about the install being complete.
d-i finish-install/reboot_in_progress note

## Figure out if we're automating OS installation for a system or a profile
#if $getVar('system_name','') != ''
#set $what = "system"
#else
#set $what = "profile"
#end if

# This first command is run as early as possible, just after preseeding is read.
# d-i preseed/early_command string [command]
d-i preseed/early_command string wget -O- \
   http://$http_server/cblr/svc/op/script/$what/$name/?script=preseed_early_default | \
   /bin/sh -s

# This command is run immediately before the partitioner starts. It may be
# useful to apply dynamic partitioner preseeding that depends on the state
# of the disks (which may not be visible when preseed/early_command runs).
# d-i partman/early_command \
#       string debconf-set partman-auto/disk "\$(list-devices disk | head -n1)"

# This command is run just before the install finishes, but when there is
# still a usable /target directory. You can chroot to /target and use it
# directly, or use the apt-install and in-target commands to easily install
# packages and run commands in the target system.
# d-i preseed/late_command string [command]
d-i preseed/late_command string wget -O- \
   http://$http_server/cblr/svc/op/script/$what/$name/?script=preseed_late_default | \
   chroot /target /bin/sh -s; wget -O- \
   http://$http_server/cblr/svc/op/nopxe/$what/$name

mirror.yandex.ru is used as a mirror. This option can be used for tests or if there is a wide and unloaded Internet channel. Otherwise, you should use the ftpmirror utility, which can be found at link, which allows to create own mirror.

Also, the above configuration uses the entire disk when partitioning. For custom partitioning, you can use the example:

d-i partman-auto/expert_recipe string                        \
     boot-root ::                                            \
             30000 5000 40000 ext4                           \
                     $primary{ } $bootable{ }                \
                     method{ format } format{ }              \
                     use_filesystem{ } filesystem{ ext4 }    \
                     mountpoint{ / }                         \
             .                                               \
             20000 3000 40000 ext3                           \
                     method{ format } format{ }              \
                     use_filesystem{ } filesystem{ ext3 }    \
                     mountpoint{ /srv }                      \
             .                                               \
             10000 2000 10000000 ext4                        \
                     method{ format } format{ }              \
                     use_filesystem{ } filesystem{ ext4 }    \
                     mountpoint{ /home }                     \
             .                                               \
             50% 6000 200% linux-swap                        \
                     method{ swap } format{ }                \
             .

Please note that at the end of the installation of the distribution, the response file contains a script call:

wget -O- http://$http_server/cblr/svc/op/nopxe/$what/$name

This allows to reset the network boot flag for the server being installed, and after rebooting the server starts from the already installed distribution.

Conclusion

Further work with Cobbler involves the creation of systems (system) indicating for each physical or virtual server a MAC address, a distribution profile, network interfaces, as well as names and ip addresses.

Changing password

To change the password use the command:

printf "foobar" | openssl dgst -sha3-512

This algorithm is written in /etc/cobbler/modules.conf:

[authentication]
module = authentication.configfile
hash_algorithm = sha3_512