<p>Ambassador is throwing a 403 while trying to access a websocket endpoint within the cluster. Here are the steps to recreate the issue:</p>
<p>[Kube Environment: Docker for Desktop on Mac]</p>
<p><strong>Install Ambassador and the Echo Service</strong></p>
<ol>
<li>Deploy Ambassador with Helm</li>
</ol>
<pre class="lang-sh prettyprint-override"><code>helm repo add datawire https://getambassador.io
helm install ambassador datawire/ambassador
</code></pre>
<ol start="2">
<li>Deploy the websocket echo deployment/service/mapping</li>
</ol>
<pre><code>---
apiVersion: v1
kind: Service
metadata:
  name: websocket-echo
  namespace: default
spec:
  ports:
    - name: http
      port: 80
      targetPort: 8080
  selector:
    app: websocket-echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: websocket-echo
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: websocket-echo
  template:
    metadata:
      labels:
        app: websocket-echo
    spec:
      containers:
        - name: backend
          image: jmalloc/echo-server
          ports:
            - name: http
              containerPort: 8080
---
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
  name: websocket-echo
  namespace: default
spec:
  prefix: /websocket/
  service: websocket-echo
  allow_upgrade:
  - websocket
</code></pre>
<p><strong>✅ Verify the echo server can be reached from a pod within the cluster</strong></p>
<ol>
<li>Create a node shell on the cluster</li>
</ol>
<pre class="lang-sh prettyprint-override"><code>kubectl run my-shell --rm -i --tty --image node:12 -- bash
</code></pre>
<ol start="2">
<li>In the shell, download <code>wscat</code></li>
</ol>
<pre class="lang-sh prettyprint-override"><code>npm i -g wscat
</code></pre>
<ol start="3">
<li>In the shell, connect to the service via the cluster service endpoint</li>
</ol>
<pre class="lang-sh prettyprint-override"><code>wscat -c websocket-echo.default.svc.cluster.local
</code></pre>
<ol start="4">
<li>Verify the connection is established and messages can be echoed back</li>
</ol>
<p><strong>❌ Verify the echo server cannot be reach from outside the cluster</strong></p>
<ol>
<li>Install <code>wscat</code> on you local machine</li>
</ol>
<pre><code>npm i -g wscat
</code></pre>
<ol start="2">
<li>Using wscat, connect to the service using the mapping</li>
</ol>
<pre class="lang-sh prettyprint-override"><code>wscat -c localhost/websocket-echo/
</code></pre>
<ol start="3">
<li>Verify that the error returned is <code>error: Unexpected server response: 403</code></li>
</ol>
<p>Am I missing something simple?</p>

Tyler Murry
<p>Ambassador will redirect incoming request froms http to https.</p>
<p>You can verify by</p>
<pre class="lang-sh prettyprint-override"><code>$ curl localhost/websocket/ -v
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 80 (#0)
&gt; GET /websocket/ HTTP/1.1
&gt; Host: localhost
&gt; User-Agent: curl/7.54.0
&gt; Accept: */*
&gt; 
&lt; HTTP/1.1 301 Moved Permanently
&lt; location: https://localhost/websocket/
&lt; date: Fri, 07 Aug 2020 08:25:38 GMT
&lt; server: envoy
&lt; content-length: 0
&lt; 
* Connection #0 to host localhost left intact
</code></pre>
<p>So, you will need to add this config to disable redirection on <code>localhost</code></p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: getambassador.io/v2
kind: Host
metadata:
  name: localhost
  namespace: default
spec:
  hostname: localhost
  acmeProvider:
    authority: none
  requestPolicy:
    insecure:
      action: Route
</code></pre>
<h2>Reference</h2>
<ul>
<li><a href="https://www.getambassador.io/docs/latest/topics/running/tls/cleartext-redirection/#cleartext-routing" rel="nofollow noreferrer">https://www.getambassador.io/docs/latest/topics/running/tls/cleartext-redirection/#cleartext-routing</a></li>
<li><a href="https://stackoverflow.com/a/9752145/3854890">https://stackoverflow.com/a/9752145/3854890</a></li>
</ul>
