Auth

基本概念

什么是 Auth

Auth 是一种在请求到达实际服务之前执行身份验证的机制。它允许你在 ALB 层统一处理身份验证,而无需在每个后端服务中实现身份验证逻辑。

支持的 Auth 方法

ALB 支持两种主要的身份验证方法:

  1. Forward Auth(外部身份验证)

    • 将请求发送到外部身份验证服务,以验证用户身份
    • 适用场景:需要复杂的身份验证逻辑,例如 OAuth、SSO 等
    • 工作流程:
      1. 用户请求到达 ALB
      2. ALB 将身份验证信息转发到身份验证服务
      3. 身份验证服务返回验证结果
      4. 根据身份验证结果,决定是否允许访问后端服务
  2. Basic Auth(基本身份验证)

    • 基于用户名和密码的简单身份验证机制
    • 适用场景:简单的访问控制、开发环境保护
    • 工作流程:
      1. 用户请求到达 ALB
      2. ALB 检查请求中的用户名和密码
      3. 与已配置的身份验证信息进行比较
      4. 如果验证通过,则转发到后端服务

Auth 配置方法

  1. 全局 Auth

    • 在 ALB 层配置,适用于所有服务
    • 在 ALB 或 FT CR 上配置
  2. 路径级 Auth

    • 在特定的 Ingress 路径上配置
    • 在特定的 Rule 上配置
    • 可以覆盖全局 Auth 配置
  3. 禁用 Auth

    • 为特定路径禁用 Auth
    • 在 Ingress 上通过注解配置:alb.ingress.cpaas.io/auth-enable: "false"
    • 在 Rule 上通过 CR 配置

Auth 结果处理

  • Auth 成功:请求将转发到后端服务
  • Auth 失败:返回 401 未授权错误
  • 可以配置 Auth 失败后的重定向行为(适用于 Forward Auth)

快速入门

使用 ALB 配置 Basic Auth

部署 ALB

cat <<EOF | kubectl apply -f -
apiVersion: crd.alauda.io/v2
kind: ALB2
metadata:
  name: auth
  namespace: cpaas-system
spec:
  config:
    networkMode: container
    projects:
    - ALL_ALL
    replicas: 1
    vip:
      enableLbSvc: false
  type: nginx
EOF
export ALB_IP=$(kubectl get pods -n cpaas-system -l service_name=alb2-auth -o jsonpath='{.items[*].status.podIP}');echo $ALB_IP

配置 Secret 和 Ingress

# echo "Zm9vOiRhcHIxJHFJQ05aNjFRJDJpb29pSlZVQU1tcHJxMjU4L0NoUDE=" | base64 -d #  foo:$apr1$qICNZ61Q$2iooiJVUAMmprq258/ChP1
# openssl passwd -apr1 -salt qICNZ61Q bar # $apr1$qICNZ61Q$2iooiJVUAMmprq258/ChP1

kubectl apply -f - <<'END'
apiVersion: v1
kind: Secret
metadata:
  name: auth-file
type: Opaque
data:
  auth: Zm9vOiRhcHIxJHFJQ05aNjFRJDJpb29pSlZVQU1tcHJxMjU4L0NoUDE=
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: auth-file
  annotations:
    "nginx.ingress.kubernetes.io/auth-type": "basic"
    "nginx.ingress.kubernetes.io/auth-secret": "default/auth-file"
    "nginx.ingress.kubernetes.io/auth-secret-type": "auth-file"
spec:
  rules:
  - http:
      paths:
      - path: /app-file
        pathType: Prefix
        backend:
          service:
            name: app-server
            port:
              number: 80
END

验证

# echo "Zm9vOiJhYXIi" | base64 -d # foo:bar
curl -v -X GET -H "Authorization: Basic Zm9vOmJhcg==" http://$ALB_IP:80/app-file # should return 200
# wrong password
curl -v -X GET -H "Authorization: Basic XXXXOmJhcg==" http://$ALB_IP:80/app-file # should return 401

相关 Ingress 注解

Ingress-nginx 定义了一系列用于配置身份验证流程详细信息的注解。下面列出了 ALB 支持的注解,其中“v”表示支持,“x”表示不支持。

支持类型说明
forward-auth通过发送 http 请求进行转发身份验证
nginx.ingress.kubernetes.io/auth-urlvstring
nginx.ingress.kubernetes.io/auth-methodvstring
nginx.ingress.kubernetes.io/auth-signinvstring
nginx.ingress.kubernetes.io/auth-signin-redirect-paramvstring
nginx.ingress.kubernetes.io/auth-response-headersvstring
nginx.ingress.kubernetes.io/auth-proxy-set-headersvstring
nginx.ingress.kubernetes.io/auth-request-redirectvstring
nginx.ingress.kubernetes.io/auth-always-set-cookievboolean
nginx.ingress.kubernetes.io/auth-snippetxstring
basic-auth使用用户名和密码 Secret 进行身份验证
nginx.ingress.kubernetes.io/auth-realmvstring
nginx.ingress.kubernetes.io/auth-secretvstring
nginx.ingress.kubernetes.io/auth-secret-typevstring
nginx.ingress.kubernetes.io/auth-type-"basic" 或 "digest"basic:支持 apr1;digest:不支持
auth-cache
nginx.ingress.kubernetes.io/auth-cache-keyxstring
nginx.ingress.kubernetes.io/auth-cache-durationxstring
auth-keepalive发送请求时保持连接。通过一系列注解指定保持连接行为
nginx.ingress.kubernetes.io/auth-keepalivexnumber
nginx.ingress.kubernetes.io/auth-keepalive-share-varsx"true" 或 "false"
nginx.ingress.kubernetes.io/auth-keepalive-requestsxnumber
nginx.ingress.kubernetes.io/auth-keepalive-timeoutxnumber
auth-tls当请求为 https 时,额外验证证书。
nginx.ingress.kubernetes.io/auth-tls-secretxstring
nginx.ingress.kubernetes.io/auth-tls-verify-depthxnumber
nginx.ingress.kubernetes.io/auth-tls-verify-clientxstring
nginx.ingress.kubernetes.io/auth-tls-error-pagexstring
nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstreamx"true" 或 "false"
nginx.ingress.kubernetes.io/auth-tls-match-cnxstring

forward-auth

相关注解:

  • nginx.ingress.kubernetes.io/auth-url
  • nginx.ingress.kubernetes.io/auth-method
  • nginx.ingress.kubernetes.io/auth-signin
  • nginx.ingress.kubernetes.io/auth-signin-redirect-param
  • nginx.ingress.kubernetes.io/auth-response-headers
  • nginx.ingress.kubernetes.io/auth-proxy-set-headers
  • nginx.ingress.kubernetes.io/auth-request-redirect
  • nginx.ingress.kubernetes.io/auth-always-set-cookie

这些注解描述了上图中对 auth-request、app-request 和 cli-response 所做的修改。

构造相关注解

auth-url

Auth-request 的 URL,值可以是变量。

auth-method

Auth-request 的方法。

auth-proxy-set-headers

值为 ConfigMap 引用,格式为 ns/name。 默认情况下,cli-request 中的所有标头都会发送到 auth-server。可以通过 proxy_set_header 配置其他标头。默认发送以下标头:

X-Original-URI          $request_uri;
X-Scheme                $pass_access_scheme;
X-Original-URL          $scheme://$http_host$request_uri;
X-Original-Method       $request_method;
X-Sent-From             "alb";
X-Real-IP               $remote_addr;
X-Forwarded-For         $proxy_add_x_forwarded_for;
X-Auth-Request-Redirect $request_uri;

构造与 app-request 相关的注解

auth-response-headers

值为逗号分隔的字符串,用于将 auth-response 中的特定标头传递到 app-request。 例如:

nginx.ingress.kubernetes.io/auth-response-headers: Remote-User,Remote-Name

ALB 发起 app-request 时,会包含 auth-response 标头中的 Remote-User 和 Remote-Name。

auth-response 和 app-response 都可以设置 Cookie。默认情况下,只有在 app-response.success 时,auth-response.set-cookie 才会合并到 cli-response.set-cookie 中。

重定向登录相关配置

当 auth-server 返回 401 时,可以在 cli-response 中设置重定向标头,指示浏览器重定向到 auth-signin 指定的 URL 进行验证。

auth-signin

值为 URL,用于指定 cli-response 中的 location 标头。

auth-signin-redirect-param

signin-url 中查询参数的名称,默认为 rd。 如果 signin-url 不包含指定的 auth-signin-redirect-param 参数名,alb 会自动添加该参数。参数值将设置为 $pass_access_scheme://$http_host$escaped_request_uri,用于记录原始请求 URL。

auth-request-redirect

在 auth-request 中设置 x-auth-request-redirect 标头。

basic-auth

basic-auth 是 RFC 7617 中描述的身份验证过程。 交互过程如下:

auth-realm

受保护区域的描述 即 cli-response 的 WWW-Authenticate 标头中的 realm 值。 WWW-Authenticate: Basic realm="$realm"

auth-type

身份验证方案的类型,目前仅支持 basic

auth-secret

用户名和密码的 Secret 引用,格式为 ns/name

auth-secret-type

Secret 支持两种类型:

  1. auth-file:Secret 的 data 仅包含一个键 "auth",其值为 Apache htpasswd 格式的字符串。例如:

    data:
      auth: "user1:$apr1$xyz..."
  2. auth-map:Secret 的 data 中每个键表示一个用户名,对应的值为密码哈希(htpasswd 格式中不包含用户名)。例如:

    data:
      user1: "$apr1$xyz...."
      user2: "$apr1$abc...."

注意:目前仅支持使用 apr1 算法生成的 htpasswd 格式密码哈希。

CR

ALB CR 新增了与身份验证相关的配置项,可在 ALB/Frontend/Rule CR 中进行配置。 运行时,ALB 会将 Ingress 上的注解转换为规则。

auth:
  # Basic authentication configuration
  basic:
    #  string; corresponding to nginx.ingress.kubernetes.io/auth-type: basic
    auth_type: 'basic'
    #  string; corresponding to nginx.ingress.kubernetes.io/auth-realm
    realm: 'Restricted Access'
    #  string; corresponding to nginx.ingress.kubernetes.io/auth-secret
    secret: 'ns/name'
    #  string; corresponding to nginx.ingress.kubernetes.io/auth-secret-type
    secret_type: 'auth-map|auth-file'
  # Forward authentication configuration
  forward:
    #  boolean; corresponding to nginx.ingress.kubernetes.io/auth-always-set-cookie
    always_set_cookie: true
    #  string; corresponding to nginx.ingress.kubernetes.io/auth-proxy-set-headers
    auth_headers_cm_ref: 'ns/name'
    #  string; corresponding to nginx.ingress.kubernetes.io/auth-request-redirect
    auth_request_redirect: '/login'
    #  string; corresponding to nginx.ingress.kubernetes.io/auth-method
    method: 'GET'
    #  string; corresponding to nginx.ingress.kubernetes.io/auth-signin
    signin: '/signin'
    #  string; corresponding to nginx.ingress.kubernetes.io/auth-signin-redirect-param
    signin_redirect_param: 'redirect_to'
    #  []string; corresponding to nginx.ingress.kubernetes.io/auth-response-headers
    upstream_headers:
      - 'X-User-ID'
      - 'X-User-Name'
      - 'X-User-Email'
    #  string; corresponding to nginx.ingress.kubernetes.io/auth-url
    url: 'http://auth-service/validate'

Auth 支持在以下位置进行配置:

  • Alb CR 的 .spec.config.auth
  • Frontend CR 的 .spec.config.auth
  • Rule CR 的 .spec.config.auth

继承顺序为 Alb > Frontend > Rule。如果子 CR 未配置,则使用父 CR 的配置。

ALB 特殊 Ingress 注解

在处理 Ingress 的过程中,ALB 根据注解的前缀确定优先级。优先级从高到低为:

  • index.$rule_index-$path_index.alb.ingress.cpaas.io
  • alb.ingress.cpaas.io
  • nginx.ingress.kubernetes.io

这样可以处理与 ingress-nginx 的兼容性问题,并在指定的 Ingress 路径上配置身份验证。

Auth-Enable

alb.ingress.cpaas.io/auth-enable: 'false'

ALB 新增的注解,用于指定是否为 Ingress 启用身份验证功能。

Ingress-Nginx 身份验证相关的其他功能

Global-Auth

在 ingress-nginx 中,可以通过 ConfigMap 设置全局身份验证。这相当于为所有 Ingress 配置身份验证。在 ALB 中,可以在 ALB2 和 FT CR 中配置身份验证。其下的规则将继承这些配置。

No-Auth-Locations

在 ALB 中,可以在 Ingress 上配置注解 alb.ingress.cpaas.io/auth-enable: "false",以禁用此 Ingress 的身份验证功能。

注意:与 Ingress-Nginx 不兼容的部分

  1. 不支持 auth-keepalive
  2. 不支持 auth-snippet
  3. 不支持 auth-cache
  4. 不支持 auth-tls
  5. Basic-auth 仅支持 basic,不支持 digest
  6. Basic-auth basic 仅支持 apr1 算法,不支持 bcrypt sha256 等

故障排除

  1. 检查 ALB Pod 的 Nginx 容器日志
  2. 检查返回内容中的 X-ALB-ERR-REASON 响应头

商标声明

NGINX® 是 F5, Inc. 在美国及其他国家/地区的注册商标。

Alauda 是一家独立供应商。本产品与 F5, Inc. 没有关联,也未获得其认可或赞助。所有商标均归其各自所有者所有,此处仅用于标识目的。