背景
在Traefik中,Fail2Ban是一个非常强大的插件,可以轻松实现IP黑名单,IP白名单,IP封禁等操作。我们可以根据不同的需求,选择封禁的时长。
比如:我想针对1分钟内请求100次以上的IP封禁1小时
。对于比DDOS小很多的某些攻击,可以有效防止。(如果处于DDOS,大部分都是在服务商那就已经将云服务拉入小黑屋了,
此时服务流量基本进不来了,所以这里只是针对小攻击的处理方法,或者某些暴力爬虫等)
对于Fail2Ban的原理,你可以参考Github,基本原理是时间窗口,go语言写这类工具再对接Kubernetes有天生的优势,所以这里就不再赘述了。
环境
traefik: v2.9.10
kubernetes: v1.24.6+k3s1
Fail2Ban: v0.7.1
安装
在K3S中,我们已经内置了Traefik,所以如果想安装插件,我们需要对内置的Traefik进行改造,添加插件。
由于K3S会周期性的执行 /var/lib/rancher/k3s/server/manifests
目录下的所有yaml,而如果我们修改了默认的traefik.yaml
,K3S会自动恢复默认文件,所以我们这里需要新建一个yaml文件,用HelmChartConfig
的方式修改traefik安装的配置即可。
创建配置文件 nano /var/lib/rancher/k3s/server/manifests/traefik-config.yaml
1 | apiVersion: helm.cattle.io/v1 |
- additionalArguments用于添加插件的启动参数,在启动Traefik时,他会自动下载,需要注意的是,他是自主访问github下载的,如果网络不通畅,下载插件会失败,但Traefik会正常启动,导致所有使用了fail2ban的Middleware全部失效,所以启动后还要确保有没有fail2ban的成功日志信息
- experimental用于启动插件(新版本好像不配置也可以)
- allowCrossNamespace允许跨命名空间调用(比如我在A命名空间创建了有关fail2ban的Middleware,但我想在B命名空间同样使用这个Middleware,所以需要允许跨命名空间调用)
- 因为自带的Traefik版本比较低,所以指定下新版本的镜像,亲测在2.10版本中无法使用,所以只能升级到2.9版本的,在自带的2.6版本同样无法使用,会报
plugin: unknown plugin type: sablier
的错误,重启也无效
additionalArguments中插件的CLI配置,可以参考每个插件右上角的Install pLugin
,里面写了具体的配置,插件地址是:https://plugins.traefik.io/plugins/628c9ebcffc0cd18356a979f/fail2-ban
在配置好之后,我们等待一会,K3S会自动执行该配置文件。
接下来使用 kubectl get jobs -n kube-system
查看下Helm job是否触发
1 | root@m3:/var/lib/rancher/k3s/server/manifests# kubectl get jobs -n kube-system |
可以看到,已经执行完了,接下来看下Traefik是否正常重启,使用kubectl describe pods -n kube-system traefik-xxxxx
,启动参数是否含有上面配置的。
1 | Containers: |
查看Traefik的日志,看看是否有fail2ban的日志信息
1 | 2024/04/23 14:05:33 Plugin: FailToBan is up and running |
接下来我们只需要创建一个Middleware,然后就可以使用Fail2Ban了。
使用
创建Middleware,规则为1分钟内请求100次以上的IP封禁1小时
1 | apiVersion: traefik.containo.us/v1alpha1 |
这里参数的配置请参考插件README即可,创建好Middle后,我们需要将流量拦截到这个Middleware上。
在你想要配置的Ingress中,添加如下信息:
1 | apiVersion: networking.k8s.io/v1 |
绑定规则:命名空间-中间件名称@kubernetescrd
如果有多个则用英文逗号分隔(traefik.ingress.kubernetes.io/router.middlewares: prod-app-api-protect1@kubernetescrd,prod-app-api-protect2@kubernetescrd)
比如,我想先从http转https,再拦截,就需要两个middleware。
在Traefik的Dashboard中,能看到对应的Middleware和绑定的pod即可,如下图所示:
测试
我们可以把条件改苛刻些测试下,比如5秒内有两次请求则ban1分钟
,请求如果返回403或者5xx则证明ban成功了(想反5xx的看我下一篇文章)
1 | spec: |
Fail2Ban基本上满足了我对于某些恶意请求的拦截,在安装的时候经常发现不起作用,后来发现是Traefik版本的问题,2.0~2.6安装插件那会,好像还需要去官网注册token,现在已经摒弃了,取而代之的是Traefik的Hub。
在后续的文章中,我会玩一玩Traefik插件中星星最多的Sablier插件,它能根据流量自动启动pod,没人访问后自动关闭pod。我的测试环境刚好只在我开发的时候才用得到,不用的时候还占用内存(没错,说的就是你这个JVM占好多内存),看我后面的文章吧~