Setting up your own app store with F-Droid

(This blog post as now been cooked into an updated HOWTO)

The Google Play Store for Android is not available in all parts of the world, US law restricts its use in certain countries like Iran, and many countries block access to the Play Store, like China. Also, the Google Play Store tracks all user actions, reporting back to Google what apps have been installed and also run on the phone. Because of the NSA leaks, we’re seeing that governments are actively tapping into the raw data streams of Google, Yahoo, and others. So that means the information the Google Play Store sends back to Google is also intercepted by the NSA (and probably other country’s agencies), and that information is shared with other governments. In other words, your activity on the Google Play Store is far from private. Lastly, the Google Play Store is not free software, unlike the core of Android itself. It is proprietary software that Google entirely controls.

your-own-app-storeF-Droid is a wonderful, free app store for Android. It is modeled after the Debian GNU/Linux distro. It has its own package repositories (repos) and build servers for all the apps that are part of the official OS. Like Debian and Ubuntu, you can also setup your own repos for anyone to use. Any free software can be added to the official F-Droid repos, where they are built and signed by the F-Droid server. This can be annoying because it means that your apps in F-Droid are signed by a different key than your apps in the Google Play Store. If you host your own F-Droid repo, then people can use F-Droid to install your own builds signed by your own signing key.

This is a quick HOWTO for how to setup such a repository on a Debian or Ubuntu box. It is somewhat technical, you will use the terminal, but you don’t need to be a terminal expert to follow along. First you need a the fdroidserver tools and a webserver. For the webserver, here we use nginx for the webserver since its lightweight, but any will do if you already have one running. The fdroidserver tools are not yet in the official Debian/Ubuntu/etc repos, so you have to add our PPA (Personal Package Archive) to get it (fingerprint: F50E ADDD 2234 F563):

sudo add-apt-repository ppa:guardianproject/ppa
sudo apt-get update
sudo apt-get install fdroidserver nginx

In the case of this HOWTO, we’re going to setup a “Simple Binary Repository” to host our official APKs. The repo will be set up in the recommended fdroid/ subdirectory. This gives the fdroid tool its own directory to work in, and makes the repo URL clearly marked as an FDroid repo. Let’s give our normal user control over this subdirectory in the web root so that we don’t need to run the F-Droid tools as root (with nginx, the webroot is /usr/share/nginx/www, it is different for other webservers):

sudo mkdir /usr/share/nginx/www/fdroid
sudo chown -R $USER /usr/share/nginx/www/fdroid
cd /usr/share/nginx/www/fdroid
fdroid init

Now put your APK files into /usr/share/nginx/www/fdroid/repo and you are ready to run the commands to build the repo (if fdroid init cannot find your Android SDK in /opt/android-sdk or $ANDROID_HOME, it will prompt you for the path):

cd /usr/share/nginx/www/fdroid
cp /path/to/*.apk /usr/share/nginx/www/fdroid/repo/
fdroid update -c
fdroid update

fdroidheader3Voila! Now you have a working F-Droid Repo! Add it to an F-Droid client on your Android device to test it out. That is done in the Manage Repos screen available from the menu. Your repo URL will be the hostname or IP address of your machine with /fdroid/repo/ added to the end of it, i.e. https://mysecureserver.com/fdroid/repo/ or http://192.168.2.53/fdroid/repo/. You can temporarily uncheck the official repos to easily see what F-Droid found in your new repo.

Customization

You can also customize your repo by editing the config file. Be sure to use a programming text editor, like editor /usr/share/nginx/www/fdroid/config.py. In the config file, you can set the name of the repo, the description, the icon, paths to specific versions of the build tools, links to a related wiki, and whether to keep stats. Here’s the basic repo description block:

repo_url = "http://guardianproject.info/fdroid/repo"
repo_name = "My Local Repo"
repo_icon = "GP_Logo_hires.png"
repo_description = """
This is a local test repository of Hans-Christoph Steiner <hans@guardianproject.info>.  It is a repository of Guardian Project apps.
"""

To put your icon into your repo, choose a PNG image to put in your repo. The PNG goes in /usr/share/nginx/www/fdroid/, the file can be named whatever you want (by default its fdroid-icon.png). If you change the name from the default, be sure to update repo_icon and archive_icon in /usr/share/nginx/www/fdroid/config.py

More Security

apgNow that you have a working repo, its time to improve the security. Generating a repo in place is very easy, that is why this HOWTO started there, but it is not as secure as it should be if your repo is going to be your main distribution point. When generating the repo in place, make sure that config.py is not accessible via the web, since it contains passwords. If the file permissions are correct (e.g. chmod 0600 config.py), then config.py will not be readable by the webserver. But the signing keys will still be that public server. To improve this situation, generate the repo on a non-public machine like your laptop, keeping config.py and the keystore only on that machine, then use fdroid server update to publish the changes to your repo on a separate server. You just need to set serverwebroot in config.py properly, then fdroid server update will do the publishing via rsync over ssh. So both computers will have to have ssh and rsync installed and setup.

You can also use your own existing signing key rather than the one generated by fdroid init, just edit repo_keyalias, keystore, keystorepass, keypass, and keydname in /usr/share/nginx/www/fdroid/config.py

Since we like Tor and its Hidden Services for providing privacy, we also want to setup an F-Droid repository that is accessible over a Tor Hidden Service aka onion address. This will be covered in a future HOWTO.

40 comments for “Setting up your own app store with F-Droid

  1. 2013/11/06 at 4:36 am

    Be sure to use a programming text editor, like editor

    What in Discordias holy name? o.0

    • Hans-Christoph Steiner
      2013/11/06 at 9:47 am

      Like emacs, vi, gnome-edit, nano, etc. But if you’re on Debian/Ubuntu/etc, try running editor in the terminal, and you’ll see that it launches an editor. 🙂

      • 2013/11/19 at 2:32 am

        well, i knew what calling “editor” does.
        my problem was more like the distinction between “programming text editors” and… what exactly is the opposite?
        Worse: on all systems i tried, this defaults to nano for new uses (at least it would, hadn’t i changed it to vim). I don’t know about you, but nano isn’t what i would use to write code. 😀

        • Hans-Christoph Steiner
          2013/11/19 at 9:21 am

          The TextEdit program included in Mac OS X is a good example of a bad editor for programming. It is difficult to write files that start with a . (i.e. .bashrc and it wraps lines without warning.

        • cough cough
          2014/12/17 at 1:03 am

          best one really if you (do) code is called geany with all geany-plugins. # apt-cache search geany

          DO IT.

  2. Hans-Christoph Steiner
    2013/11/06 at 3:11 pm

    There is a little debate about using F-Droid on twitter here that I’d like to link in here:
    https://twitter.com/guardianproject/status/398092213651251201

    Yes, F-Droid’s official repo is a centralized repo along the lines of Google’s centralized repo in Google Play Store. But since users can disable the official repo and use any repo they want, F-Droid can be used in a very decentralized way. Each developer can have their own repo of APKs signed by their own key, and that repo is also signed by their own key.

    Taking this one step further in the Bazaar project, we’re working on making F-Droid able to use the apps that you have installed on your own phone as a local repo which you can choose to share using various peer-to-peer methods (bluetooth, OTR data, NFC, local WiFi, etc).

  3. daithib8
    2013/11/07 at 11:50 am

    Yes, the default repo is centralized, and in a different way to Google Play. All apks in F-Droid.org repo are signed via the one keystore, but that could hardly be otherwise given that all the apks are built from source on the one machine. All the builds are documented though; a principle that sets it apart from Google Play and all the other stores, which are decentralized in the sense that developers upload their own apks. Yes that results in a different security model, replacing several points of weakness with one weak point. It has the basis for greater security though, because the build documentation can lead to distributed verification of apks much like how the Tor project are going and, if realized, would be a great win for freedom and security. In the mean time anybody who is nervous can use the project to build their own apks fairly easily. So I’d like to champion the default repo—it should be supported by those who want a store with only free apps, because auditing and building those apps from source code can only be done by a dedicated team.

    • Hans-Christoph Steiner
      2013/11/07 at 12:24 pm

      I definitely agree with the goals of the central F-Droid repo: providing easy access to a huge trove of Free Software. My only concern is the security side. That one server is a very attractive target for hackers. It would definitely be a huge win if F-Droid had deterministic builds so that anyone could verify the F-Droid APKs by build the source on their own machine. devrandom, a Guardian Project member, is the lead developer of Gitian, which is a system to make it easier to have reproducable builds. Perhaps we can prod him into helping F-Droid achieve this.

  4. Hans-Christoph Steiner
    2013/12/02 at 4:15 pm

    This HOWTO used to recommend setting up the FDroid repo in the webroot, but now we recommend setting it up in an fdroid/ folder. This is for a couple reasons: it gives the fdroid tools their own folder to play in, and it gives a very recognizable URL (foo.com/fdroid/repo vs. foo.com/repo).

  5. 2014/01/10 at 4:31 am

    To support communications between repo servers have a look at OpenAEP (https://github.com/onepf/OpenAEP). F-droid should be easily be able to integrate that.

    • Hans-Christoph Steiner
      2014/01/10 at 9:09 am

      Looks interesting, but I’m not sure I see the use case. Is this deployed anywhere? Or is there more info on the problem it is trying to solve?

  6. Jeroen Mönch
    2014/01/18 at 6:39 pm

    Dear Hans,

    Maybe not the right place to post this but here it is anyway.

    I have read your post thought it was exactly what i needed espacially combined with a tor hidden service.

    Got it to work after some fiddling with all the dependencies of fdroidserver.

    Now i have a problem on my main phone it works like a charm updating, installing, deleting all working fine.

    Now i try to install it on several other phones and orbot is giving me a hard time saying: WARN: resolve request to hidden services not allowed failing.

    There is no diverence in versions and or settings… Do you have some tips?

    • Hans-Christoph Steiner
      2014/01/29 at 12:44 pm

      Did you get it working via a Tor Hidden Service? I haven’t tried that yet. As for your error, it sounds like this issue, which is solved by upgrading:
      https://dev.guardianproject.info/issues/1749

  7. daithib8
    2014/01/30 at 12:25 pm

    When it comes to centralization, I’m not only concerned about security. Deterministic builds could sort the security side of things, but if only one default source is allowed in the official client it could lead to arrogance and lock-in down the road. I have my own repo and I’ve found much room for differentiation, even in the metadata. There’s room for a competitor and the apks could be built and distributed by another party that has a good security infrastructure. It could do Tor by default. Now I don’t believe F-Droid would allow other default sources in the official client (except perhaps yours), so then the client would need rebranding too. Besides the UI for multiple repos in App Details is still awful and adds considerable complexity. If anybody is interested in contributing, you can find my repo at https://gitorious.org/asdgasd.

    BTW, I didn’t get any email replies previously.

  8. daithib8
    2014/02/15 at 10:39 am

    I think it’s broken at least on my openSUSE machine. I was running into problems generating an index with fdroid (‘failed to get apk signatures’, even though I compiled getsig.class and have my config.py set up), so tried fdroid init; firstly the sample config has moved and after that’s fixed, it’s hanging at keytool -list expecting a password, but I can’t do it.

  9. daithib8
    2014/02/15 at 10:43 am

    BTW that error was cause by using Java 6. Java 7 will get the apk signature. Which is annoying because I want to build the apks with Java 6.

  10. Adam Pritchard
    2014/04/08 at 2:48 pm

    F-Droid gives an error if you call `fdroid init` when the repo directory is non-empty (or maybe when it exists at all): “Looks like this is already an F-Droid repo, cowardly refusing to overwrite it…”

    So the workflow needs to be more like:

    – `mkdir fdroid`; `cd` into it
    – `fdroid init`
    – `mkdir repo` if it doesn’t exist; `cp` your APK into it
    – fdroid update -c; fdroid update

    (Tangential: Trying to get fdroid running on Windows defeated me.)

    • Hans-Christoph Steiner
      2014/04/08 at 3:08 pm

      Thanks for that, I fixed the instructions. So far the FDroid tools have only been developed on Debian/Ubuntu, so yeah, they probably have issues on other platforms. Did you try doing it in Cygwin? I think that would be necessary to get them working on Windows.

  11. Hans-Christoph Steiner
    2014/04/23 at 11:18 am

    For anyone who wants to try installing on a non-Debian system, there are now some instructions to make it easier:

    https://f-droid.org/wiki/page/Installing_the_Server/Repo_Tools

  12. Long Ly Hoang
    2014/06/27 at 6:45 am

    I followed all above steps and every fine, no errors.
    I installed fdroidclient to my emulator, add repo like http://localhost/fdroid-server/repo and update but nothing happen, client cant get info from server, cant see list app.

    this is my repo

    https://www.dropbox.com/s/hzb1ghhw59u2hh0/Screen%20Shot%202014-06-27%20at%205.42.28%20PM.png

    Can you have any suggestion?

    • Hans-Christoph Steiner
      2014/06/27 at 10:06 am

      Looks like your repo is setup properly. The problem is most likely that you are using localhost as your hostname. localhost will only work on the same computer, a phone or tablet won’t be able to reach your repo because on that phone or tablet, localhost means that phone or tablet. You need to use your IP address (probably something like 192.168.1.123), a real domain name that you have registered, or a dynamic DNS hostname that you have setup.

      • Long Ly Hoang
        2014/06/27 at 12:05 pm

        you’re right, that’s is my fault. Thanks you very much, you save my day.

  13. 2014/07/06 at 8:57 pm

    لطفابرنامهroot رابه ادرس بنده اىمىل کنىز

  14. user1234
    2014/07/20 at 2:26 pm

    Hi,

    When I run the following commands:

    fdroid update -c
    fdroid update

    It seems to do nothing and I get an output on the screen saying:

    must be string, not None

    Would you know why this is happening?

    Thanks

    • Hans-Christoph Steiner
      2014/08/12 at 11:54 am

      Sounds like a problem with your setup somewhere. What platform are you running it on? Are the Android tools in your PATH? Is Java 7 JDK installed?

  15. Sebas
    2014/08/19 at 6:36 am

    When I’m running fdroid update -c , It prints

    Failed to get apk information, skipping repo/filename.apk
    Creating signed index with this key

    Does anyone know a solution for this problem?

    Thanks

  16. 2014/09/26 at 7:22 am

    Hi! Do you know if they make any plugins to safeguard against hackers?
    I’m kinda paranoid about losing everything I’ve worked hard
    on. Any tips?

    • Hans-Christoph Steiner
      2014/10/02 at 4:49 pm

      You can use apps that are known to have better security practices. These include Orweb, Firefox, Chromium, and Chrome browsers, ChatSecure instant messenger, TextSecure SMS texting app, etc.

  17. Hans-Christoph Steiner
    2014/09/26 at 8:15 pm

    This blog post as now been cooked into an updated HOWTO:
    https://f-droid.org/wiki/page/Setup_an_FDroid_App_Repo

  18. 2015/04/30 at 8:32 am

    These app is wonderful app
    It is fastest access app
    Download it fast

  19. Stefan
    2015/08/04 at 7:35 pm

    Is it possible to make a private repo, so that only I or a few friends can get access to it? And so that the apps that I put there can’t by touched by anyone else? Anyone know? Please email me if you know a way to do this! My Rasberry Pi need something new to do..

    • Hans-Christoph Steiner
      2015/08/05 at 6:45 am

      If your site uses HTTPS, and you make the URL have a password-like path, and don’t publish the URL, then that will be as good as password authentication. For example:

      https://example.com/myverysecretpath/fdroid/repo

  20. Aravind
    2016/05/17 at 6:30 am

    error getting index file (fdroid)

    i’m getting this error when i try to connect my fdroid server with client.

  21. Hans-Christoph Steiner
    2016/06/28 at 3:41 am

    “error getting index” could mean lots of things. The latest version of F-Droid gives better error messages. Things to check:

    * is the repo address correct?
    * is the repo metadata signed? (that’s the default, `fdroid init` sets up the signing key)
    * if the repo is using HTTPS, does it have a valid certificate?

  22. Cyberman112
    2017/02/13 at 1:40 pm

    Whever I try to run “fdroid update” It gives me this error:

    cyberman112@deviceManager1:/usr/share/nginx/www/fdroid$ fdroid update
    CRITICAL: Unknown exception found!
    Traceback (most recent call last):
    File “/usr/bin/fdroid”, line 146, in
    main()
    File “/usr/bin/fdroid”, line 123, in main
    mod.main()
    File “/usr/lib/python2.7/dist-packages/fdroidserver/update.py”, line 1209, in main
    apks, cachechanged = scan_apks(apps, apkcache, repodirs[0], knownapks)
    File “/usr/lib/python2.7/dist-packages/fdroidserver/update.py”, line 571, in scan_apks
    dt_obj = datetime(*manifest.date_time)
    ValueError: month must be in 1..12

    What is going on?

Leave a Reply

Your email address will not be published. Required fields are marked *