swift服务中间件扩展

目录

  本文讲解如何实现用ip进行访问授权的swift中间件,该中间件会在用户访问container时会判断用户的ip是否授权访问。由于container支持meta设置,可以对container的meta设置允许访问的ip来限制那些ip可以访问。

比如对test容器设置meta的allow-ip

swift post --meta allow-ip:192.168.10.160,127.0.0.1 test

查看设置的meta属性值

  为swift添加中间件实现值允许allow-ip里的ip地址能访问容器,由于swift也是采用wsgi协议来实现应用的,(参见WSGI)中间件的实现也需要遵循该协议。
创建swift/common/middleware/ip_whitelist.py文件,该文件代码如下

import socket
from swift.common.utils import get_logger
from swift.proxy.controllers.base import get_container_info
from swift.common.swob import Request, Response
class IPWhitelistMiddleware(object):
""" 允许allow-ip项里的ip地址访问容器"""
def __init__(self, app, conf, logger=None):
self.app=app
if logger:
self.logger=logger
else:
self.logger = get_logger(conf,log_route='ip_whitelist')
self.logger.debug("conf = %(conf)s",locals())
#读取配置文件中的deny_message,没有为IP deny
self.deny_message = conf.get('deny_message','IP deny')
self.local_ip = socket.gethostbyname(socket.gethostname())
def __call__(self,env, start_response):
"""WSGI 入口获取应用的上下文进行处理,return来向下传递应用 env是上下文,start_response是返回调用对象"""
req= Request(env)
self.logger.debug("env = %(env)s", locals())
try:
#url语法检查
version, account ,container,obj = req.split_path(1,4,True)
except StandardError:
return self.app(env, start_response)
container_info = get_container_info(req.environ,self.app, swift_source='IPWhitelistMiddleware')
#用户的ip地址
remote_ip =env['REMOTE_ADDR']
self.logger.debug("Remote IP: %(remot_ip)s",{'remote_ip':
remote_ip})
#访问container的meta属性
meta = container_info['meta']
#获取以allow开头的属性信息,(这里没有判断allow-ip的值为ip1,ip2的情况,而且不仅是allow-ip)
allow={k:v for k,v in meta.iteritems() if k.startswith('allow')}
allow_ips = set(allow.values())
allow_ips.add(self.local_ip)
self.logger.debug("Allow IPs: %(allow_ips)s",
{'allow_ips':allow_ips})
if remote_ip in allow_ips:
return self.app(env, start_response)
#不是允许的ip,返回403未授权的response
else:
self.logger.debug("IP %(remote_ip)s denided access to Account=%(account)s "
"Container=%(container)s. Not in %(allow_ips)s", locals())
return Response(
status=403,
body=self.deny_message,
request=req)(env,start_response)
def filter_factory(gloable_conf, **local_conf):
"""获取中间件实例,加载配置参数"""
conf =gloable_conf.copy()
conf.update(local_conf)
def ip_whitelist(app):
return IPWhitelistMiddleware(app, conf)
return ip_whitelist

代码完成后把功能集成到swift服务里。修改proxy-server.conf文件加入新的filter

[filter:ip_whitelist]
paste.filter_factory = swift.common.middleware.ip_whitelist:filter_factory
deny_message = Your IP don't be permited to pass!!!

然后在pipeline中添加ip_whitelist

[pipeline:main]
pipeline = authtoken catch_errors gatekeeper healthcheck cache container_sync bulk tempurl ratelimit keystoneauth ip_whitelist container-quotas account-quotas slo dlo proxy-logging proxy-server

保存退出,重启swift-proxy服务。

sudo swift-init proxy-server restart

  服务重启后,ip_whitelist的ip地址过滤中间件就生效了,可以有效防止某些ip访问容器里的数据。