We have built an Android app which uses Firebase for user authentication. Our (large enterprise) client is planning to deploy it behind their firewall. During initial testing, the authentication stage fails whenever we are using their network. It does work on an open network.
I am trying to find out what firewall configuration is needed to use the firebase authentication API, but I cannot find anything in the docs. I know that the firewall allows port 80 and 443 for outgoing connections. I am assuming that no specific IPs are blacklisted. Ports 5228-5230 (which would be required for FCM) are not opened yet, as we are currently not using push notifications. I am wondering if this is the issue. However, all references I can find (usually inofficial ones on stackoverflow) insist that the firebase authentification happens via https and only 443 should be needed.
Is anyone able to verify this and perhaps provide the documentation which details this?
Related
Can we check which data is sent to the server from an android app just like we can check request headers, form data etc in chrome dev tools??
There are several tools that help with that problem:
https://github.com/facebook/stetho (Here you can actually use chrome dev tools)
https://github.com/jgilfelt/chuck
https://www.charlesproxy.com/
More info: https://proandroiddev.com/various-methods-to-debug-http-traffic-in-the-android-application-8685b9183418
As I understand you need to read HTTP communication from another app. You need to set up proxy server on your local computer and then redirect traffic through that proxy on your phone. I use Proxyman (https://proxyman.io/). But remember that there are some limitations. First of all you will need to create your local SSL certificate and add it to trusted store on your phone, also you will probably need Android below 7 because they added some security configs for apps which makes it harder to sniff. Next thing is that some apps may pin their SSL certificates and despite your custom cert is in trusted store app may reject connection.
I want to have multiple clients that connect to a server over LAN and access/modify the mySQL database in the server.
How would i go about doing this? Can you guys provide some resources/links that i could research on the topic
To answer your question, you should be able to connect to a mysql database by adding the jdbc driver to your project as a jar file in Android Studio.
Now for a real app that you plan to distributed to thousands of users there are Security issues, Performance issues, and Scalability issues.
Security issues:
You expose your database directly to the internet by opening its port to public access for the apps to connect. A web app adds a layer in the middle, keeping the database access inside the intranet.
You expose your data directy to the public by providing at least one public account known by everybody (I assume this would be the way to access because managing one account per user wouldn't be realistic). A Web app isolates the user account from the database accounts.
By providing access this way, as android mobile devices can be rooted, you are potentially granting anonymous access to your data.
Performance Issues:
With a web app in the middle, it is the webapp who manages the
connections to the database. This enables sharing connections
amongst different users vs. one dedicated connection per user would
have if the different devices estable separate connections.
For the same reason, you can't take advantage of connection pooling,
which saves the overhed of establishing a connection to the database
for each incoming request.
Scalability issues:
As connections are not shared the number of concurrent users will be bound to the number of connections you can open at the same time to the database.
EDIT 1
I am adding an alternative I thought of which involves using a web application but it is not implemented using a webserver. It is a java NIO framework that runs on its own. The limitations of this solution is you need shell access to the server and java, which is not common in traditional hostings. Checkout Netty.
There are 2 ways how to do perform your task. You can either add the JDBC driver in android studio, or better implement a REST API that connects to your database, and all the android clients can send HTTP requests to the server and the server will add the information for you. Here you can implement the create, update, delete methods. For HTTP requests you can use Retrofit or Volley libraries.
If you want to use JDBC, check out the answer here How to Mysql JDBC Driver to android studio
But the best and most correct solution for this type of problems would be a REST Service
In the long run, you really need a "client" application between "users" and the database. It is usually done via a webserver, plus PHP/Java/VB/.... Yes, it requires you learn yet another language, but that is not something to avoid in a serious application.
The client can help (and hurt, if done adequately) with security. The client can insulate users from database changes, which will eventually happen. The client should 'abstract' the interface to the DB so that the users do not have to be SQL-savvy. Etc.
You have might installed WAMP Server / XAMPP Server for mySQL Database
Click on WAMP icon and select Apache, Open "httpd.conf" and find tag starts with
<Directory "c:/wamp/www">
...
</Directory>
and update the code as below
<Directory "c:/wamp/www">
AllowOverride All
Require all granted
Order Deny,Allow
Deny from none
Allow from all
Allow from 127.0.0.1
Allow from ::1
Allow from localhost
</Directory>
Now Create REST APIs in your local server as you might use PHP or whatever,
and connect android app with apis with assigned IP Address to your computer in LAN.
It is not one single answer, but a group of answers. Firstly what you need is the concept of data forwarding through introspected tunnels over the network. At the end of the day, your database is always listening on certain port, that is local to your machine, meaning only you can access and modify the contents of the database. For example if you access PHPMyAdmin, you can go the MySQL address on your local machine.
What you need to do is make that access public to the internet, what you need is to broadcast your existence(internet protocol address) to the web. Thus making a public hub, in short, Local-tunnels allows you to easily share a web service on your local development machine without messing with DNS and firewall settings.
By tunneling your local machine to web , anyone with the assigned IP address can access your machine(database) over any connection,not just LAN or WI-FI. There are many options to choose from, There is ngrok,which exposes a local server behind a NAT or firewall to the internet.
Features are,
Don’t constantly redeploy your in-progress work to get feedback from clients. ngrok creates a secure public URL (https://yourapp.ngrok.io) to a local webserver on your machine. Iterate quickly with immediate feedback without interrupting flow.
Test mobile apps against a development backend running on your machine. Point ngrok at your local dev server and then configure your app to use the ngrok URL. It won't change, even when you change networks.
Building web hook integrations can be a pain: it requires a public address and a lot of set up to trigger hooks. Save yourself time and frustration with ngrok. Inspect the HTTP traffic flowing over your tunnel. Then, replay web-hook requests with one click to iterate quickly while staying in context.
Own your data. Host personal cloud services on your own private network. Run web-mail, file syncing, and more securely on your hardware with full end-to-end encryption.
Its really great, however there is a side note, because this procedure opens up your local machine and renders it IP accessible on the internet, many different security challenges arise, so it is only recommended for testing purposes with none sensitive data.
Hope this helps:)
I have a client/server application where the clients are Android apps and the server is deployed on Amazon AWS. They communicate through REST over HTTPS to keep communication private. The server sits at https ://server.example.com and uses an SSL certificate that I created and signed myself. The client was written to check for this cert and to only communicate with a server using it.
Things generally work very well and we have thousands of users all over the world. However, sometimes I find that the client is unable to talk to the server. I can find this out because I've included a mobile analytics library that logs things like this and reports them.
When communication fails it's either because of a timeout at the client, or an error such as "Unable to resolve host server.example.com".
I believe that communication is failing because of one of the following:
The Android device is not connected to the internet
A firewall or something similar is blocking the communication
Why could we be blocked? Perhaps because we're using SSL. Perhaps we're not on someone's White List. I highly doubt we're on any Black List.
Any ideas on how to proceed? Can I somehow determine why communication cannot get through (I obviously don't have access to my user's devices). Is there something I can do to have more of the clint/server communication be successful?
Why not implement a network status checker to log network. Both timeout and unable to resolve host seem to be most probably come from losing connection.
In my own app, I'm using various 3rd party SDKs that make network calls( HTTP requests) in some form or other. Without editing this code, can I write code separately within the application to intercept all GET and POST requests that my app is making?
I want to record these HTTP calls in my app
I am aware of using Fiddler and Charles proxy tools but that is outside the app but this won't work because I can't record these HTTP calls in my app.
Is there a way to do it?
EDIT: I am using Google Analytics SDK and Facebook SDK in my code. I want to monitor all the network calls these SDK's are making from my app
On non rooted phone you can use android OS proxy and redirect traffic. But some apps doesn't respect it. Makes direct connections. Some tweaking could be done. Use Drony with VPN mode to redirect all traffic to SandroProxy. Here is video how capture then traffic with SandroProxy SandroProxy with Chrome devtools SandroProxy can also capture pcapfiles. Can also make ssl mitm on pcap flow. from SandroProxy support
Try HTTP Toolkit - it's an open-source tool I've been building to do exactly this. It can automatically intercept traffic from an Android device, with no manual setup required, and then allows you to inspect & rewrite all HTTP traffic from your computer, like so:
To intercept HTTPS traffic from your app, you just need to either a) trust 'user' certificates in your application's network security configuration (see https://stackoverflow.com/a/38770284/68051) or b) use an emulator or rooted device (in which case HTTP Toolkit can inject a 'system' certificate, which your app will trust automatically).
Charles proxy is a good way.
Others include if app is using singleton network class (which it ideally should), make one function for get and one for post. Call these functions from your classes and use log.d to output data on console. You can track request response or time taken.
If you are specifically looking for your app to be capable of recording the HTTP calls.
Android Snooper library can be the solution you are looking for.
Have you considered Stetho?
http://facebook.github.io/stetho/
You can monitor and modify all incoming and outgoing requests, among other things.
https://github.com/jgilfelt/chuck/
it adds a new app that send notifications each time a network request is made, and you can see the details of the request.
https://github.com/facebook/stetho
it allows you to use the chrome dev tools to monitor your requests created from an android app. (among other cool features)
If you root the device or running over debug (adb), then maybe this will help:
http://code.tutsplus.com/tutorials/analyzing-android-network-traffic--mobile-10663
Else I don't think its possible to do what you want to do. But you can monitor general network stuff like:
For all traffic stats see:
https://developer.android.com/reference/android/net/TrafficStats.html (just pass in your apps user id)
For monitoring network status:
https://developer.android.com/reference/android/net/ConnectivityManager.html
You Can use this as the better option. Remember to scroll down the app and check network intercept is on.
Link is here https://appetize.io/upload
Wonder if anyone here happen to know the ip range of google's gcm server (for android push notification)?
I need the information so that our network team can open the firewall port for our UAT environment for incoming UAT test.
I tried to lookup from developer.android.com/google/gcm/ but no luck.
Our network team refused to open all ip range from asn 15169 which is a rather huge list.
I think there is an existing question IP address for Google Cloud Messaging server and the person found out that those are not published by Google. I also tried to look for it once but couldn't find. I might be wrong but I am pretty sure they don't publish that. Maybe instead of using corporate wifi, you can use direct 3G or 4G data plan.
In a comment on why GCM is not giving push notification in android device? question someone has mentioned that He opened the ports 5258,29,30 and then he was able to receive the regId from GCM server behind firewall.
Also I think the answer by #Eran on Which port and protocol does Google Cloud Messaging (GCM) use? will be of help. It says:
The device accesses the GCM servers on ports 5228-5230. If your organization has a firewall that restricts the traffic to or from the Internet, you'll need to configure it to allow connectivity with GCM. The ports to open are: 5228, 5229, and 5230. GCM typically only uses 5228, but it sometimes uses 5229 and 5230. GCM doesn't provide specific IPs. It changes IPs frequently. We recommend against using ACLs but if you must use them, take a broad approach such as the method suggested in this support link.
This is relevant if your device is connected to the internet via WiFi.
Hope this helps a bit.
Update:
As per Mark Whitaker answer to a similar question here, he mentions that:
Newer versions of Android also fall back to port 443 if ports 5228-5230 are blocked by a firewall.
Although there doesn't seem to be an official list still.
To add to what Shobhit Puri already said, I've also tried to find the answer to this question to be able to poke the appropriate holes in my firewall and am extremely disappointed with Google after concluding that the IP address used for Google Cloud Messaging is not obtained using a DNS request, or are obtained using DNS requests that subvert the Always On VPN functionality in Android.
By using the Always On VPN function in later versions of Android, I made sure that all traffic went through one of my servers. This also allowed me to use that server as a DNS Resolver and by activating query logging and rebooting the phone I was able to get a list of all of the DNS requests that it makes. Then, with some scripting magic I checked all of them, but none of them resolved to the IP address(es) that show up in my firewall logs with outbound port 5228 drops.
This leads me to conclude that the IP addresses used for GCM are obtained using a method other than DNS, such as Google Play Store web traffic.
Edit (Solution?): After running a script through all of my firewall logs going back as far as I have them and pulling out all of the dstport 5228 entries, I've been able to compile a list of IP addresses that GCM has tried to connect to. I can't say that this is a complete list, it will likely change based on geographic location, but notice the pattern...
74.125.28.188
74.125.129.188
74.125.20.188
173.194.79.188
74.125.142.188
74.125.192.188
74.125.140.188
74.125.139.188
74.125.137.188
74.125.134.188
74.125.130.188
173.194.68.188
173.194.76.188
I've created a group for all of those IP addresses and have configured my firewall to use that for my GCM whitelist. I have also setup a report to check for any dstport 5228 drops to let me know if I ever need to revisit this.