We are running a couple of k8s clusters on Azure AKS. The service (ghost blog) is behind the Nginx ingress and secured with a cert from Letsencrypt. All of that works fine but the redirect behavior is what I am having trouble with.
The Ingress correctly re-directs from http://whatever.com to https://whatever.com — the issue is that it does so using a 308 redirect which strips all post/page Meta anytime a user shares a page from the site.
The issue results in users who share any page of the site on most social properties receiving a 'Preview Link' — where the title of the page and the page meta preview do not work and are instead replaced with '308 Permanent Redirect' text — which looks like this:
From the ingress-nginx docs over here I can see that this is the intended behavior (ie. 308 redirect) what I believe is not intended is the interaction with social sharing services when those services attempt to create a page preview.
While the issue would be solved by Facebook (or twitter, etc etc) pointing direct to the https site by default, I currently have no way to force those sites to look to https for the content that will be used to create the previews.
I can also see that it looks like I should be able to set the redirect code to whatever I want it to be (I believe a 301 redirect will allow Facebook et al. to correctly pull post/page snippet meta), docs on that found here.
The problem is that when I add the redirect-code annotation as specified:
nginx.ingress.kubernetes.io/permanent-redirect-code: "301"
I still get a 308 re-direct on my resources despite being able to see (from my kubectl proxy) that the redirect-code annotation correctly applied. For reference, my full list of annotations on my Ingress looks like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ghost-ingress
annotations:
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/permanent-redirect-code: "301"
To reiterate — my question is; what is the correct way to force a redirect to https via a custom error code (in my case 301)?
These directions are for Azure AKS users but the solution for this solution for facebook / social property preview links showing as 308 permanent redirect will probably work on any cloud provider (though it has not been tested) — you would just need to change the way you login / get your credentials etc.
Thanks to Rico for the solution! Since this is only tested with Facebook you may or may not want to go the ConfigMap application route (which Rico mentions above) this walks through manually editing the ConfigMap as opposed to using kubectl apply -f
to apply one saved locally.
az login
)az aks get-credentials --resource-group yourGroup --name your-cluster
az aks browse --resource-group yourGroup --name your-cluster
"data": { "some-other-setting-here": "false", "http-redirect-code": "301" }
You will need a comma after each key/value line except the last.helm upgrade ngx-ingress stable/nginx-ingress
Where ngx-ingress is the name of your helm install. Also note that using the '--reuse-values' flag will cause your upgrade to fail (re: https://github.com/helm/helm/issues/4337)helm list
to find it.curl myhttpdomain.com
You should receive something like this:```
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.15.3</center>
</body>
</html>
```
One important thing to note here is that if you are making the change to a 301 re-direct to try to fix the preview link for facebook or one of the other social media properties (twitter etc etc) then in all likelihood this will not fix any link to any page / post that you have already linked to — at least not right away.
The social properties all use intense caching to limit their resource usage but you can check to see if the above fixes your preview link issue by linking to a NEW page / post that you have not previously referenced.
So the major reason that nginx-ingress uses a code 308 is because it keeps the 'body' / payload intact in cases where you are sending a POST request (as opposed to a normal GET request link you do with a browser etc).
For me this wasn't a concern but if you are for whatever reason posting to the http address and expecting that to be re-directed seamlessly that will probably not work — after you swap to the 301 redirect discussed in post that is.
HOWEVER if you are not expecting a seamless redirect when sending POST requests (I think most people probably are not, I know I am not) then I think this is the best way to fix the Facebook 308 Permanent redirect behavior.
My guess is the TLS redirect shadows the nginx.ingress.kubernetes.io/permanent-redirect-code
annotation.
You can actually change the ConfigMap
for your nginx-configuration
so that the default redirect is 301. That's the configuration your nginx ingress controller uses for nginx itself. The ConfigMap
looks like this:
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
name: nginx-configuration
namespace: ingress-nginx
data:
use-proxy-protocol: "true"
http-redirect-code: "301"
You can find more about the ConfigMap
options here. Note that if you change the ConfigMap
you'll have to restart your nginx-ingress-controller
pod.
You can also shell into the nginx-ingress-controller
pod and see the actual nginx configs that the controller creates:
kubectl -n ingress-nginx exec -it nginx-ingress-controller-xxxxxxxxxx-xxxxx bash
www-data@nginx-ingress-controller-xxxxxxxxx-xxxxx:/etc/nginx$ cat /etc/nginx/nginx.conf