Forwarding HTTP traffic to a VM instance - google-app-engine

So I've deployed a web server as a VM instance on a google app engine. It's running and I can get to it through the ephemeral ip address. Now I want to point a domain name I have to that VM instance and I am hitting the wall here.
I added a custom domain, but the DNS entry it's injecting is with externally visible IP, which is different from the ephemeral IP of the VM.
My question is, how can I forward all the requests to my web-server running in a VM instance?

In order to send all requests to your custom domain to your web server running in any Google Compute Engine VM instance (including Managed VMs), you need to add some records to the name servers (NS, or DNS) where your domain is being served out of.
You require a DNS A-record, which has two parts: a prefix (sub-domain), and an IP address.
In case you wish to forward your whole domain (including all sub domains, i.e. *.bar.com) to your VM, you need to specify the domain itself (depending on your DNS provider, usually referred to as #, or blank field) as the prefix / sub-domain, followed by your VM's external IP address (ephemeral or static).
In case you wish to only direct a sub-domain of yours (i.e. foo.bar.com) to the web-hosting instance, the prefix / sub-domain part of the A record has to contain said sub-domain.

Related

Cloud Run static outbound IP address does not go through Google App Engine firewall

I have a python (flask) application running on Google App Engine (flex); the application is protected by the GAE firewall where:
Default rule is 'Deny' all ingress
There is a whitelist of IP addresses from which traffic is allowed.
I have some microservices deployed on Cloud Run (fully managed) which:
Receive requests from the GAE app (e.g. for heavy duty tasks)
Send the results of whatever they process as http requests back to handlers/endpoints in the GAE app
Thus the GAE app is the main point of interaction with clients and a dispatcher of heavy tasks, while the processing of those tasks is carried out by the microservices. I have set up a static outbound IP address of the Cloud Run hosted service which verfiedly works and traffic is routed through the NAT gateway as required in the documentation. The respective NAT IP address is on the firewall whitelist.
The problem is that the firewall still does not let in the Cloud Run >>> GAE app requests which bounce back with 403 statuses (of course, if I change the default firewall rule to 'Allow', traffic goes through). If I host the same microservice in a docker container on a GCE VM with a static IP address like this everything works flawlessly. This makes me hypothesize that albeit Cloud Run outbound traffic is indeed routed through the static IP address when traffic is towards addressees outside GCP, when I try to ping an internal (project-wise) asset it still goes though some dynamically selected IP (i.e. the static IP solution simply does not work). Unfortunately the logs don't show the 403-ed attempt so I can't see from what IP addresses those request seem to come (from a GAE standpoint).
I would be very grateful for ideas how this can be fixed as it greatly diminishes the value of the otherwise wonderful idea to have static outbound IP addresses for Cloud Run.
First, thank you both for your help and suggestions, they are very helpful. I found the solution with some kind help from Google:
When the Cloud Run microservice and the GAE app are hosted in the same project traffic is still routed through internal channels and appears to come from IP address 0.0.0.0 which can be whitelisted (so it would work) as long as one considers this address encompasses GCP assets which are parts of other projects too (to the best of my understanding)
A more robust solution seems to be setting up an externally facing load balancer as described here and putting it in front of the GAE app; in such a case, Cloud Run will indeed consistently use its static outbound IP address as described in the documentation
You are correct saying that the static IP is not honoured when packets are routed internally to GCP.
I think this is what you want. You have to allow in the firewall one of the IPs mentioned there (not sure which one right now).
Just as you and #Ema mentioned, this is an expected behavior having in mind that the traffic from Cloud Run to App Engine is intern.
When you use Cloud Nat to send all traffic there, it does happen. If you create a container and ping, let's say to www.github.com. You will find that the traffic goes through the IP you set. On the other hand, if you ping to www.google.com, given that the traffic is intern, and the site to reach out is in the same infrastructure, the request doesn't even goes through public internet.
Additionally, just to keep in mind Static outbound IP address is still in Beta and it is not recommended to use Beta features/products in production environments.
As you mentioned and as it is stated in Allowing requests from your services:
Creating a rule for IP 0.0.0.0 will apply to all Compute Engine instances with Private Google Access enabled, not only the ones you own. Similarly, allowing requests from 0.1.0.40 or 10.0.0.1 will allow any App Engine app to make URL Fetch requests to your app.
This questions might be of your interest:
What are the outbound IP ranges for GCP managed Cloud Run?
Possible to get static IP address for Google Cloud Functions?

Does the fact that Google App Engine supports naked domains with A records mean that GAE IPs are effectively static?

Originally, Google App Engine only supported subdomains, as it uses a CNAME to resolve your domain to IPs addresses, presumably so that Google can shuffle around IP addresses between customers if needed to better distribute traffic, and they can just update the A records their DNS server (the one you CNAME'd to) returns.
Because CNAMEs are not technically supposed to exist alongside any other DNS records for the same host according to the RFC spec, they are forbidden as # (domain root) records, thus GAE only supporting subdomains.
However, in 2014 GAE began supporting naked domains, which it does by providing you with four A records to add to your domain's root DNS records.
Wouldn't this imply that GAE IP addresses are stable, and effectively static?
If Google App Engine is telling users to set four A records pointing directly to four IP addresses, those IPs cannot change without me manually updating my DNS records, outside of Google's control.
This feels to me like a major deviation from one of underlying tenets of Google App Engine and other platform-as-a-service providers: namely that you do not get a dedicated server IP address, and cannot assume your IP is stable. In fact, it would appear that every GAE service now gets four static IP addresses.
Or is this not as big a deal as I'm inferring?
No, it isn't the same as a static IP address. For example, suppose the A record for my app is 1.2.3.4. If I go to http://1.2.3.4 or https://1.2.3.4, then I get an error.
I don't understand the magic that Google goes through with these A records, but it doesn't function the same way that a static IP would. I suspect that many GAE apps share the same A record since IPv4 addresses are in short supply.

What measures does google cloud take to protect the instances from IP spoofing?

I am running my server on google app engine and i have all of my services (e.g MongoDB, Redis, Elasticsearch) are deployed on compute engine. Now i wanted to connect my compute engine instances from App engine only that's why i deleted all of my firewall rules of my compute engines which were connecting them from external ip's, now only the instances that are within the internal network of my google cloud project can connect to themselves, now i am just wondering about IP spoofing that as nobody from outside my internal network can connect to my instances now can they fake their ip by telling my firewall that their ip is the ip which any of my instance is having because if that can happen then my whole security will be breached.
Now one question does google cloud project's firewall implement any measures to secure our instances from IP Spoofing or we have to setup something in order to avoid that.
If any of you have any idea about this please enlighten me.
Thanks
It's not quite clear which spoofing scenario you are concerned about. These two come to mind:
External party spoofing packets for your internal network, ie. the 10.0.0.0/8 range. This is not possible as packets inside your network can only come from VMs and VPNs in that private network.
Spoofing packets from other Google / GCE IP ranges; eg. the ones used for external addresses: This should be caught by Google's network ACLs.
I would however not recommend to authenticate based on IP address. For example, if you are communicating over external IP addresses between GCE/GAE entities, it's easy to be too broad, also allowing other GCE/GAE customers. Even if you only whitelist single IP addresses there is a risk that over time, your setup becomes more complex. Imagine for example, if an employee deletes a GCE instance without also removing the IP from the whitelist. In that case, the IP would be released and available to other GCE customers who could then access your service.
Therefore, it's usually safer to use an application level authentication mechanism such as SSL client certificates.

Is it possible to forward CNAME to Google App Engine without adding custom domain

I have this problem when forwarding www CNAME to a Google App Engine application. It's not working maybe I am missing something.
Is it possible to forward CNAME to Google App Engine without adding custom domain?
The documentation you linked actually contains the answer to your question: You have to add a custom domain to your app with a wildcard.
And here is the reason why you have to add every domain to your custom domain.
When you create a cname it will always point to ghs.googlehosted.com. My guess is that the servers behind that domain are one huge load balancer, but that's not really important here. What is important is, that before your HTTP request is made the DNS name is resolved to an IP address. The range of IP addresses is the same for all appengine apps, so the server doesn't know that this particular request is intended for your app. However with that IP address a TCP connection is opened to the server. Now you send a request like:
GET / HTTP/1.1
HOST: www.yourcustomdomain.com
The server looks at the HOST part and must decide which app this request should be forwarded to. But it cannot know that if you didn't add your domain to the custom domains of your project. There simply is no information about where to route that request. So the simple answer is:
Yes you must add all your custom domains to your project, but you could use wildcards
No it will not work without that step, because the Google infrastructure houses tons of apps and your app does not have a dedicated IP address by which it could be identified

Custom Domain for Google Compute Engine Server

Can I get the external IP of compute engine instance point to a custom domain name that I own ?
I've found a number of links of accomplishing it with App Engine and therefore, presently I'm thinking of calling the Compute Engine from App Engine. Kindly share your thoughts about this solution as well
You have to create an extenal static IP adress and use it in your own domain DNS setup.
Docs: https://developers.google.com/compute/docs/instances-and-network#externaladdresses
Docs: You can assign an optional externally visible IP address to specific instances. Outside callers can address a specific instance by external IP if the network firewalls allow it. Only instances with an external address can send and receive traffic from outside the network.

Resources