Odk Collect with Custom Certificate: Android 5 (works), Android 7,8 (fails)

I have installed ODK Collect on an Intranet with a Private Certification Authority created with easyrsa.

The site internaly is called sgformulare - extensions are not accepted by my router, and using the hosts file fails because of read-only permissions in not-jailbroken devices.

On three devices with Android 5, 7, and 8 I can access the ODK Collect site on my local server with a valid certificate, so I am pretty sure the CA is correctly installed via https://sgformulare and login.

On Android 5, I can also use ODK Collect connected with QR Code - download of forms and submissions work fine.

On A 7 and A 8, I get an error indicating an invalid certificate:

1 Like

I just realized that this had come up already last year:

@LN : In general, we do want to follow standard Android security practices.

I agree, but since Chrome has no problem with the certificate, I assume that this is some problem with the Android settings.

Since our development has come to a standstill because of this (we had tested with Android 5 before only), some solution would be really important. This is a pro bono project, but I might be able to find some fundings in case a solution can be guaranteed.

A custom build of ODK Collect is required:

Details are given in the Android docs.

  • Add android:networkSecurityConfig="@xml/network_security_config" to AndroidManifest.xml
  • Create xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
        <domain includeSubdomains="true">sgformulare</domain>
            <certificates src="@raw/sgformulare"/>
  • Add certificate /res/raw/sgformulare.crt. Important: remove any headers above ---BEGIN CERTIFICATE--
  • Note that the @raw/sgformulare does not include the extension crt.
  • Build and upload, get QR Code

There must be a better way without custom builds, as Chrome shows. Installing and running Android Studio is not to everybody's liking.

I unfortunately am spread pretty thin at the moment but I'll try to share a few helpful ideas.

First, did you consider using a public CA? I shared some resources at Selfsign certificate with latest Central with various approaches. In particular, https://security.stackexchange.com/a/174743 is where I'd start if I had your requirements. I also have read that CAs have official internal solutions but I haven't looked into what that entails.

It would be helpful to know more about Chrome's rationale for allowing user-specified CAs. Maybe if you really think a public CA won't work in your case, you could take a quick look to see if anything comes up? Collect can be used for quite sensitive data so it makes me uncomfortable to stray from Android defaults. I think we'd either want a strong explanation of why it's ok to accept any user-specified CA from another project such as Chrome or advice from a security professional. We really need to make sure that defaults are secure because running on an internal network is very rare.

1 Like

Thanks for your thoughts in busy times!

I know there are many mentions of using letsencrypt around, but it requires that the address is public, even if it is not accessible. Not permitted - and your default setting of "call home on errors" is neither, so I disabled it in my custom build.

We decided against using letsencrypt because of the following on their blog:

The best option: Generate your own certificate, either self-signed or signed by a local root, and trust it in your operating system’s trust store. Then use that certificate in your local web server. See below for details.

You wrote:

running on an internal network is very rare

This might be hen-and-egg: It's rare because it is so difficult. Care homes (as our use case) and small clinics would love when it would work in a local sandbox.

Some additions:

On Android 5.x, you must install the certificate in the phone settings, the code above does not give access to ODK Collect. You are forced to activate a login-screen for the tablet, and you will get a nasty message ("The network will probably be watched by a third party", translated from German) on the login screen.

On Android 8 (not tested on 7, but same as 8 per documentation), installing the certificate in the system is required for website access. For ODK Collect the certificate compiled into the app is required. When you can live without web access, you do not need a login pattern, and the nasty message does not turn up.

You can also use a long-living root certificate to avoid recompile on certificate change - the documentation is very clear, and it works.

Just to fully understand the use case here: is there a worry around running an ODK server in a publicly accessible place? If so, which server are you running? Or, are you unable to hit the internet from the internal intranet?

Or, are you unable to hit the internet from the internal intranet?

I would be able to, but to be sure that data stay inside it is safest to simply allow nothing out/in by firewall. This is standard in all hospitals and alike, to access the Internet for research etc they mostly have a second net with extra computers that cannot access patient data.

Is the worry the server being accessible on the public internet or traffic from the client travelling on the public internet? Or both? Or something else?

Sorry to be persistent! It's always good to make sure we get the full context, so we don't misinterpret the problem we're trying to solve.

The main worry is traffic from the client travelling in the Internet. If some internal API call travels abroad, it's borderline when we are sure about https:// - but I admit that after Edward Snowden and the double rejection of safe-harbor-laws by the European Court we have become very cautious - fines are horrendous.

If you ask me personally: I am pensioned and do pro-bono work, no insurance will cover me in case of a security problem. So I am better safe than sorry and just turn off all outside traffic - with the exception of an occasional port 22.

So I think it is right to let only https touch Central - but I never thought that in an Intranet settings there would be so many problems with Android and local CAs.

I can live with the "build-your-own ODK Collect" since it was pretty smooth - nevertheless, I would like to understand why Android Chrome accepts a Custom CA . Reading the documents, I would have guessed that Chrome would reject it too, but both Enketo Preview and ODK Central show valid certificates.

There are other issues: By default, ODK Collect has an Opt-Out button to report Crashes. I know that this can be switched off, but the QR-Code taken from the Central page always switches it on again.

This makes the app strictly speaking illegal under European Law if it is used to record person particulars, even if the name, address is not included. I probably will totally disable that function in my custom build, but again, that makes maintaining updates a nightmare.

Thanks for providing more details! I do wonder whether a solid VPN setup might be useful in this kind of situation but I don't have any experience in set up and management for one so it might just complicate the matter further!

This is interesting. Collect's analytics settings could probably use some love (now that the flux around Google moving everything to Firebase and then back again has settled) I would be really interested to hear more about the contexts you work in but I'm worried we'll take the thread off-topic, so I'll DM you.

In theory, it is possible to use selfsigned in .env, but I have not been able to get it to work; somehow, the certificate is always generated for localhost, even if I changed the settings in odk-setup.sh ( openssl req -x509 -newkey rsa:4086...)

Using customssl and creating a root certificate with easyrsa is anyway more flexible, but I would be interested to know how to get selfsigned to work.

I’m glad you’ve found a way forward, @dmenne, and I hope we can find a way to eliminate the need for a Collect fork in the future.

Wanting to operate entirely disconnected from the Internet does come up every once in a while and I’d like to have documentation on what we do and don’t support, what we recommend, and why. I’ve reached out to some folks who have helped us with security advice in the past to make sure we are thoughtful about tradeoffs.

It would also be helpful to organize some of the folks who have that need and see what solutions they have come up with. For example, @danbjoseph how does POSM deal with SSL?

If you have time for a user interview with @seadowg, @dmenne, that would be a great way to make sure your needs are comsidered. He’s a core Collect dev.

I started a thread at Options for Central when disconnected from the internet ?

1 Like