# 2FAuth на Rust — 0.3.0 Целевая версия: **2FAuth 8.0.3**, коммит `3516c776a1fcbd83d234efc007e3a49807d6ed91`. Это развиваемая реализация совместимости, **пока не подтверждённая как полная замена PHP**. Рабочий сервер пользователя не изменялся. Все сравнения выполняются на отдельных синтетических базах, включая копию БД, созданной настоящими Laravel-миграциями. ## Что реализовано - HOTP, TOTP и Steam; SHA-1/256/512 и MD5; атомарный HOTP-счётчик; URI и экспорт. - Шифрование Laravel AES-CBC, `APP_KEY`, предыдущие ключи; транзакционное включение/выключение шифрования данных и иконок. - Аккаунты, группы, порядок и назначения отдельно для каждого пользователя; общие аккаунты, всеобщие ссылки доступа, передача владельца с подтверждением пароля; запрет выдачи секретов получателям. - Регистрация, вход, CSRF, профиль, смена/восстановление пароля, ограничения регистрации, последний администратор, управление пользователями. - Passport 13: настоящие RSA JWT, создание/отзыв PAT, существующие PHP bearer-токены и зашифрованные браузерные `laravel_token`. Действующая PHP-cookie может быть преобразована в Rust-сессию при загрузке интерфейса. - OAuth: authorization code с PKCE, client credentials, Device Code Flow, ротация refresh-токенов и запрет повторного обмена; формат шифрования Defuse PHP совместим с эталоном. - Перенос Laravel-сессий из файлов и SQLite: JSON/PHP-сериализация, SESSION_ENCRYPT, проверка cookie/CSRF, remember-me и отзыв при выходе. - WebAuthn: регистрация, вход, список/переименование/удаление устройств, восстановление; импорт существующих зашифрованных PEM-ключей Laragear P-256/RSA/Ed25519. Проверки используют подписанные данные аутентификатора. - GitHub/OpenID SSO, PKCE, одноразовый state, проверка OIDC JWT при настройке issuer; reverse-proxy-вход только от доверенного сетевого адреса. - Импорт 2FAuth, Aegis, 2FAS, Bitwarden, текстовых URI и Google Authenticator; вложенные иконки; QR; официальные и локальные наборы иконок. - Настройки, предпочтения, журналы входа/OTP, уведомления, SMTP/STARTTLS/TLS/sendmail/log; исходный собранный Vue-интерфейс и размещение в подкаталоге. Подробные доказательства и ограничения: [compatibility/CURRENT.md](compatibility/CURRENT.md), [compatibility/VERIFICATION.md](compatibility/VERIFICATION.md). Старые разделы аудита в `compatibility/README.md` относятся к исходной версии 0.1.0. ## Готовый бинарный файл В архиве есть `bin/twofauth-rs` для Linux x86_64 GNU. Он проверен в этой среде; для запуска нужны glibc 2.39 или новее и libgcc_s. Контрольная сумма приведена в `bin/BUILD.txt`. Если система старее или имеет другую архитектуру, соберите проект из исходников либо через Docker. Запускайте бинарный файл из каталога `rust-server`; соседний каталог `public` определяется автоматически. Для новой установки сначала задайте и сохраните `APP_KEY`, затем используйте команды ниже, заменив `./target/release/twofauth-rs` на `./bin/twofauth-rs`. Для имеющейся установки ключи должны остаться прежними. ## Сборка и отдельная тестовая установка Нужны современный stable Rust, C-компилятор, make и Perl: OpenSSL собирается из исходников для WebAuthn. Сборка Docker в этой среде не запускалась. ```sh cargo build --locked --release mkdir -p data ./target/release/twofauth-rs init RUST_COOKIE_SECURE=false ./target/release/twofauth-rs serve ``` Откройте `http://127.0.0.1:8080`. На пустой БД доступна регистрация; первый пользователь становится администратором. Отключать Secure-cookie следует только для локального HTTP. Для HTTPS оставьте значение по умолчанию. Можно создать отдельного тестового пользователя через файл пароля: ```sh ./target/release/twofauth-rs create-user --name Test --email test@example.invalid --password-file /path/password.txt ``` `init` отказывается создавать схему поверх существующих пользователей. `create-user` создаёт обычного пользователя. Файл пароля должен быть доступен только владельцу; для этой CLI-команды требуется 12–72 байта. ## Проверка копии существующей SQLite Сначала сделайте согласованную копию БД и каталога `storage` средствами SQLite/вашего резервного копирования. Не копируйте только основной файл SQLite при незавершённом WAL. Настройте окружение на **копию**: ```sh export DB_CONNECTION=sqlite export DB_DATABASE=/absolute/path/to/copied/database.sqlite export APP_URL=https://test.example.invalid export STORAGE_PATH=/absolute/path/to/copied/storage export PASSPORT_KEY_PATH=/absolute/path/to/copied/storage # APP_KEY и APP_PREVIOUS_KEYS должны сохранять исходные значения. ./target/release/twofauth-rs prepare-sqlite ./target/release/twofauth-rs serve ``` `prepare-sqlite` проверяет используемые поля таблиц и добавляет только служебные таблицы Rust. Он не выполняет Laravel-миграции и не меняет историю миграций. Если эти служебные таблицы отсутствуют при запуске, `serve` также проверит схему и создаст их. Исходная БД должна уже быть обновлена до целевого PHP-коммита. Поддержка PostgreSQL/MySQL/SQL Server в этой реализации **ещё отсутствует**. Сохраняйте исходные ключи Passport `oauth-private.key`/`oauth-public.key`, `APP_KEY`, предыдущие ключи и содержимое хранилища. Не генерируйте новые ключи вместо существующих. Для encrypted WebAuthn-ключей `APP_KEY` нужен даже при выключенном шифровании OTP. ## Конфигурация `DATABASE_URL=sqlite:///absolute/file.sqlite` имеет приоритет над `DB_DATABASE`. По умолчанию используется `sqlite://data/2fauth.sqlite`. Адрес прослушивания: `LISTEN_ADDR`, по умолчанию `127.0.0.1:8080`. Применяются исходные `APP_URL`, `APP_NAME`, `APP_KEY`, `APP_PREVIOUS_KEYS`, настройки SMTP `MAIL_*`, параметры `GITHUB_*`, `OPENID_*`, `WEBAUTHN_*`, `AUTH_GUARD`/`AUTHENTICATION_GUARD`, `AUTH_PROXY_HEADER_FOR_*`, `TRUSTED_PROXIES`, предпочтения `USERPREF_DEFAULT__*`/`USERPREF_LOCKED__*`. Дополнительно: | Параметр | Назначение | |---|---| | `STORAGE_PATH` | Каталог Laravel storage; по умолчанию `storage` | | `PASSPORT_KEY_PATH` | Каталог ключей Passport; по умолчанию `storage` | | `RUST_PUBLIC_DIR` | Каталог собранного интерфейса; по умолчанию `public` рядом с исходниками | | `RUST_COOKIE_SECURE` | `false` только для локального HTTP; по умолчанию Secure | | `APP_SUBDIRECTORY` | Например `/tools/2fa`; `APP_URL` должен содержать тот же путь | | `SESSION_DRIVER`, `SESSION_TABLE`, `SESSION_COOKIE`, `SESSION_ENCRYPT` | Чтение исходных Laravel-сессий: `file` или `database`; сохраняйте исходные параметры и `STORAGE_PATH` | | `PASSPORT_JSON_API_ROUTES` | `true` включает исправленные маршруты управления OAuth-клиентами и токенами; по умолчанию выключено, как в закреплённом PHP-эталоне | | `RUST_OAUTH_CONSENT_ENABLED` | `true` включает исправленный экран согласия OAuth; это явное расширение относительно дефектного маршрута эталона | | `OPENID_ISSUER` | Включает discovery и проверку подписанного ID token; без него сохранён upstream-flow с явными URL | | `OPENID_DISCOVERY_URL`, `OPENID_JWKS_URL` | Необязательные переопределения OIDC endpoints | В Docker каталог `/data` должен быть доступен UID 10001. В образе `STORAGE_PATH` и `PASSPORT_KEY_PATH` указывают на `/data/storage`. Команды и проверки для разработчиков приведены в английском README. ## Что ещё препятствует полной замене Другие СУБД; остальные Laravel session-хранилища (Redis, cookie и другие); все варианты конфигурации и переводы ошибок; полное сравнение всех маршрутов и middleware; браузерная проверка всех экранов и реальных SSO/WebAuthn-провайдеров. Некоторые диагностические ответы сознательно описывают Rust, а не PHP. QR-код может иметь другое SVG-представление при том же URI. Отдельные ограничения удалённых иконок и почтовых драйверов описаны в `compatibility/CURRENT.md`. Прохождение ограниченного набора тестов не означает полной совместимости. Боевой PHP-сервер пока не следует выключать на основании этого архива. ## Особенности закреплённого OAuth-эталона В исходном PHP-файле AppServiceProvider флаг регистрации JSON-маршрутов Passport устанавливается после загрузки пакета. Поэтому `/oauth/clients` и `/oauth/tokens` по умолчанию возвращают SPA для GET и 405 для изменений. Стандартный GET `/oauth/authorize` также неработоспособен: отсутствует реализация AuthorizationViewResponse. По умолчанию сохранено наблюдаемое поведение. Два явных параметра выше включают рабочее управление и согласие для authorization code; экран подтверждения Device Flow в этой версии сохраняет исходную ошибку привязки представления. Эти расширения не считаются точным воспроизведением дефектов эталона.