Penyiapan Server Build

Server build F-Droid mengisolasi setiap proses build aplikasi di dalam lingkungan mesin virtual yang bersih, terisolasi, dan aman. Membangun ribuan aplikasi — terutama melalui proses otomatis atau tanpa pengawasan — dapat dianggap berisiko tinggi secara keamanan. Risiko ini semakin besar ketika hasil build (APK) didistribusikan secara luas dan semi-otomatis (misalnya “pembaruan tersedia”).

Anggap sebuah repositori sumber upstream telah disusupi. Berikut adalah beberapa hal yang bisa dilakukan penyerang dalam situasi seperti ini:

  1. Menambahkan langkah build khusus untuk menjalankan perintah berbahaya atas nama pengguna yang menjalankan proses build.
  2. Access the keystore.
  3. Memodifikasi berkas APK yang dibangun atau arsip sumber milik aplikasi lain di repositori.
  4. Mengubah metadata (termasuk skrip build, yang juga dapat menjalankan perintah apa pun) untuk aplikasi lain dalam repositori.

Melalui isolasi penuh, dampaknya setidaknya terbatas pada aplikasi yang terpengaruh. Lingkungan build tidak hanya segar untuk setiap proses build dan dihapus setelahnya, tetapi juga sepenuhnya terpisah dari lingkungan penandatanganan.

Selain masalah keamanan, ada beberapa aplikasi dengan kebutuhan khusus seperti versi lama dari NDK. Akan sangat tidak praktis (atau setidaknya sangat berantakan) jika harus memodifikasi dan memulihkan SDK di sistem yang digunakan untuk banyak tujuan. Namun, dalam batasan mesin virtual sekali pakai yang terisolasi, hal tersebut tetap memungkinkan dilakukan.

Semua ini memiliki keuntungan tambahan, yaitu menyediakan lingkungan standar yang sepenuhnya dapat direproduksi untuk membangun aplikasi. Selain itu, pendekatan ini memungkinkan pembuatan lingkungan build kustom yang disesuaikan untuk aplikasi tertentu.

Gambaran umum pengaturan

Berikut cara menyiapkan server build yang berfungsi, dimulai dari instalasi Debian/stable minimal yang bersih. Panduan ini mengasumsikan Anda telah mengatur fdroidserver. Menjalankan alat fdroidserver langsung dari git (misalnya ~/fdroidserver/fdroid build org.adaway) cenderung menjadi cara termudah untuk saat ini karena skrip penyiapan server build belum siap sepenuhnya untuk dikemas. Selain itu, proses ini mungkin hanya bekerja di Debian, Ubuntu, dan turunan Debian lainnya, karena F-Droid menggunakan Debian untuk seluruh infrastrukturnya (kontribusi porting sangat diterima!).

Server dasar harus minimal menggunakan Debian/trixie, atau Anda perlu melakukan banyak penyesuaian. Jika Anda menggunakan Ubuntu atau distribusi turunannya, Anda dapat memperoleh paket yang hilang (seperti vagrant-cachier) dari PPA ini: https://launchpad.net/~fdroid/+archive/ubuntu/buildserver/

First, install the necessary packages and create a new user to run the whole process here, e.g. fdroid. These are only the packages required by all builds, you might need to install additional packages to build apps, for example, mercurial or subversion. Once the packages are installed and the fdroid user is created, nothing else in this process should be run using root or sudo.

root:~# apt-get install vagrant git python3-certifi \
        python3-libvirt python3-requestbuilder python3-yaml \
        python3-progress python3-vagrant python3-paramiko python3-pyasn1 \
        python3-pyasn1-modules python3-requests python3-git
        vagrant-mutate vagrant-libvirt ebtables dnsmasq-base \
        libvirt-clients libvirt-daemon-system qemu-kvm qemu-utils
root:~# adduser --disabled-password fdroid
root:~# su fdroid

Kloning kode sumber dengan menjalankan perintah ini sebagai pengguna fdroid:

fdroid:~$ cd ~
fdroid:~$ git clone https://gitlab.com/fdroid/fdroidserver.git

Pastikan variabel lingkungan ANDROID_HOME Anda telah dikonfigurasi dengan benar.

For your convenience you optionally may add the fdroid executable to your path:

fdroid:~$ echo "PATH=\$PATH:$HOME/fdroidserver" >> ~/.bashrc

Ambil semua metadata build aplikasi dari repositori fdroiddata

fdroid:~/fdroidserver$ cd ~
fdroid:~$ git clone https://gitlab.com/fdroid/fdroiddata.git
fdroid:~$ cp fdroidserver/examples/config.yml fdroiddata/
fdroid:~$ sed -i "s@^[# ]*build_server_always.*@build_server_always: true@" fdroiddata/config.yml

Menyiapkan server build

In addition to the basic setup previously described, we ship a Vagrant-compatible Debian/bullseye base box called ‘fdroid/bullseye64’.

We are bootstrapping the Debian Vagrant boxes for our buildserver from scratch. Fetching and verifying our pre-build Vagrant boxes is fully automated. (If you are interested in this process or want to bootstrap those by yourself you should look at: F-Droid Base Box)

Membuat box buildserver F-Droid

Buat berkas konfigurasi untuk Vagrant di ~/fdroidserver/buildserver/Vagrantfile.yaml dengan isi sebagai berikut:

vm_provider: libvirt

Then the base buildserver image… (downloading the basebox and all the SDK platforms can take long time).

fdroid:~$ cd fdroidserver
fdroid:~/fdroidserver$ ./makebuildserver --verbose

Proses ini akan memakan waktu lama, menggunakan banyak bandwidth dan ruang penyimpanan — sebagian besar digunakan untuk menginstal komponen SDK Android yang diperlukan di berbagai platform. Untungnya, ini hanya perlu dilakukan sesekali. Setelah memiliki image server build yang berfungsi, jika ada perubahan dalam resep build (misalnya paket baru perlu ditambahkan), cukup jalankan skrip tersebut lagi untuk memperbarui image yang sudah ada.

Once it’s complete you’ll have a new base box called ‘buildserver’ which is what’s used for your App build runs. Now you can build packages as you used to, but when you run fdroid build --verbose --server ... App build runs will be isolated inside a virtual machine.

Meskipun image yang dibuat dialokasikan dengan jumlah inti CPU dan memori terbatas, Anda dapat mengubahnya secara dinamis pada saat runtime dengan menyunting ~/fdroiddata/builder/Vagrantfile, misalnya menambahkan libvirt.cpus = 6 dan libvirt.memory = 12288. Namun, pastikan tidak melampaui batas sumber daya mesin host, atau mesin virtual dapat dihentikan secara paksa.

Setiap kali build pertama kali dijalankan, mesin virtual baru akan dibuat menggunakan box ‘buildserver’ sebagai dasar. Snapshot dari kondisi mesin yang bersih ini disimpan untuk digunakan pada build berikutnya guna meningkatkan kinerja. Anda dapat memaksa sistem untuk menghapus snapshot ini dan membangun ulang dari awal dengan menggunakan perintah: fdroid build --resetserver ....

Penyesuaian caching makebuildserver (opsional)

Unduhan utama SDK/NDK akan otomatis di-cache untuk mempercepat proses build berikutnya. Namun, tidak ada cara praktis untuk melakukan cache bagi bagian yang lebih lama, seperti instalasi platform, add-on, dan alat menggunakan perintah android. Sebagai alternatif, Anda dapat menyediakan direktori cache yang sudah diisi sebelumnya, yang berisi tidak hanya unduhan tersebut, tetapi juga berkas .tar.gz untuk berbagai komponen tambahan. Jika skrip provisioning mendeteksi berkas-berkas tersebut, maka berkas tersebut akan digunakan alih-alih menjalankan alat android. Misalnya, jika Anda memiliki buildserver/addons/cache/platforms/android-19.tar.gz, file ini akan digunakan untuk menginstal platform android-19, daripada mengunduh ulang menggunakan android update sdk --no-ui -t android-19. Anda bisa membuat berkas cache ini dari instalasi SDK lokal yang sudah berisi komponen tersebut.

cd /path/to/android-sdk/platforms
tar czf android-19.tar.gz android-19
mv android-19.tar.gz /path/to/buildserver/addons/cache/platforms/

Jika Anda sudah pernah membuat server build sebelumnya, Anda juga dapat menyalin berkas cache ini langsung dari server build yang sudah ada.

vagrant ssh -- -C 'tar -C ~/android-sdk/platforms czf android-19.tar.gz android-19'
vagrant ssh -- -C 'cat ~/android-sdk/platforms/android-19.tar.gz' > /path/to/fdroidserver/buildserver/cache/platforms/android19.tar.gz

Menjalankan proses build

Saat menggunakan server build, menjalankan fdroid langsung dari checkout git fdroidserver adalah cara termudah. Jika Anda belum menginstal dan menyiapkan alat fdroidserver, lakukan terlebih dahulu dengan mengikuti panduan: Installing the Server and Repo Tools. Panduan ini mencakup semua dependensi yang diperlukan untuk menjalankan fdroidserver langsung dari git.

Sekarang Anda siap untuk menjalankan build. Cobalah dengan membangun versi terbaru fdroid:

fdroid:~/fdroidserver$ cd ~/fdroiddata
fdroid:~/fdroiddata$ ~/fdroidserver/fdroid build org.fdroid.fdroid -l --server

Menyiapkan QEMU/KVM/libvirt

While VirtualBox was used in the past, QEMU/KVM guest VMs via libvirt is still the recommended setup since that is what is used by f-droid.org. In order to make the libvirt image files directly readable by vagrant package, libvirt’s QEMU needs to be configured to always set the ownership to libvirt.libvirt.

root:~# cat << EOF >> /etc/libvirt/qemu.conf
user = "libvirt"
group = "libvirt"
dynamic_ownership = 1
EOF
root:~# service libvirtd restart
Debian/bullseye dan Ubuntu/xenial
root:~# adduser fdroid libvirt
root:~# adduser fdroid libvirt-qemu
Debian dan Ubuntu versi lama
root:~# adduser fdroid libvirtd
root:~# adduser fdroid kvm

Penyiapan KVM bertingkat (Advanced Nested KVM)

Bagian ini tidak relevan untuk penggunaan F-Droid pada pengaturan normal. Namun, jika Anda ingin menjalankan perintah fdroid build --server di dalam KVM, bagian ini akan membantu Anda memulai.

Pertimbangkan pengaturan nesting dasar berikut:

bare metal host (l0)
\- F-Droid VM (l1)
   \- F-Droid builder VM (l2)

Langkah-langkah di atas menjelaskan cara menyiapkan (l1), dan makebuildserver menyiapkan (l2).

Pertama, periksa apakah CPU Anda mendukung set instruksi vmx (atau svm untuk CPU AMD). Anda dapat menjalankan perintah berikut untuk menampilkan detail CPU Anda:

root:~# cat /proc/cpuinfo

Pada (l0), pastikan bahwa fitur nesting telah diaktifkan:

root:~# cat /sys/module/kvm_intel/parameters/nested

Jika belum diaktifkan, Anda dapat mengaktifkannya dengan menjalankan:

echo "options kvm-intel nested=Y" > /etc/modprobe.d/kvm-intel.conf

Anda perlu me-restart sistem agar perubahan ini berlaku.

Next you’ll need to make sure that your (l1) vm configuration forwards cpu features required for nesting. So open up your configuration for the VM /etc/libvirt/qemu/my-vm.xml and insert a cpu block inside your domain-tag. (virt-manager also provides a user-interface for this operation.)

<cpu mode='custom' match='exact'>
    <model fallback='allow'>SandyBridge</model>
    <vendor>Intel</vendor>
    <feature policy='require' name='vmx'/>
</cpu>

Konfigurasi yang dibutuhkan di sini tergantung pada CPU Anda. Detail lebih lanjut dapat ditemukan di panduan libvirt. Bagian paling penting adalah memastikan bahwa fitur vmx (atau svm pada AMD) diteruskan ke sistem tamu.