Meefik's Blog

Freedom and Open Source

Интеграция Linux Deploy с Android

Начиная с версии 1.5.3 в Linux Deploy начаты работы по интеграции GNU/Linux контейнеров с окружением Android. Это открывает следующие возможности:

  • доступ ко всей файловой системе Android;
  • выполнение приложений/команд Android прямо из контейнера (например, getprop, reboot, shutdown);
  • переключение между консолью контейнера и Android (команда unchroot).

Для активации возможности запуска Android-приложений нужно в параметрах разрешить монтирование (Параметры -> Монтирование), а в качестве точки монтирования (Параметры -> Точки монтирования) должен быть добавлен каталог /system (добавлен по умолчанию). После этого нужно нажать кнопку СТАРТ в приложении, чтобы каталог смонтировался в контейнере. Команды из Android будут доступны из консоли контейнера, если их названия не пересекаются с аналогичными в контейнере, либо доступны по полному пути, например /system/bin/ls. Команды reboot и shutdown автоматически переопределены в контейнере и вызывают аналогичные команды из Android.

Если возможностей запуска некоторых команд из Android недостаточно, то можно воспользоваться переключением между консолью контейнера и Android командой unchroot внутри контейнера. Вызов unchroot без параметров открывает sh из Android со всеми его переменными окружения, вызов с параметрами запускает соответствующую команду в Android. Например:

root@THL:/ # linuxdeploy shell
Configuring the container: 
dns ... done 
mtab ... done 
Debian GNU/Linux 8 (jessie) [running on Android via Linux Deploy] 
root@localhost:/# unchroot getprop ro.product.model
thl 5000
root@localhost:/# unchroot
root@THL:/ # ls /data/
...
root@THL:/ # exit
root@localhost:/#

Таким образом, имея доступ к Android прямо из контейнера, можно организовывать более плотную интеграцию запускаемых приложений внутри GNU/Linux контейнеров с системой Android.

Немного о Linux Deploy

Проекту Linux Deploy (сокращенно LD) уже три года, и вот немного статистики. Текущая версия LD 1.5.2-160 - это 52 релиза и 160 обновлений, на github выложено 18 805 строк кода. Поддерживается более 10 000 устройств начиная с версии Android 2.1. Около 500 тыс. установок. На данный момент LD поддерживает 8 дистрибутивов (Debian, Ubuntu, Kali Linux, Fedora, Arch Linux, Gentoo, openSUSE, Slackware), для которых специально написаны инсталяторы и конфигураторы. Для каждого дистрибутива поддерживается от 2 до 9 архитектур (разновидности ARM и x86, 32 и 64 бита) и от 1 до 7 релизов. В общей сложности поддерживается 121 вариант версий дистрибутивов и их архитектур. Каждый дистрибутив может быть автоматически сконфигурирован для работы с 1 из 5 поддерживаемых окружений рабочего стола (XTerm, LXDE, Xfce, GNOME, KDE), не говоря уже о конфигурировании SSH, VNC и Xorg. С учетом окружений рабочего стола (дистрибутив/архитектура/окружение рабочего стола) получается 597 вариантов установки, которые могут быть автоматически развернуты и сконфигурированы через LD.

Немногие знают, но в LD есть интерфейс командной строки (CLI), который доступен из терминала через команду linuxdeploy. С помощью CLI можно управлять процессом развертывания дистрибутивов без графического интерфейса Android. Также, в последних версиях, CLI поддерживает работу не только в Android, но и на обычных компьютерах под GNU/Linux операционными системами. Это может быть полезно для экспериментов с разными дистрибутивами, их версиями и архитектурами. Что касается архитектуры, то LD поддерживает кросс-архитектурную инсталляцию ARM <-> x86, эмуляция реализована с помощью QEMU и работает в обе стороны, т.е. можно запускать x86 дистрибутивы на ARM архитектуре и ARM дистрибутивы на x86 арxитектуре. Для поддержки режима эмуляции в Linux-ядре должна присутствовать поддержка binfmt_misc.

Часто уже готовые сборки дистрибутивов распространяют в виде rootfs-архивов, которые представляют собой tar-архив корневой файловой системы. Такие архивы используются в системах виртуализации, основанных на контейнерах, например, OpenVZ или Docker. LD поддерживает установку из rootfs-архивов, для этого в параметрах LD достаточно выбрать тип установки RootFS и указать путь к архиву на карте памяти или ссылку на архив в интернете. В последних версиях добавлена функция экспорта в виде rootfs-архива уже установленной в LD системы. В дальнейшем можно будет использовать репозитории контейнеров для развертывания и запуска их через LD.

Linux Deploy - открытый некоммерческий проект, развитие которого зависит в том числе от вклада сторонних людей. Если вы заинтересованы в данном проекте, то поддержите его своим участием или сделайте пожертвование в копилку проекта, это поможет его развитию.

Установка GNU/Linux в оперативную память

Современные модели мобильных устройств комплектуются значительным объемом оперативной памяти, например, ThL 5000 имеет 2 ГБ ОЗУ и 1 ГБ swap памяти. Система Android и системные приложения используют не более 1 ГБ оперативной памяти. Таким образом, остается еще как минимум 1 ГБ памяти, которую можно использовать в своих целях.

В Linux Deploy версии 1.5.1 добавлена поддержка установки дистрибутивов GNU/Linux в оперативную память. Для этих целей создается tmpfs точка монтирования заданного размера, куда будет осуществляться установка дистрибутива. Для использования данной функции в Linux Deploy достаточно выбрать “Параметры -> Тип установки -> Оперативная память” (“Properties -> Installation type -> RAM”) и ниже указать размер создаваемого образа в мегабайтах. Если указано 0, то размер образа будет рассчитываться автоматически, исходя из объема свободной оперативной памяти.

Производительность GNU/Linux системы в таком режиме очень хорошая, приложения моментально запускаются, а интерфейсы реагируют на действия мгновенно. Также порадует и время установки дистрибутива. Например, базовый Debian на ThL 5000 устанавливается по Wi-Fi за 3 минуты, а вместе с графическим окружением LXDE и SSH сервером - за 5 минут. Минимальный размер образа для Debian: минимальная установка - 300 МБ, окружение рабочего стола LXDE + SSH сервер - 700 МБ.

Данный тип установки хорошо подходит для быстрой проверки чего-либо или быстрого доступа к каким-то функциям GNU/Linux дистрибутива без необходимости постоянного хранения образа системы. Следует помнить, что все данные, хранящиеся на диске в оперативной памяти, бесследно пропадут при перезагрузке устройства. Эту особенность можно использовать и с точки зрения безопасности, перезагрузка устройства сотрет все следы работы в GNU/Linux без возможности какого-либо восстановления.

Piggy .js & .sh

В один из вечеров решил отдохнуть и сделал анимированную версию поросенка для терминала Linux, а затем и на JavaScript. Сам поросенок является логотипом сетевой системы обнаружения и предотвращения вторжений с открытым исходным кодом Snort.

piggy

Код запуска в shell и веб-версия: http://meefik.ru/piggy

Установка и настройка RDP-сервера

Linux Deploy в качестве графической подсистемы по умолчанию использует VNC, как наиболее нативный сбособ организации удаленного доступа к рабочему столу GNU/Linux системы. Однако можно настроить удаленный доступ и по протоколу RDP, используемый в операционных системах MS Windows. В примере используется дистрибутив Ubuntu 12.04 (Precise Pangolin), однако с небольшими изменениями это будет работать и в других дистрибутивах. В данном случае RDP будет работать поверх VNC-сервера, поэтому требуется чтобы он был установлен. В Linux Deploy VNC-сервер устанавливается по умолчанию.

Инструкция

  • Запустить предварительно установленную GNU/Linux систему кнопкой СТАРТ из главного окна приложения.

  • Подключиться к системе по SSH, VNC (IP-адрес для подключения указан в верхней строке главного окна приложения) или через Android-терминал (сценарий linuxdeploy shell).

  • Открыть командную строку (терминал) системы и переключиться в режим суперпользователя:
    sudo -s
    
  • Установить пакет xrdp:
    apt-get install xrdp
    
  • Разрешить пользователю xrdp работать с сетью:
    usermod -aG aid_inet xrdp
    
  • Для автоматического запуска и остановки RDP-сервера через интерфейс Linux Deploy необходимо в параметрах разрешить сценарии пользователя (Параметры -> Сценарии пользователя) и в список сценариев добавить путь /etc/init.d/xrdp (Параметры -> Список сценариев).

  • Перезапустить GNU/Linux систему кнопками СТОП/СТАРТ из главного окна приложения.

  • Подключиться через RDP-клиент: module - sesman-Xvnc, username - android, password - changeme.

Управление Linux Deploy из командной строки

Помимо графического интерфейса Linux Deploy позволяет управлять экземпляром GNU/Linux системы из командной строки через эмулятор терминала Android. Для данных целей служит специальный сценарий linuxdeploy, который может запускаться из командной строки Android и принимает следующие параметры:

  • prepare - подготовить контейнер, создать образ и файловую систему;
  • mount - смонтировать контейнер;
  • umount - размонтировать контейнер;
  • install - запустить установку новой системы;
  • configure - запустить переконфигурацию контейнера;
  • start - запустить контейнер;
  • stop - остановить контейнер;
  • shell - выполнить chroot в контейнер;
  • status - информация о системе.

По умолчанию сценарий linuxdeploy находится в каталоге ENV_DIR/bin/linuxdeploy, где ENV_DIR - каталог рабочего окружения (по умолчанию /data/data/ru.meefik.linuxdeploy/linux), однако доступ к нему можно сделать более удобным (без указания полного пути к сценарию), если поместить символьную ссылку на этот сценарий в /system/bin. Для этого в настройках Linux Deploy есть опция Настройки -> Создать симлинк, после изменения параметра необходимо выполнить обновление окружения (Настройки -> Обновить окружение).

Все параметры, установленные через графический интерфейс Linux Deploy, хранятся в файле ENV_DIR/etc/deploy.conf. Их можно менять путем редактирования этого файла, однако следует учесть, что любые изменения параметров через графический интерфейс приведут к перезаписи файла и потере внесенных изменений. Переключение профилей также приводит к перезаписи конфигурационного файла. Однако оригинальный конфигурационный файл можно скопировать, например, на карту памяти, отредактировать его и указать этот файл в качестве параметра “-c FILE”.

Команда linuxdeploy shell, наверное, наиболее полезна и нужна для доступа к командной строке установленного дистрибутива прямо из терминала Android. Эта команда также имеет необязательный параметр, принимающий команду, которую необходимо выполнить после перехода в chroot, по умолчанию запускается командный интерпретатор bash.

Примеры использования:

linuxdeploy shell date
linuxdeploy shell "uname -a"
linuxdeploy shell /bin/bash

Сборка ядра Linux и модулей для Android

Дистрибутивы, запускаемые через Linux Deploy, работают с ядром Android (модифицированное ядро Linux), а потому изменить конфигурацию ядра или подключить новые модули можно только путем пересборки этого ядра, либо сборки модулей под данную версию ядра.

Инструкция

  • Скачать и подготовить Android NDK:
    wget http://dl.google.com/android/ndk/android-ndk-r9d-linux-x86.tar.bz2
    tar -jxf android-ndk-r9d-linux-x86.tar.bz2
    export ARCH=arm
    export CROSS_COMPILE=$(pwd)/android-ndk-r9d/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-
    
  • Скачать и подготовить Android SDK, понадобятся утилиты adb и fastboot:
    wget http://dl.google.com/android/android-sdk_r13-linux_x86.tgz
    tar -zxf android-sdk_r13-linux_x86.tgz
    android-sdk-linux_x86/tools/android update sdk -u -t platform-tool
    export PATH=$PATH:$(pwd)/android-sdk-linux_x86/platform-tools
    
  • Получить исходники ядра данного устройства (в нашем случае это tinykernel-flo для Nexus 7 (2013), либо скачать аналогичную версию с kernel.org):
    git clone -b tiny-jb-mr2 https://github.com/meefik/tinykernel-flo
    cd tinykernel-flo
    
  • Получить файл конфигурации ядра с устройства (ядро должно быть собрано с поддержкой данной возможности):
    adb shell cat /proc/config.gz | gzip -d > .config
    

    либо из boot.img (как извлечь boot описано ниже):

    scripts/extract-ikconfig boot.img > .config
    
  • Если получить файл конфигурации ядра не получилось, то можно воспользоваться предварительной конфигурацией из поставки ядра (список конфигураций arch/arm/configs):
    make flo_defconfig
    
  • Узнать точную версию ядра устройства:
    adb shell cat /proc/version
    

    Рузультат команды:

    Linux version 3.4.0-g03485a6 (android-build@vpbs1.mtv.corp.google.com) (gcc version 4.7 (GCC) )
     #1 SMP PREEMPT Tue Mar 18 15:02:27 PDT 2014
    

    В данном случае полной версией ядра будет строка “3.4.0-g03485a6”.

  • Установить локальную версию ядра (то что отображается после основной версии 3.4.0):
    echo "-g03485a6" > .scmversion
    
  • Изменить конфигурацию ядра в файле .config или командой:
    make menuconfig
    

    В нашем случае в файл .config изменены следующие строки (включена поддержка модулей и включен модуль binfmt_misc):

    CONFIG_MODULES=y
    CONFIG_BINFMT_MISC=m
    
  • Запустить сборку ядра:
    make
    

    либо только модулей:

    make modules
    
  • Скачать утилиты для работы с загрузочным образом (boot.img):
    git clone https://github.com/meefik/binary-tools-android.git
    cd binary-tools-android
    
  • Получить загрузочный образ с устройства (ядро хранится на специальном boot разделе):
    adb shell su -с 'dd if=/dev/block/platform/msm_sdcc.1/by-name/boot' > boot.img
    

    Путь может отличаться на других устройствах, определить его можно командой:

    adb shell su -c 'ls /dev/block/platform/*/by-name/boot'
    
  • Получить информацию об образе:
    ./boot_info boot.img 
    

    Результат выглядит так:

    Page size: 2048 (0x00000800)
    Kernel size: 6722240 (0x006692c0)
    Ramdisk size: 492556 (0x0007840c)
    Second size: 0 (0x00000000)
    Board name: 
    Command line: 'console=ttyHSL0,115200,n8 androidboot.hardware=flo user_debug=31 msm_rtb.filter=0x3F ehci-hcd.park=3'
    Base address: 2149580800 (0x80200000)
    
  • Извлечь kernel и ramdisk из boot.img, заменить ядро и запаковать обратно:
    ./unmkbootimg boot.img
    ./mkbootimg --kernel ../tinykernel-flo/arch/arm/boot/zImage \
      --ramdisk initramfs.cpio.gz \
      --base 0x80200000 \
      --cmdline 'console=ttyHSL0,115200,n8 androidboot.hardware=flo user_debug=31 msm_rtb.filter=0x3F ehci-hcd.park=3' \
      -o new_boot.img
    
  • Прошить устройство новым ядром:
    adb reboot bootloader
    fastboot flash boot new_boot.img
    
  • Загрузить модуль на устройстве:
    adb push ../tinykernel-flo/fs/binfmt_misc.ko /storage/sdcard0/binfmt_misc.ko
    adb shell
    su
    mount -o rw,remount /system
    mkdir /system/lib/modules
    cp /storage/sdcard0/binfmt_misc.ko /system/lib/modules/binfmt_misc.ko
    chmod 644 /system/lib/modules/binfmt_misc.ko
    insmod /system/lib/modules/binfmt_misc.ko
    exit
    exit
    
  • Следует учесть, что vermagic модуля должен полностью соответствовать версии ядра (с точностью до символа), иначе загрузить новый модуль не удастся. Необходимо узнать vermagic модуля и сравнить его с уже присутствующими на устройстве модулями:
    modinfo binfmt_misc.ko
    

    Результат выглядит примерно так:

    filename:       /path/to/kernel/fs/binfmt_misc.ko
    license:        GPL
    depends:        
    intree:         Y
    vermagic:       3.4.0-g03485a6 SMP preempt ARMv7 
    

Запуск любого GNU/Linux дистрибутива из образа

Linux Deploy предназначен для автоматической установки через Интернет последних версий наиболее популярных Linux-дистрибутивов и последующего запуска Linux-приложений этих дистрибутивов под Android. Однако он также поддерживает запуск дистрибутив из уже готовых образов. Подготовленные образы дистрибутивов можно скачать с сайта проекта Linux-on-Android.

Инструкция

  • Скачать образ нужного дистрибутива (выбрать zip-архив с образом), распаковать и скопировать его на карту памяти.

  • В приложении Linux Deploy создать новый профиль и в параметрах указать (обязательно):
    Дистрибутив - должен соответствовать образу;
    Версия дистрибутива - должна соответствовать образу;
    Архитектура - должна соответствовать образу;
    Тип установки - Файл;
    Путь установки - путь к файлу *.img (например, /storage/sdcard0/debian.img).
    Остальные параметры настраиваются по желанию.

  • Выполнить переконфигурацию (Параметры -> Переконфигурировать).

  • Запустить GNU/Linux систему кнопкой СТАРТ из главного окна приложения.

  • Подключиться по SSH или VNC, пароль - changeme.

Запуск дистрибутива Kali Linux из образа

Дистрибутив Kali Linux основан на Debian и позиционируется как дистрибутив для тестирования информационной безопасности. Установка этого дистрибутива в Linux Deploy полностью поддерживается в автоматическом режиме с установкой из официального репозитория (см. инструкцию по установке GNU/Linux и инструкцию на сайте www.kali.org), однако в некоторых случаях может понадобиться установка из уже готового образа без доступа в Интернет.

linuxdeploy

Инструкция

  • Скачать архив ARM образа (например, для Raspberry Pi) и распаковать.

  • Извлечь из полного образа образ второго раздела (выполнять из-под Linux):
    kpartx -v -a kali-1.0.9-rpi.img
    dd if=/dev/mapper/loop0p2 of=/tmp/kali.img bs=1M
    

    Для образа Raspberry Pi это второй раздел, для образов других устройств нормер раздела может отличаться. Посмотреть таблицу разделов в образе можно командой:

    fdisk -l kali-1.0.9-rpi.img
    
  • Скопировать файл kali.img на карту памяти устройства. Если образ занимает более 4095 МБ, то карта памяти должна быть отформатирована в файловой системе exFAT, NTFS или другой, которая поддерживается на устройстве и может хранить файлы размером более 4 ГБ.

  • В приложении Linux Deploy создать новый профиль и в параметрах указать: Дистрибутив - Kali Linux; Версия дистрибутива - kali; Тип установки - Файл; Путь установки - путь к файлу kali-linux.img (например, /storage/sdcard1/kali.img); Окружение рабочего стола - Xfce.

  • Выполнить переконфигурацию (Параметры -> Переконфигурировать).

  • Запустить GNU/Linux систему кнопкой СТАРТ из главного окна приложения.

  • Подключиться по SSH или VNC, пароль - changeme.

Обзор графических подсистем Linux Deploy

Linux Deploy поддерживает несколько графических подсистем, вариантов вывода графики, которые можно использовать в зависимости от поставленной задачи.

VNC используется по умолчанию и представляет собой программный сервер, который запускается параллельно с работой Android и создает виртуальный рабочий стол, к которому можно подключиться через специальное приложение — VNC-клиент. По VNC можно подключиться как локально, прямо с устройства, так и удаленно, например, с компьютера или другого устройства. Единственным условием является то, чтобы устройства были в одной подсети, например, подключены к одному роутеру. VNC имеет два основных параметра: адрес сервера и номер дисплея. Адрес сервера — это IP или имя хоста, где запущен VNC-сервер. Номер дисплея — это номер виртуального рабочего стола с которым мы хотим работать и на котором запускается окружение рабочего стола. Номер дисплея находится в диапазоне от 0 до 99 и соответствует номеру порта VNC-сервера от 5900 до 5999 соответственно, именно этот порт будет открыт на сервере для ожидания подключения клиента. VNC прост в настройке, есть множество приложений-клиентов, кроссплатформенный, но не лишен своих недостатков. К таким недостаткам можно отнести относительно невысокую отзывчивости графики, отсутствие поддержки аппаратного ускорения, отсутствие мультитача, дополнительная нагрузка на систему и некоторые другие.

Для использования VNC в Linux Deploy достаточно зайти в параметры текущего профиля и выбрать VNC в качестве графической подсистемы (Параметры -> Графическая подсистема -> VNC). А затем, при необходимости, можно изменить настройки VNC-сервера в меню Параметры -> Параметры GUI. После этого, при запуске GNU/Linux, окружение рабочего стола будет запускаться внутри виртуального X-сервера, доступ к которому будет открыт для VNC-клиента. Для подключения к серверу в VNC-клиенте достаточно указать IP-адрес данного устройства (IP-адрес отображается в верхней строке приложения Linux Deploy) и номер дисплея, к которому следует подключиться.

Другой графической подсистемой, позволяющей запускать GNU/Linux параллельно с Android, является режим X Server (X Window System). Включается режим также в параметрах графической подсистемы (Параметры -> Графическая подсистема -> X Server). Данный режим позволяет запускать графическое окружение рабочего стола на стороннем X-сервере. Здесь сервер отвечает за прорисовку графики и отображение ее на видеоадаптере, а клиент — за выполнение приложений и передачу графики на сервер. Так, в данном случае, клиентом является GNU/Linux система и запускаемые в ней приложения, а сервером — другое приложение в Android (например, XServer XSDL), либо вообще на другом компьютере (например, Xorg, Xnest, Xephyr, Xming). X-сервер позволяет в некоторой степени решить вопрос производительности и существенно повысить отзывчивость графических интерфейсов, при этом не лишает возможности использовать необходимые функции Android-устройства в случае локального запуска сервера.

Для вывода графики на внешний X-сервер в параметрах Linux Deploy следует указать адрес сервера (IP или имя хоста) и дисплей сервера. Затем запустить X-сервер, а после запустить GNU/Linux через Linux Deploy. После этого на указанном X-сервера должно запуститься окружение рабочего стола. По такой схеме работают тонкие клиенты, только в данном случае роль тонкого клиента выполняет компьютер (или само устройство), а роль сервера — телефон/планшет.

И, наконец, следует упомянуть еще один режим графической подсистемы — фреймбуфер. В этом режиме при выводе графики GNU/Linux приложениями нет посредников, все работает как в полноценных десктопных дистрибутивах. Входящий в комплект дистрибутива X-сервер (Xorg) настраивается таким образом, что вывод графики осуществляется через специальный драйвер — fbdev. Отдельно настраивается адрес видеоустройства (например, /dev/graphics/fb0) и устройств ввода (например, /dev/input/event2 для тачскрина) для работы напрямую с железом. Данный режим дает указание X-серверу перенаправлять изображение напрямую на видеоустройство, а также использовать прямой доступ к устройствам ввода. В этом случае появляется выигрыш в производительности за счет прямого доступа к аппаратным ресурсам устройства. Однако тут есть обратная сторона. К сожалению, графическая подсистема Android и GNU/Linux не могут работать одновременно. Чтобы иметь возможность запустить графические приложения GNU/Linux в этом режиме, Linux Deploy приостанавливает работу Android на время, пока выполняются Linux-приложения. После завершения графического сеанса работа Android корректно возобновляется без необходимости перезагружать устройство (впрочем, есть и другие варианты, как с полной остановкой Android, так и вообще без остановки). Другим ограничением использования данного режима является проблема совместимости Xorg с аппаратными ресурсами устройства в некоторых случаях.

Для перевода Linux Deploy в режим фреймбуфера нужно выбрать соответствующую графическую подсистему (Параметры -> Графическая подсистема -> Framebuffer). Если в списке компонентов не выбран X-сервер, то это следует сделать (Параметры -> Выбрать компоненты) и выполнить переконфигурацию (Параметры -> Переконфигурировать) для установки необходимых пакетов. В параметрах графической подсистемы (Параметры -> Параметры GUI) следует указать видеоустройство и устройство ввода конкретного девайса. Также может потребоваться заморозить Android UI для корректной работы данного режима. Параметры Xorg сервера можно настроить более тонко в файле /etc/X11/xorg.conf внутри окружения установленного дистрибутива.