Kontrola aktualizací na serveru

Kontrola aktualizací na serveru
Kontrola aktualizací na serveru

Jako totální amatér, spravuji své dva servery pomocí postupů, které by mi tu dokázal každý profesionál vyčinit. Jo stále se přihlašuji pomocí ssh a spouštím jednou za čas dva příkazy.

sudo apt update
sudo apt upgrade

A jelikož mě to už nebaví, tak jsem si řekl, že to chce trochu zlepšit. Ano, asi na tohle existují už hotová řešení, ale nějak jsem byl línej je najít, nebo se prokousat dokumentací. Zkusil jsem tedy využití nových možností AI a zadal jsem ChatGTP jednoduchý úkol, který jsme postupně rozšiřovaly.

BASH skript

Úkol zněl jasně. Skript na automatickou kontrolu aktualizací na serveru, který zároveň pak pošle info do e-mailu. Samo sebou, že nejdříve se objevil BASH skript.

#!/bin/bash

# Nastavení e-mailu, kam se odešle zpráva
EMAIL="[email protected]"
SUBJECT="Dostupné aktualizace pro server $(hostname)"
TMPFILE="/tmp/updates.txt"

# Získání seznamu aktualizací
apt update > /dev/null 2>&1
apt list --upgradable > "$TMPFILE"

# Pokud existují aktualizace, odešle e-mail
if [ -s "$TMPFILE" ]; then
    mail -s "$SUBJECT" "$EMAIL" < "$TMPFILE"
fi

# Smazání dočasného souboru
rm -f "$TMPFILE"

Jednoduchý jak facka. Ale aby fungovalo posílání e-mailu, je nutné mít nainstalovaný mailutils .

SMTP server


A pak jsem si řekl, ok, co využít můj smtp server. To bude lepší, aby mi nepadali maily do spamu. A i to samozřejmě jde. Jen je nutné ještě nainstalovat msntp a provést konfiguraci.

sudo nano /etc/msmtprc

V nově vytvořeném souboru přidáme pak nastavení pro náš smtp server.

account default
host smtp.example.com  
port 587            
auth on
user "[email protected]"   
password "heslo"
from "[email protected]"
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile /var/log/msmtp.log

A po uložení ještě nastavit správná oprávnění.

sudo chmod 600 /etc/msmtprc
sudo chown root:root /etc/msmtprc

Bezpečnější varianta: Uložte heslo dáme do souboru a v konfiguraci místo password použijeme passwordeval cat /etc/msmtp-pass

echo "heslo" | sudo tee /etc/msmtp-pass > /dev/null
sudo chmod 600 /etc/msmtp-pass

No a upravíme, nebo znovu vytvoříme skript /usr/local/bin/check_updates.sh:

#!/bin/bash

# Nastavení e-mailu, kam se odešle zpráva
EMAIL="[email protected]"
SUBJECT="Dostupné aktualizace pro server $(hostname)"
TMPFILE="/tmp/updates.txt"

# Získání seznamu aktualizací
apt update > /dev/null 2>&1
apt list --upgradable > "$TMPFILE"

# Pokud existují aktualizace, odešle e-mail přes msmtp
if [ -s "$TMPFILE" ]; then
    echo -e "Subject: $SUBJECT\nTo: $EMAIL\n\n$(cat "$TMPFILE")" | msmtp "$EMAIL"
fi

# Smazání dočasného souboru
rm -f "$TMPFILE"

Jo a nezapomeňme ten skript udělat i spustitelný:

sudo chmod +x /usr/local/bin/check_updates.sh

CRON

Poslední věc. CRON

sudo crontab -e

a na poslední řádek přidáme:

0 3 * * * /usr/local/bin/check_updates.sh

Tím říkáme, že skript se bude spouštět každý den ve 3:00.

Jako jo, máme hotovo. Takhle to jde mít a funguje to. Ale.

"Listing..."

Po spuštění skriptu mi chodili email vždy. Obsahoval jednu jedinou řádku. "Listing...". Ok, je nutné skript upravit. Odstranit nejdříve první řádek a pak teprve kontrolovat, jestli se zde nachází něco nového a poslat e-mail.

#!/bin/bash

# Nastavení e-mailu, kam se odešle zpráva
EMAIL="[email protected]"
SUBJECT="Dostupné aktualizace pro server $(hostname)"
TMPFILE="/tmp/updates.txt"
TMPFILE_FILTERED="/tmp/updates_filtered.txt"

# Získání seznamu aktualizací
apt update > /dev/null 2>&1
apt list --upgradable > "$TMPFILE"

# Odstranění řádku začínajícího na "Listing..."
grep -v "^Listing..." "$TMPFILE" > "$TMPFILE_FILTERED"

# Pokud existují jiné aktualizace než "Listing...", odešle e-mail
if [ -s "$TMPFILE_FILTERED" ]; then
    echo -e "Subject: $SUBJECT\nTo: $EMAIL\n\n$(cat "$TMPFILE_FILTERED")" | msmtp "$EMAIL"
fi

# Smazání dočasných souborů
rm -f "$TMPFILE" "$TMPFILE_FILTERED"

Co skript dělá navíc oproti předchozí verzi?

✅ Používá grep -v "^Listing..." k odstranění řádku začínajícího na "Listing..."
✅ Kontroluje, zda po odstranění tohoto řádku zůstaly nějaké aktualizace
✅ Odesílá e-mail pouze v případě, že existují skutečné aktualizace

Formátování výstupu

Balíček: bash
Starší verze: 5.1-2ubuntu7.4
Nová verze: 5.1-2ubuntu7.5
------------------------------
Balíček: curl
Starší verze: 7.81.0-1ubuntu1.13
Nová verze: 7.81.0-1ubuntu1.14
------------------------------

Upravený skript:

#!/bin/bash

# Nastavení e-mailu, kam se odešle zpráva
EMAIL="[email protected]"
SUBJECT="Dostupné aktualizace pro server $(hostname)"
TMPFILE="/tmp/updates.txt"
TMPFILE_FILTERED="/tmp/updates_filtered.txt"
TMPFILE_FORMATTED="/tmp/updates_formatted.txt"

# Získání seznamu aktualizací
apt update > /dev/null 2>&1
apt list --upgradable > "$TMPFILE"

# Odstranění řádku začínajícího na "Listing..."
grep -v "^Listing..." "$TMPFILE" > "$TMPFILE_FILTERED"

# Pokud jsou dostupné aktualizace, zformátuje je
if [ -s "$TMPFILE_FILTERED" ]; then
    echo -e "Dostupné aktualizace pro server $(hostname):\n" > "$TMPFILE_FORMATTED"
    
    awk -F'[/ ]' '{
        printf "Balíček: %s\nStarší verze: %s\nNová verze: %s\n------------------------------\n", $1, $8, $3
    }' "$TMPFILE_FILTERED" >> "$TMPFILE_FORMATTED"

    # Odeslání e-mailu
    cat "$TMPFILE_FORMATTED" | msmtp "$EMAIL"
fi

# Smazání dočasných souborů
rm -f "$TMPFILE" "$TMPFILE_FILTERED" "$TMPFILE_FORMATTED"

HTML e-mail

Už to vypadá lépe. Ale chceme třeba mít nějaká ten i barevný výstup. Jako že nová verze bude zeleně a stará červeně. I to jde. Musíme jen upravit opět náš skript.

#!/bin/bash

# Nastavení e-mailu, kam se odešle zpráva
EMAIL="[email protected]"
SUBJECT="Dostupné aktualizace pro server $(hostname)"
TMPFILE="/tmp/updates.txt"
TMPFILE_FILTERED="/tmp/updates_filtered.txt"
TMPFILE_FORMATTED="/tmp/updates_formatted.html"

# Získání seznamu aktualizací
apt update > /dev/null 2>&1
apt list --upgradable > "$TMPFILE"

# Odstranění řádku začínajícího na "Listing..."
grep -v "^Listing..." "$TMPFILE" > "$TMPFILE_FILTERED"

# Pokud jsou dostupné aktualizace, vytvoří HTML zprávu
if [ -s "$TMPFILE_FILTERED" ]; then
    TMPFILE_FORMATTED=$(mktemp)  # Ujisti se, že existuje dočasný soubor

    # Předmět e-mailu v UTF-8, zakódovaný do Base64
    SUBJECT="Dostupné aktualizace pro server $(hostname)"
    SUBJECT_ENCODED=$(echo -n "$SUBJECT" | base64)

    {
        echo "Subject: =?UTF-8?B?$SUBJECT_ENCODED?="
        echo "Content-Type: text/html; charset=UTF-8"
        echo
        echo "<html><body>"
        echo "<h2>Dostupné aktualizace pro server $(hostname):</h2>"

        awk -F'[/ ]' '{
            printf "<p><strong>Balíček:</strong> %s<br>", $1
            printf "<span style=\"color:red;\"><strong>Starší verze:</strong> %s</span><br>", $8
            printf "<span style=\"color:green;\"><strong>Nová verze:</strong> %s</span><br>", $3
            printf "<hr></p>"
        }' "$TMPFILE_FILTERED"

        echo "</body></html>"
    } > "$TMPFILE_FORMATTED"

    # Odeslání e-mailu jako HTML
    msmtp "$EMAIL" < "$TMPFILE_FORMATTED"

    # Smazání dočasného souboru
    rm "$TMPFILE_FORMATTED"
fi

# Smazání dočasných souborů
rm -f "$TMPFILE" "$TMPFILE_FILTERED" "$TMPFILE_FORMATTED"

Co dělá HTML verze?

Zabalí výstup do HTML
Používá <span style="color:red;"> pro starší verzi (červená)
Používá <span style="color:green;"> pro novou verzi (zelená)
Lépe se zobrazí ve většině e-mailových klientů