Refine VPN installer and menu-bar app integration

This commit is contained in:
2026-06-24 23:15:38 +03:00
parent 2acf5dd50b
commit fdb15ae462
6 changed files with 1126 additions and 228 deletions

168
README.md
View File

@@ -2,15 +2,15 @@
CLI-установка корпоративного VPN `vpn.lemanapro.ru` для macOS.
**Модули по умолчанию:** Core: включён; Bitwarden: включён; Touch ID: включён; DNS cleanup: включён; Swift Menu Bar app: включён; автозапуск приложения: включён; runtime-патчи: применяются автоматически перед подключением.
**По умолчанию:** ручной вход без сохранения паролей. Откроется окно корпоративного входа, а логин, пароль и одноразовый код вводятся вручную. Bitwarden, Touch ID, сохранение пароля, подстановка 2FA и автоматический вход включаются только явно.
**Credential sources:** `bitwarden` синхронизирует LDAP-пароль и TOTP seed из Bitwarden в macOS Keychain; `keychain` хранит LDAP-пароль и постоянный TOTP seed напрямую в macOS Keychain. Оба источника используют один и тот же runtime `openconnect-lite` для SSO/autofill.
**Режимы входа:** `manual` ничего не сохраняет и ничего не подставляет; `saved-login` хранит LDAP логин/пароль в macOS Keychain и оставляет одноразовый код ручным; `saved-totp` дополнительно хранит постоянный код настройки 2FA; `auto` запускается только явно через `vpn-auto`/`--auto`.
Репозиторий собирает в один воспроизводимый пакет то, что раньше было ручной локальной настройкой:
- `openconnect` как VPN-клиент;
- `openconnect-lite` для SAML SSO через Keycloak;
- опциональный Bitwarden CLI для LDAP-пароля и TOTP seed;
- опциональный Bitwarden CLI для LDAP-пароля и постоянного кода настройки 2FA;
- опциональный Touch ID helper для мастер-пароля Bitwarden;
- Swift Menu Bar app `LemanaVPN.app`;
- безопасный DNS cleanup через root-owned wrapper;
@@ -22,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, предложит нужные модули и проведёт через настройку.
Если установка запущена из терминала, скрипт работает как простой wizard: объяснит, что будет установлено, по Enter оставит безопасный ручной режим и предложит дополнительные удобства только отдельным выбором.
После установки открой новый shell или выполни:
@@ -39,23 +39,30 @@ vpn
curl -fsSL https://git.dokops.ru/dokril/lemana-vpn/raw/branch/main/install.sh | sh
```
Первый важный вопрос — как хранить VPN credentials:
Первый важный вопрос — как подключаться:
```text
Как хранить VPN credentials?
1) Bitwarden -> macOS Keychain
2) macOS Keychain: ввести LDAP password и TOTP seed сейчас
3) macOS Keychain: настрою вручную позже
Как подключаться по умолчанию?
1) Вводить всё вручную (рекомендуется)
Откроется окно входа. Вы сами введёте логин, пароль и одноразовый код.
2) Запомнить логин и пароль на этом Mac
При входе логин и пароль подставятся сами. Одноразовый код вы введёте вручную.
3) Настроить автоматический вход
Нужно заранее сохранить пароль и постоянный код настройки 2FA.
Выбор [1/2/3, Enter=1]:
```
Что означают варианты:
- `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`.
- `1`ничего не сохранять. Это самый понятный старт: при подключении открывается окно входа, всё вводится руками.
- `2`сохранить LDAP логин и пароль в macOS Keychain. Одноразовый код всё равно вводится руками.
- `3` — продвинутый путь: сохранить полный набор данных для подстановки или подключить Bitwarden. Если не уверены, выбирайте `1`.
Дальше installer спросит только про системные модули: Touch ID для Bitwarden, sudoers, aliases, Swift Menu Bar app и автозапуск.
Дальше installer спросит только про системные модули: sudoers, aliases, Swift Menu Bar app и автозапуск. Bitwarden и Touch ID появляются только если вы явно выбрали продвинутый путь.
Флаги остаются для CI, повторяемых установок и диагностики. Для обычной установки они не нужны.
@@ -69,7 +76,7 @@ curl -fsSL https://git.dokops.ru/dokril/lemana-vpn/raw/branch/main/install.sh |
```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 -s -- --non-interactive --auth-profile saved-login --configure-login
```
Принудительно включить интерактивные вопросы:
@@ -114,7 +121,7 @@ curl -fsSL https://example.org/dokril/lemana-vpn/raw/branch/main/install.sh \
```sh
vpn --status
Modules: ✅ core=ok, bitwarden=on, ✅ touchid=on, ✅ dns=on, ✅ app=on, ✅ autostart=on, ✅ patches=active, ✅ keychain=password:yes/totp_seed:yes
Modules: ✅ core=ok, 🔐 auth_profile=manual, 🔐 credential_source=none, ⏭️ bitwarden=off, ⏭️ touchid=off, ✅ dns=on, ✅ app=on, ✅ autostart=on, ✅ patches=active, ✅ keychain=password:no/totp_seed:no
VPN disconnected
```
@@ -129,15 +136,17 @@ Emoji в human-выводе помогают быстро отличать но
| Поле | Значение |
| --- | --- |
| `core=ok` | Есть `openconnect`, `openconnect-lite` и config |
| `bitwarden=on` | Модуль включён и `bw` установлен |
| `bitwarden=off` | Модуль отключён через `--without-bitwarden` или `LEMANA_VPN_USE_BITWARDEN=0` |
| `auth_profile=manual/saved-login/saved-totp/auto` | Как CLI будет открывать окно входа и использовать сохранённые данные |
| `credential_source=none/keychain/bitwarden` | Откуда брать сохранённые данные, если выбран режим с подстановкой |
| `bitwarden=on` | Модуль явно включён и `bw` установлен |
| `bitwarden=off` | Модуль отключён по умолчанию или через `--without-bitwarden` |
| `bitwarden=missing` | Модуль включён, но `bw` не найден |
| `touchid=on/off/missing` | Состояние Touch ID helper |
| `dns=on/missing` | Наличие DNS cleanup wrapper |
| `app=on/missing` | Установлен ли `~/Applications/LemanaVPN.app` |
| `autostart=on/off` | Есть ли LaunchAgent для запуска приложения при логине |
| `patches=active/pending` | Применены ли runtime-патчи `openconnect-lite` |
| `keychain=password:yes/totp_seed:yes` | Есть ли LDAP-пароль и TOTP seed в Keychain |
| `keychain=password:yes/totp_seed:yes` | Есть ли LDAP-пароль и постоянный код настройки 2FA в Keychain |
JSON-режим тоже отдаёт модульный статус:
@@ -163,20 +172,20 @@ Detected state:
Menu Bar app: no
LaunchAgent: no
Keychain password: no
Keychain TOTP seed: no
Keychain 2FA setup: no
```
Если доступен терминал, скрипт ведёт установку вопросами:
- выбрать credential source: Bitwarden sync, Keychain с вводом credentials сейчас, или Keychain с настройкой позже;
- поставить ли Bitwarden CLI, если выбран Bitwarden и `bw` не найден;
- собрать ли Touch ID helper, если выбран Bitwarden и helper не найден;
- оставить ручной вход, сохранить только логин/пароль или настроить подстановку сохранённых данных;
- поставить Bitwarden CLI только если выбран Bitwarden;
- собрать Touch ID helper только если выбран Bitwarden;
- собрать ли Swift Menu Bar app, если `~/Applications/LemanaVPN.app` не найден;
- включить ли автозапуск Menu Bar app при логине;
- настроить ли sudoers для `openconnect` и DNS cleanup;
- добавить ли алиасы в `~/.zshrc`.
Флаги имеют приоритет над вопросами и нужны в основном для CI, диагностики или повторяемых unattended installs. Например, `--credential-source keychain --configure-keychain` сразу выберет Keychain-only flow, а `--no-shell` не будет предлагать алиасы.
Флаги имеют приоритет над вопросами и нужны в основном для CI, диагностики или повторяемых unattended installs. Например, `--auth-profile saved-login --configure-login` сразу выберет сохранение логина/пароля, а `--no-shell` не будет предлагать алиасы.
В неинтерактивной среде скрипт не задаёт вопросов и использует выбранные флаги/дефолты. Для CI или повторяемой установки лучше явно указывать `--non-interactive`.
@@ -211,54 +220,67 @@ 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.
- service `openconnect-lite`, account `totp/<LDAP username>` — постоянный код настройки 2FA, нужен только для подстановки одноразового кода и auto mode.
`credential_source=bitwarden` — это sync-режим. CLI открывает Bitwarden vault, читает item `LM LDAP`, берёт из него LDAP password и TOTP seed, нормализует `otpauth://...secret=...` если нужно, затем записывает оба секрета в macOS Keychain. После этого подключение идёт так же, как в остальных режимах: `openconnect-lite` читает данные из Keychain, генерирует текущий одноразовый TOTP-код из seed и заполняет Keycloak форму.
`auth_profile=manual` — режим по умолчанию. CLI не проверяет Keychain и Bitwarden, открывает видимое окно входа и ничего не подставляет. Логин, пароль и одноразовый код вводятся вручную.
`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-код.
`auth_profile=saved-login` — CLI берёт из Keychain только LDAP пароль и подставляет логин/пароль в видимое окно входа. Одноразовый код вводится руками. Настройка:
Важно: Lemana VPN не хранит и не принимает текущий 6-значный код как постоянную настройку. Такой код живёт около 30 секунд. Для автоматического SSO нужен именно seed: raw Base32 или `otpauth://totp/...?...secret=BASE32`.
```sh
vpn --configure-login
```
Если запуск идёт из menu-bar app, интерактивного terminal prompt нет. Поэтому при пустом Keychain приложение покажет ошибку, а настройку нужно один раз выполнить в Terminal:
`auth_profile=saved-totp` — CLI берёт LDAP пароль и постоянный код настройки 2FA из Keychain, подставляет поля в видимое окно входа, но submit не нажимает. Настройка:
```sh
vpn --configure-keychain
```
`auth_profile=auto` — старый автоматический путь: скрытый браузер, подстановка всех полей и submit. Запускается только явно:
```sh
vpn-auto
vpn --auto
```
`credential_source=bitwarden` — это sync-provider. CLI открывает Bitwarden vault, читает item `LM LDAP`, берёт из него LDAP password и постоянный код настройки 2FA, нормализует `otpauth://...secret=...` если нужно, затем записывает оба секрета в macOS Keychain. Bitwarden не включён по умолчанию.
Важно: Lemana VPN не хранит и не принимает текущий 6-значный код как постоянную настройку. Такой код живёт около 30 секунд. Для автоматического SSO нужен именно постоянный secret: raw Base32 или `otpauth://totp/...?...secret=BASE32`.
Если запуск идёт из menu-bar app, интерактивного terminal prompt нет. Поэтому настройку сохранённого логина или полного набора данных нужно один раз выполнить в Terminal.
### Bitwarden
Включён по умолчанию. CLI при каждом запуске `vpn` пытается получить LDAP-пароль и TOTP seed из записи Bitwarden `LM LDAP`, затем записывает их в macOS Keychain для `openconnect-lite`.
Отключён по умолчанию. Его стоит включать только если у пользователя уже есть запись Bitwarden с корпоративным LDAP-паролем и постоянным кодом настройки 2FA.
TOTP seed — это постоянный секрет 2FA. Сам одноразовый TOTP-код меняется каждые 30 секунд и генерируется `openconnect-lite` в момент входа.
Постоянный код настройки 2FA — это секрет, который обычно показывается при ручной настройке authenticator. Сам одноразовый код меняется каждые 30 секунд и генерируется `openconnect-lite` в момент входа.
Если vault заблокирован и Touch ID helper не смог его открыть, CLI спросит `Bitwarden master password`. Это пароль от хранилища Bitwarden, а не корпоративный LDAP-пароль. Он нужен только чтобы достать LDAP password/TOTP seed из item `LM LDAP` и переложить их в macOS Keychain.
Если vault заблокирован и Touch ID helper не смог его открыть, CLI спросит `Bitwarden master password`. Это пароль от хранилища Bitwarden, а не корпоративный LDAP-пароль. Он нужен только чтобы достать LDAP password и постоянный код настройки 2FA из item `LM LDAP` и переложить их в macOS Keychain.
Выбрать Keychain вместо Bitwarden можно прямо в installer wizard: пункт `2` вводит LDAP password и TOTP seed сразу после установки, пункт `3` оставляет настройку на потом.
Включить Bitwarden можно через продвинутый путь в installer wizard или флагами:
То же самое можно задать флагами для неинтерактивной установки:
```sh
sh install.sh --non-interactive --credential-source keychain --configure-keychain
sh install.sh --non-interactive --with-bitwarden --auth-profile saved-totp
```
В этом режиме credentials нужно положить в Keychain вручную:
Для Keychain-only режима без Bitwarden используйте:
```sh
vpn-lemanapro.sh --configure-keychain
sh install.sh --non-interactive --auth-profile saved-login --configure-login
```
Если credentials уже лежат в Keychain, подключение без Bitwarden не будет спрашивать пароль заново. CLI явно напишет, что Bitwarden отключён и используются сохранённые LDAP password/TOTP seed из macOS Keychain.
Если сохранённые данные уже лежат в Keychain, подключение без Bitwarden не будет спрашивать пароль заново. Для режима `saved-login` одноразовый код всё равно вводится вручную.
### Если Bitwarden нет
Bitwarden не обязателен. Без него установка работает как обычный `openconnect-lite` profile с секретами в macOS Keychain.
Bitwarden не обязателен. Без него установка по умолчанию работает в полностью ручном режиме: откроется окно входа, а логин, пароль и одноразовый код вводятся руками.
Интерактивная установка:
@@ -266,27 +288,34 @@ Bitwarden не обязателен. Без него установка рабо
curl -fsSL https://git.dokops.ru/dokril/lemana-vpn/raw/branch/main/install.sh | sh
```
В первом вопросе выбери пункт `2`:
В первом вопросе можно просто нажать Enter:
```text
2) macOS Keychain: ввести LDAP password и TOTP seed сейчас
1) Вводить всё вручную (рекомендуется)
```
Это встроенный бесплатный путь: не нужен Bitwarden account, платный Bitwarden TOTP или внешний password manager. Setup prompt спросит корпоративный LDAP-пароль и постоянный TOTP seed. Seed можно вставить как raw Base32 или как `otpauth://totp/...?...secret=BASE32` URI.
Это встроенный бесплатный путь: не нужен Bitwarden account, платный Bitwarden TOTP или внешний password manager.
Если хочется, чтобы логин и пароль подставлялись сами, выбери пункт `2` или выполни позже:
```sh
vpn --configure-login
```
Что понадобится:
- LDAP username;
- LDAP password: корпоративный LDAP/domain пароль, не мастер-пароль Bitwarden;
- TOTP secret из корпоративной 2FA настройки.
- одноразовый код из корпоративной 2FA при каждом подключении.
Важно: вводить нужно не текущие 6 цифр из authenticator-приложения, а постоянный secret. Обычно он есть в QR-коде как `secret=BASE32...` или может быть показан при ручной настройке TOTP.
Постоянный код настройки 2FA нужен только для `vpn --configure-keychain`, `saved-totp` и `vpn-auto`.
Не вставляй текущий 6-значный authenticator code в `vpn --configure-keychain`. Lemana VPN сохраняет в Keychain постоянный TOTP seed, а `openconnect-lite` по нему генерирует свежие одноразовые коды во время каждого SSO login.
Не вставляй текущий 6-значный authenticator code в `vpn --configure-keychain`. Lemana VPN сохраняет в Keychain постоянный код настройки 2FA, а `openconnect-lite` по нему генерирует свежие одноразовые коды во время каждого SSO login.
Если запуск идёт из `LemanaVPN.app`, приложение не может безопасно показать интерактивный terminal prompt для ввода LDAP/TOTP. Если Keychain пустой, приложение покажет ошибку. В этом случае один раз выполни в Terminal:
Если запуск идёт из `LemanaVPN.app`, приложение не может безопасно показать интерактивный terminal prompt для сохранения пароля. Настройку saved-login или saved-totp нужно один раз выполнить в Terminal:
```sh
vpn --configure-login
vpn --configure-keychain
```
@@ -295,13 +324,13 @@ vpn --configure-keychain
1. Открой QR-код в приложении/на портале, где настраивалась 2FA.
2. Найди режим ручной настройки, где показывается secret.
3. Если доступен только QR, его нужно расшифровать любым локальным QR-сканером и взять параметр `secret`.
4. Вставь secret в prompt `TOTP secret (BASE32...)`.
4. Вставь secret в prompt `2FA setup secret BASE32`.
Если TOTP secret получить нельзя, автоматический headless-вход невозможен: `openconnect-lite` не сможет сам генерировать свежий TOTP-код на каждом входе.
Если постоянный 2FA secret получить нельзя, автоматический headless-вход невозможен: `openconnect-lite` не сможет сам генерировать свежий одноразовый код на каждом входе.
### Touch ID
Включён по умолчанию. Установщик собирает `keychain-fingerprint` из `https://github.com/dss99911/keychain-fingerprint.git` и кладёт бинарник в `~/bin/keychain-fingerprint`.
Отключён по умолчанию и нужен только для Bitwarden-пути. Если пользователь выбрал Bitwarden, установщик может собрать `keychain-fingerprint` из `https://github.com/dss99911/keychain-fingerprint.git` и положить бинарник в `~/bin/keychain-fingerprint`.
Важно: этот helper показывает системный Touch ID prompt перед чтением мастер-пароля Bitwarden, но это не аппаратный Keychain ACL. Это удобный локальный гейт поверх записи Keychain.
@@ -321,6 +350,15 @@ sh install.sh --without-touchid
Приложение живёт в macOS status bar, запускает `~/bin/vpn-lemanapro.sh --json`, показывает состояние VPN, IP, оставшееся время сессии, health-check тоннеля и строку состояния модулей.
В отключённом состоянии меню показывает текущий режим установки:
- `Режим: полностью вручную` — доступна только обычная кнопка `Подключить`; логин, пароль и одноразовый код вводятся руками.
- `Режим: логин и пароль сохранены` — доступен вход с подстановкой логина/пароля и ручной ввод одноразового кода.
- `Режим: сохранённые данные без автоотправки` — доступны сохранённые данные, ручной fallback и явный automatic mode.
- `Режим: автоматический вход` — обычная кнопка `Подключить` запускает настроенный auto-flow, а ручные fallback-кнопки остаются доступны.
Кнопки, для которых текущая установка не готова, не показываются. Например, если не сохранён постоянный код настройки 2FA, в меню не будет автоматического входа. Если рядом с режимом есть подсказка `Настройте в Terminal`, выполните указанную команду в Terminal и нажмите `Обновить статус модулей`.
Строка состояния модулей в меню приложения использует те же маркеры, что CLI: `✅` для готового модуля, `⏭️` для отключённого опционального модуля и `⚠️` для проблемы. Иконка строки тоже меняется: `checkmark.circle` для полностью готового набора и `exclamationmark.triangle` для неполной установки.
Если в меню видно `modules unavailable: update CLI`, значит запущенное приложение обращается к старому `~/bin/vpn-lemanapro.sh`, который ещё не умеет отдавать модульный статус. Повтори установку через `curl`; установщик обновит CLI и перезапустит уже запущенное `LemanaVPN.app`.
@@ -352,9 +390,10 @@ open ~/Applications/LemanaVPN.app
## Использование
```sh
vpn # подключиться
vpn-auto # автоматический режим: скрытый браузер, auto-fill и submit
vpn-manual # ручной режим: видимый браузер, auto-fill без submit
vpn # подключиться в настроенном режиме; fresh install = полностью вручную
vpn-auto # явный автоматический режим: скрытый браузер, auto-fill и submit
vpn --saved-login # подставить сохранённые логин/пароль, одноразовый код руками
vpn-manual # видимый браузер, сохранённые данные auto-fill без submit
vpn-manual-full # полностью ручной режим: видимый браузер без auto-fill и submit
vpn --manual # то же самое без alias
vpn --manual-full # то же самое без alias
@@ -368,18 +407,19 @@ open ~/Applications/LemanaVPN.app # открыть Swift-приложение
Режимы подключения:
- `auto` — режим по умолчанию. Браузер скрытый, LDAP-пароль и TOTP берутся из Bitwarden/Keychain, Keycloak форма заполняется и отправляется автоматически.
- `manual` — браузер видимый, LDAP-пароль и TOTP берутся из Bitwarden/Keychain и подставляются в поля, но кнопки входа не нажимаются. Нажимаешь сам после проверки формы.
- `manual-full` — браузер видимый, auto-fill отключён полностью, проверки сохранённых LDAP/TOTP credentials пропускаются: поля Keycloak заполняешь и отправляешь сам.
- `manual` — режим fresh install по умолчанию. Браузер видимый, auto-fill отключён полностью, проверки сохранённых LDAP/TOTP credentials пропускаются: поля Keycloak заполняешь и отправляешь сам.
- `saved-login` — браузер видимый, логин/пароль берутся из Keychain, одноразовый код вводится руками, submit не нажимается.
- `saved-totp` / `--manual` — браузер видимый, LDAP-пароль и код 2FA берутся из Keychain/Bitwarden и подставляются в поля, но кнопка входа не нажимается.
- `auto` / `vpn-auto` — явный автоматический режим. Браузер скрытый, LDAP-пароль и код 2FA берутся из Keychain/Bitwarden, форма заполняется и отправляется автоматически.
- `--manual-sso` оставлен как совместимый alias для `--manual`.
- `--manual-no-autofill` оставлен как совместимый alias для `--manual-full`.
Первый запуск с Bitwarden:
Первый запуск с Bitwarden, если он выбран явно:
1. CLI проверит `bw`.
2. Если vault locked, попросит мастер-пароль.
3. Если установлен Touch ID helper, предложит сохранить мастер-пароль за Touch ID prompt.
4. Достанет `LM LDAP`, запишет LDAP-пароль и TOTP seed в Keychain.
4. Достанет `LM LDAP`, запишет LDAP-пароль и постоянный код настройки 2FA в Keychain.
5. Запустит `openconnect-lite` и пройдёт Keycloak SSO.
## Настройка
@@ -388,17 +428,19 @@ open ~/Applications/LemanaVPN.app # открыть Swift-приложение
```sh
LEMANA_VPN_USERNAME="<LDAP_USERNAME>"
LEMANA_VPN_CREDENTIAL_SOURCE="bitwarden"
LEMANA_VPN_AUTH_PROFILE="manual"
LEMANA_VPN_CREDENTIAL_SOURCE="none"
LEMANA_VPN_BW_ITEM="LM LDAP"
LEMANA_VPN_USE_BITWARDEN="1"
LEMANA_VPN_USE_TOUCHID="1"
LEMANA_VPN_USE_BITWARDEN="0"
LEMANA_VPN_USE_TOUCHID="0"
LEMANA_VPN_DNS_CLEANUP="/usr/local/sbin/lemana-vpn-dns-cleanup"
```
Для бесплатного Keychain-only источника:
Для режима с сохранённым логином и паролем:
```sh
LEMANA_VPN_USERNAME="<LDAP_USERNAME>"
LEMANA_VPN_AUTH_PROFILE="saved-login"
LEMANA_VPN_CREDENTIAL_SOURCE="keychain"
LEMANA_VPN_USE_BITWARDEN="0"
LEMANA_VPN_USE_TOUCHID="0"
@@ -421,7 +463,7 @@ curl -fsSL https://git.dokops.ru/dokril/lemana-vpn/raw/branch/main/install.sh \
- password: LDAP пароль;
- TOTP: `otpauth://...secret=BASE32...` или raw BASE32 secret.
Это не 6-значный одноразовый код. В Bitwarden должен лежать постоянный TOTP secret, из которого коды генерируются автоматически.
Это не 6-значный одноразовый код. В Bitwarden должен лежать постоянный 2FA secret, из которого коды генерируются автоматически.
## Почему DNS wrapper, а не wildcard sudoers