VPC Private Google API access for mqtt.googleapis.com (Cloud IOT) using a proxy - google-cloud-platform

I have enabled Private Google API access for a VPC and I use this HTTP proxy solution described to connect my offsite datacenter to the Google Cloud backend.
Using the solution, I have verified that the Google object storage api's work, by using gsutil to move files across the offsite network.
However I am unable to connect to mqtt.googleapis.com that is required for cloud IOT.
I think this is because the MQTT broker running at mqtt.googleapis.com cannot be accessed via a private network unless it is also proxied like the HTTP proxy solution described above.
Meanwhile actual gsutil IOT commands work fine because I presume they are running over the Google HTTP API.
To solve this I see we'd need any one of the below, unless someone has different way to do this?
Run an MQTT broker proxy in the private VPC and route MQTT packets to the mqtt.googleapis.com . Is there a suitable MQTT proxy broker that we can use in this case?
If we get a range of public IP's that the mqtt bridge (mqtt.googleapis.com) is running at then we can simply build the network routes for this one use case. Is this available?

Would it work via the HTTP protocol bridge in IoT Core? Is using HTTP instead of MQTT an option?

I managed to get this to work using NGINX as a reverse proxy and stream the TCP traffic directly to mqtt.googleapis.com. Here are the steps to achieve this
Install Nginx with the --with-stream configuration flag . This builds Nginx with the functionality of a TCP streaming proxy
My Nginx conf file contains the following to point to Google's broker. The Nginx server is running in an instance in the VPC
/etc/nginx/nginx.conf
stream {
upstream google_mqtt {
server mqtt.googleapis.com:8883;
}
server {
listen 8883;
proxy_pass google_mqtt;
}
}
The internal private VPC has a DNS Server that resolves mqtt.googleapis.com to the IP of the Nginx server

Related

Cloud Service like Reverse Proxy?

Anyone can tell me what kind of service fits on this use case below:
I want to expose a public IP that receive HTTPS/HTTP requests and forward the traffic to my services I have in on-prem.
Looking for Azure, AWS, etc, etc, are there some service that serve to my problem?
Regards...
If you are using using Azure and you want HTTPS based request to be sent to your backend APIs (which can be on prem or on any cloud) you can check for Azure API Management (APIM).
You can use the APIM with or without VNET.
APIM can be used in External Mode if you want to integrate a VNET to perform data plane operations which will expose a Public IP as well as a Gateway URL which you can be used to send HTTPS traffic.
Reference:
https://learn.microsoft.com/en-us/azure/api-management/api-management-using-with-vnet?tabs=stv2
https://learn.microsoft.com/en-us/azure/api-management/api-management-key-concepts#scenarios
Additionally, you can also check out Application Gateway
Reference:
https://learn.microsoft.com/en-us/azure/architecture/example-scenario/gateway/firewall-application-gateway

Can I listen to event hub from app service environment without service endpoint?

Basically can I have Azure Function or web job with App Service environment listening to event hub without service endpoint. This way I will be able to accept data over public internet and also listen to in vnet?
Adding probable Security architecture:
Service Endpoints saves your time by doing IP firewall and NAT and gateway configuration changes in your VNET. If you will do those changes on your own, then yes you can access any public endpoint from your VNET.

Host and Port to access the Kubernetes api

I can access the kubernetes api to get the deployments using Kubernetes proxy.
I get the list of deployments with:
127.0.0.1:8001/apis/apps/v1/deployments
This is getting the deployments locally. But what should I use the HOST and PORT to access the deployments from the cluster not locally but using the aws server.
I am new to Kubernetes, if the question is not understandable please let me know.
Any help is appreciated.
kubectl proxy forwards your traffic localy adding your authentication for you
Your public api endpoint can be exposed in different ways (or it can be completely inaccessible from public network) depending on your cluster setup.
In most cases it would be exposed on something like ie. https://api.my.cluster.fqdn or with custom port like https://api.my.cluster.fqdn:6443 and it would require authentication by ie. getting a baerer token or using client certificate. It is reasonable to use some client library to connect to API.

How to access client IP of an HTTP request from Google Container Engine?

I'm running a gunicorn+flask service in a docker container with Google Container Engine. I set up the cluster following the tutorial at http://kubernetes.io/docs/hellonode/
The REMOTE_ADDR environmental variable always contains an internal address in the Kubernetes cluster. What I was looking for is HTTP_X_FORWARDED_FOR but it's missing from the request headers. Is it possible to configure the service to retain the external client ip in the requests?
If anyone gets stuck on this there is a better approach.
You can use the following annotations depending on your kubernetes version:
service.spec.externalTrafficPolicy: Local
on 1.7
or
service.beta.kubernetes.io/external-traffic: OnlyLocal
on 1.5-1.6
before this is not supported
source: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/
note that there are caveats:
https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#caveats-and-limitations-when-preserving-source-ips
I assume you set up your service by setting the service's type to LoadBalancer? It's an unfortunate limitation of the way incoming network-load-balanced packets are routed through Kubernetes right now that the client IP gets lost.
Instead of using the service's LoadBalancer type, you could set up an Ingress object to integrate your service with a Google Cloud HTTP(s) Load Balancer, which will add the X-Forwarded-For header to incoming requests.

Why websocket don't work on the cloud?

I developed our websocket project on wildfly. When we test it on localhost or within our local network, everything work fine. But when I deployed it on AWS, websocket don't work any longer. We can access other html pages. But when we conenct to "ws://ip/project location ", chrome just says hand shake error. I have experienced the same web socket problem on jelastic hosting too. My question is
Why it is happening like this?
Is websocket protocol not stable enough?
Is there any suitable hosting for websocket projects in java?
So far balancers don't forward websocket headers. To make WS working you must have a public IP address and no other services in front of your application.
I suggest you try deploying to the cloud provider : Heroku - their sample app code using node.js and websockets will get you up and running quickly. A locally running websocket app which uses a specific port - say 8888 will run fine on heroku with :
var port = process.env.PORT || 8888;
as heroku internally will deploy your app with a run-time generated port visible via PORT .
If you are using node.js with websockets I suggest using the einaros ws implementation
var WebSocketServer = require("ws").Server;
which seamlessly handles the notion of ws port -vs- the http port
Currently ELB doesn't support Websocket in HTTP mode. To be able to handle Websocket you need to configure the ELB in tcp mode (the payload of the tcp connection will be send directly to the server, so the ELB doesn't impact the http and ws flow). With this set up you won't be able to see the caller ip.
Without the ELB Websocket works perfectly (AWS only sees ip traffic and the OS only tcp one), we haven't change any thing for a plain old http server in order to use WS (except the WS handling code in the web server).
To know if you are using ELB look at the bill, AWS can provide you a lot of very interesting services, for a fee.