Closed pascalwhoop closed 5 years ago
For context, this issue is being opened because Signal uses the Android JobScheduler to schedule message sends. As of targetSdk 26, JobScheduler is the only way to be notified when network is available (without resorting to a persistent foreground notification).
This conflicts with some people's firewall settings, as blocking the "Android System" from accessing the internet prevents JobScheduler from working.
I'm assuming that if you don't want any network calls to Google, you're using some third-party ROM (like Lineage) with no Google Play Services.
My question is, in this scenario, is Lineage, via the "Android System", truly making network calls to Google? I'd highly doubt it, and if they are, I suggest you take it up with them.
hi @greyson-signal thanks for the context. I just quickly created the ticket from the road to get the ball rolling.
For context: I am using a sammy rom and I don't necessarily completely block google from my phone but the image below shows all the stuff that handset manufacturers stuff into their "system" class. THAT is of course such a giant list that it's intuitive to say "screw that they don't need my internet!"
Ultimately I'll boil it down to this though: Telegram works with this group blocked, whatsapp does, threema does (I think, haven't tried them in a while thanks to signal). Signal should work too. At least when I open the application and send a message, there should be no argument whatsoever to say "we can't". The app has internet access... that message needs to be able to be sent
I'd be curious to see what WorkManager's logs are saying the specific issue is. Can configure your firewall to reproduce the issue, send a message, and then immediately capture a debug log and post it here?
To sum up the findings in #8365:
I can confirm that there are signal jobs queued up in JobScheduler (by running adb shell dumpsys jobscheduler
; see comment). When I go online even after a reboot, with signal not running, android tries to execute those jobs (i.e. send the messages), I can see in the iptables logs that the firewall / iptables blocks the connection.
What seems to be happening is this: signal works fine for a while, until some day there is a connectivity glitch or some such thing, and the message does not get sent right away. The message then gets queued up in JobScheduler, and the next time JobScheduler tries to execute the 'send message task', the firewall sees this connection as originating from the System and not from Signal and blocks it. Signal's backup function stops working also because it's just another signal's job added to JobScheduler's list, and JobScheduler probably tries to execute jobs in the order they were received.
It would be good to understand the mechanics of interactions between Signal -> WorkManager -> JobScheduler -> Android OS (netfilter, etc). If signal schedules all of its messages to be sent through WorkManager, why doesn't netfilter / firewall stop them all? Or does WorkManager schedule them delayed only if it does not currently see the internet connection? Or does netfilter see them as originating from the System rather then Signal, but marks them as 'related' or something like that and lets them through?
In the meantime, possible workarounds for those of us who use firewalls are:
I have reproduced this issue on a fresh install of signal.
Steps to reproduce:
Steps to fix:
Debug log (I also have the adb logcat log of the same period, let me know which parts of that to send if that's also be useful) ~19:05 - sent a message with wifi off 19:08 - received a message sent to me (but the receipt confirmation never goes back to the sender) 19:09 - received a media message sent to me (but the photo can't be downloaded) 19:11 - going to settings and turning on backups; the backup does not get created 19:18 - turning off firewall 19:20 - turning wifi off and then on 19:23 - force-stopping signal app and restarting it; my unsent message gets sent, the photo gets downloaded and the backup created.
Firewall rules, minimal working example:
iptables -I OUTPUT -j DROP
iptables -I OUTPUT -m owner --uid-owner 10116 -j ACCEPT
(org.thoughtcrime.securesms has UID 10116 on my phone) The same result can be achieved in AFWall by allowing internet access only to Signal
Actually, @greyson-signal, the issue I mentioned in #8536 more closely resembled this one. What @biaq recounted is spot on; the difference is I don't even have any firewall or iptables installed yet, just Privacy Guard set up on Signal.
(but I do block connectivitycheck.gstatic.com, www.google.com, etc at DNS and web proxy level)
(but I do block connectivitycheck.gstatic.com, www.google.com, etc at DNS and web proxy level)
Which is in fact the same. It always depends on the succeeding/failing connectivity check.
I can't send messages from my Huawei phone but can receive when port 80 is closed. Open port 80 on the firewall and messages start sending again, close port 80 and messages just show circle animation.
Which is in fact the same thing as well. The connectivity check fails if you block port 80 (obviously, as you can't reach the connectivitycheck.gstatic.com on port 80).
Just wanted to mention that Google's connectivity check is not the sole cause of this issue. On my Replicant android v6.0 (with none of google's stuff) I don't see any connections to google's servers in the logs. But when this issue is acting up, there are blocked connections to Amazon's servers on port 443 in the iptables logs.
Failing this connectivity check might still be an issue on some androids. For instance, if the OS tries to run this test, and when it fails it tells JobScheduler that there's no point in trying to run the jobs that require internet connection.
But whitelisting google's connectivity check in the firewall wouldn't completely solve this problem.
But whitelisting google's connectivity check in the firewall wouldn't completely solve this problem.
It's really a problem with Android. Older android versions did this check with HTTPS which would break in schools because they use MITM servers to monitor the kids. So in later versions it's changed to unencrypted ports but then that breaks if a firewall or privacy software stops clear text packets. A phone, and especially communication apps, should try to send as if life depends on it because there could be situations where life does depend on getting a message out.
If you have root, you can change the captive portal check URL: https://android.stackexchange.com/questions/186993/captive-portal-parameters/186995#186995
I'm going to close this issue though just because there's not much to do about it. At some level, we're always going to rely on the Android System to send stuff for us, and that means it'll need network access.
Based on #8365, we need a way for signal to function without having to contact any 3rd party we do not want to send signals to such as Google, Facebook or whatever big fish currently swims in the internet ocean.