#pets #configuration-management #linux #configuration #cattle

app pets-configurator

A configuration management system for Pets, not Cattle

6 releases

new 0.2.1 Nov 19, 2024
0.2.0 Nov 16, 2024
0.1.3 Nov 13, 2024

#14 in Configuration

Download history 276/week @ 2024-11-08 223/week @ 2024-11-15

499 downloads per month

MIT license

70KB
1.5K SLoC

PETS Configurator

A Configuration Management System for computers that are Pets, not Cattle.

This package is a fork of the original Pets package. You can understand design decisions by referring to the original project.

This is for people who need to administer a handful of machines, all fairly different from each other and all Very Important. Those systems are not Cattle! They're actually a bit more than Pets. They're almost Family. For example: a laptop, workstation, and that personal tiny server in Sweden. They are all named after something dear.

pets works on Linux systems. The following distro families are supported:

  • Debian-like (apt)
  • RedHat-like (yum)
  • Alpine (apk)
  • Arch Linux (pacman, yay)

Summary

Pets is driven by comments embedded in the config files themselves, rather than by a domain-specific language (DSL). For example, say you want to ensure that user butlerx has sudo rights. Create a file with the following contents under $HOME/pets/, run pets as root, done. The file can be called whatever you want. Note that pets will install the sudo package for you if missing.

# pets: destfile=/etc/sudoers.d/ema, owner=root, group=root, mode=0440
# pets: package=sudo
# pets: pre=/usr/sbin/visudo -cf
## ema ALL=(ALL:ALL) NOPASSWD:ALL

Usage

Build and install pets with:

cargo install pets-configurator

The following options are supported:

pets --help
A configuration management system for Pets, not Cattle

Usage: pets [OPTIONS]

Options:
      --conf-dir <CONF_DIR>  Pets configuration directory [default: /home/butlerx/pets]
      --debug                Show debugging output
      --dry-run              Only show changes without applying them
  -h, --help                 Print help
  -V, --version              Print version

Let's say you've decided to put your configuration files under /etc/pets. The system can then be used with:

pets --conf-dir /etc/pets

See sample_pet for a basic example of what your /etc/pets can look like. Note that directory structure is arbitrary, you can have as many directories as you want, call them what you want, and so on.

Configuration directives

  • destfile -- where to install this file. One of either destfile or symlink must be specified.
  • symlink -- create a symbolic link to this file, instead of copying it like destfile would.
  • owner -- the file owner, passed to chown
  • group -- the group this file belongs to, passed to chgrp
  • mode -- octal mode for chmod
  • package -- which package to install before creating the file. This directive can be specified more than once to install multiple packages. $The package manager can be specified by prepending it the package with the name of the package manager and a colon. Eg: cargo:exa would use cargo to install exa
  • pre -- validation command. This must succeed for the file to be created/updated.
  • post -- apply command. Usually something like reloading a service.

Configuration directives are passed as key/value arguments, either on multiple lines or separated by commas.

# pets: package=ssh, pre=/usr/sbin/sshd -t -f

The example above and the one below are equivalent

# pets: package=ssh
# pets: pre=/usr/sbin/sshd -t -f

Examples

Firewall

Say you want to configure the local firewall to drop all incoming traffic except for ssh? Here's an example that does the following:

  • Installs ferm if missing
  • Validates the configuration with /usr/sbin/ferm -n
  • If the configuration is valid, copies it under /etc/ferm/ferm.conf
  • Reloads the firewall rules with systemctl reload
# pets: destfile=/etc/ferm/ferm.conf, owner=root, group=root, mode=644
# pets: package=ferm
# pets: pre=/usr/sbin/ferm -n
# pets: post=/bin/systemctl reload ferm.service

domain (ip ip6) {
    table filter {
        chain INPUT {
            policy DROP;

            # connection tracking
            mod state state INVALID DROP;
            mod state state (ESTABLISHED RELATED) ACCEPT;

            # allow local packets
            interface lo ACCEPT;

            # respond to ping
            proto icmp ACCEPT;

            # allow SSH connections
            proto tcp dport ssh ACCEPT;
        }

        chain OUTPUT {
            policy ACCEPT;
        }

        chain FORWARD {
            policy DROP;
        }
    }
}

SSH Server

# pets: destfile=/etc/ssh/sshd_config, owner=root, group=root, mode=0644
# pets: package=ssh
# pets: package=openssh-client-dbgsym
# pets: pre=/usr/sbin/sshd -t -f
# pets: post=/bin/systemctl reload ssh.service
#
# Warning! This file has been generated by pets(1). Any manual modification
# will be lost.

Port 22
Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no

X11Forwarding yes

# Allow client to pass locale environment variables
AcceptEnv LANG LC_*

Subsystem sftp /usr/lib/openssh/sftp-server

UsePAM yes

Dependencies

~5–13MB
~170K SLoC