Pour atteindre un réseau isolé, j'utilise un proxy ssh -D
socks .
Afin d'éviter d'avoir à taper les détails chaque fois que je les ai ajoutés à ~/.ssh/config
:
$ awk '/Host socks-proxy/' RS= ~/.ssh/config
Host socks-proxy
Hostname pcit
BatchMode yes
RequestTTY no
Compression yes
DynamicForward localhost:9118
J'ai ensuite créé un fichier de définition d'unité de service utilisateur 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
Je laisse le démon recharger les nouvelles définitions de service, j'active le nouveau service, le démarre, vérifie son état et vérifie qu'il écoute:
$ 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
Cela fonctionne comme prévu. Ensuite, je voulais éviter d'avoir à démarrer manuellement le service ou à l'exécuter de manière permanente avec autossh , en utilisant l' activation de socket systemd pour la (re) génération à la demande. Cela n'a pas fonctionné, je pense que (ma version de) ne peut pas recevoir les descripteurs de fichiers socket.ssh
J'ai trouvé la documentation ( 1 , 2 ), et un exemple pour l' utilisation du systemd-socket-proxyd
-Outil pour créer 2 services « wrapper », un « service » et une « prise »:
$ 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
Cela semble fonctionner jusqu'à ce qu'il ssh
meure ou soit tué. Ensuite, il ne réapparaîtra pas lors de la prochaine tentative de connexion.
Des questions:
- / Usr / bin / ssh ne peut-il vraiment pas accepter les sockets passés par systemd? Ou seulement des versions plus récentes? Le mien est celui de up2date Debian 8.9 .
- Seules les unités de racine peuvent-elles utiliser l'
BindTodevice
option? - Pourquoi mon service proxy ne réapparaît-il pas correctement lors de la première nouvelle connexion après la mort de l'ancien tunnel?
- Est-ce la bonne façon de configurer un "proxy ssh socks à la demande"? Si non, comment procédez-vous?
autossh
devrait prendre soin de se reconnecter en cas d'échec de la connexion (bien que ce ne soit pas le système).autossh
.Réponses:
Je pense que ce n'est pas trop surprenant, compte tenu:
Les instances utilisateur systemd sont généralement assez isolées et ne peuvent par exemple pas communiquer avec l'instance pid-0 principale. Des choses comme dépendre des unités système des fichiers d'unité utilisateur ne sont pas possibles.
La documentation des
BindToDevice
mentions:En raison de la restriction susmentionnée, nous pouvons impliquer que l'option ne fonctionne pas à partir des instances utilisateur de systemd.
Si je comprends bien, la chaîne des événements est la suivante:
SocksProxyHelper.socket
a démarré.SocksProxyHelper.service
.SocksProxyHelper.service
, systemd démarre égalementSocksProxy.service
.systemd-socket-proxyd
accepte le socket systemd et transmet ses données àssh
.ssh
meurt ou est tué.SocksProxy.service
dans un état inactif, mais ne fait rien.SocksProxyHelper.service
continue de fonctionner et d'accepter les connexions, mais ne parvient pas à s'y connecterssh
, car il n'est plus en cours d'exécution.La solution est d'ajouter
BindsTo=SocksProxy.service
àSocksProxyHelper.service
. Citant sa documentation (soulignement ajouté):Il n'y a probablement pas de "bonne façon". Cette méthode a ses avantages (tout étant "à la demande") et ses inconvénients (dépendance à systemd, la première connexion ne passe pas car ssh n'a pas encore commencé à écouter). Peut-être que l'implémentation de la prise en charge de l'activation de socket systemd dans autossh serait une meilleure solution.
la source
BindsTo=SocksProxy.service
à la section Unité du fichier~/.config/systemd/user/SocksProxyHelper.service
, après laAfter=SocksProxy.service
ligne. Le redémarrage manuel du service SocksProxy n'est plus nécessaire, lorsque SSH meurt / obtient_killed. Existe-t-il un moyen pour systemd de "maintenir" la connexion initiale, afin qu'elle n'obtienne pas de réinitialisation TCP?$LISTEN_FDS
sans ajouter de dépendancesd_listen_fds()
, il peut donc être difficile à vendre, mais pas trop difficile.