一.简单介绍
由于Memcached本身没有做验证访问模块,一旦发布到公网,任何人都能通过ip访问。虽然可以使用iptables通过设置ip白名单限制访问ip,但仍然无法做到针对所有访问的控制的限制。如果能够做到需要使用用户名和密码来访问,这无疑会更加安全,而Cyrus-SASL就能够这样帮助我们。
SASL全称Simple Authentication and Security Layer,是一种用来扩充C/S模式验证能力的机制。简单来说SASL是一个胶合(glue)库,通过这个库把应用层与形式多样的认证系统整合在一起。SASL是一个认证过程,侧重于信任建立过程,通过使用pam、shadow等认证方式来验证什么人可以访问什么服务。在Memcached上使用SASL认证,具体的认证交给SASL,SASL会根据相应的认证机制来完成验证功能。
二.具体步骤
1. 安装SASL
通常默认情况下,Linux系统会预安装Cyrus-SASL认证包。可以使用下面的命令检查系统是否已经安装了Cyrus-SASL认证包以及 查看相应的版本:
rpm -qa | grep sasl
命令执行结果如下:
cyrus-sasl-devel-2.1.21-18.4
cyrus-sasl-2.1.21-18.4
cyrus-sasl-saslauthd-2.1.21-18.4
cyrus-sasl-lib-2.1.21-18.4
cyrus-sasl-plain-2.1.21-18.4
要能够使用SASL服务应要确保有cyrus-sasl-devel和cyrus-sasl-lib两个包,如果缺少这两个包,在安装带—enable-sasl参数的Memcached时会有错误提示:
configure: error: Failed to locate the library containing sasl_server_init
由于我的服务器系统是OpenSUSE,所以如果缺少上面两个包,要安装可以使用zypper,但前提是需要成功添加相应软件源。如果是CentOS等,可以直接只用yum安装。
这里我另外一种方法就是安装rpm包。使用rpm安装,首先要下载rpm包。这里给出一个查找下载rpm包的地址:http://rpm.pbone.net/可以到网上下载相应rpm包,然后将rpm包从本地上传到服务器。或者可以直接在服务器命令行使用wget ftp://example. rpm直接下载。
下载好rpm包后,执行以下命令安装:
rpm –ivh example.rpm –nodeps –force
安装好之后再一次执行rpm -qa | grep sasl 看是否已经安装成功。安装成功后就可以进行下一步。
首先先来了解有关SASL的几个文件:
①SASL配置文件: /etc/sysconfig/saslauthd 在配置文件里可以修改密码验证机制,默认是pam。
②SASL进程控制文件: /etc/init.d/saslauthd 可以使用该文件启动、停止、重启saslauthd进程。例如在命令行输入/etc/init.d/saslauthd start ,/etc/init.d/saslauthd restart等。
③SASL添加服务文件:/usr/sbin/saslpasswd2 使用该文件可以为特定的程序添加验证用户及密码。例如在命令行输入/usr/sbin/saslpasswd2 -a memcached –c hispace。添加后账户和密码是保存到/etc/sasldb2数据库文件里。
④SASL测试文件:/usr/bin/testsaslauthd 使用该文件可以测试saslauthd的认证功能:testsaslauthd –u hispace –p password。此验证是认证存于/etc/shadow里的系统用户。
⑤SASL数据库文件:/etc/sasldb2 该文件存储的是使用saslpasswd2添加的用户和密码。存储的是二进制文件,所以我们无法查看。但我们可以使用sasldblistusers2查看已有用户。
了解了几个常见的文件的功能后继续我们的工作。
执行以下命令启动saslauthd进程:
/etc/init.d/saslauthd start
结果如下:
Starting Service saslauthd
查看saslauthd进程是否运行:
ps aux | grep saslauthd
为了简单起见,我们使用最简单的认证,用/etc/sasldb2里的用户来认证,只需使用saslpasswd2 -a memcached –c hispace给memcached添加用户hispace(用户可自己定义)和密码,然后使用sasldblistusers2查看用户是否存在:
saslpasswd2 -a memcached -c hispace
要求输入密码:
Password:
Again (for verification):
查看用户是否添加成功,输入:
sasldblistusers2
如果想修改用户密码,直接执行添加命令覆盖,如果想删除用户,如删除用户hispace,使用下面命令:
saslpasswd2 –d hispace
如果到这里都成功了,就可以进行下一步了。
2.安装libevent和memcached
首先下载相应安装包,需要注意的是memcached在1.4.3版本之后才支持sasl。
然后按顺序安装libevent和memcached。
安装libevent:
tar -zxvf libevent.tar.gz
chmod 711 libevent/*
cd libevent
./configure --prefix=/root/workdir/memcached/libevent
make
make install
安装Memcached:
tar -zxvf memcached-1.5.0.tar.gz
cd memcached-1.5.0
./configure --enable-sasl --prefix=/root/workdir/memcached/memcached --with-libevent=/root/workdir/memcached/libevent
make
make install
注意上面要加上--enable-sasl参数。
3.启动带SASL验证的Memcached服务器
启动带SASL验证的Memcached服务器很简单,只需要在以往的命令后面加上-S参数。使用-S参数启用sasl安全验证功能,开启后,客户端需要提供用户名密码才能访问memcahced。
例如执行下面命令就可以发布带SASL验证的memcached:
memcached -d -m 512 -u root -l 192.168.0.0 -p 11211 -c 256 -S
如果想查看认证过程以及memcached服务器与客户端的交互过程,可以在上面命令后面在加上-vvv参数。
在这里需要特别注意的是,由于我们上面使用saslpasswd2添加的用户名密码是保存在/etc/sasldb2文件里,而/etc/sasldb2文件只有root用户才有权限读取,如果是使用普通用户发布memcached,就会验证失败。解决方法有两个:①使用root用户发布memcached;②使用root用户给予普通用户读取/etc/sasldb2文件的权限。
4.客户端连接
客户端可以xmemcached使用连接,这里给出一个简单例子:
public class Memcached {
public static void main(String[] args) throws IOException {
MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses("192.168.0.0:11211"));
builder.addAuthInfo(AddrUtil.getOneAddress("192.168.0.0:11211"), AuthInfo.plain("root", "root"));
builder.setCommandFactory(new BinaryCommandFactory());
MemcachedClient memcachedClient = builder.build();
try {
memcachedClient.set("hello", 0, "Hello,xmemcached");
String value = memcachedClient.get("hello");
System.out.println("hello=" + value);
memcachedClient.delete("hello");
value = memcachedClient.get("hello");
System.out.println("hello=" + value);
} catch (MemcachedException e) {
System.err.println("MemcachedClient operation fail");
e.printStackTrace();
} catch (TimeoutException e) {
System.err.println("MemcachedClient operation timeout");
e.printStackTrace();
} catch (InterruptedException e) {
// ignore
}
try {
// close memcached client
memcachedClient.shutdown();
} catch (IOException e) {
System.err.println("Shutdown MemcachedClient fail");
e.printStackTrace();
}
}
}
特别注意上面验证用户名密码是使用AuthInfo.plain方法。虽然AuthInfo.typical方法也可以提供PLAIN认证,但其是优先使用CRAM-MD5认证,这样会导致认证失败。
如果对上面过程仍有不懂地方,可以参考下面的链接,了解相关概念:
http://www.cnblogs.com/silenceli/p/4031262.html
http://www.postfix.org/SASL_README.html#saslauthd
https://github.com/memcached/memcached/wiki