Anbox is a containerized environment for Linux desktops that can run Android applications as if they were native.

Overview

  1. Use DKMS to install kernel modules
  2. Use snap to install anbox
  3. Change the container api version
  4. Fix SELinux
  5. Install google apps and ARM binary support

Install Kernel Modules

Anbox requires two kernel modules that are not available in the main line kernel yet. They are available out of the box on Ubuntu, but Fedora does not currently package them. The easiest way to manage them is to use DKMS.

Note that installing these will either require you to disable UEFI secure boot or sign them with a key that’s acceptable to your system’s UEFI configuration.

Install DKMS

DKMS is available in the fedora repositories and is installed in the usual way.

dnf install dkms

Install Modules

These instructions were taken straight from the README.md file in anbox-modules, and worked unmodified.

git clone https://github.com/anbox/anbox-modules.git
sudo cp anbox.conf /etc/modules-load.d
sudo cp 99-anbox.rules /lib/udev/rules.d
sudo cp -rT ashmem /usr/src/anbox-ashmem-1
sudo cp -rT binder /usr/src/anbox-binder-1
sudo dkms install anbox-ashmem/1
sudo dkms install anbox-binder/1

Install Anbox

Anbox is now distributed as a snap package. In theory, that means it will just work across distributions. It’s pretty close. I wound up on the edge track because the more stable version was failing in strange ways on Fedora.

sudo dnf install snapd android-tools
snap install --devmode --edge anbox

Change the Container API version

Anbox expects to be on cgroup API v1, not v2. Fedora 31 is leading the migration to v2, and runs it by default. Since I’m not running any podman controlled containers, I was happy to move it back to v1 for now.

sudo dnf install -y grubby
sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0"

Reboot so this can take effect.

Fix SELinux

The first time I tried this, anbox sat there with a loading screen for about two minutes, then failed to launch. This is because of missing SELinux type enforcement rules. To troubleshoot this, I rotated the audit log, restarted the snap.anbox.container-manager service, re-ran anbox.appmgr then looked at the audit log. audit2why and audit2allow greatly sped up this process.

Here’s the policy I finally installed:

module snapd_servicemgr 1.1;

require {
	type snappy_snap_t;
	type abrt_dump_oops_t;
	type snappy_confine_t;
	type snappy_mount_t;
	type unconfined_service_t;
	type tmp_t;
	type tmpfs_t;
	type tlp_t;
	type snappy_var_lib_t;
	type fs_t;
	class udp_socket create;
	class filesystem { mount remount unmount };
	class lnk_file { create getattr read };
	class dir { add_name create mounton read remove_name rmdir search setattr write };
	class file { create getattr mounton open read setattr };
	class binder { call set_context_mgr transfer };
}

#============= abrt_dump_oops_t ==============

#!!!! This avc is allowed in the current policy
allow abrt_dump_oops_t self:udp_socket create;

#============= snappy_confine_t ==============
allow snappy_confine_t tmpfs_t:filesystem unmount;

#============= snappy_mount_t ==============
allow snappy_mount_t fs_t:filesystem remount;
allow snappy_mount_t snappy_snap_t:dir mounton;
allow snappy_mount_t snappy_snap_t:filesystem unmount;
allow snappy_mount_t snappy_snap_t:lnk_file { getattr read };
allow snappy_mount_t tmp_t:dir { add_name create mounton read remove_name rmdir setattr write };
allow snappy_mount_t tmpfs_t:dir { add_name create mounton read setattr write };
allow snappy_mount_t tmpfs_t:file { create getattr mounton open read setattr };
allow snappy_mount_t tmpfs_t:filesystem mount;
allow snappy_mount_t tmpfs_t:lnk_file create;

#============= tlp_t ==============
allow tlp_t snappy_var_lib_t:dir search;

#============= unconfined_service_t ==============
allow unconfined_service_t self:binder set_context_mgr;
allow unconfined_service_t self:binder { call transfer };

With this in place, anbox runs with SELinux set to enforcing.

To build and install without failing and using audit2allow, save that file to snapd_servicemgr.te then run:

checkmodule -M -m -o snapd_servicemgr.mod snapd_servicemgr.te
semodule_package -o snapd_servicemgr.pp -m snapd_servicemgr.mod
semodule -i snapd_servicemgr.pp

(Optional) Install Google Apps

For running apps from the play store without sideloading them, it’s useful to install the play store itself along with ARM emulation. There’s a useful installer script available which does not quite work on Fedora 31 due to lack of a /snap directory. I’ve forked and made a pull request.