Yuva etkinleştirme özelliğine sahip sistemd kullanıcı birimleri aracılığıyla isteğe bağlı SSH Socks proxy'si istendiği gibi yeniden başlamıyor


14

Yalıtılmış bir ağa ulaşmak için -D .

Her eklediğimde ayrıntıları yazmak zorunda kalmamak için ~/.ssh/config:

$ awk '/Host socks-proxy/' RS= ~/.ssh/config
Host socks-proxy
  Hostname pcit
  BatchMode yes
  RequestTTY no
  Compression yes
  DynamicForward localhost:9118

Sonra bir servis birimi tanım dosyası oluşturdum:

$ cat ~/.config/systemd/user/SocksProxy.service 
[Unit]
Description=SocksProxy Over Bridge Host

[Service]
ExecStart=/usr/bin/ssh -Nk socks-proxy

[Install]
WantedBy=default.target

Daemon'un yeni hizmet tanımlarını yeniden yüklemesine, yeni hizmeti etkinleştirmesine, başlatmasına, durumunu kontrol etmesine ve dinlediğini doğrulamasına izin verdim:

$ 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/user@1000.service/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

Bu amaçlandığı gibi çalışır. Sonra el ile hizmetini başlatmak zorunda, ya da kalıcı olarak çalışan önlemek istediği kullanarak, on-demand yumurtlama (yeniden) için. Bu işe yaramadı, sanırım (benim sürümüm) sshsoket dosya tanımlayıcıları alamaz.

Ben belgeleri ( 1 , 2 ) ve 2 "sarmalayıcı" hizmetleri, bir "hizmet" ve bir "soket" oluşturmak için -tool kullanmak için bir örneksystemd-socket-proxyd buldum:

$ 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

Bu gibi görünüyor kadar işe sshölür veya öldürülür. O zaman bir sonraki bağlantı denemesinde yeniden doğmayacaktır.

Sorular:

  1. / Usr / bin / ssh gerçekten sistemden geçirilen soketleri kabul edemez mi? Yoksa sadece daha yeni sürümler mi? Benimki up2date Debian 8.9'dan .
  2. Yalnızca kök birimleri BindTodeviceseçeneği kullanabilir mi?
  3. Eski tünel öldükten sonra proxy hizmetim neden ilk yeni bağlantıda doğru şekilde yeniden görüntülenmiyor?
  4. Bu bir "isteğe bağlı ssh çorap vekili" kurmanın doğru yolu mu? Değilse, nasıl yapıyorsunuz?

autosshbağlantının başarısız olması durumunda (sistem yolu olmasa da) yeniden bağlanmaya dikkat etmelidir.
Jakuje

@ Jakuje: Yorum için teşekkürler, ancak bağlantının kalıcı olmasını istemiyorum. Bunu kullandığımda ortaya çıkmasını istiyorum ve daha sonra (ideal olarak x dakika içinde gönderilen hiçbir veri zaman aşımından sonra) kendi kendine sonlandır. Ayrıca, önceki çözümüm kullanıldı autossh.
Alex Stragies

Yanıtlar:


4
  • / Usr / bin / ssh gerçekten sistemden geçirilen soketleri kabul edemez mi?

Bence bu hiç de şaşırtıcı değil:

  • OpenSSH bir OpenBSD projesidir
  • systemd yalnızca Linux çekirdeğini destekler
  • systemd desteğinin isteğe bağlı / derleme zamanı bağımlılığı olarak OpenSSH'ye açıkça eklenmesi gerekir, bu nedenle büyük olasılıkla zor bir satış olacaktır.

  • Yalnızca kök birimleri BindTodeviceseçeneği kullanabilir mi?

Kullanıcı systemd örnekleri genellikle oldukça yalıtılmış olup, örneğin ana pid-0 örneği ile iletişim kuramaz. Kullanıcı birimi dosyalarından sistem birimlerine bağlı gibi şeyler mümkün değildir.

BindToDeviceBahsedilen belgeler :

Bu parametrenin ayarlanmasının, cihaza ek bağımlılıkların eklenmesine neden olabileceğini unutmayın (yukarıya bakın).

Yukarıda belirtilen kısıtlama nedeniyle, seçeneğin kullanıcı systemd örneklerinden çalışmadığını ima edebiliriz.


  • Eski tünel öldükten sonra proxy hizmetim neden ilk yeni bağlantıda doğru şekilde yeniden görüntülenmiyor?

Anladığım kadarıyla, olaylar zinciri aşağıdaki gibidir:

  • SocksProxyHelper.socket Başladı.
  • Bir SOCKS istemcisi localhost'a bağlanır: 8118.
  • systemd başlar SocksProxyHelper.service.
  • Bağımlılığı olarak SocksProxyHelper.service, systemd de başlar SocksProxy.service.
  • systemd-socket-proxydsystemd soketini kabul eder ve verilerini adresine iletir ssh.
  • ssh ölür ya da öldürülür.
  • systemd fark eder ve SocksProxy.serviceetkin olmayan bir duruma geçer, ancak hiçbir şey yapmaz.
  • SocksProxyHelper.serviceçalışmaya devam ediyor ve bağlantıları kabul ediyor, ancak sshartık çalışmadığı için bağlanamıyor .

Düzeltme eklemek BindsTo=SocksProxy.serviceiçin SocksProxyHelper.service. Belgelerinden alıntı yapma (vurgu eklendi):

Gereksinimlere bağımlılıkları yapılandırır, stile çok benzer Requires=. Ancak bu bağımlılık türü güçlüdür: etkisiyle eklenmesi halinde Requires=buna beyan bağlı birim durdurulursa, bu birim de durdurulacak . Bu, aniden etkin olmayan duruma giren başka bir birime bağlı bir birimin de durdurulacağı anlamına gelir. Birimler aniden, beklenmedik bir şekilde farklı nedenlerden dolayı etkin olmayan duruma girebilir: bir servis biriminin ana süreci kendi seçimine bağlı olarak sona erebilir, bir cihaz biriminin destek cihazı takılı olmayabilir veya bir montaj ünitesinin montaj noktası sökülmemiş olabilir. sistem ve servis yöneticisi.

After=Aynı ünite ile birlikte kullanıldığında davranışı BindsTo=daha da güçlüdür. Bu durumda, bu birimin de aktif durumda olması için kesinlikle bağlı olan ünitenin aktif durumda olması gerekir . (Örneğin bu aniden inaktif duruma girdiği başka bir birime bağlı bir birim anlamına gelir, ama aynı zamanda nedeniyle başarısız koşul check atlanır alır başka bir birime bağlı olduğu bir değil sadece ConditionPathExists=, ConditionPathIsSymbolicLink=onu gerektiği, durdurulacak - aşağıya bakınız, ...) çalışıyor. Dolayısıyla, birçok durumda bu birleştirmek için en iyisi BindsTo=ile After=.


  • Bu bir "isteğe bağlı ssh çorap vekili" kurmanın doğru yolu mu? Değilse, nasıl yapıyorsunuz?

Muhtemelen "doğru yol" yoktur. Bu yöntemin avantajları (her şey "isteğe bağlı") ve dezavantajları (sistemd'e bağımlılık, ssh henüz dinlemeye başlamadığı için ilk bağlantı gerçekleşmiyor). Belki de autossh'de systemd soketi etkinleştirme desteğinin uygulanması daha iyi bir çözüm olacaktır.


BindsTo=SocksProxy.serviceSatırdan ~/.config/systemd/user/SocksProxyHelper.servicesonra dosyanın Birim bölümüne ekledim After=SocksProxy.service. SSH öldüğünde / alındığında artık SocksProxy Hizmetini manuel olarak yeniden başlatmak artık gerekli değildir. Systemd'in TCP bağlantısını sıfırlamaması için ilk bağlantıyı "tutmasının" bir yolu var mı?
Alex Stragies

@Vladimir Panteleev bir noktaya açıklığa kavuşturmak istiyorum: sistemd soketi aktivasyonu desteği, $LISTEN_FDSbağımlılık olmadan ayrıştırılarak nispeten kolayca uygulanabilir sd_listen_fds(), bu yüzden hala zor bir satış olabilir, ancak çok zor değil.
Amir
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.