kubernetes helm chart

10/10/2018

I am trying to block user agent name wordpress using helm chart for nginx ingress.For this i have given key value in values.yml file and called the key in configmap.yml as shown below.

 - values.yml file
   configmap:
     block_user_agents: "^.*wordpress.*
quot;
- configmap.yml file data: block-user-agents: "{{ .Values.configmap.block_user_agents }}" - command to check curl -A "wordpress-blah" http://my_minikube_ip:32144(serviceport) - output <html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx/1.15.5</center> </body> </html>

After deploying the helm chart successfully using helm install i am trying to test it using curl command as to check whether its blocking the user agent or not. I am getting 404 not found as i need to get 403. Could any one please help me here and will regex work here? Am i missing something?

-- juuk
kubernetes
kubernetes-helm

1 Answer

10/10/2018

This is an example of how to block user agents in the nginx.conf:

### make sure your 'if' statement is in the server block.
### case sensitive http user agent blocking  ###
if ($http_user_agent ~ (Catall Spider|AcoiRobot) ) {
    return 403;
}
### case insensitive http user agent blocking  ###
if ($http_user_agent ~* (foo|bar) ) {
    return 403;
}

You can add some configuration part in the ingress-controller's nginx.conf using the following example. It adds a custom header to Nginx configuration that only applies to that specific Ingress:

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-configuration-snippet
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      more_set_headers "Request-Id: $req_id";
spec:
  rules:
  - host: custom.configuration.com
    http:
      paths:
      - backend:
          serviceName: http-svc
          servicePort: 80
        path: /

If you need to add some global settings to the ingress controller see the following examples:

---
apiVersion: v1
data:
  proxy-set-headers: "ingress-nginx/custom-headers"
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: v1
data:
  X-Different-Name: "true"
  X-Request-Start: t=${msec}
  X-Using-Nginx-Controller: "true"
kind: ConfigMap
metadata:
  name: custom-headers
  namespace: ingress-nginx

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
data:
  proxy-connect-timeout: "10"
  proxy-read-timeout: "120"
  proxy-send-timeout: "120"

Create a YAML file using the previous examples and apply it to your cluster:

kubectl apply -f nginx-ingress-config.yaml

You can check if settings applied to the nginx.conf in the ingress controller using the following command:

# Replace name of the ingress controller with the real name of the pod in the right namespace
$ kubectl exec nginx-ingress-controller-6bdddddb-6dmnw -n kube-system cat /etc/nginx/nginx.conf

# You can find the real name of your ingress controller and namespace using the next command
$ kubectl get pods --all-namespaces | grep nginx-ingress-controller

Without information about your chart it's hard to guess which parameter you should set.

If you are using chart from the helm repository you can fetch it's content by running

$ helm fetch <chart/name>

After that you will get a compressed chart file in the current directory. You may need to find the right value for you code snippet by reading the template files in the chart’s template directory.

If you are using chart written by you, you can use stable/nginx-ingress chart as a reference. It has a lot of configuration options.

Update:

Starting from version 0.20.0 new functionality was introduced:

#2997 Provide possibility to block IPs, User-Agents and Referers globally

Usage of parameter is explained in Map section of the manual.

If you need an example of usage you can find it in test-case.

It("should block User-Agents defined in the ConfigMap", func() {
    err := f.UpdateNginxConfigMapData("block-user-agents", "~*chrome\\/68\\.0\\.3440\\.106\\ safari\\/537\\.36,AlphaBot")
    Expect(err).NotTo(HaveOccurred())

...

    // Should be blocked
    resp, _, errs := gorequest.New().
        Get(f.IngressController.HTTPURL).
        Set("Host", host).
        Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36").
        End()
    Expect(errs).To(BeNil())
    Expect(resp.StatusCode).Should(Equal(http.StatusForbidden))

    resp, _, errs = gorequest.New().
        Get(f.IngressController.HTTPURL).
        Set("Host", host).
        Set("User-Agent", "AlphaBot").
        End()
    Expect(errs).To(BeNil())
    Expect(resp.StatusCode).Should(Equal(http.StatusForbidden))

    // Shouldn't be blocked
    resp, _, errs = gorequest.New().
        Get(f.IngressController.HTTPURL).
        Set("Host", host).
        Set("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1").
        End()
    Expect(errs).To(BeNil())
    Expect(resp.StatusCode).Should(Equal(http.StatusOK))
})
-- VAS
Source: StackOverflow