Add SSL encryption to galera
Change-Id: I9e6d9ee439cab734eba02320d58ccfcd73e23106
This commit is contained in:
parent
909d165c5e
commit
fd1d0b8d13
1
service/files/ca.pem.j2
Normal file
1
service/files/ca.pem.j2
Normal file
@ -0,0 +1 @@
|
|||||||
|
{{ security.tls.ca_cert }}
|
@ -16,6 +16,8 @@ configs:
|
|||||||
node: null
|
node: null
|
||||||
port:
|
port:
|
||||||
cont: 3306
|
cont: 3306
|
||||||
|
tls:
|
||||||
|
enabled: true
|
||||||
url:
|
url:
|
||||||
percona:
|
percona:
|
||||||
debian:
|
debian:
|
||||||
|
@ -33,11 +33,16 @@ PID_FILE = os.path.join(DATADIR, "mysqld.pid")
|
|||||||
HOSTNAME = socket.getfqdn()
|
HOSTNAME = socket.getfqdn()
|
||||||
IPADDR = socket.gethostbyname(HOSTNAME)
|
IPADDR = socket.gethostbyname(HOSTNAME)
|
||||||
|
|
||||||
|
CA_CERT = '/opt/ccp/etc/tls/ca.pem'
|
||||||
|
SERVER_CERT = '/opt/ccp/etc/tls/server-cert.pem'
|
||||||
|
SERVER_KEY = '/opt/ccp/etc/tls/server-key.pem'
|
||||||
|
|
||||||
MONITOR_PASSWORD = None
|
MONITOR_PASSWORD = None
|
||||||
CLUSTER_NAME = None
|
CLUSTER_NAME = None
|
||||||
ETCD_PATH = None
|
ETCD_PATH = None
|
||||||
ETCD_HOST = None
|
ETCD_HOST = None
|
||||||
ETCD_PORT = None
|
ETCD_PORT = None
|
||||||
|
TLS = None
|
||||||
|
|
||||||
|
|
||||||
def retry(f):
|
def retry(f):
|
||||||
@ -64,11 +69,22 @@ def retry(f):
|
|||||||
|
|
||||||
def get_etcd_client():
|
def get_etcd_client():
|
||||||
|
|
||||||
etcd_client = etcd.Client(host=ETCD_HOST,
|
if TLS:
|
||||||
port=ETCD_PORT,
|
protocol = 'https'
|
||||||
allow_reconnect=True,
|
cert = (SERVER_CERT, SERVER_KEY)
|
||||||
read_timeout=2)
|
ca_cert = CA_CERT
|
||||||
return etcd_client
|
else:
|
||||||
|
protocol = 'http'
|
||||||
|
cert = None
|
||||||
|
ca_cert = None
|
||||||
|
|
||||||
|
return etcd.Client(host=ETCD_HOST,
|
||||||
|
port=ETCD_PORT,
|
||||||
|
allow_reconnect=True,
|
||||||
|
protocol=protocol,
|
||||||
|
cert=cert,
|
||||||
|
ca_cert=ca_cert,
|
||||||
|
read_timeout=2)
|
||||||
|
|
||||||
|
|
||||||
@retry
|
@retry
|
||||||
@ -287,7 +303,7 @@ def get_config():
|
|||||||
variables = {}
|
variables = {}
|
||||||
with open(GLOBALS_PATH) as f:
|
with open(GLOBALS_PATH) as f:
|
||||||
global_conf = json.load(f)
|
global_conf = json.load(f)
|
||||||
for key in ['percona', 'etcd', 'namespace', 'cluster_domain']:
|
for key in ['percona', 'etcd', 'namespace', 'cluster_domain', 'security']:
|
||||||
variables[key] = global_conf[key]
|
variables[key] = global_conf[key]
|
||||||
LOG.debug(variables)
|
LOG.debug(variables)
|
||||||
return variables
|
return variables
|
||||||
@ -297,7 +313,7 @@ def set_globals():
|
|||||||
|
|
||||||
config = get_config()
|
config = get_config()
|
||||||
global MONITOR_PASSWORD, CLUSTER_NAME
|
global MONITOR_PASSWORD, CLUSTER_NAME
|
||||||
global ETCD_PATH, ETCD_HOST, ETCD_PORT
|
global ETCD_PATH, ETCD_HOST, ETCD_PORT, TLS
|
||||||
|
|
||||||
CLUSTER_NAME = config['percona']['cluster_name']
|
CLUSTER_NAME = config['percona']['cluster_name']
|
||||||
MONITOR_PASSWORD = config['percona']['monitor_password']
|
MONITOR_PASSWORD = config['percona']['monitor_password']
|
||||||
@ -305,6 +321,7 @@ def set_globals():
|
|||||||
ETCD_HOST = "etcd.%s.svc.%s" % (config['namespace'],
|
ETCD_HOST = "etcd.%s.svc.%s" % (config['namespace'],
|
||||||
config['cluster_domain'])
|
config['cluster_domain'])
|
||||||
ETCD_PORT = int(config['etcd']['client_port']['cont'])
|
ETCD_PORT = int(config['etcd']['client_port']['cont'])
|
||||||
|
TLS = config['security']['tls']['enabled']
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -18,6 +18,10 @@ BACKEND_NAME = "galera-cluster"
|
|||||||
SERVER_NAME = "primary"
|
SERVER_NAME = "primary"
|
||||||
GLOBALS_PATH = '/etc/ccp/globals/globals.json'
|
GLOBALS_PATH = '/etc/ccp/globals/globals.json'
|
||||||
|
|
||||||
|
CA_CERT = '/opt/ccp/etc/tls/ca.pem'
|
||||||
|
SERVER_CERT = '/opt/ccp/etc/tls/server-cert.pem'
|
||||||
|
SERVER_KEY = '/opt/ccp/etc/tls/server-key.pem'
|
||||||
|
|
||||||
LOG_DATEFMT = "%Y-%m-%d %H:%M:%S"
|
LOG_DATEFMT = "%Y-%m-%d %H:%M:%S"
|
||||||
LOG_FORMAT = "%(asctime)s.%(msecs)03d - %(levelname)s - %(message)s"
|
LOG_FORMAT = "%(asctime)s.%(msecs)03d - %(levelname)s - %(message)s"
|
||||||
logging.basicConfig(format=LOG_FORMAT, datefmt=LOG_DATEFMT)
|
logging.basicConfig(format=LOG_FORMAT, datefmt=LOG_DATEFMT)
|
||||||
@ -58,7 +62,7 @@ def get_config():
|
|||||||
variables = {}
|
variables = {}
|
||||||
with open(GLOBALS_PATH) as f:
|
with open(GLOBALS_PATH) as f:
|
||||||
global_conf = json.load(f)
|
global_conf = json.load(f)
|
||||||
for key in ['percona', 'etcd', 'namespace', 'cluster_domain']:
|
for key in ['percona', 'etcd', 'namespace', 'cluster_domain', 'security']:
|
||||||
variables[key] = global_conf[key]
|
variables[key] = global_conf[key]
|
||||||
LOG.debug(variables)
|
LOG.debug(variables)
|
||||||
return variables
|
return variables
|
||||||
@ -68,7 +72,7 @@ def set_globals():
|
|||||||
|
|
||||||
config = get_config()
|
config = get_config()
|
||||||
global CONNECTION_ATTEMPTS, CONNECTION_DELAY
|
global CONNECTION_ATTEMPTS, CONNECTION_DELAY
|
||||||
global ETCD_PATH, ETCD_HOST, ETCD_PORT
|
global ETCD_PATH, ETCD_HOST, ETCD_PORT, TLS
|
||||||
|
|
||||||
CONNECTION_ATTEMPTS = config['etcd']['connection_attempts']
|
CONNECTION_ATTEMPTS = config['etcd']['connection_attempts']
|
||||||
CONNECTION_DELAY = config['etcd']['connection_delay']
|
CONNECTION_DELAY = config['etcd']['connection_delay']
|
||||||
@ -76,13 +80,26 @@ def set_globals():
|
|||||||
ETCD_HOST = "etcd.%s.svc.%s" % (config['namespace'],
|
ETCD_HOST = "etcd.%s.svc.%s" % (config['namespace'],
|
||||||
config['cluster_domain'])
|
config['cluster_domain'])
|
||||||
ETCD_PORT = int(config['etcd']['client_port']['cont'])
|
ETCD_PORT = int(config['etcd']['client_port']['cont'])
|
||||||
|
TLS = config['security']['tls']['enabled']
|
||||||
|
|
||||||
|
|
||||||
def get_etcd_client():
|
def get_etcd_client():
|
||||||
|
|
||||||
|
if TLS:
|
||||||
|
protocol = 'https'
|
||||||
|
cert = (SERVER_CERT, SERVER_KEY)
|
||||||
|
ca_cert = CA_CERT
|
||||||
|
else:
|
||||||
|
protocol = 'http'
|
||||||
|
cert = None
|
||||||
|
ca_cert = None
|
||||||
|
|
||||||
return etcd.Client(host=ETCD_HOST,
|
return etcd.Client(host=ETCD_HOST,
|
||||||
port=ETCD_PORT,
|
port=ETCD_PORT,
|
||||||
allow_reconnect=True,
|
allow_reconnect=True,
|
||||||
|
protocol=protocol,
|
||||||
|
cert=cert,
|
||||||
|
ca_cert=ca_cert,
|
||||||
read_timeout=2)
|
read_timeout=2)
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,4 +35,16 @@ wsrep_provider = /usr/lib/galera3/libgalera_smm.so
|
|||||||
wsrep_cluster_name = {{ percona.cluster_name }}
|
wsrep_cluster_name = {{ percona.cluster_name }}
|
||||||
wsrep_sst_method = xtrabackup-v2
|
wsrep_sst_method = xtrabackup-v2
|
||||||
wsrep_sst_auth = "xtrabackup:{{ percona.xtrabackup_password }}"
|
wsrep_sst_auth = "xtrabackup:{{ percona.xtrabackup_password }}"
|
||||||
wsrep_provider_options = "gcache.size={{ percona.gcache_size }};gcache.recover=yes"
|
wsrep_provider_options = "gcache.size={{ percona.gcache_size }};gcache.recover=yes{% if percona.tls.enabled and security.tls.enabled %};socket.ssl=yes;socket.ssl_key=/opt/ccp/etc/tls/server-key.pem;socket.ssl_cert=/opt/ccp/etc/tls/server-cert.pem;socket.ssl_ca=/opt/ccp/etc/tls/ca.pem"{% endif %}
|
||||||
|
|
||||||
|
{% if percona.tls.enabled and security.tls.enabled %}
|
||||||
|
ssl-ca = /opt/ccp/etc/tls/ca.pem
|
||||||
|
ssl-cert = /opt/ccp/etc/tls/server-cert.pem
|
||||||
|
ssl-key = /opt/ccp/etc/tls/server-key.pem
|
||||||
|
|
||||||
|
[sst]
|
||||||
|
encrypt = 4
|
||||||
|
ssl-ca = /opt/ccp/etc/tls/ca.pem
|
||||||
|
ssl-cert = /opt/ccp/etc/tls/server-cert.pem
|
||||||
|
ssl-key = /opt/ccp/etc/tls/server-key.pem
|
||||||
|
{% endif %}
|
||||||
|
@ -26,6 +26,10 @@ GRASTATE_FILE = os.path.join(DATADIR, 'grastate.dat')
|
|||||||
SST_FLAG = os.path.join(DATADIR, "sst_in_progress")
|
SST_FLAG = os.path.join(DATADIR, "sst_in_progress")
|
||||||
GLOBALS_PATH = '/etc/ccp/globals/globals.json'
|
GLOBALS_PATH = '/etc/ccp/globals/globals.json'
|
||||||
|
|
||||||
|
CA_CERT = '/opt/ccp/etc/tls/ca.pem'
|
||||||
|
SERVER_CERT = '/opt/ccp/etc/tls/server-cert.pem'
|
||||||
|
SERVER_KEY = '/opt/ccp/etc/tls/server-key.pem'
|
||||||
|
|
||||||
LOG_DATEFMT = "%Y-%m-%d %H:%M:%S"
|
LOG_DATEFMT = "%Y-%m-%d %H:%M:%S"
|
||||||
LOG_FORMAT = "%(asctime)s.%(msecs)03d - %(levelname)s - %(message)s"
|
LOG_FORMAT = "%(asctime)s.%(msecs)03d - %(levelname)s - %(message)s"
|
||||||
logging.basicConfig(format=LOG_FORMAT, datefmt=LOG_DATEFMT)
|
logging.basicConfig(format=LOG_FORMAT, datefmt=LOG_DATEFMT)
|
||||||
@ -44,6 +48,7 @@ CONNECTION_DELAY = None
|
|||||||
ETCD_PATH = None
|
ETCD_PATH = None
|
||||||
ETCD_HOST = None
|
ETCD_HOST = None
|
||||||
ETCD_PORT = None
|
ETCD_PORT = None
|
||||||
|
TLS = None
|
||||||
|
|
||||||
|
|
||||||
class ProcessException(Exception):
|
class ProcessException(Exception):
|
||||||
@ -76,7 +81,8 @@ def get_config():
|
|||||||
variables = {}
|
variables = {}
|
||||||
with open(GLOBALS_PATH) as f:
|
with open(GLOBALS_PATH) as f:
|
||||||
global_conf = json.load(f)
|
global_conf = json.load(f)
|
||||||
for key in ['percona', 'db', 'etcd', 'namespace', 'cluster_domain']:
|
for key in ['percona', 'db', 'etcd', 'namespace', 'cluster_domain',
|
||||||
|
'security']:
|
||||||
variables[key] = global_conf[key]
|
variables[key] = global_conf[key]
|
||||||
LOG.debug(variables)
|
LOG.debug(variables)
|
||||||
return variables
|
return variables
|
||||||
@ -88,7 +94,7 @@ def set_globals():
|
|||||||
global MYSQL_ROOT_PASSWORD, CLUSTER_NAME, XTRABACKUP_PASSWORD
|
global MYSQL_ROOT_PASSWORD, CLUSTER_NAME, XTRABACKUP_PASSWORD
|
||||||
global MONITOR_PASSWORD, CONNECTION_ATTEMPTS, CONNECTION_DELAY
|
global MONITOR_PASSWORD, CONNECTION_ATTEMPTS, CONNECTION_DELAY
|
||||||
global ETCD_PATH, ETCD_HOST, ETCD_PORT, EXPECTED_NODES
|
global ETCD_PATH, ETCD_HOST, ETCD_PORT, EXPECTED_NODES
|
||||||
global FORCE_BOOTSTRAP, FORCE_BOOTSTRAP_NODE
|
global FORCE_BOOTSTRAP, FORCE_BOOTSTRAP_NODE, TLS
|
||||||
|
|
||||||
FORCE_BOOTSTRAP = config['percona']['force_bootstrap']['enabled']
|
FORCE_BOOTSTRAP = config['percona']['force_bootstrap']['enabled']
|
||||||
FORCE_BOOTSTRAP_NODE = config['percona']['force_bootstrap']['node']
|
FORCE_BOOTSTRAP_NODE = config['percona']['force_bootstrap']['node']
|
||||||
@ -103,6 +109,7 @@ def set_globals():
|
|||||||
ETCD_HOST = "etcd.%s.svc.%s" % (config['namespace'],
|
ETCD_HOST = "etcd.%s.svc.%s" % (config['namespace'],
|
||||||
config['cluster_domain'])
|
config['cluster_domain'])
|
||||||
ETCD_PORT = int(config['etcd']['client_port']['cont'])
|
ETCD_PORT = int(config['etcd']['client_port']['cont'])
|
||||||
|
TLS = config['security']['tls']['enabled']
|
||||||
|
|
||||||
|
|
||||||
def get_mysql_client(insecure=False):
|
def get_mysql_client(insecure=False):
|
||||||
@ -118,9 +125,21 @@ def get_mysql_client(insecure=False):
|
|||||||
|
|
||||||
def get_etcd_client():
|
def get_etcd_client():
|
||||||
|
|
||||||
|
if TLS:
|
||||||
|
protocol = 'https'
|
||||||
|
cert = (SERVER_CERT, SERVER_KEY)
|
||||||
|
ca_cert = CA_CERT
|
||||||
|
else:
|
||||||
|
protocol = 'http'
|
||||||
|
cert = None
|
||||||
|
ca_cert = None
|
||||||
|
|
||||||
return etcd.Client(host=ETCD_HOST,
|
return etcd.Client(host=ETCD_HOST,
|
||||||
port=ETCD_PORT,
|
port=ETCD_PORT,
|
||||||
allow_reconnect=True,
|
allow_reconnect=True,
|
||||||
|
protocol=protocol,
|
||||||
|
cert=cert,
|
||||||
|
ca_cert=ca_cert,
|
||||||
read_timeout=2)
|
read_timeout=2)
|
||||||
|
|
||||||
|
|
||||||
@ -476,7 +495,9 @@ def wait_for_mysqld(proc):
|
|||||||
def wait_for_mysqld_to_start(proc, insecure):
|
def wait_for_mysqld_to_start(proc, insecure):
|
||||||
|
|
||||||
LOG.info("Waiting mysql to start...")
|
LOG.info("Waiting mysql to start...")
|
||||||
time.sleep(5)
|
# Sometimes initial mysql start could take some time, especialy with SSL
|
||||||
|
# enabled. FIXME - replace sleep with some additional checks.
|
||||||
|
time.sleep(30)
|
||||||
while True:
|
while True:
|
||||||
if check_if_sst_running():
|
if check_if_sst_running():
|
||||||
LOG.debug("SST sync detected, waiting...")
|
LOG.debug("SST sync detected, waiting...")
|
||||||
|
1
service/files/server-cert.pem.j2
Normal file
1
service/files/server-cert.pem.j2
Normal file
@ -0,0 +1 @@
|
|||||||
|
{{ security.tls.server_cert }}
|
1
service/files/server-key.pem.j2
Normal file
1
service/files/server-key.pem.j2
Normal file
@ -0,0 +1 @@
|
|||||||
|
{{ security.tls.server_key }}
|
@ -15,6 +15,11 @@ service:
|
|||||||
daemon:
|
daemon:
|
||||||
files:
|
files:
|
||||||
- galera-checker
|
- galera-checker
|
||||||
|
# {% if percona.tls.enabled %}
|
||||||
|
- ca.pem
|
||||||
|
- server-key.pem
|
||||||
|
- server-cert.pem
|
||||||
|
# {% endif %}
|
||||||
dependencies:
|
dependencies:
|
||||||
- etcd
|
- etcd
|
||||||
command: "/opt/ccp/bin/galera_checker.py"
|
command: "/opt/ccp/bin/galera_checker.py"
|
||||||
@ -31,6 +36,11 @@ service:
|
|||||||
files:
|
files:
|
||||||
- haproxy-conf
|
- haproxy-conf
|
||||||
- haproxy_entrypoint
|
- haproxy_entrypoint
|
||||||
|
# {% if percona.tls.enabled %}
|
||||||
|
- ca.pem
|
||||||
|
- server-key.pem
|
||||||
|
- server-cert.pem
|
||||||
|
# {% endif %}
|
||||||
dependencies:
|
dependencies:
|
||||||
- etcd
|
- etcd
|
||||||
command: "/opt/ccp/bin/haproxy_entrypoint.py daemon"
|
command: "/opt/ccp/bin/haproxy_entrypoint.py daemon"
|
||||||
@ -67,6 +77,11 @@ service:
|
|||||||
- entrypoint
|
- entrypoint
|
||||||
- mycnf
|
- mycnf
|
||||||
- galera-checker
|
- galera-checker
|
||||||
|
# {% if percona.tls.enabled %}
|
||||||
|
- ca.pem
|
||||||
|
- server-key.pem
|
||||||
|
- server-cert.pem
|
||||||
|
# {% endif %}
|
||||||
dependencies:
|
dependencies:
|
||||||
- etcd
|
- etcd
|
||||||
command: /opt/ccp/bin/entrypoint.py
|
command: /opt/ccp/bin/entrypoint.py
|
||||||
@ -90,3 +105,17 @@ files:
|
|||||||
path: /opt/ccp/bin/haproxy_entrypoint.py
|
path: /opt/ccp/bin/haproxy_entrypoint.py
|
||||||
content: haproxy_entrypoint.py
|
content: haproxy_entrypoint.py
|
||||||
perm: "0755"
|
perm: "0755"
|
||||||
|
# {% if percona.tls.enabled %}
|
||||||
|
ca.pem:
|
||||||
|
path: /opt/ccp/etc/tls/ca.pem
|
||||||
|
content: ca.pem.j2
|
||||||
|
perm: "0400"
|
||||||
|
server-key.pem:
|
||||||
|
path: /opt/ccp/etc/tls/server-key.pem
|
||||||
|
content: server-key.pem.j2
|
||||||
|
perm: "0400"
|
||||||
|
server-cert.pem:
|
||||||
|
path: /opt/ccp/etc/tls/server-cert.pem
|
||||||
|
content: server-cert.pem.j2
|
||||||
|
perm: "0400"
|
||||||
|
# {% endif %}
|
||||||
|
Loading…
Reference in New Issue
Block a user