Para acessar uma rede isolada, eu uso um proxy ssh -D
socks .
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 um arquivo de definição da unidade de serviço systemd-user :
$ cat ~/.config/systemd/user/SocksProxy.service
[Unit]
Description=SocksProxy Over Bridge Host
[Service]
ExecStart=/usr/bin/ssh -Nk socks-proxy
[Install]
WantedBy=default.target
Deixei o daemon recarregar as novas definições de serviço, habilitei o novo serviço, iniciei-o, verifiquei seu status e verifiquei que ele estava ouvindo:
$ 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 manualmente o serviço ou executá-lo permanentemente com autossh , usando a ativação do soquete systemd para a (re) geração sob demanda. Isso não funcionou, acho que (minha versão do) não pode receber descritores de arquivos de soquete.ssh
Encontrei a documentação ( 1 , 2 ) e um exemplo para usar a systemd-socket-proxyd
ferramenta-para criar 2 serviços "wrapper", um "serviço" e um "soquete":
$ 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é ssh
morrer ou ser morto. Em seguida, ele não voltará a aparecer na próxima tentativa de conexão, quando deveria.
Questões:
- O / usr / bin / ssh pode realmente não aceitar soquetes passados pelo systemd? Ou apenas versões mais recentes? A minha é a do up2date Debian 8.9 .
- Apenas unidades de raiz podem usar a
BindTodevice
opção? - Por que meu serviço de proxy não está reaparecendo corretamente na primeira conexão nova após a morte do túnel antigo?
- Essa é a maneira correta de configurar um "proxy sob demanda ssh socks"? Se não, como você faz isso?
autossh
deve se reconectar caso a conexão falhe (embora não seja o caminho do sistema).autossh
.Respostas:
Eu acho que isso não é muito surpreendente, considerando:
As instâncias systemd do usuário geralmente são bastante isoladas e, por exemplo, não podem se comunicar com a instância principal do pid-0. Coisas como depender das unidades do sistema dos arquivos das unidades do usuário não são possíveis.
A documentação para
BindToDevice
menções:Devido à restrição mencionada acima, podemos sugerir que a opção não funciona nas instâncias do usuário systemd.
Pelo que entendi, a cadeia de eventos é a seguinte:
SocksProxyHelper.socket
começou.SocksProxyHelper.service
.SocksProxyHelper.service
, systemd também iniciaSocksProxy.service
.systemd-socket-proxyd
aceita o soquete systemd e encaminha seus dados parassh
.ssh
morre ou é morto.SocksProxy.service
em um estado inativo, mas não faz nada.SocksProxyHelper.service
continua executando e aceitando conexões, mas não consegue se conectarssh
, pois não está mais em execução.A correção é adicionar
BindsTo=SocksProxy.service
aSocksProxyHelper.service
. Citando sua documentação (ênfase adicionada):Provavelmente não há "caminho certo". Este método tem suas vantagens (tudo "sob demanda") e desvantagens (dependência do systemd, a primeira conexão não é concluída porque o ssh ainda não começou a escutar). Talvez implementar o suporte à ativação do soquete systemd no autossh seja uma solução melhor.
fonte
BindsTo=SocksProxy.service
à seção Unidade do arquivo~/.config/systemd/user/SocksProxyHelper.service
, após aAfter=SocksProxy.service
linha. Agora, a reinicialização manual do serviço SocksProxy não é mais necessária, quando o SSH morre / fica_qualificado. Existe uma maneira de o systemd "reter" a conexão inicial, para que ela não seja redefinida como TCP?$LISTEN_FDS
sem adicionar uma dependênciasd_listen_fds()
, por isso ainda pode ser uma venda difícil, mas não muito difícil.