Correctly assign HTTPS only custom domain to flex env - google-app-engine

What is the correct way to map a custom domain to Google App Engine project?
I've added the custom domain, set up all the DNS records etc. and it is working! But how do I enforce HTTPS only? (Like the custom domain generated does)
From reading around many posts I have seen secure: always in a handler which I have tried, but doesn't seem to work (saw some comments that it doesn't work on flex environments?)
So how can I correctly map my domain to a flex php environment being HTTPS only?! Seems such a simple thing to want to be able to do!

While being somewhat related to a custom domain (for example the SSL certificate used by HTTPS being tied to the domain) the HTTPS-only behaviour is not really an attribute of the custom domain mapping operation, it's just a behaviour of the app itself (regardless of being mapped to a custom domain or not).
For standard environment GAE apps part of the HTTPS-only behaviour is an automatic http -> https redirection performed by the GAE infra on behalf of the app if secure: always is set in the app.yaml configuration file.
But that configuration has, indeed, been deprecated for the flexible environment GAE apps. The PHP-specific deprecation note can be found at app.yaml changes:
Secure handlers
The secure setting under handlers is now deprecated for the App
Engine flexible environment. If you need SSL redirection, you can
update your application code and use the X-Forwarded-Proto header to
redirect http traffic. You can also use the HTTP Strict Transport
Security response header.
You'll also note that there is no mentioning of secure (or handlers for that matter) in the app.yaml Configuration File doc.
So you need to take care of the http -> https redirection inside your app code (or the framework you use for it, if any and if it has such capability), possibly following the suggestions from the above quote. I can't really help with details on this as I'm not a PHP user.

Related

Disabling version specific urls in Google appengine

Google App-Engine supports version-specific routing of requests as documented here.
This is useful for example for testing a new version prior to deploying it.
However, this may also be problematic. Say the new version includes security enhancements - there should be a way to prevent access to previous versions without deleting them completely (in order to allow for quick roll-back for instance). Could not find a way to disable previous versions.
Is there a way to accomplish that ?
Thanks.
There is no way to disable default/soft/targeted routing on the appspot.com domain.
But you could analyze the request's url structure and specifically reject requests with such undesired urls.
Or, if you're using a custom domain, reject all appspot.com requests (see Disable default domain https://[project-id].appspot.com of Node JS on Google App Engine) and only leave the custom domain operational. Then the domain will be served following the service's traffic migration/splitting configuration which you'd manipulate in your deployments/rollback actions (you cannot route to a specific service version in the dispatch.yaml file)
Update: indeed, as comments mentioned, blindly rejecting all appspot.com requests isn't a good idea. Since URLs would need to be parsed to select the undesired ones it may be worthy to take the opportunity to redirect to canonical custom domain counterparts instead of just rejecting the requests.

How to force https on Google Cloud AppEngine

I am trying to force https for all traffic to an app hosted on Google Cloud AppEngine. https works, but despite following the instructions for rewriting http traffic to https, it's still possible to access the site with http, which causes problems.
I have added this to the app.yaml:
handlers:
- url: /.*
script: _go_app
secure: always
redirect_http_response_code: 301
but it doesn't seem to make any difference.
I am using the julienschmidt router and then this to handle all routes:
log.Fatal(fmt.Println(http.ListenAndServe(":8080", router)))
I have looked at using http.ListenAndServeTLS but this takes extra parameters and I can't work out what the values of those should be in the Google AppEngine context.
log.Fatal(fmt.Println(http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", router)))
Where are "cert.pem" and "key.pem"?
I've read that I don't need to explicitly serve TLS in my app, because AppEngine will handle it for me, so even if I knew what the parameters were, I'm not sure it would help in forcing https.
http://sapling.appspot.com
https://sapling.appspot.com
http://sapling.money
https://sapling.money
All of the above work, but I don't seem able to force either of the http versions to https.
If you are using the secure:always handler and the requests are not being automatically redirected, then you are probably using App Engine Flex?
App Engine Flex does not support handlers, you can see this in the Flexible app.yaml documentation.
Instead, you can check in your code if a request was sent via HTTP or HTTPs and redirect. This is done with the App Engine specific header X-Forwarded-Proto.
The implementation is configured on your end and there is a brief paragraph on the subject.
You can also view similar Stack posts with the same answers 1
I hope this helps!
You are correct for including the secure: always element in your app.yaml as this will force HTTPS for your app's handlers.
However, I believe the following App Engine Documentation for "Securing Your App" found here may be of some use to you. As indicated in that link, you can convert HTTP URLs to HTTPS by simply replacing the periods between each resource with a -dot- instead. You may see the example provided below.
http://[SERVICE_ID].[MY_PROJECT_ID].appspot.com
https://[SERVICE_ID]-dot-[MY_PROJECT_ID].appspot.com
For additional information about HTTPS URLs and resource targeting you may see how requests are routed here.
Hope this helps!
You can use the Strict-Transport-Security header to instruct the browser to prefer https over http for a given page or an entire domain as outlined in this document. In order to add HTTP Strict-Transport-Security headers (HSTS) to your app, you must implement the headers within your app's code, not within your app's config file (app.yaml or appengine-web.xml).
It is also a good idea to enable HSTS preloading if you register your application with Google's HSTS preload list. Firefox and Chrome will never load your site over a non-secure connection.

Applying firewall rules to a specific tag in google cloud didn't work

I have a spring boot application deployed to an app engine service. The instance tag for this application is my_tag, this is configured inside the app.yaml file:
network:
instance_tag: my_tag
I created a few firewall rules with a target tag "my_tag" but non of them worked except one (the only one) which is deny all request (IP ranges: 0.0.0.0/0), this rule worked fine and it worked for one tag (my_tag), which is exactly what I want.
Note: even with making the priority higher for other rules, they also didn't work.
I am very glad to be of help. I've found feature request in the public issue tracker of Google in which another user is also asking for the creation of a specific set of rules for a specific service.
As explained there, a possible workaround would be to deploy the backend service to a project where the GAE Firewall rules prevent any requests except the other GAE services or to check that the requests are coming from the right service by adding an additional payload to the request.

Is it possible to have https://yourdomain.com on an App Engine site?

I know the Google App Engine docs say you can only have HTTPS on your foo.appspot.com domain, not with a custom domain.
But is it possible (and safe) to host a custom domain somewhere else, and set it up to proxy all HTTPS requests to https://foo.appspot.com?
If so, how would you recommend setting it up? And would it be much slower, compared to using https://foo.appspot.com directly?
Yes, it's possible to do this. It's secure if you trust your proxy and you use SSL from the proxy to the app. It will be noticeably slower, since there's a longer path between your user and your app. In addition, unless you get multiple proxies, all your traffic will have to go via a single global location, whereas the appspot domain is served from frontends all round the globe.

Many Custom Domains for AppEngine Instance

For our e-commerce service running on AppEngine we would like to offer the option for customers to run the stores on their custom domains (eg: www.mystore.com instead of www.enstore.com/mystore).
From a user perspective, I'd like them to enter the domain name they want to use in their preference screen and tell them how to configure their dns.
I know how you normally add domains to an AppEngine instance (through Google Apps) but I'm not sure you can automate that. And even if that's possible they would be all (hundreds) listed on our google apps page.
Anyone know if this is possible/if there is a good way to do it?
I don't think there is a way to add domains "programatically" to an AppEngine instance. Apparently, domains can only be added by using the Google Apps method that you described. This is confirmed in this SO post: How do i get foo.somedomain.com get handled by myapp.appspot.com/foo on appengine
The only options that pop to mind are the following:
HTTP Redirection
Many DNS providers support HTTP Redirection. In this case, your clients would be able to set up mystore.com and www.mystore.com to redirect to www.enstore.com/mystore. There are some obvious disadvantages with this method that might not be acceptable. First of all, with 301 and 302 redirects, the users will still be forwarded to the registered AppEngine URL: www.enstore.com/mystore, and it will show in their browser. In addition, choosing between a 301 and 302 redirect can make SEO tricky, since you'd have to get into how search engines behave with these redirects. For example most search engines will not use the original URL as a source for keywords when you use a 301 redirect.
In addition to 301 and 302 redirects, some DNS providers (like DNS Made Easy) also provide what they call a "masked hidden-iframe redirect". The page will render inside a hidden iframe, so the URL does not change in the user's browsers. However this makes SEO even more tricky, and it will not allow users to bookmark internal pages, or to reference them easily.
As you can see, this option is less than ideal, but it is one option to consider in some situations. Also note that at the moment, HTTP Redirection using 301 redirects is the suggested workaround for the Naked Domain Issue 777 on the AppEngine issue tracker.
Reverse Proxy
Another option could be to set up a small server somewhere else, like a small Amazon EC2 Instance, and set up a simple reverse proxy. You would be able to set this up very easily, just by using Apache and mod_proxy (or various other alternatives). This would allow you to ask your clients to set up a normal A Record pointing to this instance, while the Apache HTTP server would be acting as a proxy to your AppEngine.
The fundamental configuration directive to set up a reverse proxy in mod_proxy is the ProxyPass. You would typically set it up with one line like these for each VirtualHost (for each client domain):
ProxyPass / http://www.enmystore.com/mystore/
The configuration of the remote proxy could be easily handled by your back-end software.
This is a neater solution which gives you plenty of control - but there are obviously some costs for these benefits. First of all, there is the expense to host the reverse proxy. You would also be adding another point of failure, so you have to add this to your high-availability plan. In addition, if you are serving some pages through SSL it can become quite complicated.
Another option is to have each customer sign up for google apps, and then add your appengine app to their app. That way they can manage the url. They will need to use a cname for this, so urls will be limited to something like 'store.customer.com' You will have to support the multitenancy off of the host-header, but that isn't hard to do given that you already have a way to support multitenancy already. You might want to do the setup for the first couple of clients yourself so you can document the easiest way to set it up.
The rietveld code review app does this as you can add it to your google apps domain. See http://code.google.com/p/rietveld/wiki/CodeReviewHelp#Using_Code_Reviews_with_Google_Apps for more detail.
The preferred option is probably to offer your solution through the Google Solutions Marketplace: http://www.google.com/enterprise/enterprise_marketplace/about.html
We did something similar to Daniel Vassallo second proposal.
We created a python app on the Heroku cloud
(there is no limit for connecting custom domains).
This app is using python requests 1.2.0 lib to get the correct page from your app engine application according to the request domain.
all you need to tell your clients is to put your Heroku app url as their CNAME
For naked domains you can always use wwwizer

Resources