|
| 1 | +## Basic Concepts |
| 2 | +### What is Auth |
| 3 | +Auth is a mechanism that performs identity verification before requests reach the actual service. It allows you to handle authentication uniformly at the ALB layer without implementing authentication logic in each backend service. |
| 4 | + |
| 5 | +### Supported Authentication Methods |
| 6 | +ALB supports two main authentication methods: |
| 7 | + |
| 8 | +1. **Forward Auth (External Authentication)** |
| 9 | + - Validates user identity by sending requests to an external authentication service |
| 10 | + - Use cases: Complex authentication logic like OAuth, SSO, etc. |
| 11 | + - Workflow: |
| 12 | + 1. User request reaches ALB |
| 13 | + 2. ALB forwards authentication info to auth service |
| 14 | + 3. Auth service returns verification result |
| 15 | + 4. Access to backend service is determined based on auth result |
| 16 | + |
| 17 | +2. **Basic Auth (Basic Authentication)** |
| 18 | + - Simple authentication mechanism based on username and password |
| 19 | + - Use cases: Simple access control, development environment protection |
| 20 | + - Workflow: |
| 21 | + 1. User request reaches ALB |
| 22 | + 2. ALB checks username/password in request |
| 23 | + 3. Compares with configured auth credentials |
| 24 | + 4. Forwards to backend service after validation |
| 25 | + |
| 26 | +### Authentication Configuration Methods |
| 27 | +1. **Global Authentication** |
| 28 | + - Configured at ALB level, applies to all services |
| 29 | + - Configured through ALB2 or FT CR |
| 30 | + |
| 31 | +2. **Path-level Authentication** |
| 32 | + - Configured on specific Ingress paths |
| 33 | + - Configured on specific Rules |
| 34 | + - Can override global auth configuration |
| 35 | + |
| 36 | +3. **Disable Authentication** |
| 37 | + - Can disable auth for specific paths |
| 38 | + - Via ingress annotation: `alb.ingress.cpaas.io/auth-enable: "false"` |
| 39 | + - Via rule CR configuration |
| 40 | + |
| 41 | +### Authentication Result Handling |
| 42 | +- Success: Request forwarded to backend service |
| 43 | +- Failure: Returns 401 Unauthorized error |
| 44 | +- Can configure redirect behavior on auth failure (for Forward Auth) |
| 45 | + |
| 46 | +## Quick Start |
| 47 | +Configure basic-auth with ALB |
| 48 | + |
| 49 | +### Deploy ALB |
| 50 | +```bash |
| 51 | +cat <<EOF | kubectl apply -f - |
| 52 | +apiVersion: crd.alauda.io/v2 |
| 53 | +kind: ALB2 |
| 54 | +metadata: |
| 55 | + name: auth |
| 56 | + namespace: cpaas-system |
| 57 | +spec: |
| 58 | + config: |
| 59 | + networkMode: container |
| 60 | + projects: |
| 61 | + - ALL_ALL |
| 62 | + replicas: 1 |
| 63 | + vip: |
| 64 | + enableLbSvc: false |
| 65 | + type: nginx |
| 66 | +EOF |
| 67 | +export ALB_IP=$(kubectl get pods -n cpaas-system -l service_name=alb2-auth -o jsonpath='{.items[*].status.podIP}');echo $ALB_IP |
| 68 | +``` |
| 69 | + |
| 70 | +### Configure Secret and Ingress |
| 71 | +```bash |
| 72 | +# echo "Zm9vOiRhcHIxJHFJQ05aNjFRJDJpb29pSlZVQU1tcHJxMjU4L0NoUDE=" | base64 -d # foo:$apr1$qICNZ61Q$2iooiJVUAMmprq258/ChP1 |
| 73 | +# openssl passwd -apr1 -salt qICNZ61Q bar # $apr1$qICNZ61Q$2iooiJVUAMmprq258/ChP1 |
| 74 | + |
| 75 | +kubectl apply -f - <<'END' |
| 76 | +apiVersion: v1 |
| 77 | +kind: Secret |
| 78 | +metadata: |
| 79 | + name: auth-file |
| 80 | +type: Opaque |
| 81 | +data: |
| 82 | + auth: Zm9vOiRhcHIxJHFJQ05aNjFRJDJpb29pSlZVQU1tcHJxMjU4L0NoUDE= |
| 83 | +--- |
| 84 | +apiVersion: networking.k8s.io/v1 |
| 85 | +kind: Ingress |
| 86 | +metadata: |
| 87 | + name: auth-file |
| 88 | + annotations: |
| 89 | + "nginx.ingress.kubernetes.io/auth-type": "basic" |
| 90 | + "nginx.ingress.kubernetes.io/auth-secret": "default/auth-file" |
| 91 | + "nginx.ingress.kubernetes.io/auth-secret-type": "auth-file" |
| 92 | +spec: |
| 93 | + rules: |
| 94 | + - http: |
| 95 | + paths: |
| 96 | + - path: /app-file |
| 97 | + pathType: Prefix |
| 98 | + backend: |
| 99 | + service: |
| 100 | + name: app-server |
| 101 | + port: |
| 102 | + number: 80 |
| 103 | +END |
| 104 | +``` |
| 105 | + |
| 106 | +### Testing |
| 107 | +```bash |
| 108 | +# echo "Zm9vOiJhYXIi" | base64 -d # foo:bar |
| 109 | +curl -v -X GET -H "Authorization: Basic Zm9vOmJhcg==" http://$ALB_IP:80/app-file # Should return 200 |
| 110 | +# Wrong password |
| 111 | +curl -v -X GET -H "Authorization: Basic XXXXOmJhcg==" http://$ALB_IP:80/app-file # Should return 401 |
| 112 | +``` |
| 113 | + |
| 114 | +## Ingress Annotation Overview |
| 115 | +ingress-nginx defines a series of annotations to configure authentication details. Below is the list of annotations compatible with ALB. v means supported, x means not supported. |
| 116 | + |
| 117 | +| | support | type | note | |
| 118 | +|--------------------------------------------------------------------------------------------------------------------------------------------------------|---------|---------------------|----------------------------------------------------------------------| |
| 119 | +| forward-auth | | | Authentication via HTTP request | |
| 120 | +| nginx.ingress.kubernetes.io/auth-url | v | string | | |
| 121 | +| nginx.ingress.kubernetes.io/auth-method | v | string | | |
| 122 | +| nginx.ingress.kubernetes.io/auth-signin | v | string | | |
| 123 | +| nginx.ingress.kubernetes.io/auth-signin-redirect-param | v | string | | |
| 124 | +| nginx.ingress.kubernetes.io/auth-response-headers | v | string | | |
| 125 | +| nginx.ingress.kubernetes.io/auth-proxy-set-headers | v | string | | |
| 126 | +| nginx.ingress.kubernetes.io/auth-request-redirect | v | string | | |
| 127 | +| nginx.ingress.kubernetes.io/auth-always-set-cookie | v | boolean | | |
| 128 | +| nginx.ingress.kubernetes.io/auth-snippet | x | string | | |
| 129 | +| basic-auth | | | Authentication via username/password secret | |
| 130 | +| nginx.ingress.kubernetes.io/auth-realm | v | string | | |
| 131 | +| nginx.ingress.kubernetes.io/auth-secret | v | string | | |
| 132 | +| nginx.ingress.kubernetes.io/auth-secret-type | v | string | | |
| 133 | +| nginx.ingress.kubernetes.io/auth-type | - | "basic" or "digest" | basic: supports apr1 algorithm<br>**digest: not supported** | |
| 134 | +| auth-cache | | | | |
| 135 | +| nginx.ingress.kubernetes.io/auth-cache-key | x | string | | |
| 136 | +| nginx.ingress.kubernetes.io/auth-cache-duration | x | string | | |
| 137 | +| auth-keepalive | | | Use keepalive connections for requests. Configure via annotations | |
| 138 | +| nginx.ingress.kubernetes.io/auth-keepalive | x | number | | |
| 139 | +| nginx.ingress.kubernetes.io/auth-keepalive-share-vars | x | "true" or "false" | | |
| 140 | +| nginx.ingress.kubernetes.io/auth-keepalive-requests | x | number | | |
| 141 | +| nginx.ingress.kubernetes.io/auth-keepalive-timeout | x | number | | |
| 142 | +| [auth-tls](https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md#client-certificate-authentication) | | | Additional certificate validation for HTTPS requests | |
| 143 | +| nginx.ingress.kubernetes.io/auth-tls-secret | x | string | | |
| 144 | +| nginx.ingress.kubernetes.io/auth-tls-verify-depth | x | number | | |
| 145 | +| nginx.ingress.kubernetes.io/auth-tls-verify-client | x | string | | |
| 146 | +| nginx.ingress.kubernetes.io/auth-tls-error-page | x | string | | |
| 147 | +| nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream | x | "true" or "false" | | |
| 148 | +| nginx.ingress.kubernetes.io/auth-tls-match-cn | x | string | | |
| 149 | + |
| 150 | +## Forward Auth |
| 151 | + |
| 152 | + |
| 153 | +Related annotations: |
| 154 | +- nginx.ingress.kubernetes.io/auth-url |
| 155 | +- nginx.ingress.kubernetes.io/auth-method |
| 156 | +- nginx.ingress.kubernetes.io/auth-signin |
| 157 | +- nginx.ingress.kubernetes.io/auth-signin-redirect-param |
| 158 | +- nginx.ingress.kubernetes.io/auth-response-headers |
| 159 | +- nginx.ingress.kubernetes.io/auth-proxy-set-headers |
| 160 | +- nginx.ingress.kubernetes.io/auth-request-redirect |
| 161 | +- nginx.ingress.kubernetes.io/auth-always-set-cookie |
| 162 | + |
| 163 | +These annotations describe modifications to auth-request, app-request, and cli-response in the flow diagram above. |
| 164 | + |
| 165 | +### Auth Request Related Annotations |
| 166 | +#### auth-url |
| 167 | +URL for auth-request, value can be variables. |
| 168 | + |
| 169 | +#### auth-method |
| 170 | +Method for auth-request. |
| 171 | + |
| 172 | +#### auth-proxy-set-headers |
| 173 | +Value is a configmap reference in format `ns/name`. |
| 174 | +By default, all cli-request headers are sent to auth-server. Additional headers can be configured via proxy_set_header. Default additional headers: |
| 175 | +``` |
| 176 | +X-Original-URI $request_uri; |
| 177 | +X-Scheme $pass_access_scheme; |
| 178 | +X-Original-URL $scheme://$http_host$request_uri; |
| 179 | +X-Original-Method $request_method; |
| 180 | +X-Sent-From "alb"; |
| 181 | +X-Real-IP $remote_addr; |
| 182 | +X-Forwarded-For $proxy_add_x_forwarded_for; |
| 183 | +X-Auth-Request-Redirect $request_uri; |
| 184 | +``` |
| 185 | + |
| 186 | +### App Request Related Annotations |
| 187 | +#### auth-response-headers |
| 188 | +Value is a comma-separated string allowing specific auth-response headers in app-request. |
| 189 | +Example: |
| 190 | +``` |
| 191 | +nginx.ingress.kubernetes.io/auth-response-headers: Remote-User,Remote-Name |
| 192 | +``` |
| 193 | +When ALB sends request to app (app-request), it will include Remote-User and Remote-Name from auth-response headers. |
| 194 | + |
| 195 | +### Cookie Handling |
| 196 | +Both auth-response and app-response can set cookies. By default, auth-response.set-cookie is merged into cli-response.set-cookie only when app-response.success. |
| 197 | +```mermaid |
| 198 | +flowchart TD |
| 199 | + subgraph "always-set-cookie disabled" |
| 200 | + A[app-response.set-cookie] --> C{app-response.success?} |
| 201 | + B[auth-response.set-cookie] --> C |
| 202 | + C -->|Yes| D[Merge Cookies] |
| 203 | + C -->|No| E[Use app-response.set-cookie only] |
| 204 | + D --> F[cli-response.set-cookie] |
| 205 | + E --> F |
| 206 | + end |
| 207 | + subgraph "always-set-cookie enabled" |
| 208 | + G[app-response.set-cookie] --> I[Merge Cookies] |
| 209 | + H[auth-response.set-cookie] --> I |
| 210 | + I --> J[cli-response.set-cookie] |
| 211 | + end |
| 212 | +``` |
| 213 | + |
| 214 | +### Sign Redirect Related Configuration |
| 215 | +When auth-server returns 401, we can redirect browser to auth-signin URL via redirect header in cli-response |
| 216 | + |
| 217 | + |
| 218 | +#### auth-signin |
| 219 | +Value is URL specifying location header in cli-response. |
| 220 | + |
| 221 | +#### auth-signin-redirect-param |
| 222 | +Query parameter name in signin-url, default is rd. |
| 223 | +If auth-signin URL doesn't contain parameter specified by `auth-signin-redirect-param`, system automatically adds it. Parameter value is set to `$pass_access_scheme://$http_host$escaped_request_uri` to record original request URL. |
| 224 | + |
| 225 | +#### auth-request-redirect |
| 226 | +Sets `x-auth-request-redirect` header in auth-request |
| 227 | + |
| 228 | +## Basic Auth |
| 229 | +Basic auth refers to authentication process described in [RFC 7617](https://datatracker.ietf.org/doc/html/rfc7617). |
| 230 | +Interaction flow: |
| 231 | + |
| 232 | + |
| 233 | +### auth-realm |
| 234 | +[String describing protected area](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/WWW-Authenticate#realm) |
| 235 | +Realm value in `WWW-Authenticate` header of cli-response |
| 236 | +WWW-Authenticate: Basic realm="$realm" |
| 237 | + |
| 238 | +### auth-type |
| 239 | +Authentication scheme type, currently only supports basic |
| 240 | + |
| 241 | +### auth-secret |
| 242 | +Secret reference containing username/password config, format is ns/name |
| 243 | + |
| 244 | +### auth-secret-type |
| 245 | +Two supported secret formats: |
| 246 | +1. auth-file: secret data contains single "auth" key with Apache htpasswd format string value. Example: |
| 247 | + ``` |
| 248 | + data: |
| 249 | + auth: "user1:$apr1$xyz..." |
| 250 | + ``` |
| 251 | + |
| 252 | +2. auth-map: each key in secret data represents username, corresponding value is password hash (htpasswd format without username). Example: |
| 253 | + ``` |
| 254 | + data: |
| 255 | + user1: "$apr1$xyz...." |
| 256 | + user2: "$apr1$abc...." |
| 257 | + ``` |
| 258 | + |
| 259 | +Note: Currently only supports htpasswd format password hashes generated with apr1 algorithm. |
| 260 | + |
| 261 | +## New ALB CR Configuration Items |
| 262 | +ALB CR adds auth-related configuration items configurable in alb2/ft/rule CRs. |
| 263 | +During runtime, ALB converts ingress annotations to rules |
| 264 | +```yaml |
| 265 | +auth: |
| 266 | + # Basic auth config |
| 267 | + basic: |
| 268 | + # string; corresponds to nginx.ingress.kubernetes.io/auth-type: basic |
| 269 | + auth_type: "basic" |
| 270 | + # string; corresponds to nginx.ingress.kubernetes.io/auth-realm |
| 271 | + realm: "Restricted Access" |
| 272 | + # string; corresponds to nginx.ingress.kubernetes.io/auth-secret |
| 273 | + secret: "ns/name" |
| 274 | + # string; corresponds to nginx.ingress.kubernetes.io/auth-secret-type |
| 275 | + secret_type: "auth-map|auth-file" |
| 276 | + # Forward auth config |
| 277 | + forward: |
| 278 | + # boolean; corresponds to nginx.ingress.kubernetes.io/auth-always-set-cookie |
| 279 | + always_set_cookie: true |
| 280 | + # string; corresponds to nginx.ingress.kubernetes.io/auth-proxy-set-headers |
| 281 | + auth_headers_cm_ref: "ns/name" |
| 282 | + # string; corresponds to nginx.ingress.kubernetes.io/auth-request-redirect |
| 283 | + auth_request_redirect: "/login" |
| 284 | + # corresponds to nginx.ingress.kubernetes.io/auth-method |
| 285 | + method: "GET" |
| 286 | + # corresponds to nginx.ingress.kubernetes.io/auth-signin |
| 287 | + signin: "/signin" |
| 288 | + # corresponds to nginx.ingress.kubernetes.io/auth-signin-redirect-param |
| 289 | + signin_redirect_param: "redirect_to" |
| 290 | + # corresponds to nginx.ingress.kubernetes.io/auth-response-headers |
| 291 | + upstream_headers: |
| 292 | + - "X-User-ID" |
| 293 | + - "X-User-Name" |
| 294 | + - "X-User-Email" |
| 295 | + # corresponds to nginx.ingress.kubernetes.io/auth-url |
| 296 | + url: "http://auth-service/validate" |
| 297 | +``` |
| 298 | +Auth can be configured in: |
| 299 | +- Alb CR's `.spec.config.auth` |
| 300 | +- Frontend CR's `.spec.config.auth` |
| 301 | +- Rule CR's `.spec.config.auth` |
| 302 | + |
| 303 | +Inheritance order is Alb>Frontend>Rule. If child CR has no configuration, it uses parent CR's configuration. |
| 304 | + |
| 305 | +## ALB Special Ingress Annotations |
| 306 | +When processing ingress, ALB decides priority based on annotation prefix |
| 307 | +Priority from high to low: |
| 308 | +- `index.$rule_index-$path_index.alb.ingress.cpaas.io` |
| 309 | +- `alb.ingress.cpaas.io` |
| 310 | +- `nginx.ingress.kubernetes.io` |
| 311 | +This handles compatibility with ingress-nginx and specifies auth config for specific ingress paths |
| 312 | + |
| 313 | +### auth-enable |
| 314 | +```yaml |
| 315 | +alb.ingress.cpaas.io/auth-enable: "false" |
| 316 | +``` |
| 317 | +New ALB annotation specifying whether to enable auth for ingress. |
| 318 | + |
| 319 | +## Other ingress-nginx Auth Features |
| 320 | +### global-auth |
| 321 | +In ingress-nginx, global auth can be set via configmap, equivalent to configuring auth for all ingresses |
| 322 | +In ALB, auth can be configured on alb2 and ft CRs. Rules under them inherit these configurations |
| 323 | + |
| 324 | +### no-auth-locations |
| 325 | +In ALB, auth can be disabled for an ingress via annotation: `alb.ingress.cpaas.io/auth-enable: "false"` |
| 326 | + |
| 327 | +## Note: Incompatibilities with ingress-nginx |
| 328 | +1. No auth-keepalive support |
| 329 | +2. No auth-snippet support |
| 330 | +3. No auth-cache support |
| 331 | +4. No auth-tls support |
| 332 | +5. Basic-auth only supports basic, not digest |
| 333 | +6. Basic-auth basic only supports apr1 algorithm, not bcrypt sha256 etc. |
| 334 | + |
| 335 | +## Troubleshooting |
| 336 | +1. Check ALB pod nginx container logs |
| 337 | +2. Check X-ALB-ERR-REASON header in response |
| 338 | + |
| 339 | +## Other Resources |
| 340 | +[ALB with oauth-proxy](./配置oauth2-proxy.md) |
| 341 | +[Test Cases](./测试用例.md) |
| 342 | +[ALB Auth Implementation Details](./dev_readme.md) |
| 343 | +[ingress-nginx Annotations Details](https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md#authentication) |
0 commit comments