在传统nginx上,如果想要对nginx 里面的虚拟主机做白名单访问控制很easy。但在kubernetes中,如何通过 ingress resource配置文件来达到这个效果呢?

场景

最近项目开发团队提出一个需求,想要关闭API某个接口的path公开访问。不用开白名单,而是直接deny掉everyone。

分析

在传统运维里面,我们只要去修改该API虚拟主机中的配置文件,针对匹配该location path的访问请求,可以加allow,或者deny

Example:

location /secure_path {
    deny  192.168.1.8;
    allow 192.168.1.0/24;
    allow 10.1.1.0/16;
    deny  all;
}

上面的例子中,实现的效果如下:

问题在于,我们需要把这些配置放到哪?怎么放呢? 很简单,去nginx controller官网找到了答案。可放到ingress中的annotations中。

验证

以下是该Hosts的 ingress resource文件中的Annotations内容:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx-ingress-public
    nginx.ingress.kubernetes.io/server-snippet: |
        location ~* /*/secure_path/ {
            deny all;
        }
  labels:
    app: api-service
  name: backend-svc
  namespace: xxxxx

nginx.ingress.kubernetes.io/server-snippet

Annotations 支持让用户在ingress里可以自定义传统server配置,灵活方便。而且不必遵守yaml语法。

将该更新通过kubectl apply提交到集群中,nginx就会自动reload。这样就可以实现对 /*/secure_path/ 访问控制。是不是so easy?

关于ingress-nginx controller 检测 ingress资源的更新变动,自动reload机制,可以参考官方文档:How it works.

总结

在Nginx 中我们可以针对客户端的IP做白名单访问限制,这全靠 ngx_http_access_module 模块. 该模块支持对 CIDR、单个IP、以及unix socket 来源做访问控制。

并且可以支持在全局访问配置access、deny,即在http配置段落中;支持的其它范围有 server、location,以及limit_except中。

另外传统的nginx支持的配置,在nginx controoler中都可以在Annotations得到实现。具体的可以去官网文档查看相关用法。

参考

Ingress nginx user guide