etcd权限系统认证过程加cache

最近在研究etcd的权限机制,etcd用的认证方式比较简单basic auth。原理也比较简单易懂,但轻率上线后,发现一个大坑,就是认证时候用来比较密码的哈希是bcript,而且是每个请求都会调。这个耗时很大,导致集群性能下降的厉害,基本不能用了。

查遍官方文档,说3.1+ 用https common name的方式可以解决这个问题,但是我就不想上https,涉及改造的工作量有点大,就想通过auth简单的把误操作的行为隔离一下。

于是乎只能开始动手改了,简单的加一个cache先用。

首先我们用的etcd版本为2.1.1

git clone https://github.com/coreos/etcd.git

git checkout v2.1.1

下载代码后,切换到 v2.1.1 tag下

打开目录 etcdserver

扫描二维码关注公众号,回复: 267832 查看本文章

在目录下添加新文件,姑且叫做 password_map.go

添加如下代码

?
// author:ZeaLoVe
// password map of etcd v2 api
 
package auth
 
import (
     "fmt"
     "sync"
)
 
// key  : string  meke by hashed password + plaintext password
// value: error   the result of CompareHashAndPassword
type PasswordMap struct {
     sync.RWMutex
     M map[string]error
}
 
var DefaultPasswdMap = PasswordMap{
     M: make(map[string]error),
}
 
func (this *PasswordMap) Hit(hashed, pt string) bool {
     this.RLock()
     defer this.RUnlock()
     if _, ok := this.M[hashed+pt]; ok {
         return ok
     }
     return false
}
 
// Get must called after Hit
func (this *PasswordMap) Get(hashed, pt string) error {
     this.RLock()
     defer this.RUnlock()
     if val, ok := this.M[hashed+pt]; ok {
         return val
     }
     return fmt.Errorf("no hit")
}
 
func (this *PasswordMap) Set(hashed string, pt string, err error) {
     if hashed == "" {
         return
     }
     this.Lock()
     defer this.Unlock()
     this.M[hashed+pt] = err
}

打开该文件夹下的auth.go 找到 CheckPassword函数

修改为

?
func (u User) CheckPassword(password string) bool {
     if DefaultPasswdMap.Hit(u.Password, password) {
         return DefaultPasswdMap.Get(u.Password, password) == nil
     }
     err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
     DefaultPasswdMap.Set(u.Password, password, err)
     return err == nil
}

对于其他版本,虽然实现上可能有些区别,但整个原理是一样的(我看过3.1的基本没怎么改变)。此改造不会影响第一次请求的耗时,但后面不会对相同的密码再次调用bcript,会直接返回缓存的结果,极大提高了性能

 

但该实现没有回收缓存的空间,所以如果有人对同一个账号用各种不同的密码轮番攻击,可能会导致内存持续上升。但经过压测,发现即使试十万次内存也只上涨不到30M。可以暂时忽略这个问题。

即使内存大到一定程度,重启也可以恢复。

猜你喜欢

转载自zealove.iteye.com/blog/2369198