Чтобы добраться до изолированной сети, я использую ssh -D
socks proxy .
Чтобы избежать необходимости вводить детали каждый раз, я добавляю их в ~/.ssh/config
:
$ awk '/Host socks-proxy/' RS= ~/.ssh/config
Host socks-proxy
Hostname pcit
BatchMode yes
RequestTTY no
Compression yes
DynamicForward localhost:9118
Затем я создал файл определения модуля обслуживания 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
Я позволил демону перезагрузить определения новых сервисов, включил новый сервис, запустил его, проверил его статус и проверил, что он прослушивает:
$ 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
Это работает как задумано. Затем я хотел избежать необходимости вручную запускать службу или постоянно запускать ее с помощью autossh , используя systemd socket-активацию для порождения по требованию (повторного). Это не сработало, я думаю (моя версия) ssh
не может получить дескрипторы файлов сокетов.
Я нашел документацию ( 1 , 2 ) и пример использования systemd-socket-proxyd
-tool для создания 2 сервисов «обертки», «сервиса» и «сокета»:
$ 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
Это не похоже , чтобы работать, пока ssh
умирает или погибает. Тогда он не будет вновь появляться при следующей попытке подключения, когда это необходимо.
Вопросов:
- Может ли / usr / bin / ssh действительно не принимать системные сокеты? Или только более новые версии? Мой из up2date Debian 8.9 .
- Только единицы root могут использовать эту
BindTodevice
опцию? - Почему мой прокси-сервер не восстанавливается правильно при первом новом подключении после того, как старый туннель умирает?
- Это правильный способ настроить «прокси ssh socks по требованию»? Если нет, то как ты это делаешь?
autossh
следует позаботиться о повторном подключении в случае сбоя подключения (хотя это не системный путь).autossh
.Ответы:
Я думаю, что это не так уж удивительно, учитывая:
Пользовательские экземпляры systemd обычно довольно изолированы и, например, не могут взаимодействовать с основным экземпляром pid-0. Такие вещи, как зависимость от системных модулей из файлов пользовательских модулей, невозможны.
Документация для
BindToDevice
упоминаний:Из-за вышеупомянутого ограничения мы можем подразумевать, что опция не работает с пользовательскими экземплярами systemd.
Как я понимаю, цепочка событий выглядит следующим образом:
SocksProxyHelper.socket
запущенSocksProxyHelper.service
.SocksProxyHelper.service
, systemd также запускаетсяSocksProxy.service
.systemd-socket-proxyd
принимает сокет systemd и пересылает свои данные вssh
.ssh
умирает или убит.SocksProxy.service
в неактивное состояние, но ничего не делает.SocksProxyHelper.service
продолжает работать и принимать подключения, но не может подключитьсяssh
, так как он больше не работает.Исправление должно добавить
BindsTo=SocksProxy.service
кSocksProxyHelper.service
. Цитирую свою документацию (выделение добавлено):Там, вероятно, нет "правильного пути". У этого метода есть свои преимущества (все по требованию) и недостатки (зависимость от systemd, первое соединение не проходит, потому что ssh еще не начал слушать). Возможно, реализация поддержки активации сокетов systemd в autossh была бы лучшим решением.
источник
BindsTo=SocksProxy.service
в раздел Unit файла~/.config/systemd/user/SocksProxyHelper.service
, послеAfter=SocksProxy.service
строки. Перезапуск службы SocksProxy вручную больше не требуется, когда SSH умирает / gets_killed. Есть ли способ для systemd «удерживать» исходное соединение, чтобы он не получал сброс TCP?$LISTEN_FDS
без добавления зависимостиsd_listen_fds()
, так что это может быть трудно продать, но не слишком сложно.