Ich habe einen Server unter Ubuntu 20.04 laufen, auf den per git eine Website deployt werden soll. Aus den mit git push ins Repo übertragenen Daten soll automatisch ein Docker-Image erzeugt werden. Ich habe dazu ein bash-Skript geschrieben, das alle 10 sec prüft, ob eine vom git-hook post-receive geschriebene Datei existiert und ggf. die darin enthaltenen Kommandos ausführt und die Datei löscht. Das funktioniert so weit. Jetzt würde ich gerne dieses Skript automatisch starten, wenn das home-Verzeichnis auf dem Server per sftp oder per ssh geöffnet wird. Das Skript soll aber nur genau einmal laufen und sich verabschieden, wenn niemand mehr eingeloggt ist. Wie stellt man das am besten an?
> home-Verzeichnis auf dem Server per sftp oder per ssh geöffnet wird
man sshd, script nach: ~/.ssh/rc
Taucher schrieb: > Wie stellt man das am besten an? Vielleicht indem Du uns Deinen Anwendungsfall genauer erklärst?! ;-)
Taucher schrieb: > Jetzt würde ich gerne dieses Skript automatisch starten, wenn das > home-Verzeichnis auf dem Server per sftp oder per ssh geöffnet wird. Du könntest zum Beispiel mit entr die atime überprüfen. Bei Verzeichnissen geht das aber nur in einer Loop. Zum Beispiel: while true; do ls home/* | entr -pd <was auch immer du damit vorhast>; done
Ich mache das deploy direkt aus dem post-update hook heraus.
Taucher schrieb: > Ich habe einen Server unter Ubuntu 20.04 laufen, auf den per git eine > Website deployt werden soll. Aus den mit git push ins Repo übertragenen > Daten soll automatisch ein Docker-Image erzeugt werden. Soweit so Normal, die meisten verwenden für sowas eine CI/CD Pipeline, Jenkins und Gitlab oder nur Gitlab sind da weit verbreitet. Taucher schrieb: > Ich habe dazu ein bash-Skript geschrieben, das alle 10 sec prüft, ob > eine vom git-hook post-receive geschriebene Datei existiert und ggf. die > darin enthaltenen Kommandos ausführt und die Datei löscht. > > Das funktioniert so weit. Die Erfahrung sagt, das klingt aus mehreren Gründen falsch. Die Wichtigsten sind: 1.) Du machst Busy Waiting, Dein Bash script wird die meiste Zeit nichts zu tun haben, aber um das zu Prüfen muss es immer mal wieder den Prozessor bemühen. Warum lässt Du den post-receive hook nicht gleich das Script starten oder arbeitest notfalls mit iNotify. 2.) unter Umständen kommt es hier zu einer Privilege escalation wenn der Prozess mehr rechte hat als der Benutzer, welche die Befehle in die Datei tut. Mit genügend krimineller Energie, kann der Benutzer das System benutzen, um dauerhaft die gleichen rechte zu bekommen wie der Prozess. 3.) das Umgehen Löschen nach dem Ausführen, klingt auch aus unterschiedlichen Gründen fehleranfällig. Was passiert, wenn das Löschen nicht klappt, weil das Script abbricht? Nach 10 Sekunden kommt dann der nächste Bash lauf und so weiter... Was wenn das Scipt durchläuft aber einen Fehler macht, kann ich das Script irgendwo zu debug zwecken sehen? Taucher schrieb: > Jetzt würde ich gerne dieses Skript automatisch starten, wenn das > home-Verzeichnis auf dem Server per sftp oder per ssh geöffnet wird. Das > Skript soll aber nur genau einmal laufen und sich verabschieden, wenn > niemand mehr eingeloggt ist. Denn Teil verstehe ich nicht, meinst Du das Bash Script das alle 10 Sekunden pollt, oder das Script mit den Befehlen welches Dir, der post-receive hook erzeugt oder was ganz anderes. Was meinst Du mit das Script soll genau einmal laufen und sich verabschieden, ich denke das post-receive Skript löscht sich, wenn des erfolgreich war. Und so ein wenig widerspricht sich das einmal laufen auch mit den" und sich verabschieden, wenn niemand mehr eingeloggt ist." ist Dein ominöse Skript vielleicht ein Dämon der die ganze Zeit läuft? Taucher schrieb: > Wie stellt man das am besten an? systemd/User https://wiki.archlinux.org/title/systemd/User) vielleicht, dort ein oneshot bauen der wird genau einmal gestartet, wenn sich der Benutzer einloggt. Ich bin mir aber nicht sicher, ob Deine Architektur, so eine gute Idee ist. Vielleicht gehst Du vorher nochmal zurück ans Zeichenbrett und siehst Dir an wie andere eine ähnliche Architektur gebaut haben. Ich vermute mit einer gut geplanten CI/CD Pipeline, wird sich Deine aktuelle Fragestellung wahrscheinlich nicht ergeben.
MaWin schrieb: > Ich mache das deploy direkt aus dem post-update hook heraus. Das hat nur den Nachteil, dass dann die git-Verbindung so lange gesperrt ist, bis das Generierungsskript fertig ist. Das dauert in meinem Fall. Ich hatte auch schon versucht, aus dem git-Hook heraus das Skript einfach in den Hintergrund zu schieben, das hat aber aus unklaren Gründen nicht funktioniert.
Imonbln schrieb: > Soweit so Normal, die meisten verwenden für sowas eine CI/CD Pipeline, > Jenkins und Gitlab oder nur Gitlab sind da weit verbreitet. Ich mache es ohne Github & Co. mit einem einfachen git push. > Die Erfahrung sagt, das klingt aus mehreren Gründen falsch. Die > Wichtigsten sind: Ist es aber nicht… > 1.) Du machst Busy Waiting, Dein Bash script wird die meiste Zeit nichts > zu tun haben, aber um das zu Prüfen muss es immer mal wieder den > Prozessor bemühen. Na ja, alle 10 sec nachsehen und dann wieder sleep würde ich nicht als Busy Waiting bezeichnen… Innerhalb der 10 sec kommt genug Rauschen von außen rein, dass die CPU immer wieder aktiv werden muss. > Warum lässt Du den post-receive hook nicht gleich das > Script starten oder arbeitest notfalls mit iNotify. S.o. > 2.) unter Umständen kommt es hier zu einer Privilege escalation wenn der > Prozess mehr rechte hat als der Benutzer, welche die Befehle in die > Datei tut. Mit genügend krimineller Energie, kann der Benutzer das > System benutzen, um dauerhaft die gleichen rechte zu bekommen wie der > Prozess. Das ist eine ziemlich theoretische Gefahr: in diesem Fall müsste sich der Hacker auf dem Server einloggen, was voraus setzt, dass er die Zugangsdaten kennt. Damit könnte er aber auf dem Server sowieso tun und lassen, was er will… > 3.) das Umgehen Löschen nach dem Ausführen, klingt auch aus > unterschiedlichen Gründen fehleranfällig. Was passiert, wenn das Löschen > nicht klappt, weil das Script abbricht? Nach 10 Sekunden kommt dann der > nächste Bash lauf und so weiter... Schon mal was von Fehlerbehandlung gehört? Die soll es angeblich auch in der bash geben ;-) > Was wenn das Scipt durchläuft aber einen Fehler macht, kann ich das > Script irgendwo zu debug zwecken sehen? Weißt du, was man unter "logging" versteht? > Denn Teil verstehe ich nicht, meinst Du das Bash Script das alle 10 > Sekunden pollt, oder das Script mit den Befehlen welches Dir, der > post-receive hook erzeugt oder was ganz anderes. Nochmal zum mitmeißeln: - Das Skript, um das es hier geht, läuft in einer unendlichen Schleife und guckt alle 10 sec nach, ob was zu tun ist - Dieses Skript soll automatisch starten, wenn eine sftp- oder ssh-Verbindung aufgebaut wird und terminieren, wenn die letzte Verbindung abgebrochen wurde. - Das Signal, dass was zu tun ist, ist die Datei mit den auszuführenden Kommandos, die der git-Hook schreibt. Damit habe ich das ssh-/sftp-Login als Authentifizierungsprozess vor die ganze Sache gestellt. Damit sollten keine über das übliche Maß hinaus gehenden Sicherheitsprobleme entstehen.
Imonbln schrieb: > systemd/User https://wiki.archlinux.org/title/systemd/User) vielleicht, > dort ein oneshot bauen der wird genau einmal gestartet, wenn sich der > Benutzer einloggt. Das ist ein guter Tipp. Jetzt muss ich nur noch herausbekommen, wie man das 10-sec-Skript dort verdrahten muss.
Hm, mir scheint, systemd/User ist für dieses Problemchen etwas überdimensioniert. ps kann den User-Namen ausgeben – damit kann das 10-sec-Skript feststellen, wieviele Prozesse unter diesem Namen noch laufen. Wenn es nur noch einer – er selbst – ist, dann verabschiedet es sich und das Terminierungsproblem ist gelöst. Starten kann man das Skript aus ~/.bash_profile heraus. Die wird bei jedem Login über ssh abgearbeitet. Das Skript stellt fest, ob schon eine Instanz läuft. Wenn nein, schickt es sich selbst in den Hintergrund und wenn ja, terminiert es stillschweigend. Die Hintergrund-Instanz schreibt ihre PID in eine Datei in /tmp – dort können weitere Instanzen nachsehen (und mit ps prüfen, ob ein Prozess mit der dort vermerkten PID existiert). Jetzt weiß ich nur noch nicht, ob der automatische Start auch mit sftp funktioniert.
Taucher schrieb: > MaWin schrieb: >> Ich mache das deploy direkt aus dem post-update hook heraus. > > Das hat nur den Nachteil, dass dann die git-Verbindung so lange gesperrt > ist, bis das Generierungsskript fertig ist. Das dauert in meinem Fall. > > Ich hatte auch schon versucht, aus dem git-Hook heraus das Skript > einfach in den Hintergrund zu schieben, das hat aber aus unklaren > Gründen nicht funktioniert. Das solltest du dir weiter anschauen. Hast du schonmal versucht das Skript mit nohup in den Hintergrund zu schicken?
JE schrieb: > Das solltest du dir weiter anschauen. Hast du schonmal versucht das > Skript mit nohup in den Hintergrund zu schicken? Das habe ich eben probiert – funktioniert leider nicht, egal ob per
1 | nohub skript </dev/null &>/dev/null & |
oder mit
1 | nohub bash -c skript </dev/null &>/dev/null & |
Ist es vielleicht mal wieder Systemd? https://www.freedesktop.org/software/systemd/man/logind.conf.html#KillUserProcesses=
Taucher schrieb: > Das habe ich eben probiert – funktioniert leider nicht, egal ob per Hast du mehr Infos was nicht geht? Du könntest die Ausgabe der Scripte auch mal auffangen. Statt bash -c macht bash -lic oft viel besser.
JE schrieb: > Hast du mehr Infos was nicht geht? Ich sehe nur mit ps, dass das Skript nach dem git push nicht läuft. > Statt bash -c macht bash -lic oft viel besser. Die -i-Option macht die Shell interaktiv – das ist das Skript aber definitiv nicht.
🐧 DPA 🐧 schrieb: > Ist es vielleicht mal wieder Systemd? > > https://www.freedesktop.org/software/systemd/man/logind.conf.html#KillUserProcesses= Das ist ein guter Tipp, danke.
Taucher schrieb: >> Statt bash -c macht bash -lic oft viel besser. > > Die -i-Option macht die Shell interaktiv – das ist das Skript aber > definitiv nicht. Das -i stellt der Shell auch einen STDIN zur Verfügung und führt andere Login Scripte aus, eventuell benötigt dein Script das. Das -l führt die Login Scripte aus - vielleicht wird dort ein Pfad gesetzt der benötigt wird. Solange wir nicht sehen was die Scripte ausgeben ist das aber alles rumraterei. Ersetze doch mal die ganzen /dev/null Umleitungen durch >> /tmp/logfile.txt 2>&1 und schau nach was angemeckert wird. Ich bin mir bei den Git-Hooks jetzt nicht ganz sicher - aber sind die Scripte ausführbar?
JE schrieb: > Ich bin mir bei den Git-Hooks jetzt nicht ganz sicher - aber sind die > Scripte ausführbar? Die Skripte sind alle ausführbar. Wenn ich nach einem git push das Generierungsskript zu Fuß anwerfe, läuft alles durch und die Änderungen greifen.
Taucher schrieb: > ps kann den User-Namen ausgeben – damit kann das 10-sec-Skript > feststellen, wieviele Prozesse unter diesem Namen noch laufen. Wenn es > nur noch einer – er selbst – ist, dann verabschiedet es sich und das > Terminierungsproblem ist gelöst. Ich gebe Zehn von Zehn Frickelpunkten
Etwas OT, aber ich mußte sofort an einen alten Comic denken. In etwa so: http://ronald-wagner.de/tauchwi.gif
Oh sorry, oben ist mir die Formatierung kaputt gegangen ``` /Pfad/zum/Script >> /tmp/logfile.txt 2>&1 ``` schreibt die die Ausgabe des Scipts in eine Datei.
in meinem früheren leben habe ich das deployment über gitlab-ci in zwei branches (dev, prod) durchgeführt. bei einem push in den jeweiligen branch wurde ein deploy script (normales shell script) ausgeführt. die anzahl der auszuführenden scripts ist dabei variabel.
Taucher schrieb: > JE schrieb: >> Das solltest du dir weiter anschauen. Hast du schonmal versucht das >> Skript mit nohup in den Hintergrund zu schicken? > > Das habe ich eben probiert – funktioniert leider nicht, egal ob per > nohub skript </dev/null &>/dev/null & > oder mit nohub bash -c skript </dev/null &>/dev/null & Es heißt ja auch "nohup" mit P und nicht mit B. Wie in "no hangup".
Nop schrieb: > Es heißt ja auch "nohup" mit P und nicht mit B. Wie in "no hangup". Oh, das war die Gurke… Jetzt läuft das Generierungsskrip aus dem git-hook heraus, danke für den Hinweis. Damit ist mein 10-sec-Skript überflüssig. Dank an alle, die Tipps geliefert haben.
Taucher schrieb: > Jetzt würde ich gerne dieses Skript automatisch starten, wenn das > home-Verzeichnis auf dem Server per sftp oder per ssh geöffnet wird. Das > Skript soll aber nur genau einmal laufen und sich verabschieden, wenn > niemand mehr eingeloggt ist. Ich hab nicht so richtig verstanden, was du willst. Wenn sich jemand einlogt, soll ein Skript ausgeführt werden, das einen Docker-Image erstellt? Und wenn sich der letzte auslogt, soll das Skript gekillt werden? Oder was meinst du mit "sich verabschieden"? > Ich habe dazu ein bash-Skript geschrieben, das alle 10 sec prüft, ob > eine vom git-hook post-receive geschriebene Datei existiert und ggf. die > darin enthaltenen Kommandos ausführt und die Datei löscht. Das könnte man vermutlich mit inotifywait geschickter machen. Damit kannst du auf Änderungen warten, ohne sie explizit abfragen zu müssen.
:
Bearbeitet durch User
Ich heb einen Server, der schickt mir eine eMail beim Login per ssh, das mache ich über die Datei /etc/profile, da habe ich folgendes angehängt:
1 | if [ -n "$SSH_CLIENT" ]; then |
2 | ip=`echo $SSH_CONNECTION | cut -d " " -f 1` |
3 | name=`nslookup $ip | grep "name =" | cut -d " " -f 3` |
4 | echo -e "subject: LOGIN auf BLABLA\n\nLOGIN auf BLABLA - von $USER @ $ip - $name - am $(date -d today +\%d.\%m\.%Y) $(date -d today +\%H:\%M:\%S)" | sendmail email@domain.domain |
5 | fi |
Müsste auch für sftp gehen und dann kein sendmail sondern das script starten
Rolf M. schrieb: > Das könnte man vermutlich mit inotifywait geschickter machen. Oder incrond... ;-) Aber, sorry, für mich hört sich der ganze Anwendungsfall ein bisschen... komisch an, wie dreimal um die Ecke gedacht und sich am Ende dann doch sehenden Auges in beide Füße, ein Knie und ein Ohr geschossen. Wird aber wohl an mir liegen...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.