add ProxyJump function
This commit is contained in:
1 parent
56e20e5464
commit
7f0e0fdb23
48 files changed
+3875
-44
No files matched your search
+55
-15
@@ -46,13 +46,20 @@ TUI работает поверх уже существующего SSH+`sudo`-
|
||||
(`State.DeleteHost`, `State.RemoveServiceRefs`) — переименование/удаление
|
||||
одного сервиса никогда не задевает остальные сервисы того же хоста.
|
||||
|
||||
Ключевой момент: пользователь **никогда не подключается по SSH к целевому
|
||||
хосту напрямую** (ни через `ProxyJump`, ни как-то ещё) — он открывает одно
|
||||
соединение к самому jump-хосту и локально пробрасывает (`LocalForward`)
|
||||
порты к каждому нужному сервису через это соединение. Не важно, слушает ли
|
||||
на целевом порту настоящий SSH (22) или произвольный TCP-сервис (7888) —
|
||||
для форвардинга это не имеет значения, оба варианта — это просто
|
||||
"локальный порт → host:port через jump".
|
||||
Ключевой момент: и в `LocalForward`, и в `ProxyJump`-режиме клиентского
|
||||
конфига (`model.User.ProxyJump`, см. ниже) канал до целевого хоста —
|
||||
это всегда один и тот же серверный примитив, `direct-tcpip` через
|
||||
jump-хост: пользователь никогда не получает интерактивный шелл на целевом
|
||||
хосте через jump, только форвардинг порта до него. В `LocalForward`-режиме
|
||||
он открывает одно соединение к самому jump-хосту и локально пробрасывает
|
||||
порты к каждому нужному сервису через это соединение; в `ProxyJump`-режиме
|
||||
клиентский `ssh` сам открывает по одному `direct-tcpip`-каналу через то же
|
||||
соединение к jump-хосту на время каждой команды (`ssh <alias>`), без
|
||||
постоянно висящего туннеля и без локальных портов — разница только в том,
|
||||
как клиент организует один и тот же тип канала, а не в том, что jump-хост
|
||||
разрешает. Не важно, слушает ли на целевом порту настоящий SSH (22) или
|
||||
произвольный TCP-сервис (7888) — для форвардинга это не имеет значения,
|
||||
оба варианта — это просто "порт → host:port через jump".
|
||||
|
||||
## Как на самом деле работает ограничение "только прыжок/форвардинг"
|
||||
|
||||
@@ -84,14 +91,41 @@ TUI работает поверх уже существующего SSH+`sudo`-
|
||||
повреждены/потеряны, а не основной механизм.
|
||||
|
||||
2. **Клиент (только удобство).** Файл `~/.ssh/config`, который уезжает
|
||||
пользователю в архиве, — это один блок `Host jump` с набором строк
|
||||
`LocalForward <локальный_порт> <host>:<port>` (`internal/keymgr/clientconfig.go`).
|
||||
Он ничего не запрещает: пользователь может отредактировать его или
|
||||
вызвать `ssh` руками с любым хостом. Единственная причина, по которой это
|
||||
не работает, — сервер отклонит `permitopen`, которого нет в списке.
|
||||
Список форвардов в клиентском конфиге должен генерироваться из того же
|
||||
источника правды (группы в `state.yaml`), что и `permitopen=`, — иначе
|
||||
конфиг и реальные права разойдутся.
|
||||
пользователю в архиве, зависит от `model.User.ProxyJump` (переключается
|
||||
чекбоксом на экране групп пользователя, `internal/ui/users.go`) и
|
||||
генерируется одним из двух рендереров
|
||||
(`internal/keymgr/clientconfig.go`), но оба **одинаково не являются
|
||||
границей безопасности**:
|
||||
- `false` (по умолчанию, `LocalForward`) — один блок `Host jump` с
|
||||
набором строк `LocalForward <локальный_порт> <host>:<port>`, одно
|
||||
всегда открытое соединение сразу даёт локальные порты на все сервисы
|
||||
(`RenderClientConfig`).
|
||||
- `true` (`ProxyJump`) — отдельный блок `Host <alias>` на каждый
|
||||
разрешённый сервис с `ProxyJump jump` вместо `HostName jump`, без
|
||||
локальных портов и без постоянно открытого соединения — каждый вызов
|
||||
`ssh <alias>` сам поднимает и закрывает канал по требованию
|
||||
(`RenderClientConfigProxyJump`).
|
||||
|
||||
Ни один из двух вариантов ничего не запрещает: пользователь может
|
||||
отредактировать любой из них или вызвать `ssh` руками с любым хостом.
|
||||
Единственная причина, по которой это не работает, — сервер отклонит
|
||||
`permitopen`, которого нет в списке, и это ограничение **идентично для
|
||||
обоих режимов**: `BuildUserArchive`/`BuildConfigOnlyArchive` в обоих
|
||||
случаях берут один и тот же `[]model.Forward` (`State.AllowedForwards`)
|
||||
и не трогают `internal/sysadm/authorizedkeys.go` — переключение
|
||||
`ProxyJump` меняет только то, как выглядит клиентский конфиг, а не какие
|
||||
`permitopen=` попадают в `authorized_keys`. Список форвардов в
|
||||
клиентском конфиге (в любом из двух форматов) должен генерироваться из
|
||||
того же источника правды (группы в `state.yaml`), что и `permitopen=`, —
|
||||
иначе конфиг и реальные права разойдутся.
|
||||
|
||||
Переключение режима у уже существующего пользователя не применяется
|
||||
автоматически: `ForwardsHash`/`IsConfigStale` отслеживают только
|
||||
изменения состава форвардов, а не смену стиля конфига (само
|
||||
переключение `ProxyJump` без изменения групп не помечает конфиг как
|
||||
устаревший) — администратор должен вручную прогнать «Обновить конфиги»
|
||||
после переключения, если хочет, чтобы у пользователя оказался конфиг
|
||||
нового формата.
|
||||
|
||||
Reverse/remote forwarding (`-R`) в этой модели не выдаётся вообще
|
||||
(`AllowStreamLocalForwarding no`, никаких `permitlisten=`) — по вашему же
|
||||
@@ -249,3 +283,9 @@ session" вместо тихой порчи данных. Если реальн
|
||||
получение.
|
||||
- Полностью параллельная работа нескольких админов не поддерживается
|
||||
(см. «Конкурентность»).
|
||||
- Переключение `ProxyJump`/`LocalForward` у уже существующего пользователя
|
||||
не переиздаёт и не помечает его конфиг устаревшим автоматически (см.
|
||||
выше, «Клиент (только удобство)») — после переключения нужно вручную
|
||||
прогнать «Обновить конфиги» для этого пользователя, иначе у него на
|
||||
диске останется конфиг старого формата (что ничего не ломает: доступ на
|
||||
сервере не зависит от этого режима, только удобство пользователя).
|
||||
Reference in new issue
Block a user