Create an Ingress with Basic Authentication (nginx)

If you install Longhorn on a Kubernetes cluster with kubectl or Helm, you will need to create an Ingress to allow external traffic to reach the Longhorn UI.

Authentication is not enabled by default for kubectl and Helm installations. In these steps, you’ll learn how to create an Ingress with basic authentication using annotations for the nginx ingress controller.

  1. Create a basic auth file auth. It’s important the file generated is named auth (actually - that the secret has a key data.auth), otherwise the Ingress returns a 503.

    1. $ USER=<USERNAME_HERE>; PASSWORD=<PASSWORD_HERE>; echo "${USER}:$(openssl passwd -stdin -apr1 <<< ${PASSWORD})" >> auth
  2. Create a secret:

    1. $ kubectl -n longhorn-system create secret generic basic-auth --from-file=auth
  3. Create an Ingress manifest longhorn-ingress.yml :

    Since v1.2.0, Longhorn supports uploading backing image from the UI, so please specify nginx.ingress.kubernetes.io/proxy-body-size: 10000m as below to ensure uploading images work as expected.

    1. apiVersion: networking.k8s.io/v1
    2. kind: Ingress
    3. metadata:
    4. name: longhorn-ingress
    5. namespace: longhorn-system
    6. annotations:
    7. # type of authentication
    8. nginx.ingress.kubernetes.io/auth-type: basic
    9. # prevent the controller from redirecting (308) to HTTPS
    10. nginx.ingress.kubernetes.io/ssl-redirect: 'false'
    11. # name of the secret that contains the user/password definitions
    12. nginx.ingress.kubernetes.io/auth-secret: basic-auth
    13. # message to display with an appropriate context why the authentication is required
    14. nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required '
    15. # custom max body size for file uploading like backing image uploading
    16. nginx.ingress.kubernetes.io/proxy-body-size: 10000m
    17. spec:
    18. ingressClassName: nginx
    19. rules:
    20. - http:
    21. paths:
    22. - pathType: Prefix
    23. path: "/"
    24. backend:
    25. service:
    26. name: longhorn-frontend
    27. port:
    28. number: 80
  4. Create the Ingress:

    1. $ kubectl -n longhorn-system apply -f longhorn-ingress.yml

e.g.:

  1. $ USER=foo; PASSWORD=bar; echo "${USER}:$(openssl passwd -stdin -apr1 <<< ${PASSWORD})" >> auth
  2. $ cat auth
  3. foo:$apr1$FnyKCYKb$6IP2C45fZxMcoLwkOwf7k0
  4. $ kubectl -n longhorn-system create secret generic basic-auth --from-file=auth
  5. secret/basic-auth created
  6. $ kubectl -n longhorn-system get secret basic-auth -o yaml
  7. apiVersion: v1
  8. data:
  9. auth: Zm9vOiRhcHIxJEZueUtDWUtiJDZJUDJDNDVmWnhNY29Md2tPd2Y3azAK
  10. kind: Secret
  11. metadata:
  12. creationTimestamp: "2020-05-29T10:10:16Z"
  13. name: basic-auth
  14. namespace: longhorn-system
  15. resourceVersion: "2168509"
  16. selfLink: /api/v1/namespaces/longhorn-system/secrets/basic-auth
  17. uid: 9f66233f-b12f-4204-9c9d-5bcaca794bb7
  18. type: Opaque
  19. $ echo "
  20. apiVersion: networking.k8s.io/v1
  21. kind: Ingress
  22. metadata:
  23. name: longhorn-ingress
  24. namespace: longhorn-system
  25. annotations:
  26. # type of authentication
  27. nginx.ingress.kubernetes.io/auth-type: basic
  28. # prevent the controller from redirecting (308) to HTTPS
  29. nginx.ingress.kubernetes.io/ssl-redirect: 'false'
  30. # name of the secret that contains the user/password definitions
  31. nginx.ingress.kubernetes.io/auth-secret: basic-auth
  32. # message to display with an appropriate context why the authentication is required
  33. nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required '
  34. spec:
  35. rules:
  36. - http:
  37. paths:
  38. - pathType: Prefix
  39. path: "/"
  40. backend:
  41. service:
  42. name: longhorn-frontend
  43. port:
  44. number: 80
  45. " | kubectl -n longhorn-system create -f -
  46. ingress.networking.k8s.io/longhorn-ingress created
  47. $ kubectl -n longhorn-system get ingress
  48. NAME HOSTS ADDRESS PORTS AGE
  49. longhorn-ingress * 45.79.165.114,66.228.45.37,97.107.142.125 80 2m7s
  50. $ curl -v http://97.107.142.125/
  51. * Trying 97.107.142.125...
  52. * TCP_NODELAY set
  53. * Connected to 97.107.142.125 (97.107.142.125) port 80 (#0)
  54. > GET / HTTP/1.1
  55. > Host: 97.107.142.125
  56. > User-Agent: curl/7.64.1
  57. > Accept: */*
  58. >
  59. < HTTP/1.1 401 Unauthorized
  60. < Server: openresty/1.15.8.1
  61. < Date: Fri, 29 May 2020 11:47:33 GMT
  62. < Content-Type: text/html
  63. < Content-Length: 185
  64. < Connection: keep-alive
  65. < WWW-Authenticate: Basic realm="Authentication Required"
  66. <
  67. <html>
  68. <head><title>401 Authorization Required</title></head>
  69. <body>
  70. <center><h1>401 Authorization Required</h1></center>
  71. <hr><center>openresty/1.15.8.1</center>
  72. </body>
  73. </html>
  74. * Connection #0 to host 97.107.142.125 left intact
  75. * Closing connection 0
  76. $ curl -v http://97.107.142.125/ -u foo:bar
  77. * Trying 97.107.142.125...
  78. * TCP_NODELAY set
  79. * Connected to 97.107.142.125 (97.107.142.125) port 80 (#0)
  80. * Server auth using Basic with user 'foo'
  81. > GET / HTTP/1.1
  82. > Host: 97.107.142.125
  83. > Authorization: Basic Zm9vOmJhcg==
  84. > User-Agent: curl/7.64.1
  85. > Accept: */*
  86. >
  87. < HTTP/1.1 200 OK
  88. < Date: Fri, 29 May 2020 11:51:27 GMT
  89. < Content-Type: text/html
  90. < Content-Length: 1118
  91. < Last-Modified: Thu, 28 May 2020 00:39:41 GMT
  92. < ETag: "5ecf084d-3fd"
  93. < Cache-Control: max-age=0
  94. <
  95. <!DOCTYPE html>
  96. <html lang="en">
  97. ......

Additional Steps for AWS EKS Kubernetes Clusters

You will need to create an ELB (Elastic Load Balancer) to expose the nginx Ingress controller to the Internet. Additional costs may apply.

  1. Create pre-requisite resources according to the nginx ingress controller documentation.

  2. Create an ELB by following these steps.

References

https://kubernetes.github.io/ingress-nginx/