Перейти к основному содержимому

Аутентификация API и TLS

Узел защищает свои владельческие поверхности с помощью HTTP Basic, сверяясь с файлом секрета на диске. Owner API v3 кошелька использует токен, полученный с паролем кошелька. Внешние поверхности не требуют учётных данных, поскольку интерактивный перевод требует, чтобы принимающая сторона была доступна для стороннего участника. Терминация TLS остаётся на усмотрение оператора.

Поверхности

ПоверхностьПорт по умолчаниюУчётные данныеКто должен вызывать
Node /v1/*3413Basic, api_secret_path, на весь префиксВы, с той же машины
Node /v2/owner3413Basic, api_secret_pathВы, с той же машины
Node /v2/foreign3413Опциональный Basic, foreign_api_secret_pathВсё, что читает цепочку
Wallet Owner /v3/owner3420Токен из open_wallet, внутри зашифрованного конвертаВы, с той же машины
Wallet Owner /v2/owner3420Нет. Заменён на /v3/ownerНичего. Привяжите слушатель к loopback
Wallet Foreign /v2/foreign3415НетКонтрагент, оплачивающий вам

Foreign API кошелька принимает слейт (Slate), возвращает частично подписанный слейт, формирует coinbase для майнера, настроенного на выплату в этот кошелёк, и сообщает свою версию. Ограничьте доступ к нему на уровне прокси.

Учётные данные /v1 узла распространяются на весь префикс, включая операции чтения цепочки, открытые на /v2/foreign. См. поверхность v1 REST.

api_secret_path указывает на разный файл в конфигурации каждого бинарника. Обе поверхности узла читают файл узла, которым является .api_secret.

Доступ владельца к кошельку

/v3/owner защищён токеном, а не HTTP-учётными данными. Каждый метод трейта v3 принимает токен (api/src/owner_rpc_s.rs:78), а его получение означает завершение ECDH-рукопожатия и последующий вызов open_wallet с паролем кошелька. Пароль является ключом доступа. См. зашифрованное рукопожатие.

Первый вызов устанавливает общий ключ и не несёт учётных данных:

curl -s \
-d '{"jsonrpc":"2.0","method":"init_secure_api","params":{"ecdh_pubkey":"<your compressed public key, hex>"},"id":1}' \
http://127.0.0.1:3420/v3/owner

Помимо этих учётных данных, каждый метод на /v3/owner принимает token, а токен поступает из open_wallet, которому требуется пароль кошелька. owner_api_listen_interface по умолчанию равен 127.0.0.1; для удалённого доступа используйте туннель к loopback. Слушатель — controller/src/controller.rs:123.

Полный список методов, зашифрованный конверт и информация о том, какие вызовы перемещают средства, находятся на странице Owner API кошелька.

Учётные данные узла

Префикс /v1 узла и /v2/owner используют HTTP Basic с именем пользователя буквально epic и содержимым файла секрета в качестве пароля:

Authorization: Basic base64("epic:" + <secret file contents>)

Узел создаёт ~/.epic/<network>/.api_secret при первом запуске и указывает на него в api_secret_path, поэтому это работает без настройки:

curl -u epic:$(cat ~/.epic/main/.api_secret) \
-d '{"jsonrpc":"2.0","method":"get_status","params":[],"id":1}' \
http://127.0.0.1:3413/v2/owner

Файлы секретов содержат одну случайную буквенно-цифровую строку из 20 символов без завершающего символа новой строки (config/src/config.rs:84), а сравнение выполняется за постоянное время (api/src/auth.rs:74). Realm равен EpicAPI на владельческой поверхности и EpicForeignAPI на внешней. Отклонённый вызов, в любом из бинарников, возвращает 401 с заголовком WWW-Authenticate и телом ошибки JSON-RPC:

{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Unauthorized"}, "id": null}
  • При закомментированном api_secret_path слушатель работает без учётных данных.
  • Пустой .api_secret перегенерируется с новым значением, а не читается как «нет секрета», поэтому очистка файла не отключает аутентификацию (config/src/config.rs:96).
  • OPTIONS пропускается до проверки учётных данных, что обеспечивает работу CORS preflight.

Опциональные учётные данные на внешней поверхности узла

foreign_api_secret_path заставляет /v2/foreign узла также требовать учётные данные. Создайте секрет самостоятельно и укажите его абсолютный путь:

head -c 40 /dev/urandom | base64 | tr -dc 'A-Za-z0-9' | head -c 20 > ~/.epic/main/.foreign_api_secret
[server]
foreign_api_secret_path = "/home/you/.epic/main/.foreign_api_secret"

Realm равен EpicForeignAPI, имя пользователя по-прежнему epic. Проверьте с помощью:

curl -s -o /dev/null -w '%{http_code}\n' -X POST http://127.0.0.1:3413/v2/foreign
# 401 после установки секрета

Учётные данные, которые кошелёк передаёт узлу

node_api_secret_path указывает в обратном направлении: это то, что кошелёк отправляет при обращении к узлу, и по умолчанию равен <wallet dir>/.api_secret. При значениях по умолчанию узел и кошелёк совместно используют ~/.epic/<network>/ и разрешают его в один и тот же файл, поэтому они согласованы без дополнительной настройки. Если изменить секрет узла, переместить любой из каталогов или направить кошелёк на другой узел — это ключ, который нужно обновить.

TLS

Оба бинарника принимают одну и ту же пару, по умолчанию закомментированную:

tls_certificate_file = "/path/to/fullchain.pem"
tls_certificate_key = "/path/to/privkey.pem"

Указание сертификата переключает слушатель с HTTP на HTTPS. Указание сертификата без ключа является ошибкой при запуске. Сертификаты читаются как PEM-цепочка; ключи могут быть в формате PKCS#1, PKCS#8 или SEC1 PEM. Файл, который не удаётся открыть, разобрать или который не соответствует своему сертификату, останавливает процесс вместо отката к HTTP, поэтому неверная пара явно завершается ошибкой при запуске.

Встроенные подкоманды epic client обращаются к узлу через http:// (src/bin/cmd/client.rs:160). Используйте curl для работы с TLS-слушателем.

Далее