- Python 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| add_custom_cas.py | ||
| README.md | ||
Сборка Firefox Android со встроенными CA-сертификатами
Инструкция по сборке Firefox для Android ARM64 из исходников Mozilla с добавлением собственных CA-сертификатов непосредственно во встроенное NSS-хранилище Firefox.
В результате Firefox будет доверять указанным CA без установки сертификатов в системное хранилище Android.
1. Требования
Рекомендуется использовать Linux x86_64.
Для работы понадобятся:
- Git
- Python 3
- Perl
- OpenSSL
- Mercurial
- необходимые пакеты для сборки Firefox
- Android SDK/NDK
- Java 17
Для Arch Linux:
sudo pacman -S --needed \
git \
mercurial \
python \
perl \
openssl \
base-devel \
unzip \
zip \
yasm \
nasm \
ccache
Также должен быть доступен adb, если APK планируется устанавливать непосредственно на телефон:
sudo pacman -S --needed android-tools
2. Создание директории для исходников
В этой инструкции используется:
/mnt/games/firefox
Создаём её:
mkdir -p /mnt/games/firefox
cd /mnt/games/firefox
3. Получение исходников Firefox
Клонируем Mozilla Firefox:
git clone https://github.com/mozilla-firefox/firefox.git mozilla-central
Переходим в исходники:
cd /mnt/games/firefox/mozilla-central
Проверяем:
git status
4. Настройка Mozilla build environment
Создаём отдельную директорию для инструментов Mozilla:
mkdir -p /mnt/games/firefox/.mozbuild
Выставляем:
export MOZBUILD_STATE_PATH=/mnt/games/firefox/.mozbuild
Чтобы переменная сохранялась между сессиями shell:
echo 'export MOZBUILD_STATE_PATH=/mnt/games/firefox/.mozbuild' >> ~/.zshrc
Если используется bash:
echo 'export MOZBUILD_STATE_PATH=/mnt/games/firefox/.mozbuild' >> ~/.bashrc
После этого перезапустить shell или выполнить:
source ~/.zshrc
5. Создание mozconfig для Android ARM64
В директории исходников создаём:
cd /mnt/games/firefox/mozilla-central
nano mozconfig.android
Содержимое:
ac_add_options --enable-project=mobile/android
ac_add_options --target=aarch64
Выставляем этот конфиг:
export MOZCONFIG=/mnt/games/firefox/mozilla-central/mozconfig.android
Для постоянного использования:
echo 'export MOZCONFIG=/mnt/games/firefox/mozilla-central/mozconfig.android' >> ~/.zshrc
Проверить:
echo "$MOZCONFIG"
Должно быть:
/mnt/games/firefox/mozilla-central/mozconfig.android
6. Получение Android SDK, NDK и JDK
Firefox использует инструменты из .mozbuild.
Запускаем configure:
cd /mnt/games/firefox/mozilla-central
./mach configure
При первом запуске Mozilla build system автоматически установит необходимые инструменты.
После этого в .mozbuild должны появиться соответствующие компоненты, например:
/mnt/games/firefox/.mozbuild/android-sdk-linux
/mnt/games/firefox/.mozbuild/android-ndk-r30
/mnt/games/firefox/.mozbuild/jdk/
Проверить:
ls /mnt/games/firefox/.mozbuild
7. Проверка конфигурации
Повторно:
./mach configure
В выводе должно быть видно, что target — Android ARM64.
После успешного configure можно переходить к сборке.
8. Первая сборка Firefox
Собираем native-часть:
./mach build
Первая сборка может занимать значительное время и требует много дискового пространства.
После успешного завершения собираем Android debug APK:
./mach gradle fenix:assembleDebug
APK будет находиться примерно здесь:
obj-aarch64-unknown-linux-android/gradle/build/mobile/android/fenix/app/outputs/apk/debug/
Debug-сборку можно установить для проверки:
adb install -r \
obj-aarch64-unknown-linux-android/gradle/build/mobile/android/fenix/app/outputs/apk/debug/*.apk
9. Подготовка собственных CA-сертификатов
Создаём отдельную директорию:
mkdir -p /mnt/games/firefox/certs
Помещаем туда сертификаты:
/mnt/games/firefox/certs/
├── rt_root_ca.cer
├── rt_sub_ca.cer
└── rt_sub_ca_2024.cer
Формат сертификатов должен быть PEM X.509.
Проверить:
file /mnt/games/firefox/certs/*.cer
Также можно проверить каждый сертификат:
openssl x509 \
-in /mnt/games/firefox/certs/rt_root_ca.cer \
-noout \
-subject \
-issuer \
-serial
Для всех:
for cert in /mnt/games/firefox/certs/*.cer; do
echo "===== $cert ====="
openssl x509 \
-in "$cert" \
-noout \
-subject \
-issuer \
-serial
done
10. Скрипт автоматического добавления CA в NSS
Firefox использует NSS для встроенного хранилища сертификатов.
Основной файл:
security/nss/lib/ckfw/builtins/certdata.txt
Вместо ручного преобразования сертификатов используется автоматический скрипт.
Создаём:
cd /mnt/games/firefox
nano add_custom_cas.py
Вставляем полный скрипт add_custom_cas.py из этой инструкции/проекта.
Скрипт должен находиться здесь:
/mnt/games/firefox/add_custom_cas.py
И использовать:
/mnt/games/firefox/certs/
как источник сертификатов.
Делаем его исполняемым:
chmod +x /mnt/games/firefox/add_custom_cas.py
11. Проверка сертификатов перед изменением Firefox
Сначала запускаем скрипт без --apply:
cd /mnt/games/firefox
./add_custom_cas.py
На этом этапе скрипт:
- находит все
.cer; - проверяет их через OpenSSL;
- определяет self-signed root;
- определяет intermediate CA;
- проверяет цепочку;
- конвертирует сертификаты в DER;
- генерирует NSS
certdata.txt; - проверяет результат через
certdata.perl.
В конце должно быть:
Validating generated certdata.txt...
certdata.perl: OK
Dry run only. Nothing was modified.
Run with --apply to modify certdata.txt.
До этого момента исходники Firefox не изменяются.
12. Добавление CA в Firefox
Если dry-run завершился успешно:
cd /mnt/games/firefox
./add_custom_cas.py --apply
Скрипт добавит сертификаты в:
mozilla-central/security/nss/lib/ckfw/builtins/certdata.txt
При первом изменении создаётся backup:
certdata.txt.orig
13. Проверка внесённых изменений
Проверить ошибки форматирования:
git -C /mnt/games/firefox/mozilla-central diff --check
Посмотреть статистику:
git -C /mnt/games/firefox/mozilla-central diff --stat
Найти добавленный блок:
grep -n -A20 -B3 \
'BEGIN CUSTOM FIREFOX CA' \
/mnt/games/firefox/mozilla-central/security/nss/lib/ckfw/builtins/certdata.txt
В конце файла должен находиться блок:
# BEGIN CUSTOM FIREFOX CA
...
# END CUSTOM FIREFOX CA
14. Проверка trust-настроек
Root CA должен иметь:
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
Intermediate CA должны иметь:
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
Таким образом:
Russian Trusted Root CA
│
│ trusted
▼
Russian Trusted Sub CA
│
│ certificate chain
▼
Server certificate
Root является trust anchor.
Intermediate сертификаты добавляются в NSS для построения цепочки, но сами не становятся отдельными trust anchors.
15. Повторный запуск скрипта
Скрипт является идемпотентным.
Если выполнить:
./add_custom_cas.py --apply
повторно, он не должен создавать второй такой же блок.
Существующий блок:
# BEGIN CUSTOM FIREFOX CA
...
# END CUSTOM FIREFOX CA
будет заменён актуальным.
Это позволяет менять сертификаты в:
/mnt/games/firefox/certs/
и затем повторно запускать:
./add_custom_cas.py --apply
16. Сборка Firefox после добавления CA
После изменения certdata.txt:
cd /mnt/games/firefox/mozilla-central
./mach build
Затем собираем release APK:
./mach gradle fenix:assembleRelease
Готовый ARM64 APK:
obj-aarch64-unknown-linux-android/gradle/build/mobile/android/fenix/app/outputs/apk/release/fenix-arm64-v8a-release.apk
Полный путь:
/mnt/games/firefox/mozilla-central/obj-aarch64-unknown-linux-android/gradle/build/mobile/android/fenix/app/outputs/apk/release/fenix-arm64-v8a-release.apk
17. Проверка APK
Проверяем подпись:
$ANDROID_HOME/build-tools/*/apksigner verify --verbose \
/mnt/games/firefox/mozilla-central/obj-aarch64-unknown-linux-android/gradle/build/mobile/android/fenix/app/outputs/apk/release/fenix-arm64-v8a-release.apk
Должно быть:
Verified using v2 scheme: true
Версия Android SDK build-tools может отличаться, поэтому при необходимости посмотреть:
ls "$ANDROID_HOME/build-tools"
18. Установка на Android
Подключаем устройство с включённым USB debugging.
Проверяем:
adb devices
Устанавливаем:
adb install -r \
/mnt/games/firefox/mozilla-central/obj-aarch64-unknown-linux-android/gradle/build/mobile/android/fenix/app/outputs/apk/release/fenix-arm64-v8a-release.apk
19. Проверка работы custom CA
Открываем в собранном Firefox сайт, сертификат которого построен через добавленный CA.
Системный CA store Android при этом не требуется изменять.
Если сайт открывается без ошибки TLS, значит цепочка:
Firefox NSS
│
├── Russian Trusted Root CA
│ └── trusted
│
├── Russian Trusted Sub CA
│
└── Russian Trusted Sub CA 2024
работает внутри самого Firefox.
20. Обновление сертификатов
При замене сертификатов:
rm /mnt/games/firefox/certs/*.cer
поместить новые .cer:
/mnt/games/firefox/certs/
Затем:
cd /mnt/games/firefox
./add_custom_cas.py
Если проверка успешна:
./add_custom_cas.py --apply
После этого:
cd /mnt/games/firefox/mozilla-central
./mach build
./mach gradle fenix:assembleRelease
21. Полный workflow после первоначальной настройки
Когда Firefox уже один раз сконфигурирован, обычный процесс выглядит так:
cd /mnt/games/firefox
# 1. Положить/обновить CA
ls certs/
# 2. Проверить сертификаты и будущий certdata
./add_custom_cas.py
# 3. Применить изменения
./add_custom_cas.py --apply
# 4. Проверить git diff
git -C mozilla-central diff --check
# 5. Собрать Firefox
cd mozilla-central
./mach build
# 6. Собрать release APK
./mach gradle fenix:assembleRelease
Готовый APK:
obj-aarch64-unknown-linux-android/gradle/build/mobile/android/fenix/app/outputs/apk/release/fenix-arm64-v8a-release.apk
22. Структура рабочего каталога
В итоге структура выглядит примерно так:
/mnt/games/firefox/
├── .mozbuild/
│ ├── android-sdk-linux/
│ ├── android-ndk-r30/
│ └── jdk/
│
├── certs/
│ ├── rt_root_ca.cer
│ ├── rt_sub_ca.cer
│ └── rt_sub_ca_2024.cer
│
├── add_custom_cas.py
│
└── mozilla-central/
├── mozconfig.android
├── security/
│ └── nss/
│ └── lib/
│ └── ckfw/
│ └── builtins/
│ ├── certdata.txt
│ └── certdata.txt.orig
│
└── obj-aarch64-unknown-linux-android/
└── gradle/
└── build/
└── mobile/
└── android/
└── fenix/
└── app/
└── outputs/
└── apk/
└── release/
└── fenix-arm64-v8a-release.apk
Примечания
Почему сертификаты добавляются именно в NSS
Firefox не обязан использовать системное Android-хранилище CA для своей проверки TLS. Встроенное NSS-хранилище позволяет добавить CA непосредственно в приложение.
Поэтому установка CA через настройки Android не требуется.
Почему root и intermediate обрабатываются по-разному
Root CA является доверенным якорем:
CKT_NSS_TRUSTED_DELEGATOR
Intermediate CA не является самостоятельным trust anchor:
CKT_NSS_MUST_VERIFY_TRUST
Это позволяет Firefox использовать intermediate при построении цепочки, не превращая его в отдельный корень доверия.
Почему нельзя просто добавить PEM-файл
certdata.txt — это не PEM-хранилище. NSS build system ожидает сертификаты и связанные с ними атрибуты в формате certdata.txt.
add_custom_cas.py автоматически:
PEM
│
▼
DER
│
├── subject
├── issuer
├── serial
├── SHA-1
├── MD5
└── полный certificate DER
│
▼
NSS certdata.txt
│
▼
certdata.c
│
▼
Firefox/NSS
Поэтому сертификаты не нужно вручную преобразовывать или вставлять огромными DER/octal-блоками.