Web socket with cloud run behind a load balancer behind IAP - websocket

I have an API under cloud run. My cloud run service is behind a Load Balancer.
I'd like to open a socket connection from my front end app to my API (wss protocol).
When I use the cloud run service url it works but when I use my custom domain name I receive an error "undefined" and the connection is closed immediately. There is no log, making it very difficult for me to debug.
As I want to limit my ingress permission to Allow internal traffic and traffic from Cloud Load Balancing I can't use the cloud run service url.
On my load balancer my front end is using HTTPS protocol.
I do not understand what is blocking my socket connection.
Please ask for any details or further investigation. As I do not know where to begin my investigation I am having a hard time making a great post.
Update
If I connect using the cloud run url under allow all, it works, as I was saying. But I noticed another behavior. If I make a first connection using the cloud run url and then, try to connect using my custom domain url on the same browser. It works, whereas if I do the same operation on another browser or on a private window it fails with a 302 status code.
Update
So it appears that dis-activating IAP allow my front end to open a websocket connection to my API..
now I am trying to find a way to do the same but with IAP activated..
Thanks

Related

WebSocket API gateway connection issue

We are working on the ASP.Net core API application. In this application, we have a SignalR module for notification. We planned to host the application in the AWS environment. We have used the AWS lambda service to host the API, and also the WebSocket API gateway to consume the notification/SignalR part.
We are facing an issue with connecting the notification URL.
When we tried to connect the Web socket URL from Commandline using Node, it is showing "Unexpected server response 403".
When we tried to consume the URL from the frontend application, it showed the below error.
"WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled. ."
We are stuck with this issue. Any help to resolve this issue would be appreciable.

How to integrate internal APIs (Not accessible outside office network) to slack slash commands

I am trying to use slash commands to my one of the slack channel. I tried to do a POC using git API and it worked fine.
I first created a slash command from this link :
https://api.slack.com/censored/slash-commands
Commnad: /poc
Request URL: http://jsonplaceholder.typicode.com/posts
This worked fine when I type /opc on slack chat box of my channel. It returns some data.
But when I change the Request URL to an internal API, which is accessible only from the office domain, I get error:
Darn – that slash command didn't work (error message: Failure when
receiving data from the peer). Manage the command at .
I believe, slack is not able to access my internal URL in case. Is that possible to see the slack logs?
Can anyone please help me here.
This can not work, since the request URL needs to be accessible from the public Internet in order to work with Slack.
In general most of Slack's interactive features (Slash commands, Interactive messages, Modals, Events API, ...) require your app to provide a public endpoint that can be called by Slack via HTTP.
In order to access internal APIs with Slack you will need some kind of gateway or tunnel through the firewall of your company that exposes the request URL to Slack. There are many ways how to do that and the solution needs to be designed according to the security policy of your company.
Here are a couple of suggestions:
VPN tunnel
One approach would be to run your script for the slash command on an internal webserver (one that has access to the internal API) use a VPN tunnel to expose that web server to the Internet, e.g. with a tool like ngrok.
DMZ
Another approach would be to run your app in the DMZ of your companies network and configure the firewall on both sides to allow access to Slack form the public Internet and your app to you your internal network.
Bridge
Another approach is to host and run that part of your app that interacts with Slack on the public Internet and the part that interacts with your internal network on your internal company network. Then add a secure connection that allows the public part to communicate with the part running on the internal company network.
If opening a connection into the internal network is not an option, there is another way that can allow communication with internal services by inverting the communication direction with a queue.
To do this, you need to deploy a public endpoint that accepts the requests from Slack and puts them onto a queue (e. g. AWS Lambda + SQS, Flask + RabbitMQ) and then poll the queue from the internal network. The polling needs to happen fairly often (at least once a second) to ensure the communication is quick enough for the users not to notice the lag too much. By doing this you can avoid exposing any endpoint of the internal network.
The drawbacks of this approach are more infrastructure complexity and slower response times, but it can be a good alternative in some corporate environments.

GKE + WebSocket + NodePort 30s dropped connections

I have a golang service that implements a WebSocket client using gorilla that is exposed to a Google Container Engine (GKE)/k8s cluster via a NodePort (30002 in this case).
I've got a manually created load balancer (i.e. NOT at k8s ingress/load balancer) with HTTP/HTTPS frontends (i.e. 80/443) that forward traffic to nodes in my GKE/k8s cluster on port 30002.
I can get my JavaScript WebSocket implementation in the browser (Chrome 58.0.3029.110 on OSX) to connect, upgrade and send / receive messages.
I log ping/pongs in the golang WebSocket client and all looks good until 30s in. 30s after connection my golang WebSocket client gets an EOF / close 1006 (abnormal closure) and my JavaScript code gets a close event. As far as I can tell, neither my Golang or JavaScript code is initiating the WebSocket closure.
I don't particularly care about session affinity in this case AFAIK, but I have tried both IP and cookie based affinity in the load balancer with long lived cookies.
Additionally, this exact same set of k8s deployment/pod/service specs and golang service code works great on my KOPS based k8s cluster on AWS through AWS' ELBs.
Any ideas where the 30s forced closures might be coming from? Could that be a k8s default cluster setting specific to GKE or something on the GCE load balancer?
Thanks for reading!
-- UPDATE --
There is a backend configuration timeout setting on the load balancer which is for "How long to wait for the backend service to respond before considering it a failed request".
The WebSocket is not unresponsive. It is sending ping/pong and other messages right up until getting killed which I can verify by console.log's in the browser and logs in the golang service.
That said, if I bump the load balancer backend timeout setting to 30000 seconds, things "work".
Doesn't feel like a real fix though because the load balancer will continue to feed actual unresponsive services traffic inappropriately, never mind if the WebSocket does become unresponsive.
I've isolated the high timeout setting to a specific backend setting using a path map, but hoping to come up with a real fix to the problem.
I think this may be Working as Intended. Google just updated the documentation today (about an hour ago).
LB Proxy Support docs
Backend Service Components docs
Cheers,
Matt
Check out the following example: https://github.com/kubernetes/ingress-gce/tree/master/examples/websocket

get port number of stream server on client side [running on heroku]

I am trying to deploy my dart application on heroku but even when i have got my stream server running in the dyno, i don't have any idea as to how can i get the port number on client side code to connect to the server via websocket. Since i cannot use Platform.environment['PORT'], i don't know how to get the port.
My client side websocket address is this:
var port = '<The port number i need>';
var url = 'ws://0.0.0.0:$port/ws';
It has taken a lot of effort to deploy successfully to heroku. Please tell me that there is a way to make this work.
I haven't used Heroku myself yet but here the doc says
The Heroku platform automatically routes HTTP requests sent to your app’s > hostname(s) to your web dynos. The entry point for all applications on >the Cedar stack is the herokuapp.com domain which offers a direct routing path to your web dynos.
It should be possible to make a HTTP request to the hostname of your web dyno to connect to your server and your server should be able to do the Platform.environment['PORT'] and report the result back.
Referring to the link given by Gunter Why won't my app establish websocket connection on Heroku?, it just happens to be that the client side doesn't require an actual port to connect.
Doing the window.location.origin and replacing http:// with ws:// did the trick! Although problem is that even when my database opens up and all, there's some problem when using objectory to query upon it.
You can try " heroku run bash " and run your server in terminal then you can easily find your port in which your app is running.

HTTP GET requests work but POST requests do not

Our Spring application is running on several different servers. For one of those servers POST requests do not seem to be working. All site functionality that uses GET requests works completely fine; however, as soon as I hit something that uses a POST request (ex. form submit) the site just hangs permanently. The server won't give any response. We can see the requests in Tomcat Manager but they don't time out.
Has anyone ever seen this?
We have found the problem. Our DBA accidentally deleted the MySQL database files on that particular server (/sigh). In our Spring application we use GET requests for record retrieval and the records we were trying to retrieve must have been cached by MySQL. This made it seem as if GET requests were working. When trying to add new data to the database, which we use POST requests to do, Tomcat would wait for a response, which never came, from MySQL.
In my experience if you're getting a timeout error it's almost always due to not having correct ports open for your application. For example, go into your virtual machine's rules and insure port 8080, 8443 or 80, 443 are open for http and https traffic.
In google cloud platform: its under VPC networking -> firewall rules. Azure and AWS are similar.

Resources