Aby połączyć się z izolowaną siecią, używam proxy ssh -D
socks .
Aby uniknąć konieczności wpisywania szczegółów za każdym razem, gdy dodawałem je do ~/.ssh/config
:
$ awk '/Host socks-proxy/' RS= ~/.ssh/config
Host socks-proxy
Hostname pcit
BatchMode yes
RequestTTY no
Compression yes
DynamicForward localhost:9118
Następnie utworzyłem plik definicji jednostki serwisowej użytkownika systemd :
$ cat ~/.config/systemd/user/SocksProxy.service
[Unit]
Description=SocksProxy Over Bridge Host
[Service]
ExecStart=/usr/bin/ssh -Nk socks-proxy
[Install]
WantedBy=default.target
Pozwoliłem demonowi ponownie załadować nowe definicje usługi, włączyłem nową usługę, uruchomiłem ją, sprawdziłem jej status i zweryfikowałem, że nasłuchuje:
$ systemctl --user daemon-reload
$ systemctl --user list-unit-files | grep SocksP
SocksProxy.service disabled
$ systemctl --user enable SocksProxy.service
Created symlink from ~/.config/systemd/user/default.target.wants/SocksProxy.service to ~/.config/systemd/user/SocksProxy.service.
$ systemctl --user start SocksProxy.service
$ systemctl --user status SocksProxy.service
● SocksProxy.service - SocksProxy Over Bridge Host
Loaded: loaded (/home/alex/.config/systemd/user/SocksProxy.service; enabled)
Active: active (running) since Thu 2017-08-03 10:45:29 CEST; 2s ago
Main PID: 26490 (ssh)
CGroup: /user.slice/user-1000.slice/[email protected]/SocksProxy.service
└─26490 /usr/bin/ssh -Nk socks-proxy
$ netstat -tnlp | grep 118
tcp 0 0 127.0.0.1:9118 0.0.0.0:* LISTEN
tcp6 0 0 ::1:9118 :::* LISTEN
Działa to zgodnie z przeznaczeniem. Następnie chciałem uniknąć konieczności ręcznego uruchamiania usługi lub ciągłego uruchamiania jej z autossh , używając systemowej aktywacji gniazd do (ponownego) odradzania na żądanie. To nie działało, myślę, że (moja wersja) ssh
nie może odbierać deskryptorów plików gniazd.
Znalazłem dokumentację ( 1 , 2 ) i przykład użycia systemd-socket-proxyd
-tool do utworzenia 2 usług „otoki”, „usługi” i „gniazda”:
$ cat ~/.config/systemd/user/SocksProxyHelper.socket
[Unit]
Description=On Demand Socks proxy into Work
[Socket]
ListenStream=8118
#BindToDevice=lo
#Accept=yes
[Install]
WantedBy=sockets.target
$ cat ~/.config/systemd/user/SocksProxyHelper.service
[Unit]
Description=On demand Work Socks tunnel
After=network.target SocksProxyHelper.socket
Requires=SocksProxyHelper.socket SocksProxy.service
After=SocksProxy.service
[Service]
#Type=simple
#Accept=false
ExecStart=/lib/systemd/systemd-socket-proxyd 127.0.0.1:9118
TimeoutStopSec=5
[Install]
WantedBy=multi-user.target
$ systemctl --user daemon-reload
To wydaje się działać, dopóki nie ssh
umrze lub nie zostanie zabity. Wtedy nie odrodzi się przy kolejnej próbie połączenia, kiedy powinna.
Pytania:
- Czy / usr / bin / ssh naprawdę nie akceptuje gniazd przekazywanych przez system? Czy tylko nowsze wersje? Mój jest tym z wersji Debian 8.9 .
- Czy tylko jednostki root mogą korzystać z tej
BindTodevice
opcji? - Dlaczego moja usługa proxy nie odradza się poprawnie przy pierwszym nowym połączeniu po śmierci starego tunelu?
- Czy to właściwy sposób na skonfigurowanie „proxy proxy socks na żądanie”? Jeśli nie, jak to robisz?
autossh
powinien zająć się ponownym połączeniem w przypadku awarii połączenia (choć nie jest to sposób systemowy).autossh
.Odpowiedzi:
Myślę, że nie jest to zbyt zaskakujące, biorąc pod uwagę:
Wystąpienia systemowe użytkownika są na ogół dość odizolowane i np. Nie mogą komunikować się z głównym wystąpieniem pid-0. Rzeczy takie jak zależność od jednostek systemowych z plików jednostek użytkownika nie są możliwe.
Dokumentacja dla
BindToDevice
wzmianek:Z powodu wyżej wspomnianego ograniczenia możemy sugerować, że opcja nie działa z wystąpień systemowych użytkownika.
Jak rozumiem, łańcuch wydarzeń jest następujący:
SocksProxyHelper.socket
jest rozpoczęty.SocksProxyHelper.service
.SocksProxyHelper.service
uruchamia się także systemdSocksProxy.service
.systemd-socket-proxyd
akceptuje gniazdo systemowe i przesyła dane dossh
.ssh
umiera lub zostaje zabity.SocksProxy.service
w stan nieaktywny, ale nic nie robi.SocksProxyHelper.service
nadal działa i akceptuje połączenia, ale nie nawiązuje połączeniassh
, ponieważ nie jest już uruchomiony.Poprawka polega na dodaniu
BindsTo=SocksProxy.service
doSocksProxyHelper.service
. Cytując swoją dokumentację (wyróżnienie dodane):Prawdopodobnie nie ma „właściwej drogi”. Ta metoda ma swoje zalety (wszystkie są „na żądanie”) i wady (zależność od systemd, pierwsze połączenie nie przechodzi, ponieważ ssh jeszcze nie zaczął nasłuchiwać). Być może lepszym rozwiązaniem byłoby wdrożenie obsługi aktywacji gniazd systemowych w autossh.
źródło
BindsTo=SocksProxy.service
do sekcji Unit pliku~/.config/systemd/user/SocksProxyHelper.service
, poAfter=SocksProxy.service
wierszu. Ręczne ponowne uruchomienie usługi SocksProxy nie jest już wymagane, gdy SSH umrze / zostanie zabity. Czy istnieje sposób, aby systemd „wstrzymał” połączenie początkowe, aby nie otrzymał resetowania TCP?$LISTEN_FDS
bez dodawania zależnościsd_listen_fds()
, więc może to być trudna sprzedaż, ale niezbyt trudna.