Проксі-сервер SSH Socks проксі через системні одиниці користувача з активацією сокета не перезапускається так, як хотілося


14

Для доступу до ізольованої мережі я використовую -D .

Щоб уникнути необхідності вводити деталі кожного разу, коли я додавав їх до ~/.ssh/config:

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

Потім я створив файл визначення модуля обслуговування :

$ 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

Це працює за призначенням. Тоді я хотів би уникнути необхідності вручну запустити службу або запустити його на постійній основі з , використовуючи для на вимогу нересту (повторно). Це не спрацювало, я думаю (моя версія) 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помре або не вб'є. Тоді він не буде повторно створювати ікру при наступній спробі з'єднання, коли слід.

Запитання:

  1. Чи / usr / bin / ssh дійсно не може приймати сокети, передані системою? Або лише новіші версії? Моя - з up2date Debian 8.9 .
  2. Чи можуть лише параметри root використовувати BindTodeviceопцію?
  3. Чому моя служба проксі не відновлюється належним чином при першому новому з'єднанні після відмирання старого тунелю?
  4. Це правильний спосіб налаштувати проксі-проксі-шкарпетки "на вимогу"? Якщо ні, то як це зробити?

autosshслід подбати про повторне підключення у випадку збою (хоча це не системний шлях).
Jakuje

@Jakuje: Thx для коментаря, але я не хочу, щоб з'єднання було постійним. Я хочу, щоб він породжувався, коли я його використовую, а потім (в ідеалі після закінчення тайм-ауту, який не надсилається даними, через x-хвилини) самостійно припиняється. Також використовувалось моє попереднє рішення autossh.
Alex Stragies

Відповіді:


4
  • Чи / usr / bin / ssh дійсно не може приймати сокет-передані передачі?

Я думаю, що це не надто дивно, враховуючи:

  • OpenSSH - проект OpenBSD
  • systemd підтримує лише ядро ​​Linux
  • Підтримка системної системи повинна бути явно додана до OpenSSH, як факультативна залежність / час складання, тому, ймовірно, це буде важко продати.

  • Чи можуть лише параметри root використовувати BindTodeviceопцію?

Екземпляри системних користувачів, як правило, є досить ізольованими, наприклад, не можуть спілкуватися з основним екземпляром pid-0 Такі речі, як залежність від системних одиниць від файлів блоку користувача, неможливі.

Документація для BindToDeviceзгадок:

Зверніть увагу, що встановлення цього параметра може спричинити додаткові залежності, що додаються до одиниці (див. Вище).

Через вищезазначене обмеження, ми можемо мати на увазі, що опція не працює з екземплярами системних користувачів.


  • Чому моя служба проксі не відновлюється належним чином при першому новому з'єднанні після відмирання старого тунелю?

Як я розумію, ланцюжок подій такий:

  • SocksProxyHelper.socket запускається.
  • Клієнт SOCKS підключається до localhost: 8118.
  • запускається systemd SocksProxyHelper.service.
  • Як залежність від SocksProxyHelper.service, також починається systemd SocksProxy.service.
  • systemd-socket-proxydприймає системний сокет і пересилає його дані ssh.
  • ssh гине або вбивається.
  • systemd помічає і SocksProxy.serviceпереходить у неактивний стан, але нічого не робить.
  • SocksProxyHelper.serviceпродовжує працювати та приймати з'єднання, але не вдається підключитися ssh, оскільки він більше не працює.

Для вирішення проблеми необхідно додати BindsTo=SocksProxy.serviceдо SocksProxyHelper.service. Цитуючи свою документацію (наголос додано):

Налаштування залежностей від вимог, дуже схожих за стилем Requires=. Однак цей тип залежності є сильнішим: окрім ефекту від Requires=нього заявляється, що якщо одиниця, до якої прив’язана зупинена, ця одиниця буде зупинена і . Це означає, що одиниця, прив’язана до іншого підрозділу, який раптово переходить у неактивний стан, також буде зупинена. Блоки можуть раптово, несподівано перейти в неактивний стан з різних причин: основний процес сервісного блоку може закінчитися за власним вибором , резервний пристрій блоку пристрою може бути відключений або точка монтажу блоку монтування може бути відключена без участі системний і сервісний менеджер.

При використанні спільно з After=тим же блоком поведінка BindsTo=ще сильніше. У цьому випадку одиниця, прив'язана до строго, повинна перебувати в активному стані, щоб цей пристрій також знаходився в активному стані . Це означає не тільки блок , пов'язаний з іншим блоком , який раптово входить в неактивний стан, але і один , який пов'язаний з іншим блоком , який отримує пропущено з - за перевірки не вдалося умов (таких як ConditionPathExists=, ConditionPathIsSymbolicLink=... - дивись нижче) буде зупинений, якщо він бігати. Таким чином, у багатьох випадках найкраще поєднувати BindsTo=з After=.


  • Це правильний спосіб налаштувати проксі-проксі-шкарпетки "на вимогу"? Якщо ні, то як це зробити?

Мабуть, немає "правильного шляху". У цього методу є свої переваги (все "за запитом") та недоліки (залежність від systemd, перше з'єднання не проходить через те, що ssh ще не почав слухати). Можливо, реалізація підтримки активації системного сокета в autossh було б кращим рішенням.


Після рядка я додав BindsTo=SocksProxy.serviceдо розділу «Елемент» файлу . Ручний перезапуск служби SocksProxy тепер більше не потрібен, коли SSH гине / отримує_убиття. Чи існує спосіб, щоб системний "утримував" початкове з'єднання, щоб не отримати скидання TCP? ~/.config/systemd/user/SocksProxyHelper.serviceAfter=SocksProxy.service
Alex Stragies

@ Володимир Пантелєєв один момент я хотів би уточнити: підтримка активації системного сокета може бути реалізована порівняно легко шляхом аналізу $LISTEN_FDSбез додавання залежності sd_listen_fds(), тому це все ще може бути важким продажем, але не надто важким.
Амір
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.