Zapobiegaj uśpieniu maszyny, gdy połączenia SSH są włączone

13

Próbuję oszczędzać energię, przełączając komputery stacjonarne w tryb zawieszenia, gdy są nieaktywne. Ale do wielu komputerów stacjonarnych ma również dostęp przez SSH ich właścicieli. Wdrożono rozwiązanie Wakeonlan, aby umożliwić właścicielom włączenie komputera, ale problem polega na tym, że komputery automatycznie zawieszą się ponownie za 10 minut, nawet jeśli połączenie SSH jest włączone.

Staram się zawrzeć aktywne sesje SSH w definicjach „aktywności”.

Pytanie, czy można to zrobić, ustawiając regułę polkit? Czy można to zrobić, umieszczając skrypt działający przed rzeczywistym zawieszeniem i przerywający go, jeśli zostaną znalezione sesje SSH? Potrzebuję czystego, legalnego sposobu na zrobienie tego. Jeśli nie to, mile widziane są również metody hakerskie.

Obecne naiwne hacky rozwiązanie: edytuj /usr/sbin/pm-suspend:

#check for SSH sessions, and prevent suspending:
if [ "$(who | grep -cv "(:")" -gt 0 ]; then
    echo "SSH session(s) are on. Not suspending."
    exit 1
fi

Służy to celowi. Ale nie wiem, kiedy aktualizacja zastąpi plik /usr/sbin/pm-suspend. Nie wiem też, jak to będzie działać z innymi implementacjami zawieszenia, takimi jak smoking.

Bhavin Doshi
źródło
2
Czy mogę zasugerować użycie grep -cv :0zamiast przejścia wc?
terdon
1
Kolejny pomysł na większą elegancję: możesz porzucić inwokację, [jeśli piszesz if who | grep -qv :0; then(zakładając, że masz POSIX zgodny z grepGNU grep).
David Foerster

Odpowiedzi:

19

Do Ubuntu 14.10 (w oparciu o Upstart)

Zajrzyj pm-action(8)i wyszukaj /etc/pm/sleep.dw dziale „PLIKI”. Jeśli jeden z tych skryptów powróci z niezerowym statusem wyjścia, zawieszenie jest niemożliwe.

Zaktualizowane instrukcje dla przejrzystości:

  1. Utwórz plik /etc/pm/sleep.d/05_ssh_keepawake.

  2. Wpisz shebang ( #!/bin/sh) i kod wymieniony w pytaniu w tym pliku.

  3. Ustaw uprawnienia do wykonywania na nim:

    chmod +x /etc/pm/sleep.d/05_ssh_keepawake
    

Od wersji Ubuntu 15.04 (systemowa)

systemd nie używa pm-utils do zarządzania przechwytami stanu zasilania, ale ma własną infrastrukturę do tego samego celu. Kontrolery wstrzymujące sen nie są już wykonywane podczas snu, ale muszą być ustawione przez działanie, które hamuje sen (patrz 1 ).

W związku z tym musisz dodać polecenia do sesji logowania SSH i wylogowania, które rejestruje inhibitor snu w systemd (np. Via systemd-inhibit(1)), a następnie zwalnia inhibitor. Jeśli ktoś wie, jak podłączyć się do logowania i wylogowania z SSH, powitałbym komentarz lub edycję, abyśmy mogli opracować odpowiednie kroki i polecenia.

Poniższa sekcja jest w toku - używaj jej tylko wtedy, gdy wiesz, co robisz!

Możesz być w stanie napisać jednostkę systemową, /etc/systemd/system/ssh-inhibt-sleep.servicektóra uzależnia się od sleep.targetkorzystania z RequiredByopcji. Jeśli twoja nowa jednostka ulegnie awarii (z niezerowym statusem wyjścia z wywołanego procesu), wykona ona, sleep.targeta tym samym kolejne działanie uśpienia.

[Unit]
Description=Check for running SSH sessions and, if any, inhibit sleep
Before=sleep.target

[Service]
Type=oneshot
ExecStart=/bin/sh -c '! who | grep -qv :0'`

[Install]
RequiredBy=sleep.target

Jak zawsze musisz aktywować systemowe jednostki, aby zaczęły działać:

sudo systemctl enable ssh-inhibt-sleep.service

Aby uzyskać więcej informacji, zobacz systemd.unit(5)i systemd.service(5).

David Foerster
źródło
to nie działa w 18.04. Czy to już nie jest rozwiązanie?
Michael Jarret,
1
@MichaelJarret: Rzeczywiście. Zaktualizowałem swoje pytanie, dodając trochę informacji o sytuacji z systemd.
David Foerster,
Wczoraj próbowałem rozwiązać ten problem, ale nie mogłem zmodyfikować poprzedniego skryptu, aby wykonać zadanie tutaj
Michael Jarret
Nie mogę edytować mojego komentarza, ale wydaje się to również istotne
Michael Jarret
1
@MichaelJarret: Miałem inny pomysł, że możesz spróbować. Zobacz aktualizację mojej odpowiedzi.
David Foerster