Kubernetes Ingress headers single quotes - kubernetes

I am running into a very strange issue, I cannot set single quotes that are required by Content-Security-Policy. I assume I was running an older version of ingress which only got updated after I disabled and re-enabled it (microk8s).
nginx.ingress.kubernetes.io/configuration-snippet: |
add_header Access-Control-Allow-Origin "https://myhost";
more_set_headers "X-FRAME-OPTIONS: SAMEORIGIN";
more_set_headers "Content-Security-Policy: default-src 'self' blob:;";
Result:
skipping ingress ...: nginx.ingress.kubernetes.io/configuration-snippet annotation contains invalid word '
I've tried using x2, escaping with \, wrapping everything with single quotes and escaping, nothing worked. I'm grateful if anyone can tell me how to add single quotes to the headers or if I can avoid them and still send the CSP.
EDIT: just to be clear, this configuration used to work on older versions, right now the ingress version is v1.0.5. There is nothing wrong with the syntax or other settings.

Changes has been appeared exactly in 1.0.5 related to sanitizing annotation inputs.
You may want to check CVE-2021-25742: Ingress-nginx custom snippets. I put in bold interested for you part.
annotation-value-word-blocklist defaults are
"load_module,lua_package,_by_lua,location,root,proxy_pass,serviceaccount,{,},',"
Users from mod_security and other features should be aware that some
blocked values may be used by those features and must be manually
unblocked by the Ingress Administrator.
It seems to me your issue related to mod_security + above blocklist, that contains ' symbol.
For more details please check https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#annotation-value-word-blocklist
In order to fix your issue you should either
set the value of annotation-value-word-blocklist to an empty string ""
or
change the value of annotation-value-word-blocklist and remove ' from its list.

Related

How to see the headers in a request while using Kong Ingress controller

In any ingress controller like https://traefik.io/ there is usually a DEBUG mode to run. In this mode you can actually see the headers in the request which help in debugging.
However in https://docs.konghq.com/kubernetes-ingress-controller I am unable to find the same.
I have installed kong using helm and it installs and runs fine.
I want to be able to see the headers in a request and I can't seem to find a way around it. There is no logging level defined in values.yaml file.
Turns out you can enable debug mode by using the following environment variable. Add the following with other environment variables to get log in DEBUG mode
env:
log_level: debug
However, to see the values of requst headers and response you will need the following
plugin
You might want to redirect it to /dev/stdout so it comes in output of kong logs.
for debugging one can send a header; Kong-Debug: 1 (see https://docs.konghq.com/gateway-oss/2.5.x/proxy/#evaluation-order ) and there is an upcoming change in 2.6 that might be helpful as well; see https://github.com/Kong/kong/pull/6744

How to setup a Kubernetes secret using GoDaddy certs for Nginx Ingress controller

I'm struggling to setup a kubernetes secret using GoDaddy certs in order to use it with the Ingress Nginx controller in a Kubernetes cluster.
I know that GoDaddy isn't the go-to place for that but that's not on my hands...
Here what I tried (mainly based on this github post):
I have a mail from GoDaddy with two files: generated-csr.txt and generated-private-key.txt.
Then I downloaded the cert package on GoDaddy's website (I took the "Apache" server type, as it's the recommended on for Nginx). The archive contains three files (with generated names): xxxx.crt and xxxx.pem (same content for both files, they represent the domain cert) and gd_bundle-g2-g1.crt (which is the intermediate cert).
Then I proceed to concat the domain cert and the intermediate cert (let's name it chain.crt) and tried to create a secret using these file with the following command:
kubectl create secret tls organization-tls --key generated-private-key.txt --cert chain.crt
And my struggle starts here, as it throw this error:
error: tls: failed to find any PEM data in key input
How can I fix this, or what I'm missing?
Sorry to bother with something trivial like this, but it's been two days and I'm really struggling to find proper documentation or example that works for the Ingress Nginx use case...
Any help or hint is really welcome, thanks a lot to you!
This is a Community Wiki answer, posted for better visibility, so feel free to edit it and add any additional details you consider important.
As OP mentioned in comments, the issue was solved by adding a new line in the beginning of the file.
"The key wasn't format correctly as it was lacking a newline in the
beginning of the file. So this particular problem is now resolved."
Similar issue was also addressed in this answer.
The issue is tricky but easy to fix.
The private key file given by GoDaddy is not properly encoded: it is encoded in UTF8 with BOM, so it starts with a byte that shouldn't be there. It is not understood by nginx ingress when ingesting the private key, and leads to the error.
The simple fix is to run the following command to properly encode the private key file:
iconv -c -f UTF8 -t ASCII generated-private-key.txt > generated-private-key-anssi.txt
And then you get the base64 private key as usual:
cat generated-private-key-anssi.txt | base64 -w 0
Now, the ingress properly gets the ssl certificate. In case you need to see the logs of the ingress to see how the CERT is processed, just list pods & logs in the ingress-nginx namespace.

Ingress session-cookie-path setting regular express in Ingress Session Cookie; resulting in user logout

I have created an ingress controller configuration with following path definitions:
paths:
- path: (USA)/my-app/(.*)$
...............
- path: (UK)/my-app/(.*)$
The problem happening here is when I don't set the following annotation;
nginx.ingress.kubernetes.io/session-cookie-path
I get regular expression in INGRESSCOOKIE path as:
cookie-name: INGRESSCOOKIE --------cookie-path: /(USA)/my-app/(.*)$
This is coming from the given path i.e. /(USA)/my-app/(.*)$.
As a result this response cookie from Ingress doesn't go back to Ingress for any subsequent request for http://USA/my-app/?id=1. (as HTTP request path differs from path in INGRESSCOOKIE)
And because of this HTTP request at times hit a different upstream server and user logs out; as session id in request is generated by a different server managed through the same load balancer.
I then tried setting annotation as:
nginx.ingress.kubernetes.io/session-cookie-path= /$1/my-app
But $1 doesn't actually resolve here; probably we cant give expressions in session-cookie-path.
Is there anything I am not doing in a right way here? Or, I should try something else to achieve session affinity.
Thanks
I know this is pretty old but wanted to share my view anyway.
For your issue, you might want to try the following annotation: nginx.ingress.kubernetes.io/use-regex
Please remove "session-cookie-path" from annotations as Session Cookie Paths doesn't support regex
For more information, please visit below links:
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#use-regex
https://kubernetes.github.io/ingress-nginx/user-guide/ingress-path-matching/
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#cookie-affinity

kubernetes ingress controller not forwarding request headers

I am working on a kubernetes cluster and problem faced is:
From UI/browser, I can see it is sending a request header called "request_id" please refer to image:
But while checking on backend it is unavailable. While searching through internet, I could see that people are talking about adding following entry to Ingress object:
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header request_id "$req_id";
But it is generating a new value for this and not passing value submitted by browser.
Any ideas, what might be missing here?
If you want to pass a custom header to your backend, you need to use this kind of annotation:
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "Request-Id: $request_id
In your configuration you are using the variable $req_id, but you need to pass the variable sent by UI/browser.
Basically, ingress-nginx-controller drops any request headers that contains "_" in them. You can find various threads which discuss this issue like,
Why HTTP servers forbid underscores in HTTP header names
So, I just enabled ingress controller to pass such request headers. This can be done by adding following entry to configmap "nginx-configuration"
data:
enable-underscores-in-headers: "true"
IMO, this is a much clean solution as there could be many applications that might use "_" in request headers.

Why does BitBake error if it can't find www.example.com?

BitBake fails for me because it can't find https://www.example.com.
My computer is an x86-64 running native Xubuntu 18.04. Network connection is via DSL. I'm using the latest versions of the OpenEmbedded/Yocto toolchain.
This is the response I get when I run BitBake:
$ bitbake -k core-image-sato
WARNING: Host distribution "ubuntu-18.04" has not been validated with this version of the build system; you may possibly experience unexpected failures. It is recommended that you use a tested distribution.
ERROR: OE-core's config sanity checker detected a potential misconfiguration.
Either fix the cause of this error or at your own risk disable the checker (see sanity.conf).
Following is the list of potential problems / advisories:
Fetcher failure for URL: 'https://www.example.com/'. URL https://www.example.com/ doesn't work.
Please ensure your host's network is configured correctly,
or set BB_NO_NETWORK = "1" to disable network access if
all required sources are on local disk.
Summary: There was 1 WARNING message shown.
Summary: There was 1 ERROR message shown, returning a non-zero exit code.
The networking issue, the reason why I can't access www.example.com, is a question for the SuperUser forum. My question here is, why does BitBake rely on the existence of www.example.com? What is it about that website that is so vital to BitBake's operation? Why does BitBake post an Error if it cannot find https://www.example.com?
At this time, I don't wish to set BB_NO_NETWORK = "1". I would rather understand and resolve the root cause of the problem first.
Modifying poky.conf didn't work for me (and from what I read, modifying anything under Poky is a no-no for a long term solution).
Modifying /conf/local.conf was the only solution that worked for me. Simply add one of the two options:
#check connectivity using google
CONNECTIVITY_CHECK_URIS = "https://www.google.com/"
#skip connectivity checks
CONNECTIVITY_CHECK_URIS = ""
This solution was originally found here.
For me, this appears to be a problem with my ISP (CenturyLink) not correctly resolving www.example.com. If I try to navigate to https://www.example.com in the browser address bar I just get taken to the ISP's "this is not a valid address" page.
Technically speaking, this isn't supposed to happen, but for whatever reason it does. I was able to work around this temporarily by modifying the CONNECTIVITY_CHECK_URIS in poky/meta-poky/conf/distro/poky.conf to something that actually resolves:
# The CONNECTIVITY_CHECK_URI's are used to test whether we can succesfully
# fetch from the network (and warn you if not). To disable the test set
# the variable to be empty.
# Git example url: git://git.yoctoproject.org/yocto-firewall-test;protocol=git;rev=master
CONNECTIVITY_CHECK_URIS ?= "https://www.google.com/"
See this commit for more insight and discussion on the addition of the www.example.com check. Not sure what the best long-term fix is, but the change above allowed me to build successfully.
If you want to resolve this issue without modifying poky.conf or local.conf or any of the files for that matter, just do:
$touch conf/sanity.conf
It is clearly written in meta/conf/sanity.conf that:
Expert users can confirm their sanity with "touch conf/sanity.conf"
If you don't want to execute this command on every session or build, you can comment out the line INHERIT += "sanity" from meta/conf/sanity.conf, so the file looks something like this:
Had same issue with Bell ISP when accessing example.com gave DNS error.
Solved by switching ISP's DNS IP to Google's DNS (to avoid making changes to configs):
https://developers.google.com/speed/public-dns/docs/using