Podsumowanie : Próbuję dowiedzieć się, dlaczego moja sesja tmux umiera, kiedy rozłączam się z ssh
Szczegóły :
Mam tmux zainstalowany na systemie Arch Linux. Kiedy rozpoczynam sesję tmux, mogę się od niej odłączyć, a następnie dołączyć ponownie, gdy sesja ssh jest aktywna. Ale jeśli zakończę moją sesję ssh, sesja tmux zostanie zabita.
Wiem, że to nie jest normalne zachowanie, ponieważ mam inny system, w którym sesja tmux kontynuuje działanie, nawet jeśli sesja ssh jest zakończona i mogę nawiązać połączenie z sesją tmux po ustanowieniu nowego połączenia ssh. System, który ma problem i ten, który działa poprawnie, ma bardzo podobne konfiguracje, więc nie jestem pewien, co sprawdzić.
Korzystam z wersji Tmux 1.9a. System, który ma problem (dla którego mam dostęp do roota) ma wersję jądra Linuksa 3.17.4-1, a system, który działa poprawnie, ma wersję jądra 3.16.4-1-ARCH (nie mam roota na tym system). Wątpię jednak, aby źródłem problemu była wersja jądra, zauważyłem tylko jedną różnicę.
Pomyślałem, że zapytam, czy ktoś widział podobny problem i wie o możliwym rozwiązaniu.
Dokładne kroki prowadzące do problemu to:
- ssh do maszyny
- uruchom,
tmux
aby uruchomić tmux ctrl-B D
oderwać (w tym momencie mogłem ponownie się połączyćtmux attach
- zamknij sesję ssh (w tym momencie sesja tmux została zabita, mogłem to zaobserwować, gdy jestem zalogowany jako root w innym terminalu)
- połącz się ponownie z ssh i uruchom,
tmux attach
a dostaję komunikatno sessions
itmux ls
powracamfailed to connect to server: Connection refused
. Ma to sens, ponieważ serw nie działa. Nie ma dla mnie sensu, dlaczego zostaje zabity w kroku 4, kiedy rozłączam się z sesją ssh.
dane śledzenia:
W odpowiedzi na jeden z komentarzy użyłem strace, aby zobaczyć, jakie systemy nazywają proces serwera tmux. Wygląda na to, że kiedy kończę sesję ssh (przez pisanie exit
lub za pomocą ctrl-d
), proces tmux zostaje zabity. Oto fragment końcowej części wyniku strace.
poll([{fd=4, events=POLLIN}, {fd=11, events=POLLIN}, {fd=6, events=POLLIN}], 3, 424) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=1, si_uid=0} ---
sendto(3, "\17", 1, 0, NULL, 0) = 1
+++ killed by SIGKILL +++
Porównałem to z innym systemem, w którym tmux działa poprawnie i na tym systemie proces tmux kontynuuje działanie nawet po wyjściu z niego. Wydaje się więc, że główną przyczyną jest zakończenie procesu tmux po zamknięciu sesji ssh. Będę musiał poświęcić trochę czasu na rozwiązanie tego problemu, aby dowiedzieć się, dlaczego, ale pomyślałem, że zaktualizuję moje pytanie, ponieważ sugestia śledzenia była przydatna.
Odpowiedzi:
Teoria
Niektóre systemy init, w tym systemd, zapewniają funkcję zabijania wszystkich procesów należących do usługi. Usługa zazwyczaj uruchamia pojedynczy proces, który tworzy więcej procesów przez rozwidlenie i te procesy mogą to zrobić. Wszystkie takie procesy są zwykle uważane za część usługi. W systemd odbywa się to za pomocą cgroups .
W systemd wszystkie procesy należące do usługi są zabijane, gdy usługa jest domyślnie zatrzymana. Serwer SSH jest oczywiście częścią usługi. Gdy łączysz się z serwerem, serwer SSH zwykle rozwidla się, a nowy proces obsługuje sesję SSH. Po przejściu przez proces sesji SSH lub jej potomków uruchamiane są inne procesy po stronie serwera, w tym ekran lub tmux .
Aktywacja trybu Kill i gniazda
Domyślne zachowanie można zmienić za pomocą
KillMode
dyrektywy. Projekt nadrzędny nie zawiera.service
plików AFAIK, więc różnią się one w zależności od dystrybucji. Istnieją zazwyczaj dwa sposoby włączenia SSH w systemie. Jednym z nich jest klasyk,ssh.service
który utrzymuje długo działający demon SSH nasłuchujący w sieci. Drugi polega na aktywacji gniazda obsługiwanej przez to,ssh.socket
które z kolei się uruchamia,[email protected]
które działa tylko dla jednej sesji SSH.Rozwiązania
Jeśli procesy zostaną zabite pod koniec sesji, możliwe, że używasz aktywacji gniazda i zostanie zabity przez systemd, gdy zauważy, że proces sesji SSH zakończył się. W takim przypadku istnieją dwa rozwiązania. Jednym z nich jest unikanie aktywacji gniazda za pomocą
ssh.service
zamiastssh.socket
. Drugim jest ustawienieKillMode=process
wService
sekcji[email protected]
.To
KillMode=process
ustawienie może być również przydatne w przypadku klasycznegossh.service
, ponieważ pozwala uniknąć zabijania procesu sesji SSH lub procesów ekranu lub tmux , gdy serwer zostanie zatrzymany lub zrestartowany.Przyszłe notatki
Ta odpowiedź najwyraźniej zyskała popularność. Chociaż działał on dla OP, może się zdarzyć, że nie zadziała dla kogoś w przyszłości z powodu rozwoju lub konfiguracji systemd-logind . Sprawdź dokumentację dotyczącą sesji logowania, jeśli występują inne zachowania niż opis w tej odpowiedzi.
źródło
init
raczej niżsystemd
. Ale i tak jest nieco inaczej, patrz moje pytanie .Czy używasz systemd z aktywacją gniazda dla SSH?
Jeśli tak, istnieje znany problem . Według zwolenników systemd jest to w rzeczywistości funkcja - systemd zabija wszystkie procesy powstałe w wyniku sesji po jej zakończeniu. (Widzę, że jest to przydatne, ale w GNU
screen
lubtmux
, na pewno , nie chcesz tego ☺ ani w większości innych przypadków, w których użytkownicy mogą oczywiście uruchamiać procesy w tle).Jeśli tak, spróbuj przełączyć się z
sshd.socket
nasshd.service
.źródło
Miałem ten sam problem z tmuxem i ekranem na Ubuntu 16.04 (kde neon). Kiedy sesja ssh została odłączona screen / tmux został zakończony.
krótko mówiąc, systemd zmienił swoje domyślne ustawienie na killuserprocess = yes, więc po opuszczeniu sesji ssh każdy utworzony przez nią proces zostanie zakończony.
Łatwa naprawa (po wielu godzinach próbowania) uruchom screen / tmux za pomocą tego polecenia
Na ekranie
systemd-run --scope --user screen
dla Tmux
systemd-run --scope --user tmux
Możesz utworzyć alias, aby to ułatwić
alias tmux= "systemd-run --scope --user tmux"
źródło
-bash: systemd-run: command not found
naRed Hat Enterprise Linux Server release 6.8 (Santiago)
.Innym rozwiązaniem, aby to, co nie wymaga przejścia od
sshd.socket
celusshd.service
, jest uruchomienietmux
serwera jako Systemd usługi [0]. W ten sposóbtmux
serwer jest już uruchomiony, gdy SSH do niego, zamiast odradzać się przeztmux
polecenie w SSH, więc nie zostanie zabity.[0] https://wiki.archlinux.org/index.php/tmux#Autostart_with_systemd
źródło
Najlepsza odpowiedź, jaką znalazłem, IMO, znajduje się na stronie Prevent Logoff from Killing tmux Session :
Ta „funkcja” istnieje w
systemd
wcześniej, ale gdysystemd
deweloperzy postanowili dokonać zmiany ustawień domyślnych , aby umożliwić ustawienie zakończenie procesów potomnych momencie wylogowania z sesji.Możesz przywrócić to ustawienie w swoim
logind.conf
(/etc/systemd/logind.conf
):źródło