O proxy SSH Socks sob demanda através de unidades de usuário systemd com ativação de soquete não reinicia conforme desejado

14

Para alcançar uma rede isolada, eu uso uma -D < um href="/ perguntas / tagged / socks" class="post-tag" title="mostrar questões marcadas 'meias'"> meias proxy .

Para evitar a necessidade de digitar os detalhes toda vez que os adicionei a ~/.ssh/config :

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

Em seguida, criei uma unidade de serviço arquivo de definição:

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

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

[Install]
WantedBy=default.target

Eu deixei o daemon recarregar as novas definições de serviço, ativar o novo serviço, iniciá-lo, verificar seu status e verificar se está atendendo:

$ 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

Isso funciona como pretendido. Então, eu queria evitar ter que iniciar o serviço manualmente ou executá-lo permanentemente com , usando para (re) desova sob demanda. Isso não funcionou, eu acho (minha versão de) ssh não pode receber descritores de arquivo de soquete.

Eu encontrei a documentação ( 1 , 2 ) e um exemplo para usar o systemd-socket-proxyd -tool para criar dois serviços" wrapper ", um" serviço "e um" socket ":

$ 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

Isso parece funcionar, até que ssh morra ou seja morto. Então, ele não será reproduzido novamente na próxima tentativa de conexão.

Perguntas:

  1. O / usr / bin / ssh não pode aceitar soquetes passados pelo sistema? Ou apenas versões mais recentes? O meu é o um do up2date Debian 8.9 .
  2. Somente unidades de raiz podem usar a opção BindTodevice ?
  3. Por que meu serviço de proxy não reaparece corretamente na primeira nova conexão depois que o antigo túnel morre?
  4. Este é o caminho certo para configurar um "proxy de socks on-demand ssh"? Se não, como você faz isso?
por Alex Stragies 03.08.2017 / 14:38

1 resposta

2
  • Can /usr/bin/ssh really not accept systemd-passed sockets?

Acho que isso não é muito surpreendente, considerando:

  • OpenSSH é um projeto do OpenBSD
  • o systemd suporta apenas o kernel do Linux
  • O suporte ao
  • systemd precisaria ser adicionado explicitamente ao OpenSSH, como uma dependência opcional / de tempo de construção, portanto, provavelmente seria uma tarefa difícil.
  • Can only units of root use the BindTodevice option?

As instâncias do systemd do usuário geralmente são bastante isoladas e, por exemplo, não pode se comunicar com a instância principal pid-0. Coisas como dependendo das unidades do sistema a partir dos arquivos da unidade do usuário não são possíveis.

A documentação para BindToDevice menciona:

Note that setting this parameter might result in additional dependencies to be added to the unit (see above).

Devido à restrição mencionada acima, podemos sugerir que a opção não funciona nas instâncias do sistema do usuário.

  • Why is my proxy service not respawning correctly on first new connection after the old tunnel dies?

Pelo que entendi, a cadeia de eventos é a seguinte:

  • SocksProxyHelper.socket é iniciado.
  • Um cliente SOCKS se conecta ao localhost: 8118.
  • o systemd inicia SocksProxyHelper.service .
  • Como uma dependência de SocksProxyHelper.service , o systemd também inicia SocksProxy.service .
  • systemd-socket-proxyd aceita o soquete systemd e encaminha seus dados para ssh .
  • ssh morre ou é morto.
  • avisos do systemd e coloca SocksProxy.service em um estado inativo, mas não faz nada.
  • SocksProxyHelper.service continua em execução e aceitando conexões, mas não consegue se conectar a ssh , pois não está mais em execução.

A correção é adicionar BindsTo=SocksProxy.service a SocksProxyHelper.service . Citando sua documentação (ênfase adicionada):

Configures requirement dependencies, very similar in style to Requires=. However, this dependency type is stronger: in addition to the effect of Requires= it declares that if the unit bound to is stopped, this unit will be stopped too. This means a unit bound to another unit that suddenly enters inactive state will be stopped too. Units can suddenly, unexpectedly enter inactive state for different reasons: the main process of a service unit might terminate on its own choice, the backing device of a device unit might be unplugged or the mount point of a mount unit might be unmounted without involvement of the system and service manager.

When used in conjunction with After= on the same unit the behaviour of BindsTo= is even stronger. In this case, the unit bound to strictly has to be in active state for this unit to also be in active state. This not only means a unit bound to another unit that suddenly enters inactive state, but also one that is bound to another unit that gets skipped due to a failed condition check (such as ConditionPathExists=, ConditionPathIsSymbolicLink=, … — see below) will be stopped, should it be running. Hence, in many cases it is best to combine BindsTo= with After=.

  • Is this the right way to set-up an "on-demand ssh socks proxy"? If, not, how do you do it?

Provavelmente não há "caminho certo". Este método tem suas vantagens (tudo sendo "on-demand") e desvantagens (dependência do systemd, a primeira conexão não sendo obtida porque o ssh não começou a escutar ainda). Talvez a implementação do suporte à ativação do soquete systemd no autossh seja uma solução melhor.

    
por 22.07.2018 / 06:42