New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Websocket establishment does not work with Supermicro X9 to X11 HTML5 console #3935
Comments
I was not able to reproduce this issue. Testing with a simple websocket server and client its working for me: package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
"github.com/gorilla/websocket"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
ws, err := (&websocket.Upgrader{}).Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
defer ws.Close()
for {
// Write
err := ws.WriteMessage(websocket.TextMessage, []byte("Hello, Client!"))
if err != nil {
return
}
// Read
_, msg, err := ws.ReadMessage()
if err != nil {
return
}
fmt.Printf("%s\n", msg)
}
})
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
_, _ = io.WriteString(w, `<!doctype html>
<html lang="en">
<body>
<p id="output"></p>
<script>
var loc = window.location;
var uri = 'ws:';
if (loc.protocol === 'https:') {
uri = 'wss:';
}
uri += '//' + loc.host;
uri += loc.pathname + 'ws';
ws = new WebSocket(uri)
ws.onopen = function() {
console.log('Connected')
}
ws.onmessage = function(evt) {
var out = document.getElementById('output');
out.innerHTML += evt.data + '<br>';
}
setInterval(function() {
ws.send('Hello, Server!');
}, 1000);
</script>
</body>
</html>
`)
})
err := http.ListenAndServeTLS("127.0.0.1:20001", "_wildcard.localhost.pomerium.io.pem", "_wildcard.localhost.pomerium.io-key.pem", mux)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
} I am not familiar with Supermicro X9, X11 or IPMI/BMC. Perhaps they use a variation of Websockets that's different from the example I'm using. Based on the error message above (which doesn't happen for me), it sounds like HTTP/2 is being used. Could you try forcing the codec type to |
No change with I replaced the target with a
Shouldn't Pomerium include EDIT: These headers are included if the client sends a HTTP1.1 (as opposed to the the default HTTP/2) request it seems:
|
Ok, so I spent some more time digging into the particulars for the Supermicro BMC console application. For it to be happy to accept a websocket connection the request needs to:
This is the minimum request that I have managed to get working:
If I change e.g. |
Envoy's default behavior is to convert all headers to lowercase. It looks like there is a way we can change this when using websockets which may fix the issue: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/header_casing#config-http-conn-man-header-casing. |
I tested the main branch just now with the #3956 PR merged, and can happily confirm it appears to be working! The configuration that works for me: - from: https://xyz-bmc.local.my.domain
to: https://10.1.2.3
tls_skip_verify: true
allow_websockets: true
allowed_users: *bmc_admins 🥳 |
What happened?
I am configuring Pomerium to front the IPMI/BMC HTML5 console for a couple of Supermicro servers.
Firmware Revision : 03.94
What did you expect to happen?
When I use the console it can connect. If I copy Websocket request from Firefox as cURL and manually run it, I expect it to print the RFB/VNC data channel.
How'd it happen?
Using the web interface, activating HTML5 fails with "Server disconnected (code: 1006)".
Also with cURL:
HTTP/2 200
and the index page, and not the expected101 Switching Protocols
and the data channel.What's your environment like?
Hardware: SYS-2028TP-HTR, BMC version 03.94 (latest as of this writing)
What's your config.yaml?
What did you see in the logs?
Nothing that stands out
However, I noticed that if I inspect the headers that are sent from Pomerium to the backend it appears that the 'Upgrade: websocket' and 'Conneciton: upgrade' headers are not set as I would expect.
Additional context
Proxying this service works just fine with nginx instead of Pomerium using the following configuration:
Since it works fine with nginx I believe this to be a bug in Pomerium and/or Envoy.
The text was updated successfully, but these errors were encountered: