Make installer interactive for credential source selection

This commit is contained in:
2026-05-26 14:05:36 +03:00
parent 7c625e840e
commit a52b4ecdd4
10 changed files with 1634 additions and 45 deletions

102
README.md
View File

@@ -4,6 +4,8 @@ CLI-установка корпоративного VPN `vpn.lemanapro.ru` дл
**Модули по умолчанию:** Core: включён; Bitwarden: включён; Touch ID: включён; DNS cleanup: включён; Swift Menu Bar app: включён; автозапуск приложения: включён; runtime-патчи: применяются автоматически перед подключением.
**Credential sources:** `bitwarden` синхронизирует LDAP-пароль и TOTP seed из Bitwarden в macOS Keychain; `keychain` хранит LDAP-пароль и постоянный TOTP seed напрямую в macOS Keychain. Оба источника используют один и тот же runtime `openconnect-lite` для SSO/autofill.
Репозиторий собирает в один воспроизводимый пакет то, что раньше было ручной локальной настройкой:
- `openconnect` как VPN-клиент;
@@ -20,7 +22,7 @@ CLI-установка корпоративного VPN `vpn.lemanapro.ru` дл
curl -fsSL https://git.dokops.ru/dokril/lemana-vpn/raw/branch/main/install.sh | sh
```
Если установка запущена из терминала, скрипт сначала проверит, что уже стоит, и спросит по отсутствующим опциональным модулям.
Если установка запущена из терминала, скрипт работает как интерактивный wizard: проверит, что уже стоит, спросит как хранить credentials, предложит нужные модули и проведёт через настройку.
После установки открой новый shell или выполни:
@@ -29,25 +31,33 @@ exec zsh
vpn
```
## Варианты установки
## Интерактивная установка
Полная установка, режим по умолчанию:
Обычный путь — запустить installer без флагов и ответить на вопросы:
```sh
curl -fsSL https://git.dokops.ru/dokril/lemana-vpn/raw/branch/main/install.sh | sh
```
Без Touch ID, но с Bitwarden:
Первый важный вопрос — как хранить VPN credentials:
```sh
curl -fsSL https://git.dokops.ru/dokril/lemana-vpn/raw/branch/main/install.sh | sh -s -- --without-touchid
```text
Как хранить VPN credentials?
1) Bitwarden -> macOS Keychain
2) macOS Keychain: ввести LDAP password и TOTP seed сейчас
3) macOS Keychain: настрою вручную позже
Выбор [1/2/3, Enter=1]:
```
Минимальная установка без Bitwarden и Touch ID. В macOS Keychain вручную будут записаны LDAP-пароль и TOTP secret. Не текущий 30-секундный TOTP-код, а постоянный seed из настройки 2FA.
Что означают варианты:
```sh
curl -fsSL https://git.dokops.ru/dokril/lemana-vpn/raw/branch/main/install.sh | sh -s -- --minimal --configure-keychain
```
- `1` — использовать Bitwarden как sync-provider: installer поставит/проверит `bw`, а при запуске `vpn` CLI переложит LDAP password и TOTP seed из Bitwarden в macOS Keychain.
- `2` — бесплатный Keychain-only путь: после установки CLI спросит LDAP password и постоянный TOTP seed или `otpauth://...secret=...`, затем сохранит их в macOS Keychain.
- `3` — поставить CLI/app сейчас, а credentials настроить позже командой `vpn --configure-keychain`.
Дальше installer спросит только про системные модули: Touch ID для Bitwarden, sudoers, aliases, Swift Menu Bar app и автозапуск.
Флаги остаются для CI, повторяемых установок и диагностики. Для обычной установки они не нужны.
Проверить действия без изменений:
@@ -55,6 +65,13 @@ curl -fsSL https://git.dokops.ru/dokril/lemana-vpn/raw/branch/main/install.sh |
curl -fsSL https://git.dokops.ru/dokril/lemana-vpn/raw/branch/main/install.sh | sh -s -- --dry-run
```
Пример неинтерактивного режима для автоматизации:
```sh
curl -fsSL https://git.dokops.ru/dokril/lemana-vpn/raw/branch/main/install.sh \
| sh -s -- --non-interactive --credential-source keychain --configure-keychain
```
Принудительно включить интерактивные вопросы:
```sh
@@ -149,17 +166,17 @@ Detected state:
Keychain TOTP seed: no
```
Если доступен терминал (`/dev/tty`), скрипт спросит только по тому, чего не хватает:
Если доступен терминал, скрипт ведёт установку вопросами:
- поставить ли Bitwarden CLI, если `bw` не найден;
- собрать ли Touch ID helper, если его нет и Bitwarden включён;
- выбрать credential source: Bitwarden sync, Keychain с вводом credentials сейчас, или Keychain с настройкой позже;
- поставить ли Bitwarden CLI, если выбран Bitwarden и `bw` не найден;
- собрать ли Touch ID helper, если выбран Bitwarden и helper не найден;
- собрать ли Swift Menu Bar app, если `~/Applications/LemanaVPN.app` не найден;
- включить ли автозапуск Menu Bar app при логине;
- настроить ли sudoers для `openconnect` и DNS cleanup;
- добавить ли алиасы в `~/.zshrc`;
- записать ли LDAP-пароль и TOTP seed в Keychain, если Bitwarden отключён.
- добавить ли алиасы в `~/.zshrc`.
Флаги имеют приоритет над вопросами. Например, `--without-bitwarden` не будет спрашивать про Bitwarden, а `--no-shell` не будет предлагать алиасы.
Флаги имеют приоритет над вопросами и нужны в основном для CI, диагностики или повторяемых unattended installs. Например, `--credential-source keychain --configure-keychain` сразу выберет Keychain-only flow, а `--no-shell` не будет предлагать алиасы.
В неинтерактивной среде скрипт не задаёт вопросов и использует выбранные флаги/дефолты. Для CI или повторяемой установки лучше явно указывать `--non-interactive`.
@@ -194,6 +211,27 @@ LEMANA_VPN_NO_EMOJI=1 sh uninstall.sh
- `openconnect-lite` config;
- DNS cleanup wrapper.
### Как работают credential sources
У Lemana VPN есть два разных способа подготовить credentials, но один общий runtime-контракт: перед запуском SSO в macOS Keychain должны лежать LDAP-пароль и постоянный TOTP seed для `openconnect-lite`.
Keychain entries:
- service `openconnect-lite`, account `<LDAP username>` — корпоративный LDAP/domain пароль;
- service `openconnect-lite`, account `totp/<LDAP username>` — постоянный TOTP seed.
`credential_source=bitwarden` — это sync-режим. CLI открывает Bitwarden vault, читает item `LM LDAP`, берёт из него LDAP password и TOTP seed, нормализует `otpauth://...secret=...` если нужно, затем записывает оба секрета в macOS Keychain. После этого подключение идёт так же, как в остальных режимах: `openconnect-lite` читает данные из Keychain, генерирует текущий одноразовый TOTP-код из seed и заполняет Keycloak форму.
`credential_source=keychain` — это бесплатный built-in режим без Bitwarden. Пользователь один раз запускает `vpn --configure-keychain` или установку с `--credential-source keychain --configure-keychain`, вводит LDAP password и постоянный TOTP seed. CLI сохраняет их напрямую в macOS Keychain и при следующих подключениях не спрашивает Bitwarden, master password или текущий OTP-код.
Важно: Lemana VPN не хранит и не принимает текущий 6-значный код как постоянную настройку. Такой код живёт около 30 секунд. Для автоматического SSO нужен именно seed: raw Base32 или `otpauth://totp/...?...secret=BASE32`.
Если запуск идёт из menu-bar app, интерактивного terminal prompt нет. Поэтому при пустом Keychain приложение покажет ошибку, а настройку нужно один раз выполнить в Terminal:
```sh
vpn --configure-keychain
```
### Bitwarden
Включён по умолчанию. CLI при каждом запуске `vpn` пытается получить LDAP-пароль и TOTP seed из записи Bitwarden `LM LDAP`, затем записывает их в macOS Keychain для `openconnect-lite`.
@@ -202,10 +240,12 @@ TOTP seed — это постоянный секрет 2FA. Сам однора
Если vault заблокирован и Touch ID helper не смог его открыть, CLI спросит `Bitwarden master password`. Это пароль от хранилища Bitwarden, а не корпоративный LDAP-пароль. Он нужен только чтобы достать LDAP password/TOTP seed из item `LM LDAP` и переложить их в macOS Keychain.
Отключить:
Выбрать Keychain вместо Bitwarden можно прямо в installer wizard: пункт `2` вводит LDAP password и TOTP seed сразу после установки, пункт `3` оставляет настройку на потом.
То же самое можно задать флагами для неинтерактивной установки:
```sh
sh install.sh --without-bitwarden
sh install.sh --non-interactive --credential-source keychain --configure-keychain
```
В этом режиме credentials нужно положить в Keychain вручную:
@@ -220,13 +260,20 @@ vpn-lemanapro.sh --configure-keychain
Bitwarden не обязателен. Без него установка работает как обычный `openconnect-lite` profile с секретами в macOS Keychain.
Установка:
Интерактивная установка:
```sh
curl -fsSL https://git.dokops.ru/dokril/lemana-vpn/raw/branch/main/install.sh \
| sh -s -- --without-bitwarden --without-touchid --configure-keychain
curl -fsSL https://git.dokops.ru/dokril/lemana-vpn/raw/branch/main/install.sh | sh
```
В первом вопросе выбери пункт `2`:
```text
2) macOS Keychain: ввести LDAP password и TOTP seed сейчас
```
Это встроенный бесплатный путь: не нужен Bitwarden account, платный Bitwarden TOTP или внешний password manager. Setup prompt спросит корпоративный LDAP-пароль и постоянный TOTP seed. Seed можно вставить как raw Base32 или как `otpauth://totp/...?...secret=BASE32` URI.
Что понадобится:
- LDAP username;
@@ -235,6 +282,8 @@ curl -fsSL https://git.dokops.ru/dokril/lemana-vpn/raw/branch/main/install.sh \
Важно: вводить нужно не текущие 6 цифр из authenticator-приложения, а постоянный secret. Обычно он есть в QR-коде как `secret=BASE32...` или может быть показан при ручной настройке TOTP.
Не вставляй текущий 6-значный authenticator code в `vpn --configure-keychain`. Lemana VPN сохраняет в Keychain постоянный TOTP seed, а `openconnect-lite` по нему генерирует свежие одноразовые коды во время каждого SSO login.
Если запуск идёт из `LemanaVPN.app`, приложение не может безопасно показать интерактивный terminal prompt для ввода LDAP/TOTP. Если Keychain пустой, приложение покажет ошибку. В этом случае один раз выполни в Terminal:
```sh
@@ -335,12 +384,23 @@ open ~/Applications/LemanaVPN.app # открыть Swift-приложение
```sh
LEMANA_VPN_USERNAME="60103293"
LEMANA_VPN_CREDENTIAL_SOURCE="bitwarden"
LEMANA_VPN_BW_ITEM="LM LDAP"
LEMANA_VPN_USE_BITWARDEN="1"
LEMANA_VPN_USE_TOUCHID="1"
LEMANA_VPN_DNS_CLEANUP="/usr/local/sbin/lemana-vpn-dns-cleanup"
```
Для бесплатного Keychain-only источника:
```sh
LEMANA_VPN_USERNAME="60103293"
LEMANA_VPN_CREDENTIAL_SOURCE="keychain"
LEMANA_VPN_USE_BITWARDEN="0"
LEMANA_VPN_USE_TOUCHID="0"
LEMANA_VPN_DNS_CLEANUP="/usr/local/sbin/lemana-vpn-dns-cleanup"
```
Для другого логина:
```sh