提交 3d0c26f5 编写于 作者: A alesapin

Fix ipv4 mask restrictions for users and add integration tests

上级 bf7401ce
......@@ -70,18 +70,20 @@ public:
else
{
String addr(str, 0, pos - str.c_str());
mask_address = toIPv6(Poco::Net::IPAddress(addr));
auto real_address = Poco::Net::IPAddress(addr);
String str_mask(str, addr.length() + 1, str.length() - addr.length() - 1);
if (isDigits(str_mask))
{
UInt8 prefix_bits = parse<UInt8>(pos + 1);
construct(prefix_bits);
construct(prefix_bits, real_address.family() == Poco::Net::AddressFamily::IPv4);
}
else
{
subnet_mask = netmaskToIPv6(Poco::Net::IPAddress(str_mask));
}
mask_address = toIPv6(real_address);
}
}
......@@ -97,9 +99,9 @@ private:
subnet_mask = Poco::Net::IPAddress(128, Poco::Net::IPAddress::IPv6);
}
void construct(UInt8 prefix_bits)
void construct(UInt8 prefix_bits, bool is_ipv4)
{
prefix_bits = mask_address.family() == Poco::Net::IPAddress::IPv4 ? prefix_bits + 96 : prefix_bits;
prefix_bits = is_ipv4 ? prefix_bits + 96 : prefix_bits;
subnet_mask = Poco::Net::IPAddress(prefix_bits, Poco::Net::IPAddress::IPv6);
}
......
......@@ -97,7 +97,7 @@ class ClickHouseCluster:
cmd += " client"
return cmd
def add_instance(self, name, config_dir=None, main_configs=[], user_configs=[], macros={}, with_zookeeper=False, with_mysql=False, with_kafka=False, clickhouse_path_dir=None, with_odbc_drivers=False, with_postgres=False, with_hdfs=False, hostname=None, env_variables={}, image="yandex/clickhouse-integration-test", stay_alive=False):
def add_instance(self, name, config_dir=None, main_configs=[], user_configs=[], macros={}, with_zookeeper=False, with_mysql=False, with_kafka=False, clickhouse_path_dir=None, with_odbc_drivers=False, with_postgres=False, with_hdfs=False, hostname=None, env_variables={}, image="yandex/clickhouse-integration-test", stay_alive=False, ipv4_address=None, ipv6_address=None):
"""Add an instance to the cluster.
name - the name of the instance directory and the value of the 'instance' macro in ClickHouse.
......@@ -116,7 +116,8 @@ class ClickHouseCluster:
instance = ClickHouseInstance(
self, self.base_dir, name, config_dir, main_configs, user_configs, macros, with_zookeeper,
self.zookeeper_config_path, with_mysql, with_kafka, self.base_configs_dir, self.server_bin_path,
clickhouse_path_dir, with_odbc_drivers, hostname=hostname, env_variables=env_variables, image=image, stay_alive=stay_alive)
clickhouse_path_dir, with_odbc_drivers, hostname=hostname, env_variables=env_variables, image=image,
stay_alive=stay_alive, ipv4_address=ipv4_address, ipv6_address=ipv6_address)
self.instances[name] = instance
self.base_cmd.extend(['--file', instance.docker_compose_path])
......@@ -332,7 +333,7 @@ CLICKHOUSE_START_COMMAND = "clickhouse server --config-file=/etc/clickhouse-serv
CLICKHOUSE_STAY_ALIVE_COMMAND = 'bash -c "{} --daemon; tail -f /dev/null"'.format(CLICKHOUSE_START_COMMAND)
DOCKER_COMPOSE_TEMPLATE = '''
version: '2'
version: '2.2'
services:
{name}:
image: {image}
......@@ -347,6 +348,22 @@ services:
depends_on: {depends_on}
env_file:
- {env_file}
{networks}
{app_net}
{ipv4_address}
{ipv6_address}
networks:
app_net:
driver: bridge
enable_ipv6: true
ipam:
driver: default
config:
- subnet: 10.5.0.0/12
gateway: 10.5.1.1
- subnet: 2001:3984:3989::/64
gateway: 2001:3984:3989::1
'''
class ClickHouseInstance:
......@@ -354,7 +371,8 @@ class ClickHouseInstance:
def __init__(
self, cluster, base_path, name, custom_config_dir, custom_main_configs, custom_user_configs, macros,
with_zookeeper, zookeeper_config_path, with_mysql, with_kafka, base_configs_dir, server_bin_path,
clickhouse_path_dir, with_odbc_drivers, hostname=None, env_variables={}, image="yandex/clickhouse-integration-test", stay_alive=False):
clickhouse_path_dir, with_odbc_drivers, hostname=None, env_variables={}, image="yandex/clickhouse-integration-test",
stay_alive=False, ipv4_address=None, ipv6_address=None):
self.name = name
self.base_cmd = cluster.base_cmd[:]
......@@ -391,6 +409,8 @@ class ClickHouseInstance:
self.default_timeout = 20.0 # 20 sec
self.image = image
self.stay_alive = stay_alive
self.ipv4_address = ipv4_address
self.ipv6_address = ipv6_address
# Connects to the instance via clickhouse-client, sends a query (1st argument) and returns the answer
def query(self, sql, stdin=None, timeout=None, settings=None, user=None, ignore_error=False):
......@@ -609,6 +629,18 @@ class ClickHouseInstance:
if self.stay_alive:
entrypoint_cmd = CLICKHOUSE_STAY_ALIVE_COMMAND
ipv4_address = ipv6_address = ""
if self.ipv4_address is None and self.ipv6_address is None:
networks = ""
app_net = ""
else:
networks = "networks:"
app_net = "app_net:"
if self.ipv4_address is not None:
ipv4_address = "ipv4_address: " + self.ipv4_address
if self.ipv6_address is not None:
ipv6_address = "ipv6_address: " + self.ipv6_address
with open(self.docker_compose_path, 'w') as docker_compose:
docker_compose.write(DOCKER_COMPOSE_TEMPLATE.format(
image=self.image,
......@@ -623,6 +655,10 @@ class ClickHouseInstance:
env_file=env_file,
odbc_ini_path=odbc_ini_path,
entrypoint_cmd=entrypoint_cmd,
networks=networks,
app_net=app_net,
ipv4_address=ipv4_address,
ipv6_address=ipv6_address,
))
......
version: '2'
version: '2.2'
services:
hdfs1:
image: sequenceiq/hadoop-docker:2.7.0
......
version: '2'
version: '2.2'
services:
kafka_zookeeper:
......
version: '2'
version: '2.2'
services:
mysql1:
image: mysql:5.7
......
version: '2'
version: '2.2'
services:
postgres1:
image: postgres
......
version: '2'
version: '2.2'
services:
zoo1:
image: zookeeper
......
<yandex>
<profiles>
<default>
<max_memory_usage>10000000000</max_memory_usage>
<use_uncompressed_cache>0</use_uncompressed_cache>
<load_balancing>random</load_balancing>
</default>
</profiles>
<users>
<default>
<password></password>
<networks incl="networks" replace="replace">
<ip>10.5.173.1</ip>
<ip>10.5.172.0/24</ip>
<ip>10.5.175.0/255.255.255.0</ip>
</networks>
<profile>default</profile>
<quota>default</quota>
</default>
</users>
<quotas>
<default>
</default>
</quotas>
</yandex>
<yandex>
<profiles>
<default>
<max_memory_usage>10000000000</max_memory_usage>
<use_uncompressed_cache>0</use_uncompressed_cache>
<load_balancing>random</load_balancing>
</default>
</profiles>
<users>
<default>
<password></password>
<networks incl="networks" replace="replace">
<ip>2001:3984:3989:0:0:0:1:1111</ip>
<ip>2001:3984:3989:0:0:0:0:0/112</ip>
</networks>
<profile>default</profile>
<quota>default</quota>
</default>
</users>
<quotas>
<default>
</default>
</quotas>
</yandex>
import time
import pytest
from helpers.cluster import ClickHouseCluster
from helpers.test_tools import assert_eq_with_retry
cluster = ClickHouseCluster(__file__)
node_ipv4 = cluster.add_instance('node_ipv4', config_dir="configs", user_configs=['configs/users_ipv4.xml'], ipv4_address='10.5.172.77')
client_ipv4_ok = cluster.add_instance('client_ipv4_ok', config_dir="configs", ipv4_address='10.5.172.10')
client_ipv4_ok_direct = cluster.add_instance('client_ipv4_ok_direct', config_dir="configs", ipv4_address='10.5.173.1')
client_ipv4_ok_full_mask = cluster.add_instance('client_ipv4_ok_full_mask', config_dir="configs", ipv4_address='10.5.175.77')
client_ipv4_bad = cluster.add_instance('client_ipv4_bad', config_dir="configs", ipv4_address='10.5.173.10')
node_ipv6 = cluster.add_instance('node_ipv6', config_dir="configs", main_configs=["configs/config_ipv6.xml"], user_configs=['configs/users_ipv6.xml'], ipv6_address='2001:3984:3989::1:1000')
client_ipv6_ok = cluster.add_instance('client_ipv6_ok', config_dir="configs", ipv6_address='2001:3984:3989::5555')
client_ipv6_ok_direct = cluster.add_instance('client_ipv6_ok_direct', config_dir="configs", ipv6_address='2001:3984:3989::1:1111')
client_ipv6_bad = cluster.add_instance('client_ipv6_bad', config_dir="configs", ipv6_address='2001:3984:3989::1:1112')
@pytest.fixture(scope="module")
def setup_cluster():
try:
cluster.start()
yield cluster
finally:
cluster.shutdown()
def test_ipv4(setup_cluster):
try:
client_ipv4_ok.exec_in_container(["bash", "-c", "/usr/bin/clickhouse client --host 10.5.172.77 --query 'select 1'"], privileged=True, user='root')
except Exception as ex:
assert False, "allowed client with 10.5.172.10 cannot connect to server with allowed mask '10.5.172.0/24'"
try:
client_ipv4_ok_direct.exec_in_container(["bash", "-c", "/usr/bin/clickhouse client --host 10.5.172.77 --query 'select 1'"], privileged=True, user='root')
except Exception as ex:
assert False, "allowed client with 10.5.173.1 cannot connect to server with allowed ip '10.5.173.1'"
try:
client_ipv4_ok_full_mask.exec_in_container(["bash", "-c", "/usr/bin/clickhouse client --host 10.5.172.77 --query 'select 1'"], privileged=True, user='root')
except Exception as ex:
assert False, "allowed client with 10.5.175.77 cannot connect to server with allowed ip '10.5.175.0/255.255.255.0'"
try:
client_ipv4_bad.exec_in_container(["bash", "-c", "/usr/bin/clickhouse client --host 10.5.172.77 --query 'select 1'"], privileged=True, user='root')
assert False, "restricted client with 10.5.173.10 can connect to server with allowed mask '10.5.172.0/24'"
except AssertionError:
raise
except Exception as ex:
print ex
def test_ipv6(setup_cluster):
try:
client_ipv6_ok.exec_in_container(["bash", "-c", "/usr/bin/clickhouse client --host 2001:3984:3989::1:1000 --query 'select 1'"], privileged=True, user='root')
except Exception as ex:
print ex
assert False, "allowed client with 2001:3984:3989:0:0:0:1:1111 cannot connect to server with allowed mask '2001:3984:3989:0:0:0:0:0/112'"
try:
client_ipv6_ok_direct.exec_in_container(["bash", "-c", "/usr/bin/clickhouse client --host 2001:3984:3989:0:0:0:1:1000 --query 'select 1'"], privileged=True, user='root')
except Exception as ex:
assert False, "allowed client with 2001:3984:3989:0:0:0:1:1111 cannot connect to server with allowed ip '2001:3984:3989:0:0:0:1:1111'"
try:
client_ipv6_bad.exec_in_container(["bash", "-c", "/usr/bin/clickhouse client --host 2001:3984:3989:0:0:0:1:1000 --query 'select 1'"], privileged=True, user='root')
assert False, "restricted client with 2001:3984:3989:0:0:0:1:1112 can connect to server with allowed mask '2001:3984:3989:0:0:0:0:0/112'"
except AssertionError:
raise
except Exception as ex:
print ex
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册