5

我正在设置一个 ghost 实例,并尝试通过客户端证书验证来保护 /ghost 路径。

我已经启动并运行了一个初始入口,它使用指定为 / 的路径非常愉快地为该站点提供服务。

我正在尝试为 /ghost 路径添加第二个入口(几乎相同)。如果我这样做并添加基本身份验证的注释,一切似乎都有效。即,如果我浏览到 /ghost,系统会提示我输入基本身份验证密钥中的凭据,如果我浏览到任何其他 URL,它会在没有身份验证的情况下提供。

然后我根据这个例子切换到客户端证书验证:https ://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/auth/client-certs

当我尝试整个站点或没有站点是安全的,而不是基于路径的分离时,我得到了基本身份验证。从正在运行的 pod 中查看 nginx.conf, proxy_set_header ssl-client-verify在根 / 路径和 /ghost 路径下添加了proxy_set_header ssl-client-subject-dn&proxy_set_header ssl-client-issuer-dn元素。我已经尝试删除这些(仅从根目录)并将配置直接复制回 pod,但也没有运气。

我通过 Helm 将 nginx-ingress(图表版本 0.23.0)作为依赖项

位置的入口定义/- 这个有效

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    certmanager.k8s.io/cluster-issuer: letsencrypt-staging
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: "true"
  labels:
    app: my-app
    chart: my-app-0.1.1
    heritage: Tiller
    release: my-app
  name: my-app
  namespace: default
spec:
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          serviceName: my-app
          servicePort: http
        path: /
  tls:
  - hosts:
    - example.com
    secretName: mysite-tls

位置的入口定义/ghost- 这个不起作用

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
    nginx.ingress.kubernetes.io/auth-tls-secret: "default/auth-tls-chain"
    nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
    nginx.ingress.kubernetes.io/auth-tls-error-page: "http://www.example.com/error-cert.html"
    nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "false"
    kubernetes.io/ingress.class: "nginx"
  labels:
    app: my-app
    chart: my-app-0.1.1
    heritage: Tiller
    release: my-app
  name: my-app-secure
  namespace: default
spec:
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          serviceName: my-app
          servicePort: http
        path: /ghost
  tls:
  - hosts:
    - example.com
    secretName: mysite-tls
4

2 回答 2

2

如果您想安全地为所有页面提供服务,并且您只需要另一个规则,那么您需要'*'在您的第二个入口处设置一条路径。像这样的东西:/ghost/ghost

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
    nginx.ingress.kubernetes.io/auth-tls-secret: "default/auth-tls-chain"
    nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
    nginx.ingress.kubernetes.io/auth-tls-error-page: "http://www.example.com/error-cert.html"
    nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "false"
    kubernetes.io/ingress.class: "nginx"
  labels:
    app: my-app
    chart: my-app-0.1.1
    heritage: Tiller
    release: my-app
  name: my-app-secure
  namespace: default
spec:
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          serviceName: my-app
          servicePort: http
        path: /ghost
      - backend:
          serviceName: my-app
          servicePort: http
        path: /ghost/*
  tls:
  - hosts:
    - example.com
    secretName: mysite-tls

但是,如果您想要像/unsecured 和/ghostsecured 这样的东西,我相信您将无法做到。例如,如果您使用的是 nginx,这是 nginx 本身的限制,当您server {}在 nginx 中配置带有 TLS 的块时,它看起来像这样:

server {
    listen              443 ssl;
    server_name         example.com;
    ssl_certificate     example.com.crt;
    ssl_certificate_key example.com.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ...
}

入口控制器创建如下路径:

server {
    listen              443 ssl;
    server_name         example.com;
    ssl_certificate     example.com.crt;
    ssl_certificate_key example.com.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ...

    location / {
       ...
    }

    location /ghost {
       ...
    }

}

因此,当您配置另一个server {}具有相同主机名且没有 SSL 的块时,它将覆盖第一个块。

您可以- host:在入口中使用不同的规则来执行此操作,例如ghost.example.com使用 TLS 和main.example.com不使用 TLS。所以在你的 nginx.conf 中你会有不同的server {}块。

您始终可以进入入口控制器 pod 以检查配置,例如:

$ kubectl exec -it nginx-ingress-controller-xxxxxxxxx-xxxxx bash
www-data@nginx-ingress-controller-6bd7c597cb-8kzjh:/etc/nginx$ cat nginx.conf
于 2018-10-25T03:20:44.217 回答
0

您可以添加位置片段

  annotations:
    nginx.ingress.kubernetes.io/location-snippet: |
       if ($location ^~ ghost) {
          set $ban_info = "location";
       }

       if ($ssl_client_s_dn !~ "CN=ok_client") {
          set $ban_info = "${ban_info}+no_client";
       }

       if ($ban_info = "location+no_client") {
         return 403;
       }
于 2019-10-02T17:03:28.770 回答