Tips en Trucs 2023

Configuratiebestanden aanpassen met een Bash script

Met een Bash-script kun je ervoor zorgen dat bepaalde configuratieparameters in een configuratiebestand worden ingesteld.

Bash is tegenwoordig de standaard shell op de meeste Linux systemen. Het kan worden gebruikt om interactief opdrachten uit te voeren en als scripttaal om veelvoorkomende taken te automatiseren. Vandaag laten we zien hoe je een Bash-script kunt gebruiken om ervoor te zorgen dat specifieke configuratieparameters worden ingesteld in het bestand /etc/ssh/sshd_config.

Waarom een script gebruiken in plaats van een editor?

Het meerdere malen op meerdere systemen handmatig bewerken van /etc/ssh/sshd_config met een editor is gevoelig voor fouten. Er is altijd het risico dat je een typefout maakt of een parameter vergeet in te stellen. Deze fouten kunnen ernstige gevolgen hebben voor het systeem.

Het gebruik van een script is een vorm van configuratie als code en biedt verschillende voordelen. Zo hoef je de parameters slechts éénmaal op te geven en kan je het script hergebruiken om ze op elk gewenst systeem in te stellen. Bovendien zorgt het gebruik van een script ervoor dat dezelfde parameters met dezelfde waarden op dezelfde manier worden ingesteld op elk systeem waarop het script wordt uitgevoerd.

Het scenario

De taak is ervoor te zorgen dat de volgende vier configuratieparameters worden gebruikt in elk /etc/ssh/sshd_config bestand op alle Linux systemen in de infrastructuur:

PermitRootLogin no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no

Stel dat jouw computeromgeving er zo uitziet:

Het script

Er verschillende manieren om dit te doen. De volgende methode volgt het "hou het simpel" principe en heeft een vrij robuuste oplossing. Dus hier is het script, gevolgd door wat uitleg:

#!/bin/bash
#
# Description:
# This script sets certain parameters in /etc/ssh/sshd_config.
# It's not production ready and only used for training purposes.
#
# What should it do?
# * Check whether a /etc/ssh/sshd_config file exists
# * Create a backup of this file
# * Edit the file to set certain parameters
# * Reload the sshd configuration
# To enable debugging mode remove '#' from the following line
#set -x
# Variables

file="$1"
param[1]="PermitRootLogin "
param[2]="PubkeyAuthentication"
param[3]="AuthorizedKeysFile"
param[4]="PasswordAuthentication"

# Functions
usage(){
  cat << EOF
    usage: $0 ARG1
    ARG1 Name of the sshd_config file to edit.
    In case ARG1 is empty, /etc/ssh/sshd_config will be used as default.

    Description:
    This script sets certain parameters in /etc/ssh/sshd_config.
    It's not production ready and only used for training purposes.

    What should it do?
    * Check whether a /etc/ssh/sshd_config file exists
    * Create a backup of this file
    * Edit the file to set certain parameters
EOF
}

backup_sshd_config(){
  if [ -f ${file} ]
  then
    /usr/bin/cp ${file} ${file}.1
  else
    /usr/bin/echo "File ${file} not found."
    exit 1
  fi
}

edit_sshd_config(){
  for PARAM in ${param[@]}
  do
    /usr/bin/sed -i '/^'"${PARAM}"'/d' ${file}
    /usr/bin/echo "All lines beginning with '${PARAM}' were deleted from ${file}."
  done
  /usr/bin/echo "${param[1]} no" >> ${file}
  /usr/bin/echo "'${param[1]} no' was added to ${file}."
  /usr/bin/echo "${param[2]} yes" >> ${file}
  /usr/bin/echo "'${param[2]} yes' was added to ${file}."
  /usr/bin/echo "${param[3]} .ssh/authorized_keys" >> ${file}
  /usr/bin/echo "'${param[3]} .ssh/authorized_keys' was added to ${file}."
  /usr/bin/echo "${param[4]} no" >> ${file}
  /usr/bin/echo "'${param[4]} no' was added to ${file}"
}

reload_sshd(){
  /usr/bin/systemctl reload sshd.service
  /usr/bin/echo "Run '/usr/bin/systemctl reload sshd.service'...OK"
}

# main
while getopts .h. OPTION
do
  case $OPTION in
    h)
      usage
      exit;;
    ?)
      usage
      exit;;
  esac
done

if [ -z "${file}" ]
then
  file="/etc/ssh/sshd_config"
fi
backup_sshd_config
edit_sshd_config
reload_sshd

Het script begint met de shebang en enkele regels commentaar. We plaatsen de commentaar graag bovenaan om kort te beschrijven wat het script moet doen. Daarna activeren we een debug schakelaar met set -x. Probeer het uit als je niet bekend bent met debuggen. Het is erg handig bij het opsporen van fouten in scripts.

Daarna definiëren we alle variabelen die we gebruiken op één plaats. Ze staan in de regels na het commentaar en voordat we enkele functies definiëren. Je hoeft functies niet te gebruiken, maar ze zijn handig omdat ze het script meer structuur geven. En functies helpen je bij het oplossen van problemen. Je kunt gemakkelijk grote delen van je code (de functies) weglaten en je concentreren op de delen die problemen geven. Als je niet vertrouwd bent met functies, bekijk dan de "Shell Function Definitions" sectie in de bash(1) man pagina.

We doorlopen de rest van het script functie voor functie.

usage()

Deze functie geeft een korte uitleg over het gebruik van dit script. Hij wordt aangeroepen wanneer het script wordt uitgevoerd met de optie -h of -?.

dany@pindabook:~> sudo sh ./config_sshd.sh -h
[sudo] wachtwoord voor root: 
    usage: ./config_sshd.sh ARG1
    ARG1 Name of the sshd_config file to edit.
    In case ARG1 is empty, /etc/ssh/sshd_config will be used as default.

    Description:
    This script sets certain parameters in /etc/ssh/sshd_config.
    It's not production ready and only used for training purposes.

    What should it do?
    * Check whether a /etc/ssh/sshd_config file exists
    * Create a backup of this file
    * Edit the file to set certain parameters

backup_sshd_config()

Voordat je iets verandert op een systeem, wordt aangeraden om een back-up te maken van de bestanden die gewijzigd moeten worden. En dat is wat hier gebeurt, door ${file} te kopiëren naar ${file}.1.

Als het bestand in ${file} niet bestaat, drukt het script een foutmelding af op STDOUT.

edit_sshd_config()

Nu we een back-up hebben, bewerken we het bestand. Omdat we niet weten hoe vaak de opgegeven parameters in het bestand voorkomen, verwijderen we alle regels die beginnen met deze parameters. We moeten ervoor zorgen dat uiteindelijk alleen de gewenste configuratie aanwezig is. Dit is de taak van de sed opdracht die in een for-lus wordt uitgevoerd.

Aangezien de parameters zijn opgeslagen als elementen in een Bash array, doorlopen we in de lus alle array-elementen om ze te verwijderen. Je kan informatie vinden over Bash arrays in de "Arrays" sectie op de bash(1) man pagina.

Ten tweede worden de gewenste parameters met hun gewenste waarden toegevoegd aan het sshd_config bestand. De wijzigingen worden afgedrukt op STDOUT om de gebruiker te informeren.

reload_sshd()

SSHD moet de configuratie laden om het in werking te stellen. Dat is wat hier gebeurt.

# main

Nadat alle variabelen en functies zijn gedeclareerd, begint het script te werken. De volgende code zal een beschrijving van het gebruik van dit script afdrukken naar STDOUT wanneer het wordt uitgevoerd met de optie -h of -?.

while getopts .h. OPTION
do
  case $OPTION in
    h)
      usage
      exit;;
    ?)
      usage
      exit;;
  esac
done

Als er geen argument wordt opgegeven, wordt /etc/ssh/sshd_config als standaardbestand gebruikt:

if [ -z "${file}" ]
then
  file="/etc/ssh/sshd_config"
fi

En tenslotte worden de functies aangeroepen om een back-up te maken, de sshd_config te bewerken en opnieuw te laden.

Het script uitvoeren

Let op: dit script zal de bestaande SSH server configuratie aanpassen en toepassen. M.a.w. als je via SSH werkt met wachtwoorden kan het zijn dat je jezelf buitensluit (de toegang ontzegt).

Daar het script een systeemconfiguratie aanpast, heb je systeemrechten (root) nodig. Deze rechten krijg je door de sudo opdracht voor de script opdracht te plaatsen:

dany@pindabook:~> sudo sh ./config_sshd.sh
All lines beginning with 'PermitRootLogin' were deleted from /etc/ssh/sshd_config.
All lines beginning with 'PubkeyAuthentication' were deleted from /etc/ssh/sshd_config.
All lines beginning with 'AuthorizedKeysFile' were deleted from /etc/ssh/sshd_config.
All lines beginning with 'PasswordAuthentication' were deleted from /etc/ssh/sshd_config.
'PermitRootLogin  no' was added to /etc/ssh/sshd_config.
'PubkeyAuthentication yes' was added to /etc/ssh/sshd_config.
'AuthorizedKeysFile .ssh/authorized_keys' was added to /etc/ssh/sshd_config.
'PasswordAuthentication no' was added to /etc/ssh/sshd_config
Run '/usr/bin/systemctl reload sshd.service'...OK
Config script

Om te zorgen dat de instellingen steeds gebruikt worden, ook na het aanpassen voor een tijdelijke test, kan je het script opnemen in de opstartprocedure van het systeem of op regelmatige tijdstippen uitvoeren, bijvoorbeeld met cron.