App Engine flexible behind a CDN (Fastly) - google-app-engine

We are running an App Engine Flexible app behind with Fastly (CDN) on the front. We have set up ghs.googlehosted.com as the origin server, so the CDN forwards the request to that server if it doesn't have the cached version. This has been running fine for months.
However, we want now to ensure Fastly connects to the origin (ghs.googlehosted.com) over TLS. It seems ghs.googlehosted.com does not support TLS. Any ideas of how to overcome this situation?

So far, this is what we have found out when choosing the origin host of our CDN (Fastly):
myapp.appspot.com: Supports TLS but requires the Host HTTP header to be exactly myapp.appspot.com. Therefore, the Host header needs to be overridden.
ghs.googlehosted.com: Does not support TLS, but accepts any Host HTTP header, so you can use any of your App Engine custom domains.
More info in this thread in the App Engine group.
Edit: I was missing sending the SNI in the request. Now it works well with ghs.googlehosted.com and TLS.

Related

Provisioning SSL certs for Google App Engine app w/custom domain DNS

I purchased a custom domain mydomain.com w/Google Domains last year. Until earlier this week, I was hosting a small single-page React app on that domain (in a Cloud Storage bucket) that connected to a GAE Flask app backend. Wasn't using SSL anywhere. All was well.
I now wish to use SSL. Since I'm new to all of this stuff, I followed the documentation to map my custom domain and secure it with SSL using Google-managed SSL certs. During this process, I created my first load balancer in GCP, then updated my domain's DNS entries for # A and www A to the LB's IP. The guides didn't say anything about changing the # AAAA entries, so I left them in place. Cloud CDN is disabled. Google Domains DNS Settings:
When creating the Google-managed SSL cert, I entered both mydomain.com and www.mydomain.com since I want both addresses to be secured w/SSL. After a few hours, the domain status for www.mydomain.com became active, but the status is FAILED_NOT_VISIBLE for mydomain.com. Guessing this is the source of my problems? Google SSL Cert Statuses:
Troubleshooting tips for this error:
The SSL Certificate isn't attached to the load balancer's target proxy. To resolve this issue, update the load balancer configuration. Done, and confirmed via both the GCP UI and the gcloud cli.
The domain's DNS record doesn't resolve to the IP address of the Google Cloud load balancer. To resolve this issue, update the DNS records to point to the load balancer's IP address. Thought I did this too, see my GAE custom domain settings below:
Attempting to load to mydomain.com or www.mydomain.com in the browser yields:
This site can’t provide a secure connection
www.mydomain.com uses an unsupported protocol.
ERR_SSL_VERSION_OR_CIPHER_MISMATCH
Unsupported protocol
The client and server don't support a common SSL protocol version or cipher suite.
It's been ~40hrs since I created the LB and updated the DNS settings for my domain, so I suspect the issue is my config and not DNS propagation. Where am I going wrong?
EDIT
Editing to clarify a few critical things:
I'm hosting my UI as a static website in a Google Cloud Storage bucket. Cloud Storage doesn't support HTTPS on its own, and therefore requires an HTTPS load balancer to work with custom domains.
If I wanted to go down this path, I'd need to ensure the load balancer pointed to my Cloud Storage bucket, which wasn't mentioned in my original post.
To roll back all changes from this SSL attempt, I'd need to update the # A DNS entry to the GAE IP, then update the www CNAME entry to c.storage.googleapis.com.. Note this CNAME entry is for Cloud Storage, not for GAE.
I ended up aborting the SSL idea and going with #3 (for now). The app in question is for a personal project that doesn't deal with any sensitive info, so SSL really isn't necessary.
You’ve gone through the process and receive the message:
ERR_SSL_VERSION_OR_CIPHER_MISMATCH
I’ve found some information for you. The main points are listed below.
Verify SSL Status of Website,
Check for Certificate Name Not Matching
Verify TLS Version
Verify RC4 Cipher Suite
Manually Inspect Security Certificate
There is more detail in this document here

With Identity Aware Proxy, is it possible to make a cross origin request to another GAE "service" in the same GCP project with a different hostname?

The setup:
Service A (frontend): GAE serving static site, all calls made from A are happening on client side.
Service B (api): GAE instance hosting REST API.
Without Identity Aware Proxy, I am able to make requests from the clientside of the frontend to the api on a different hostname by setting CORS to allow calls from the service A hostname.
I would like to be able to do the same thing while both services are behind Identity Aware Proxy.
Following the instructions in IAP docs I have:
Set my app to respond the OPTIONS requests
Changed the setting access_settings.cors_settings.allow_http_options to true using gcloud CLI.
Here is the error I'm facing:
Access to XMLHttpRequest at 'https://api-dot-my-app-dev.appspot.com/api/123' from origin 'https://frontend-dot-my-app-dev.appspot.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
When I make the same requests from localhost to localhost or from service A (client side) to localhost api the requests succeed.
This leads me to believe that the issue is related to Identity Aware Proxy. My only guess is that it's related to the preflight request, which I don't see anything about in the network requests in the browser console.
I would really like to be able to keep both apps behind IAP with their own hostnames while still communicating. Unfortunately, I have about exhausted ideas for how to do this.
In the meantime I have it working using alternative #2 below for now.
Alternatives:
Have the API serve the static site so they are on the same hostname
Use dispatch.yaml to serve both sites from the same hostname
Any ideas if this is possible or what might be going wrong?
Edit: Here is a repo to demonstrate my problem.
Edit 2: According to this article, this functionality used to work and Google said it would be a good idea to support it but offered not timeline.
Not sure if that can be applied on your use case but I have seen this kind of issue being resolved by allowing CORS preflight request to be passed through IAP by changing the access_settings.cors_settings.allow_http_options to true.

How to restrict public access to google app engine flexible environment?

I have many microservices in app engine only for internal use. But, by default, app engine opens service-project.appspot.com domain to public, and anyone can access them via http or https.
Is there a way to restrict access only for certain IP address?
The trivial way i can think of is checking source IP address in application code.
Or, I can create custom docker image with nginx configuration which checks source ip address. But, these are not quite clean solutions because access control is actually independent from application, and I don't want to hard code static IP address inside the container.
I assumed there is a way to setup firewall rule for app engine, but I could not find it. Identity-Aware Proxy seems like another option, but it is not available for app engine flex.
I know this is cold comfort, but we're working on re-enabling App Engine flex support for IAP. It's going to be more than just a few days, though.
https://cloud.google.com/appengine/docs/flexible/java/migrating#users has some options that might be more palatable than hardcoding IPs. You won't be able to use GCE firewall rules because the appspot.com traffic is coming through Cloud HTTP Load Balancer, so the GCE instance firewall only sees the IP of the load balancer. If you do want to verify IPs within your app, use X-Forwarded-For as described at https://cloud.google.com/compute/docs/load-balancing/http/#components .
Hope this helps! --Matthew, Cloud IAP engineer

Custom Domain for App Engine App Wrongly Pointing to SSL

I have an App Engine App at http://1.lyfekit.appspot.com/ and I want to use the custom domain http:// www. lyfekit .com/
I verified the domain and added it to app engine app settings. I added the CNAME record www pointing to ghs.googlehosted .com
BUT, http:// www. lyfekit .com/ is going to https: //lyfekit .com/ and is giving me an SSL error. I do not need https. I simply want http.
The way I understand, if I am not using https, I do not need to configure a Google Apps Account for the domain.
HTTPS is a protocol. It's totally separate from a domain name.
Somewhere in your app.yaml or web.xml file you have specified that you want a connection to be secure. App Engine follows your instructions and tries to use HTTPS protocol instead of HTTP protocol. Remove these instructions, and App Engine will stop using HTTPS
I'm not sure what you have done but the default module for your app (the one which your domain is mapped to) can be seen here:
http://lyfekit.appspot.com
and as you can see it redirects to https (because it will have secured:always set in the app.yaml file).
With your original URL you are specifying a particular version of your app (version 1) but as you can see by accessing the main appspot domain that version is not set as the default version.

Google App Engine SSL and Unique IP

My domain is hosted by Dreamhost. My app engine app is served by a custom domain, but is a sub-domain: app.example.com. My app is not accessed by a browser, but requests are made from an iOS app.
Now, I've purchased a basic SSL certificate from Dreamhost specifically for the subdomain app.example.com.
Next, I've uploaded the necessary crt and pem files to Google Domain Settings, and everything went ok with that. The domain settings do show that the upload was successful, and I have assigned the CNAME to ghs.googlehosted.com.
At this point, I'm not exactly sure what to do. Am I to expect SSL to just magically be enabled by this point? Because it still doesn't look like it has been.
What's confusing me is this talk about SNI and unique IPs. Dreamhost says, aside from GAE, that I'd need a unique IP to host my certificate. I'm not sure though if that's just a Dreamhost thing, or I really do need that. If so, do I need a unique IP for the subdomain separate from the main domain?
Or is this what SNI takes care of? What exactly should I be doing at this point?
You should understand what SNI is: http://en.wikipedia.org/wiki/Server_Name_Indication
Then you should follow the config docs for SSL on custom domains.
Btw, iOS since v4 supports SNI so you should be OK.
Update: if you want unique IP, then you should use VIP. But this costs extra and is not necessary in your case as iOS supports SNI. VIP is only needed for some older browsers.

Resources