1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
#!/usr/bin/env python3
from .common import *
all_redis = [
RedisServer('127.0.0.1', 2100, '/tmp/r/redis-2100/',
CLUSTER_NAME, 'redis-2100', auth = 'hellopasswd'),
RedisServer('127.0.0.1', 2101, '/tmp/r/redis-2101/',
CLUSTER_NAME, 'redis-2101', auth = 'hellopasswd'),
]
nc = NutCracker('127.0.0.1', 4100, '/tmp/r/nutcracker-4100', CLUSTER_NAME,
all_redis, mbuf=mbuf, verbose=nc_verbose,
redis_auth = 'hellopasswd')
nc_badpass = NutCracker('127.0.0.1', 4101, '/tmp/r/nutcracker-4101', CLUSTER_NAME,
all_redis, mbuf=mbuf, verbose=nc_verbose,
redis_auth = 'badpasswd')
nc_nopass = NutCracker('127.0.0.1', 4102, '/tmp/r/nutcracker-4102', CLUSTER_NAME,
all_redis, mbuf=mbuf, verbose=nc_verbose)
def setup():
print('setup(mbuf=%s, verbose=%s)' %(mbuf, nc_verbose))
for r in all_redis + [nc, nc_badpass, nc_nopass]:
r.clean()
r.deploy()
r.stop()
r.start()
def teardown():
for r in all_redis + [nc, nc_badpass, nc_nopass]:
assert(r._alive())
r.stop()
default_kv = {bytes('kkk-%s' % i, encoding='utf-8') : bytes('vvv-%s' % i, encoding='utf-8') for i in range(10)}
def getconn():
r = redis.Redis(nc.host(), nc.port())
return r
'''
cases:
redis proxy case
1 1 test_auth_basic
1 bad test_badpass_on_proxy
1 0 test_nopass_on_proxy
0 0 already tested on other case
0 1
'''
def test_auth_basic():
# we hope to have same behavior when the server is redis or twemproxy
conns = [
redis.Redis(all_redis[0].host(), all_redis[0].port()),
redis.Redis(nc.host(), nc.port()),
]
for r in conns:
assert_fail('Authentication required', r.ping)
assert_fail('Authentication required', r.set, 'k', 'v')
assert_fail('Authentication required', r.get, 'k')
# bad passwd
assert_fail('invalid password|WRONGPASS', r.execute_command, 'AUTH', 'badpasswd')
# everything is ok after auth
r.execute_command('AUTH', 'hellopasswd')
r.set('k', 'v')
assert(r.ping() == True)
assert_equal(b'v', r.get('k'))
# auth fail here, should we return ok or not => we will mark the conn state as not authed
assert_fail('invalid password|WRONGPASS', r.execute_command, 'AUTH', 'badpasswd')
# https://redis.io/commands/auth changed in redis 6.0.0 and auth now appears to be additive for valid credentials?
# We can get the redis version by invoking a shell command, but not going to bother. Just assert that it if it throws, it's for the expected reason.
try:
r.ping()
except Exception as e:
assert re.search('Authentication required', str(e))
try:
r.get('k')
except Exception as e:
assert re.search('Authentication required', str(e))
def test_nopass_on_proxy():
r = redis.Redis(nc_nopass.host(), nc_nopass.port())
# if you config pass on redis but not on twemproxy,
# twemproxy will reply ok for ping, but once you do get/set, you will get errmsg from redis
assert(r.ping() == True)
assert_fail('Authentication required', r.set, 'k', 'v')
assert_fail('Authentication required', r.get, 'k')
# proxy has no pass, when we try to auth
assert_fail('Client sent AUTH, but no password is set', r.execute_command, 'AUTH', 'anypasswd')
pass
def test_badpass_on_proxy():
r = redis.Redis(nc_badpass.host(), nc_badpass.port())
assert_fail('Authentication required', r.ping)
assert_fail('Authentication required', r.set, 'k', 'v')
assert_fail('Authentication required', r.get, 'k')
# we can auth with bad pass (twemproxy will say ok for this)
r.execute_command('AUTH', 'badpasswd')
# after that, we still got NOAUTH for get/set (return from redis-server)
assert(r.ping() == True)
assert_fail('Authentication required', r.set, 'k', 'v')
assert_fail('Authentication required', r.get, 'k')
def setup_and_wait():
time.sleep(60*60)
|