Can I have my cloudrun server receive http/2 requests? - http2

Can I have Google send http/2 requests to my server in cloud run?
I am not sure how google would know my server supports it since google terminates the SSL on the loadbalancer and sends http to the stateless servers in cloud run.
If possible, I am thinking of grabbing a few pieces from webpieces and creating a pure http/2 server with no http1.1 for microservices that I 'know' will only be doing http/2.
Also, if I have a pure http/2 server, is there a way that google translates from http1 requests to http/2 when needed so I could host websites as well?
The only info I could find was a great FAQ that seems to be missing the does it support http/2 on the server side(rather than client)...
https://github.com/ahmetb/cloud-run-faq
thanks,
Dean

Cloud Run container contract requires your application to serve on an unencrypted HTTP endpoint. However, this can be either HTTP/1 or HTTP/2.
Today, gRPC apps work on Cloud Run and gRPC actually uses HTTP/2 as its transport. This works because the gRPC servers (unless configured with TLS certificates) use the H2C (HTTP/2 unencrypted cleartext) protocol.
So, if your application can actually serve traffic unencrypted using h2c protocol, the traffic between Cloud Run load balancer <=> your application can be HTTP/2, without ever being downgraded to HTTP/1.
For example, in Go, you can use https://godoc.org/golang.org/x/net/http2/h2c package to automatically detect and upgrade http2 connections.
To test if your application implements h2c correctly, you need to locally run:
curl -v --http2-prior-knowledge http://localhost:8080
and see < HTTP/2 200 response.
(I'll make sure to add this to the FAQ repo.)

Related

Gateway API - Apache APISIX with Secured Websockets

I am trying to add an API Gateway to a client-server system, which communicates through WebSockets.
The Server is an audio recognition engine that sits in a remote machine, and clients are connecting to it through WebSockets ('wss://...'), sending audio files and receiving their text translate representation.
My main goal is to add a free open-source API Gateway in the middle in order to authenticate\authorize\rate limit\etc (Tried Kong\Tyk\krakenD, but they are not free).
After searching the web, I focused on Apache APISIX gateway.
As a test, I managed to connect the APISIX to a client-server which communicates by http/https and it worked fine.
Moreover, I managed to connect the client with the server on regular websocket connection (ws://) and the data transactions were successful, but no matter what I do I cant connect to the secured connection. Are there any special configurations I should edit in the dashboard?
I'm wondering if anyone knows from experience if it's possible to use
the secured WebSockets with Apache APISIX and if yes, how exactly it should be done - because the docs are missing any informative info\examples, or if there are better solutions known to my problem.
The only WebSocket reference in APISIX dashboard -
What you should do is create an SSL object (you can find it in the sidebar on the left side). See https://apisix.apache.org/docs/apisix/admin-api/#ssl to learn the APISIX SSL object.
You can see an example at https://apisix.apache.org/docs/apisix/certificate
The SSL object provides the required TLS Certificate and Private Key so that this key pair can be used in a TLS handshake according to the TLS SNI sent from clients. After that, your client established a secured connection with APISIX, and now you can send the WebSocket traffic securely.

Restrict insecure web socket protocol connections in PCF

We are hosting an application in the preprod azure PCF environment which exposes websocket endpoints for client devices to connect to. Is there a prescribed methodology to secure the said websocket endpoint using TLS/SSL when hosted on PCF and running behind the PCF HAProxy?
I am having trouble interpreting this information, as in, are we supposed to expose port 4443 on the server and PCF shall by default pick it up to be a secure port that ensures unsecured connections cannot be established? Or does it require some configuration to be done on HAProxy?
Is there a prescribed methodology to secure the said websocket endpoint using TLS/SSL when hosted on PCF and running behind the PCF HAProxy?
A few things:
You don't need to configure certs or anything like that when deploying your app to PCF. The platform takes care of all that. In your case, it'll likely be handled by HAProxy, but it could be some other load balancer or even Gorouter depending on your platform operations team installed PCF. The net result is that TLS is first terminated before it hits your app, so you don't need to worry about it.
Your app should always force users to HTTPS. How you do this depends on the language/framework you're using, but most have some functionality for this.
This process generally works by checking to see if the incoming request was over HTTP or HTTPS. If it's HTTP, then you issue a redirect to the same URL, but over HTTPS. This is important for all apps, not just ones using WebSockets. Encrypt all the things.
Do keep in mind that you are behind one or more reverse proxies, so if you are doing this manually, you'll need to consider what's in x-forwarded-proto or x-forwarded-port, not just the upstream connection which would be Gorouter, not your client's browser.
https://docs.pivotal.io/platform/application-service/2-7/concepts/http-routing.html#http-headers
If you are forcing your user's to HTTPS (#1 above), then your users will be unable to initiate an insecure WebSocket connection to your app. Browsers like Chrome & Firefox have restrictions to prevent an insecure WebSocket connection from being made when the site was loaded over HTTPS.
You'll get a message like The operation is insecure in Firefox or Cannot connect: SecurityError: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS. in Chrome.
I am having trouble interpreting this information, as in, are we supposed to expose port 4443 on the server and PCF shall by default pick it up to be a secure port that ensures unsecured connections cannot be established? Or does it require some configuration to be done on HAProxy?
From the application perspective, you don't do anything different. Your app is supposed to start and listen on the assigned port, i.e. what's in $PORT. This is the same for HTTP, HTTP, WS & WSS traffic. In short, as an app developer you don't need to think about this when deploying to PCF.
The only exception would be if your platform operations team uses a load balancer that does not natively support WebSockets. In this case, to work around the issue they need to separate traffic. HTTP and HTTPS go on the traditional ports 80 and 443, and they will route WebSockets on a different port. The PCF docs recommend 4443, which is where you're probably seeing that port. I can't tell you if your platform is set up this way, but if you know that you're using HAproxy, it is probably not.
https://docs.pivotal.io/platform/application-service/2-8/adminguide/supporting-websockets.html
At any rate, if you don't know just push an app and try to initiate a secure WebSocket connection over port 443 and see if it works. If it fails, try 4443 and see if that works. That or ask your platform operations team.
For what it's worth, even if your need to use port 4443 there is no difference to your application that runs on PCF. The only difference would be in your JavaScript code that initiates the WebSocket connection. It would need to know to use port 4443 instead of the default 443.

How to proxy gRPC calls

I'm trying to analyse what information an app is sending so I setup Charles but to my surprise nothing was logged out.
After decompiling the app I see that it doesn't use simple REST calls but rather a library called gRPC.
Is there a good tool out there that will allow me too see what is send out from the app?
The Mediator is a Cross-platform GUI gRPC debugging proxy like Charles but design for gRPC.
You can dump all gRPC requests without any configuration.
Mediator can render the binary message into a JSON tree, when you have the API schema.
It support decode gRPC/TLS, but you should download and install the Mediator Root Certificate to your device.
gRPC uses HTTP/2 as a transport protocol. Any proxy which supports HTTP/2 for both the front-end and back-end connections should be able to be used to inspect the packets a gRPC connection. Note, some proxies only support HTTP/2 for the front-end or back-end connections and those are incompatible with gRPC.
Envoy Proxy (https://www.envoyproxy.io/) supports proxying gRPC connections and can be configured to log out request information.
Some other example proxies include:
Nginx https://medium.com/nirman-tech-blog/nginx-as-reverse-proxy-with-grpc-820d35642bff
https://github.com/mwitkow/grpc-proxy
https://github.com/mercari/grpc-http-proxy
If you are asking for android there is a app called HttpCanry. It can log request/ respond.

Open Source SPDY Proxy

Has anyone developed an open source SPDY proxy?
I can't find one via Google, but I believe the Amazon Silk browser uses one?
I wrote SPDY reverse proxy called shrpx in C/C++.
It also serves as SSL/SPDY proxy with squid as backend server.
The SPDY proxy has been implemented in jetty:
https://groups.google.com/forum/?fromgroups#!topic/spdy-dev/and5OLY4AsI
We've finished the basic documentation which can be found here:
http://www.eclipse.org/jetty/documentation/current/spdy-configuring-proxy.html
The proxy is now also able to receive SPDY and talk plain HTTP to an upstream server to terminate SPDY on the frontend servers for example.
Jetty SPDY does not provide directly a SPDY proxy, but provides both SPDY client and SPDY server functionalities - in Java - that are needed to build a proxy.
We may be working on a SPDY proxy in the next future.

Why don't current websocket client implementations support proxies?

A Web Socket detects the presence of a proxy server and automatically sets up a tunnel to pass through the proxy. The tunnel is established by issuing an HTTP CONNECT statement to the proxy server, which requests for the proxy server to open a TCP/IP connection to a specific host and port. Once the tunnel is set up, communication can flow unimpeded through the proxy. Since HTTP/S works in a similar fashion, secure Web Sockets over SSL can leverage the same HTTP CONNECT technique. [1]
OK, sounds useful! But, in the client implementations I've seen thus far (Go [2], Java [3]) I do not see anything related to proxy detection.
Am I missing something or are these implementations just young? I know WebSockets is extremely new and client implementations may be equally young and immature. I just want to know if I'm missing something about proxy detection and handling.
[1] http://www.kaazing.org/confluence/display/KAAZING/What+is+an+HTML+5+WebSocket
[2] http://golang.org/src/pkg/websocket/client.go
[3] http://github.com/adamac/Java-WebSocket-client/raw/master/src/com/sixfire/websocket/WebSocket.java
Let me try to explain the different success rates you may have encountered. While the HTML5 Web Socket protocol itself is unaware of proxy servers and firewalls, it features an HTTP-compatible handshake so that HTTP servers can share their default HTTP and HTTPS ports (80 and 443) with a Web Sockets gateway or server.
The Web Socket protocol defines a ws:// and wss:// prefix to indicate a WebSocket and a WebSocket Secure connection, respectively. Both schemes use an HTTP upgrade mechanism to upgrade to the Web Socket protocol. Some proxy servers are harmless and work fine with Web Sockets; others will prevent Web Sockets from working correctly, causing the connection to fail. In some cases additional proxy server configuration may be required, and certain proxy servers may need to be upgraded to support Web Sockets.
If unencrypted WebSocket traffic flows through an explicit or a transparent proxy server on its way the WebSocket server, then, whether or not the proxy server behaves as it should, the connection is almost certainly bound to fail today (in the future, proxy servers may become Web Socket aware). Therefore, unencrypted WebSocket connections should be used only in the simplest topologies.
If encrypted WebSocket connection is used, then the use of Transport Layer Security (TLS) in the Web Sockets Secure connection ensures that an HTTP CONNECT command is issued when the browser is configured to use an explicit proxy server. This sets up a tunnel, which provides low-level end-to-end TCP communication through the HTTP proxy, between the Web Sockets Secure client and the WebSocket server. In the case of transparent proxy servers, the browser is unaware of the proxy server, so no HTTP CONNECT is sent. However, since the wire traffic is encrypted, intermediate transparent proxy servers may simply allow the encrypted traffic through, so there is a much better chance that the WebSocket connection will succeed if Web Sockets Secure is used. Using encryption, of course, is not free, but often provides the highest success rate.
One way to see it in action is to download and install the Kaazing WebSocket Gateway--a highly optimized, proxy-aware WebSocket gateway, which provides native WebSocket support as well as a full emulation of the standard for older browsers.
The answer is that these clients simply do not support proxies.
-Occam
The communication channel is already established by the time the WebSocket protocol enters the scene. The WebSocket is built on top of TCP and HTTP so you don't have to care about the things already done by these protocols, including proxies.
When a WebSocket connection is established it always starts with a HTTP/TCP connection which is later "upgraded" during the "handshake" phase of WebSocket. At this time the tunnel is established so the proxies are transparent, there's no need to care about them.
Regarding websocket clients and transparent proxies,
I think websocket client connections will fail most of the time for the following reasons (not tested):
If the connection is in clear, since the client does not know it is communicating with a http proxy server, it won't send the "CONNECT TO" instruction that turns the http proxy into a tcp proxy (needed for the client after the websocket handshake). It could work if the proxy supports natively websocket and handles the URL with the ws scheme differently than http.
If the connection is in SSL, the transparent proxy cannot know to which server it should connect to since it has decrypt the host name in the https request. It could by either generating a self-signed certificate on the fly (like for SSLStrip) or providing its own static certificate and decrypt the communication but if the client validates the server certificate it will fail (see https://serverfault.com/questions/369829/setting-up-a-transparent-ssl-proxy).
You mentioned Java proxies, and to respond to that I wanted to mention that Java-Websocket now supports proxies.
You can see the information about that here: http://github.com/TooTallNate/Java-WebSocket/issues/88
websocket-client, a Python package, supports proxies, at the very least over secure scheme wss:// as in that case proxy need no be aware of the traffic it forwards.
https://github.com/liris/websocket-client/commit/9f4cdb9ec982bfedb9270e883adab2e028bbd8e9

Resources