# 11. Kali Linux in the Enterprise

### 11.1. Installing Kali Linux Over the Network (PXE Boot)

**Overview:**

Setting up PXE (Preboot eXecution Environment) allows you to boot and install Kali Linux on multiple machines over the network without needing physical boot media. This is ideal for environments where you need to perform a large-scale deployment of Kali Linux or streamline the installation process. PXE uses a combination of TFTP (Trivial File Transfer Protocol) and DHCP (Dynamic Host Configuration Protocol) servers to enable network booting.

Here’s a step-by-step guide to configuring PXE boot for Kali Linux installation:

***

#### **1. Setting Up the Network Boot Environment**

To get started, you'll need to set up both **TFTP** and **DHCP/BOOTP** servers. You can either use **dnsmasq** to handle both services together or configure them separately for more complex setups.

* **Dnsmasq** is a lightweight solution for DHCP and TFTP, which simplifies the setup.
* **Separate DHCP and TFTP daemons**: In more advanced scenarios, you might prefer using **isc-dhcp-server** and **tftpd-hpa**.

***

#### **2. Installing and Configuring Dnsmasq (for DHCP and TFTP)**

1.  **Install dnsmasq**:

    ```bash
    sudo apt install dnsmasq
    ```
2.  **Configure dnsmasq**: Edit the `/etc/dnsmasq.conf` file to define network interface, DHCP range, and TFTP settings. Example configuration:

    ```bash
    # Network interface to handle
    interface=eth0

    # DHCP options
    dhcp-range=192.168.101.100,192.168.101.200,12h
    dhcp-option=option:router,192.168.101.1
    dhcp-option=option:dns-server,8.8.8.8,8.8.4.4

    # Boot file to announce to clients
    dhcp-boot=pxelinux.0

    # TFTP options
    enable-tftp
    tftp-root=/tftpboot/
    ```
3.  **Restart dnsmasq**: After saving the configuration, restart dnsmasq to apply the changes:

    ```bash
    sudo systemctl restart dnsmasq
    ```

***

#### **3. Download and Configure Kali Linux Installation Files**

Now, you need to download the necessary Kali Linux installation files to serve them over the network.

1.  **Create the TFTP root directory**:

    ```bash
    sudo mkdir /tftpboot
    ```
2. **Download the appropriate Kali netboot archive**:
   *   For **64-bit (amd64)**, use:

       ```bash
       wget http://http.kali.org/dists/kali-rolling/main/installer-amd64/current/images/netboot/netboot.tar.gz
       ```
   *   For **32-bit (i386)**, use:

       ```bash
       wget http://http.kali.org/dists/kali-rolling/main/installer-i386/current/images/netboot/netboot.tar.gz
       ```
3.  **Extract the archive**:

    ```bash
    tar xf netboot.tar.gz -C /tftpboot/
    ```
4.  **Verify files**: Check that the files have been extracted correctly. You should see files like:

    ```bash
    drwxrwxr-x 3 root root     4096 May  6 04:43 debian-installer
    lrwxrwxrwx 1 root root       47 May  6 04:43 ldlinux.c32 -> debian-installer/amd64/boot-screens/ldlinux.c32
    lrwxrwxrwx 1 root root       33 May  6 04:43 pxelinux.0 -> debian-installer/amd64/pxelinux.0
    ```

***

#### **4. Customizing Boot Parameters**

To automate the installation, you can predefine settings such as language, keyboard layout, and network configuration using a **preseed file**. A preseed file is used to provide automatic answers to the installation process.

1.  **Modify the boot parameters in the `txt.cfg` file**: Edit the `/tftpboot/debian-installer/amd64/txt.cfg` file to add your custom preseed settings:

    ```bash
    label install
            menu label ^Install
            kernel debian-installer/amd64/linux
            append vga=788 initrd=debian-installer/amd64/initrd.gz --- quiet language=en country=US keymap=us hostname=kali domain= url=http://192.168.101.1/preseed.cfg
    ```
2.  **Modify the timeout settings**: In the `/tftpboot/debian-installer/amd64/syslinux.cfg`, adjust the boot menu timeout to automatically boot Kali if no key is pressed:

    ```bash
    prompt 0
    timeout 50
    ```

***

#### **5. Using a Preseed File for Unattended Installation**

The preseed file can be used to automate the entire installation, including partitioning, package selection, and user creation.

1. **Create the preseed.cfg file**:
   * This file should define all necessary configurations for the installation process. You can host this file on your web server (e.g., Apache) at a URL like `http://192.168.101.1/preseed.cfg`.
2.  **Link the preseed file in your `txt.cfg`**: As shown earlier, you can reference the preseed file in the boot parameters:

    ```bash
    url=http://192.168.101.1/preseed.cfg
    ```

***

#### **6. Boot the Client Machine via PXE**

1. **Enable PXE booting**: Ensure that the target machine is set to boot from the network in its BIOS/UEFI settings.
2. **Start the installation**:\
   The client machine should now automatically receive a network boot request, download the necessary boot files from your PXE server, and begin the Kali Linux installation process. If you've configured a preseed file, the installation will proceed fully automatically.

***

#### **Benefits of PXE Boot for Kali Linux Installation**:

* **Automated Installations**: You can automate the installation process for multiple machines without needing physical media.
* **Customizable**: With preseed files, you can fully customize the installation process to suit your environment.
* **Quick Deployment**: Ideal for large-scale deployments where installing Kali on multiple machines quickly is needed.

By following these steps, you can set up a PXE boot server and install Kali Linux over the network, enabling you to efficiently deploy Kali across multiple systems.

## 11.2. Leveraging Configuration Management

* With the ability to install Kali on multiple computers very quickly, you will need some help in managing those machines post-installation.
* Configuration management tools can be leveraged to manage these machines or configure replacement computers to any desired state.
* Kali Linux contains many popular configuration management tools that you might want to use (Ansible, Chef, Puppet, SaltStack, etc.), but in this section, we will only cover SaltStack.

For more information, visit [SaltStack's official site](https://www.saltstack.com).

### 11.2.1. Setting Up SaltStack

* SaltStack is a centralized configuration management service where a salt master manages many salt minions. To set up SaltStack, you need to install the salt-master package on a server that is reachable by all the hosts you want to manage, and the salt-minion package on the hosts that you wish to manage.
* Each minion must be configured to know where to find its master. To do this, you need to edit the `/etc/salt/minion` file and set the `master` key to the DNS name or IP address of the Salt master.

For example:

```
minion# vim /etc/salt/minion
minion# grep ^master /etc/salt/minion
master: 192.168.122.105
```

* Every minion has a unique identifier stored in `/etc/salt/minion_id`, which defaults to its hostname. This identifier is important for configuration rules, so it’s essential to set it properly before the minion connects to the master.

To set the identifier and start the minion service, use:

```
minion# echo kali-scratch >/etc/salt/minion_id
minion# systemctl enable salt-minion
minion# systemctl start salt-minion
```

* When the salt-minion service is running, it will try to connect to the Salt master and exchange cryptographic keys. On the master side, you need to accept the minion’s key to allow the connection.

To start the master service and accept the minion’s key, use the following commands:

```
master# systemctl enable salt-master
master# systemctl start salt-master
master# salt-key --list all
```

You’ll see an output with `Unaccepted Keys` that includes the minion’s identifier. To accept the key:

```
master# salt-key --accept kali-scratch
The following keys are going to be accepted:
Unaccepted Keys:
kali-scratch
Proceed? [n/Y] y
Key for minion kali-scratch accepted.
```

### 11.2.2. Executing Commands on Minions

* Once the minions are connected, you can execute commands on them from the master. For example, to test the connection between the master and the minions, you can use the `test.ping` function. This will return `True` if the connection is working.

Example:

```
master# salt '*' test.ping
kali-scratch:
    True
kali-master:
    True
```

The `'*'` wildcard targets all minions. You can also target specific minions by their identifier or use a more specific wildcard (e.g., "_-scratch" or "kali-_").

For example, to execute an arbitrary shell command on a specific minion (`kali-scratch`):

```
master# salt kali-scratch cmd.shell 'uptime; uname -a'
kali-scratch:
     05:25:48 up 44 min,  2 users,  load average: 0.00, 0.01, 0.05
    Linux kali-scratch 4.5.0-kali1-amd64 #1 SMP Debian 4.5.3-2kali1 (2020-05-09) x86_64 GNU/Linux
```

* SaltStack has many execution modules for various tasks. The full list of modules is available at [SaltStack's documentation](https://docs.saltproject.io/en/latest/ref/modules/all/index.html). You can also list functions available on a given minion by running `salt minion sys.doc` command. For example:

```
master# salt kali-scratch sys.doc disk.usage
disk.usage:

    Return usage information for volumes mounted on this minion
```

* One of the most useful modules is `pkg`, which abstracts package management. For example, `pkg.refresh_db` updates the package list, `pkg.upgrade` installs available updates, and `pkg.list_upgrades` lists pending upgrades.

Examples:

```
master# salt '*' service.enable ssh
kali-scratch:
    True
kali-master:
    True
master# salt '*' service.start ssh
kali-master:
    True
kali-scratch:
    True
master# salt '*' pkg.refresh_db
kali-scratch:
    ----------
kali-master:
    ----------
master# salt '*' pkg.upgrade dist_upgrade=True
kali-scratch:
    ----------
    changes:
        ----------
        base-files:
            ----------
            new:
                1:2020.2.1
            old:
                1:2020.2.0
[...]
        zaproxy:
            ----------
            new:
                2.5.0-0kali1
            old:
                2.4.3-0kali3
    comment:
    result:
        True
```

* For a more complex task, you could set up a distributed Nmap scan with `dnmap`. First, install the package on all the minions:

```
server# salt '*' pkg.install dnmap
[...]
server# vim dnmap.txt
server# dnmap_server -f dnmap.txt
```

Next, instruct all minions to start a client process that connects to the server:

```
server# salt '*' cmd.run_bg template=jinja 'dnmap_client -s 1.2.3.4 -a {{ grains.id }}'
kali-scratch:
    ----------
    pid:
        17137
[...]
```

Note that `cmd.run_bg` runs the command in the background. Since it's a long-running process, don't wait for it to finish. If needed, you can clean up the process later:

```
server# salt '*' cmd.shell 'pkill -f dnmap_client'
```

### 11.2.3. Salt States and Other Features

* SaltStack offers more than just remote execution; one of its most powerful features is Salt States. These are reusable configuration templates that can be applied to manage systems. By formalizing common setup tasks in state files, you can run multiple operations with a single command using `state.apply`.
* Many ready-to-use state files are available through "Salt formulas," which are shared by the community. You can explore and use these formulas to save time in your configuration management. More about Salt formulas can be found [here](https://docs.saltproject.io/en/latest/topics/development/conventions/formulas.html).
* SaltStack provides several features that can be combined, such as:
  * Scheduled execution of actions
  * Defining actions triggered by events from minions
  * Collecting data from minions
  * Orchestrating sequences of operations across multiple minions
  * Applying states over SSH without needing to install the salt-minion service
  * Provisioning systems on cloud infrastructures and bringing them under management
* The full range of SaltStack’s capabilities is vast and can be explored in detail. For those managing many systems, SaltStack can significantly save time in deploying and maintaining configurations. More information can be found in the [official documentation](https://docs.saltproject.io/en/latest/).
* To give you a practical example of working with state files, let's go over a simple one that enables an APT repository, installs a package, and registers an SSH key in root's account.
* State files are stored in `/srv/salt` on the master and use YAML with the `.sls` extension. State files rely on various state modules to define actions. For example, the following state file (`/srv/salt/offsec.sls`) calls three modules:

```yaml
offsec_repository:
  pkgrepo.managed:
    - name: deb http://pkgrepo.offsec.com offsec-internal main
    - file: /etc/apt/sources.list.d/offsec.list
    - key_url: salt://offsec-apt-key.asc
    - require_in:
      - pkg: offsec-defaults

offsec-defaults:
  pkg.installed

ssh_key_for_root:
  ssh_auth.present:
    - user: root
    - name: ssh-rsa AAAAB3NzaC1yc2...89C4N rhertzog@kali
```

* The `offsec_repository` state registers a package repository using the `pkgrepo.managed` function. It includes a GPG key fetched from the master to verify the repository. The `require_in` ensures the repository is set up before the package `offsec-defaults` can be installed. The `ssh_key_for_root` state adds an SSH key to `/root/.ssh/authorized_keys` for root’s account.
* To apply this state to a minion:

```
server# salt kali-scratch state.apply offsec
```

This command will run the states in the `offsec.sls` file, and you will see output indicating the success of each action (e.g., configuring the repository, installing the package, adding the SSH key).

* States can also be associated with specific minions by adding them to the `/srv/salt/top.sls` file, which is used by the `state.highstate` command to apply all relevant states in a single pass:

```yaml
base:
  kali-scratch:
    - offsec
```

To apply the highstate:

```
server# salt kali-scratch state.highstate
```

This will run all the states listed under the `base` section for the specified minion (`kali-scratch`), ensuring that the configuration is consistent.

* The output of `state.highstate` will show that the states have already been applied (if they are already configured), ensuring idempotency. This is beneficial for maintaining a consistent configuration across many systems.

## 11.3. Extending and Customizing Kali Linux

Sometimes you need to modify Kali Linux to make it fit your local needs. The best way to achieve this is to maintain your own package repository hosting the modified versions of the Kali packages that you had to fork, as well as supplementary packages providing custom configuration and extra software (not provided by Kali Linux).

### 11.3.1. Forking Kali Packages

* Forking a package in Kali Linux should be done with caution, as it comes with the responsibility of keeping the package updated with the latest changes from Kali. Forking is appropriate when there's a valid reason to make changes that Kali’s maintainers have not included, but it requires ongoing maintenance to ensure that updates don't conflict with the original version.
* **Reasons to fork a package**:
  * **To add a patch or feature**: If you need to fix a bug or introduce a new feature not yet addressed by the upstream developers, forking the package can allow you to make those changes. However, it’s recommended to submit your patch to the upstream maintainers so the fix or feature can be added to the main version.
  * **To compile with different options**: If Kali did not compile the package with certain options you need, forking might be the solution. However, it’s best to check with Kali’s maintainers to see if they can incorporate those options, rather than maintaining your own fork.
* **Bad reasons to fork a package** and how to handle them:
  * **Modifying configuration files**: Instead of forking a package to change configuration files, you should explore alternatives like using configuration management tools to deploy the modified configuration files automatically. You can also create or use existing configuration packages that place the modified file in the correct directory or divert the original file.
  * **Updating to a newer upstream version**: In Kali’s rolling release model, package updates are pushed quickly. Instead of forking the package, it’s better to work with Kali developers to ensure the package is updated in the official repositories.
* **Key packages that could be interesting to fork** in certain scenarios:
  * **kali-meta**: This source package builds the `kali-linux-*` and `kali-tools-*` metapackages, including `kali-linux-default`, which defines the default packages in the Kali Linux ISO image. You may fork this package if you need to customize the default installation.
  * **desktop-base**: This package contains files for the default desktop installation. If you want to customize the default desktop appearance, such as changing the background or theme to reflect your organization’s branding, forking this package is an option.
  * **kali-menu**: This package defines the structure of the Kali menu and provides `.desktop` files for the applications listed in the menu. If you need to alter the menu layout or add/remove items, forking `kali-menu` might be necessary.

By carefully considering these scenarios, you can avoid unnecessary forks and instead find more efficient ways to customize and maintain your Kali Linux environment.

### 11.3.2. Creating Configuration Packages

1. **APT Sources & GPG Key:**
   * `/etc/apt/sources.list.d/offsec.list`: Adds a custom repository for your internal package repository.
   * `/etc/apt/trusted.gpg.d/offsec.gpg`: Contains the GnuPG key used to sign the internal repository.
2. **SaltStack Configuration:**
   * `/etc/salt/minion.d/offsec.conf`: Configures the Salt minion to connect to your Salt master.
3. **Desktop Configuration:**
   * `/usr/share/images/offsec/background.png`: Custom background image for Kali systems.
   * `/usr/share/glib-2.0/schemas/90_offsec-defaults.gschema.override`: GNOME desktop settings (like setting the background image).

#### Steps to Create the Custom Package:

1.  **Create Package Directory and Files:** Start by creating a directory to hold the package contents and place your files in the appropriate locations.

    ```bash
    mkdir offsec-defaults-1.0
    cd offsec-defaults-1.0
    ```
2.  **Run `dh_make` to Set Up Packaging:** This will create a basic Debian package structure and required files.

    ```bash
    dh_make --native
    ```

    When prompted, select `i` for "indep" (since it's architecture-independent) and fill in the necessary information such as email and license details.
3. **Edit the Files Created by `dh_make`:** After `dh_make`, several files will be created in the `debian/` directory. Here are the files that require editing:
   * **control**: Modify the `Section` field to `misc` and provide details about the package, such as its dependencies and description.
   * **copyright**: Specify the license (GPL-3.0 in this case) and include the authors.
   * **changelog**: Update this file to describe what changes this package introduces (e.g., adding APT sources, configuring SaltStack, setting desktop settings).
4.  **Install Configuration Files:** Use the `.install` file to specify where to install your configuration files. For example:

    ```bash
    apt/offsec.list etc/apt/sources.list.d/
    apt/offsec.gpg etc/apt/trusted.gpg.d/
    salt/offsec.conf etc/salt/minion.d/
    images/background.png usr/share/images/offsec/
    ```
5.  **GNOME Settings File:** Create a `gsettings-override` file to modify the GNOME desktop background and place it in the correct directory (`debian/offsec-defaults.gsettings-override`):

    ```ini
    [org.gnome.desktop.background]
    picture-options='zoom'
    picture-uri='file:///usr/share/images/offsec/background.png'
    ```
6.  **Override `dh_installgsettings`:** In `debian/rules`, override the `dh_installgsettings` command to use a priority of 90 (the priority level for organizational settings):

    ```bash
    #!/usr/bin/make -f

    %:
        dh $@

    override_dh_installgsettings:
        dh_installgsettings --priority=90
    ```
7.  **Build the Package:** Once all files are configured, use `dpkg-buildpackage` to build the package:

    ```bash
    dpkg-buildpackage -us -uc
    ```

    This will generate the `.deb` package, which can then be installed on any Kali system.
8. **Deploy the Package:** The generated package `offsec-defaults_1.0_all.deb` can be distributed and installed on multiple machines. When installed, it will:
   * Add the custom APT sources and GPG key.
   * Configure SaltStack to connect to the Salt master.
   * Set the custom background image.
   * Apply custom GNOME desktop settings.

#### Summary:

This process is a great way to manage configuration across multiple machines. By creating a custom package with configuration files, you ensure that your systems are consistently configured. While it may seem complex at first, once you get the hang of it, creating and maintaining custom configuration packages can save a lot of time in managing systems at scale.

### 11.3.3. Creating a Package Repository for APT

1. **Creating the Custom Package:**
   * First, a custom configuration package (`offsec-defaults`) was created. This package contains configuration files (e.g., APT sources, SaltStack configurations, custom background images, and GNOME desktop settings) to be deployed across multiple machines.
   * The `dh_make` tool was used to initialize the package structure, followed by editing files like `control`, `changelog`, and `rules` to customize the package.
   * After building the package using `dpkg-buildpackage`, the final `.deb` package (`offsec-defaults_1.0_all.deb`) was created.
2. **Setting Up the APT Package Repository:**
   * The `reprepro` tool was used to create and manage a custom APT repository where the package would be stored.
   * A new user (`pkgrepo`) was created to manage the repository and GPG key.
   * The GPG key was generated to sign the repository and ensure authenticity.
   * The repository was initialized, and the custom package was added using the `reprepro include` command.
3. **Configuring the Web Server for Repository Access:**
   * An Apache server was configured to serve the repository's `dists` and `pool` directories over HTTP.
   * A corresponding `sources.list` entry was created on client machines to access the repository and install the custom package.
4. **PXE Booting and SaltStack Integration:**
   * PXE booting allows machines to boot over the network, fetching the preseed file and the necessary package configurations to install Kali Linux automatically.
   * SaltStack manages the configuration on client machines, ensuring that they are configured and updated automatically via the Salt master.
5. **Deployment:**
   * Once the setup is complete, new machines can be PXE-booted, automatically configured, and managed without manual intervention.
   * The custom package can be installed during the installation process or through subsequent updates.

#### Final Thoughts:

This process is highly flexible and scalable. You can use it to manage a large number of Kali Linux installations across a network, ensuring that they are all uniformly configured and up-to-date with minimal effort. Here are a few additional recommendations and considerations:

* **Security:** Ensure that the GPG keys used for signing the repository and packages are kept secure. If the repository is publicly accessible, ensure proper encryption and security measures are in place (e.g., HTTPS).
* **Updating Packages:** Whenever new updates or configurations are needed, simply update the package and add the new version to the repository. The client machines will automatically pull the latest version when updated via SaltStack.
* **Automation & Customization:** With SaltStack's flexibility, you can easily extend this setup to manage more complex configurations, deploy additional software, or monitor systems across your network.
* **Backup and Disaster Recovery:** Consider implementing a backup strategy for the repository and configuration files. This ensures that you can quickly recover from any issues, whether they be accidental deletions or server failures.

This setup provides a powerful solution for managing and deploying consistent, secure environments across a network of Kali Linux systems, which can be particularly useful for enterprise, educational, or research environments.

## 11.4. Summary

* **Kali Linux in Large-Scale Deployments**\
  Kali Linux is capable of scaling beyond desktop usage, catering to medium and large-scale deployments, including enterprise-level environments. To facilitate the management of multiple Kali installations, **SaltStack** can be utilized, enabling centralized management. This setup helps deploy highly secure Kali systems that are preconfigured for specific needs, and ensures synchronization through the semi-automatic installation of package updates.
* **Package Forking**\
  Forking packages allows you to create customized distributable source packages. This capability can be particularly useful for tailoring Kali Linux to fit specific requirements. However, it’s important to evaluate the pros and cons of forking a package, as the process can be complex and challenging.
* **Steps for Setting Up SaltStack**\
  To establish **Salt Masters** and **Minions** for remote control and configuration of systems, follow these major steps:
  * Boot the machine via PXE with the necessary file servers: TFTP, DHCP/BOOTP, and a web server for debconf preseeding.
  * Use **dnsmasq** for DHCP and TFTP server configuration. Basic configuration includes defining the interface, DHCP range, gateway, DNS servers, and boot file for PXE booting.
  * Unpack Kali Linux installation boot files from the Kali archive into the `/tftpboot/` directory.
  * Modify `txt.cfg` for unattended installations if needed.
* **PXE Setup with dnsmasq**\
  The **dnsmasq** configuration for PXE booting should include the network interface to handle (e.g., `interface=eth0`), IP range allocation (`dhcp-range`), gateway, DNS servers, boot file (`dhcp-boot=pxelinux.0`), and TFTP options (`enable-tftp`). The boot files can be downloaded and unpacked from the Kali archive, with specific netboot files for 32-bit and 64-bit versions.
*   **SaltStack Configuration**\
    Once you have Kali Linux systems set up, **SaltStack** can be used to manage them. Install `salt-master` on the central server and `salt-minion` on the managed hosts. Configure the `/etc/salt/minion` file with the master’s DNS name or IP address. Set the minion’s unique identifier using `/etc/salt/minion_id`. Start the `salt-minion` service and enable it on boot:

    ```bash
    systemctl enable salt-minion
    systemctl start salt-minion
    ```

    On the Salt master, accept the minion's key:

    ```bash
    salt-key --accept kali-scratch
    ```

    After the minion is connected, you can run commands on it from the master, such as checking connectivity with:

    ```bash
    salt '*' test.ping
    ```
* **Execution and State Modules in SaltStack**\
  Salt allows executing commands remotely using **execution modules**. Examples include checking system information (`salt kali-scratch cmd.shell 'uptime; uname -a'`) or managing services (`salt '*' service.enable ssh`). Package management can also be handled with commands like `salt '*' pkg.refresh_db` or `salt '*' pkg.upgrade dist_upgrade=True`.
* **Salt State Files**\
  For efficient configuration management, **Salt state files** are used to define reusable configuration templates. These can be used to orchestrate operations, provision cloud systems, and ensure desired configurations across multiple systems. Predefined **Salt formulas** are also available to speed up deployment.
* **Forking Packages**\
  Forking a package, such as **kali-meta**, **desktop-base**, or **kali-menu**, can be a viable strategy for customization. However, forking comes with its own challenges, and it is essential to carefully assess whether it is the best approach for your needs.

***

***

***

**`Hacker's Mantra:`**` ``The hacker mindset doesn’t actually see what’s there; it sees what’s missing. -- Bruce Schneier`
