Bash Script curl sendet 2 mal ?

OpenMedia

Lieutenant
Registriert
Okt. 2016
Beiträge
706
Hallo zusammen,
ich habe ein Script, was automatisiert über die PAM eine Slack Notification sendet. Leider schickt das Script 2x die gleiche Notification an Slack. Ich finde leider keinen Fehler im Script, kann mir jemand helfen oder einen Tipp geben :

Code:
#!/bin/bash
function slack_post () {


        SLACK_URL=https://hooks.slack.com/services/T1asdasdasdasdasd...
        COLOR="#808080"  # Standardfarbe (Grau)


        # Check User
        if [ "$2" == "adm" ]; then
            COLOR="#3498db"  # USer "adm"
        elif [ "$2" == "root" ]; then
            COLOR="#e74c3c"  # User "root"
        fi


        # Payload for slack_post
        PAYLOAD="{\"attachments\":[{\"color\":\"$COLOR\",\"text\":\"${SLACK_MESSAGE}\",\"username\":\"SSH-Bot\"}]}"


        curl -X POST --data "payload=$PAYLOAD" ${SLACK_URL}
}


USER="User:          $PAM_USER"
REMOTE="Remote:        $PAM_RHOST"
DATE="Date:          `date +"%H:%M:%S - %d. %B %Y"`"
SERVER="Server:        `hostname`"
LOGINMESSAGE="ogin on `hostname` for account $PAM_USER"


if [ "$PAM_TYPE" = "open_session" ]
then
        slack_post "${LOGINMESSAGE}\n${USER}\n${REMOTE}\n${DATE}\n${SERVER}" "$PAM_USER"
fi
exit 0
 
Nimm das mal alles raus, teste ob es wirklich nicht läuft und ruf dann das script einmal selbst auf.
 
Vieleicht siehts du so mehr
Code:
 session optional pam_exec.so debug log=/var/log/pamlog.log  /usr/myscript.sh
 
  • Gefällt mir
Reaktionen: lokked
So etwas ähnliches hatten wir auch mal. Da wurde das Skript wird tatsächlich 2x aufgerufen weil 2 SSH Sessions kurz hintereinander gestartet wurden. Grund waren irgendwelche Einstellungen, die ein unsichtbares und dann ein sichtbares Password Prompt zur Folge hatten. Als User merkst du dann nix davon.

In dem Fall wurde das Script also 2x gestartet bevor irgendeine SSH Session zugemacht wurde, d.h. nicht nacheinander auf und wieder zu, sondern 2x zeitverzögert gestartet.

Wenn das bei dir der Fall ist, kann man das Problem ohne die zu Ursache zu beseitigen (geht vielleicht gar nicht) umgehen, indem man eine simple Sperrdatei beim ersten Aufruf erstellt. Das verhindert, das bei nachfolgenden - zeitverzögerten - Aufrufen der Request nochmal geschickt wird, weil man vorher immer guckt, ob die Sperrdatei existiert.

Melde dich, wenn du ein Beispiel gebrauchen kannst. Wenn du Systemd hast, wird es sehr einfach, weil man die Lockfile dann im /run/user_id verzeichnis speichern kann und der service für dich den ordner (und damit die file) löscht wenn der user ausloggt.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: OpenMedia
lokked schrieb:
So etwas ähnliches hatten wir auch mal. Da wurde das Skript wird tatsächlich 2x aufgerufen weil 2 SSH Sessions kurz hintereinander gestartet wurden. Grund waren irgendwelche Einstellungen, die ein unsichtbares und dann ein sichtbares Password Prompt zur Folge hatten. Als User merkst du dann nix davon.

In dem Fall wurde das Script also 2x gestartet bevor irgendeine SSH Session zugemacht wurde, d.h. nicht nacheinander auf und wieder zu, sondern 2x zeitverzögert gestartet.

Wenn das bei dir der Fall ist, kann man das Problem ohne die zu Ursache zu beseitigen (geht vielleicht gar nicht) umgehen, indem man eine simple Sperrdatei beim ersten Aufruf erstellt. Das verhindert, das bei nachfolgenden - zeitverzögerten - Aufrufen der Request nochmal geschickt wird, weil man vorher immer guckt, ob die Sperrdatei existiert.

Melde dich, wenn du ein Beispiel gebrauchen kannst. Wenn du Systemd hast, wird es sehr einfach, weil man die Lockfile dann im /run/user_id verzeichnis speichern kann und der service für dich den ordner (und damit die file) löscht wenn der user ausloggt.

Vielen Dank, genau das gleiche habe ich tatsächlich durch das Loggen, wie im Kommentar hiervor gesehen. Es wird tatsächlich beim pam.d/sshd das ganze Script oder der Befehl zwei mal ausgeführt.

Ein einfacher
ping -c 4 google.de

Lief einmal ganz kurz durch also 1 Ping zu google.de und dann wurde der Befehl nochmal ausgeführt aber diesmal komplett durch.

Ich würde mich freuen wenn du mir ein Beispiel schicken könntest.
 
So ähnlich vom Prinzip her:
Funktioniert aber nur, wenn auch ein /run/userid Verzeichnis für den User angelegt wird (kannst du ja überprüfen). Ansonsten müsstest du die Lockfile einfach in /tmp ablegen und den usernamen mit in den dateinamen reinpacken.

Code:
#!/bin/bash
lock="/run/user/$(id -u "$PAM_USER")/notify_slack_ssh.lock"

slack_post () {
    SLACK_URL=https://hooks.slack.com/services/T1asdasdasdasdasd...
    COLOR="#808080"  # Standardfarbe (Grau)
    # Check User
    if [ "$2" == "adm" ]; then
        COLOR="#3498db"  # User "adm"
    elif [ "$2" == "root" ]; then
        COLOR="#e74c3c"  # User "root"
    fi
   # Payload for slack_post
   PAYLOAD="{\"attachments\":[{\"color\":\"$COLOR\",\"text\":\"${SLACK_MESSAGE}\",\"username\":\"SSH-Bot\"}]}"
   curl -X POST --data "payload=$PAYLOAD" ${SLACK_URL}
}

if [ "$PAM_TYPE" = "open_session" ]; then
    if [ -f $lock ]; then
        # Session Counter in Lockfile schreiben
        count=$(cat $lock)
        echo $(($count + 1)) > $lock
    else
        # Noch keine Session offen; Lockfile anlegen
        echo 1 > $lock

        USER="User: $PAM_USER"
        REMOTE="Remote: $PAM_RHOST"
        DATE="Date: $(date +"%H:%M:%S - %d. %B %Y")"
        SERVER="Server: $(hostname)"
        LOGINMESSAGE="Login on $(hostname) for account $PAM_USER"

        slack_post "${LOGINMESSAGE}\n${USER}\n${REMOTE}\n${DATE}\n${SERVER}"
    fi
elif [ "$PAM_TYPE" = "close_session" ] && [ -f $lock ]; then
    count=$(cat $lock)
    next_count=$(($count - 1))
    if [ $next_count -gt 0 ]; then
        # Counter runtersetzen, wenn noch andere Sessions laufen
        echo $next_count > $lock
    else
        # Letzte Session; Lockfile kann weg
        rm -f $lock
   fi
fi

Je nachdem wie dein Anwendungsfall aussieht kannst du ja den Zählmechanismus für Sessions rausnehmen. Bei uns war es so, das ein User mehrere Session hintereinander aufmachen konnte, aber nur 1x was gemacht werden sollte (= Kritischer Pfad in der Funktion) , bis der User alle seine Sessions wieder geschlossen hatte.
Um unnötigen Traffic/Spam zu vermeiden.

Die Lockfile wird nur dann gelöscht wenn keine anderen Sitzungen mehr offen sind. Bei dir wäre es dann so, dass das 2. Login keinen Aufruf mehr verursacht, weil die Datei noch da ist. Nur die Lockfile zu löschen wenn irgendeine Session zugemacht wird, bedeutet das trotzdem nochmal der zu schützende Code ausgeführt wird, wenn danach wieder connected wird vom gleichen User. Daher der Zähler.

Was hier noch fehlt ist eine Aufräumfunktion, die ganz am Anfang guckt ob aus irgendwelchem Grund noch eine Lockfile da ist, wenn man sich das erste Mal verbindet (was ein Ausnahmefall ist), um 100% auf Nummer Sicher zu gehen.

Wenn es nicht geht, heißt das auch das nicht alle Sitzungen sofort geschlossen werden wenn du dich aus deiner Sicht komplett vom Server abmeldest. Dann wäre es nicht ratsam so ein Skript zu nutzen und man sollte lieber das Problem (wenns eins ist) abstellen.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: OpenMedia
Zurück
Oben