Add SSL encryption to galera
Change-Id: I9e6d9ee439cab734eba02320d58ccfcd73e23106
This commit is contained in:
parent
909d165c5e
commit
a760305ede
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
|
||||
port:
|
||||
cont: 3306
|
||||
tls:
|
||||
enabled: true
|
||||
url:
|
||||
percona:
|
||||
debian:
|
||||
|
1
service/files/dhparams.pem.j2
Normal file
1
service/files/dhparams.pem.j2
Normal file
@ -0,0 +1 @@
|
||||
{{ security.tls.dhparam }}
|
@ -33,11 +33,16 @@ PID_FILE = os.path.join(DATADIR, "mysqld.pid")
|
||||
HOSTNAME = socket.getfqdn()
|
||||
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
|
||||
CLUSTER_NAME = None
|
||||
ETCD_PATH = None
|
||||
ETCD_HOST = None
|
||||
ETCD_PORT = None
|
||||
ETCD_TLS = None
|
||||
|
||||
|
||||
def retry(f):
|
||||
@ -64,11 +69,22 @@ def retry(f):
|
||||
|
||||
def get_etcd_client():
|
||||
|
||||
etcd_client = etcd.Client(host=ETCD_HOST,
|
||||
port=ETCD_PORT,
|
||||
allow_reconnect=True,
|
||||
read_timeout=2)
|
||||
return etcd_client
|
||||
if ETCD_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,
|
||||
port=ETCD_PORT,
|
||||
allow_reconnect=True,
|
||||
protocol=protocol,
|
||||
cert=cert,
|
||||
ca_cert=ca_cert,
|
||||
read_timeout=2)
|
||||
|
||||
|
||||
@retry
|
||||
@ -297,7 +313,7 @@ def set_globals():
|
||||
|
||||
config = get_config()
|
||||
global MONITOR_PASSWORD, CLUSTER_NAME
|
||||
global ETCD_PATH, ETCD_HOST, ETCD_PORT
|
||||
global ETCD_PATH, ETCD_HOST, ETCD_PORT, ETCD_TLS
|
||||
|
||||
CLUSTER_NAME = config['percona']['cluster_name']
|
||||
MONITOR_PASSWORD = config['percona']['monitor_password']
|
||||
@ -305,6 +321,7 @@ def set_globals():
|
||||
ETCD_HOST = "etcd.%s.svc.%s" % (config['namespace'],
|
||||
config['cluster_domain'])
|
||||
ETCD_PORT = int(config['etcd']['client_port']['cont'])
|
||||
ETCD_TLS = config['etcd']['tls']['enabled']
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -18,6 +18,10 @@ BACKEND_NAME = "galera-cluster"
|
||||
SERVER_NAME = "primary"
|
||||
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_FORMAT = "%(asctime)s.%(msecs)03d - %(levelname)s - %(message)s"
|
||||
logging.basicConfig(format=LOG_FORMAT, datefmt=LOG_DATEFMT)
|
||||
@ -29,6 +33,7 @@ CONNECTION_DELAY = None
|
||||
ETCD_PATH = None
|
||||
ETCD_HOST = None
|
||||
ETCD_PORT = None
|
||||
ETCD_TLS = None
|
||||
|
||||
# Haproxy constant for health checks
|
||||
SRV_STATE_RUNNING = 2
|
||||
@ -68,7 +73,7 @@ def set_globals():
|
||||
|
||||
config = get_config()
|
||||
global CONNECTION_ATTEMPTS, CONNECTION_DELAY
|
||||
global ETCD_PATH, ETCD_HOST, ETCD_PORT
|
||||
global ETCD_PATH, ETCD_HOST, ETCD_PORT, ETCD_TLS
|
||||
|
||||
CONNECTION_ATTEMPTS = config['etcd']['connection_attempts']
|
||||
CONNECTION_DELAY = config['etcd']['connection_delay']
|
||||
@ -76,13 +81,26 @@ def set_globals():
|
||||
ETCD_HOST = "etcd.%s.svc.%s" % (config['namespace'],
|
||||
config['cluster_domain'])
|
||||
ETCD_PORT = int(config['etcd']['client_port']['cont'])
|
||||
ETCD_TLS = config['etcd']['tls']['enabled']
|
||||
|
||||
|
||||
def get_etcd_client():
|
||||
|
||||
if ETCD_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,
|
||||
port=ETCD_PORT,
|
||||
allow_reconnect=True,
|
||||
protocol=protocol,
|
||||
cert=cert,
|
||||
ca_cert=ca_cert,
|
||||
read_timeout=2)
|
||||
|
||||
|
||||
|
@ -35,4 +35,16 @@ wsrep_provider = /usr/lib/galera3/libgalera_smm.so
|
||||
wsrep_cluster_name = {{ percona.cluster_name }}
|
||||
wsrep_sst_method = xtrabackup-v2
|
||||
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 %};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 %}
|
||||
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 %}
|
||||
|
@ -24,8 +24,13 @@ INIT_FILE = os.path.join(DATADIR, 'init.ok')
|
||||
PID_FILE = os.path.join(DATADIR, "mysqld.pid")
|
||||
GRASTATE_FILE = os.path.join(DATADIR, 'grastate.dat')
|
||||
SST_FLAG = os.path.join(DATADIR, "sst_in_progress")
|
||||
DHPARAM = os.path.join(DATADIR, "dhparams.pem")
|
||||
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_FORMAT = "%(asctime)s.%(msecs)03d - %(levelname)s - %(message)s"
|
||||
logging.basicConfig(format=LOG_FORMAT, datefmt=LOG_DATEFMT)
|
||||
@ -44,6 +49,8 @@ CONNECTION_DELAY = None
|
||||
ETCD_PATH = None
|
||||
ETCD_HOST = None
|
||||
ETCD_PORT = None
|
||||
ETCD_TLS = None
|
||||
DHPARAM_CERT = None
|
||||
|
||||
|
||||
class ProcessException(Exception):
|
||||
@ -76,7 +83,8 @@ def get_config():
|
||||
variables = {}
|
||||
with open(GLOBALS_PATH) as 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]
|
||||
LOG.debug(variables)
|
||||
return variables
|
||||
@ -88,7 +96,7 @@ def set_globals():
|
||||
global MYSQL_ROOT_PASSWORD, CLUSTER_NAME, XTRABACKUP_PASSWORD
|
||||
global MONITOR_PASSWORD, CONNECTION_ATTEMPTS, CONNECTION_DELAY
|
||||
global ETCD_PATH, ETCD_HOST, ETCD_PORT, EXPECTED_NODES
|
||||
global FORCE_BOOTSTRAP, FORCE_BOOTSTRAP_NODE
|
||||
global FORCE_BOOTSTRAP, FORCE_BOOTSTRAP_NODE, ETCD_TLS, DHPARAM_CERT
|
||||
|
||||
FORCE_BOOTSTRAP = config['percona']['force_bootstrap']['enabled']
|
||||
FORCE_BOOTSTRAP_NODE = config['percona']['force_bootstrap']['node']
|
||||
@ -103,6 +111,8 @@ def set_globals():
|
||||
ETCD_HOST = "etcd.%s.svc.%s" % (config['namespace'],
|
||||
config['cluster_domain'])
|
||||
ETCD_PORT = int(config['etcd']['client_port']['cont'])
|
||||
ETCD_TLS = config['etcd']['tls']['enabled']
|
||||
DHPARAM_CERT = config['security']['tls']['dhparam']
|
||||
|
||||
|
||||
def get_mysql_client(insecure=False):
|
||||
@ -118,9 +128,21 @@ def get_mysql_client(insecure=False):
|
||||
|
||||
def get_etcd_client():
|
||||
|
||||
if ETCD_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,
|
||||
port=ETCD_PORT,
|
||||
allow_reconnect=True,
|
||||
protocol=protocol,
|
||||
cert=cert,
|
||||
ca_cert=ca_cert,
|
||||
read_timeout=2)
|
||||
|
||||
|
||||
@ -134,6 +156,15 @@ def datadir_cleanup(path):
|
||||
os.remove(fullpath)
|
||||
|
||||
|
||||
def create_dhparam():
|
||||
if not os.path.isfile(DHPARAM):
|
||||
with open(DHPARAM, 'w') as f:
|
||||
f.write(DHPARAM_CERT)
|
||||
LOG.info("dhparam cert created in %s", DHPARAM)
|
||||
else:
|
||||
LOG.info("%s exists, not overriding it", DHPARAM)
|
||||
|
||||
|
||||
def create_init_flag():
|
||||
|
||||
if not os.path.isfile(INIT_FILE):
|
||||
@ -156,6 +187,7 @@ def run_cmd(cmd, check_result=False):
|
||||
|
||||
def run_mysqld(available_nodes, donors_list, etcd_client, lock):
|
||||
|
||||
create_dhparam()
|
||||
cmd = ("mysqld --user=mysql --wsrep_cluster_name=%s"
|
||||
" --wsrep_cluster_address=%s"
|
||||
" --wsrep_sst_method=xtrabackup-v2"
|
||||
@ -476,7 +508,9 @@ def wait_for_mysqld(proc):
|
||||
def wait_for_mysqld_to_start(proc, insecure):
|
||||
|
||||
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:
|
||||
if check_if_sst_running():
|
||||
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:
|
||||
files:
|
||||
- galera-checker
|
||||
# {% if percona.tls.enabled %}
|
||||
- ca.pem
|
||||
- server-key.pem
|
||||
- server-cert.pem
|
||||
# {% endif %}
|
||||
dependencies:
|
||||
- etcd
|
||||
command: "/opt/ccp/bin/galera_checker.py"
|
||||
@ -31,6 +36,11 @@ service:
|
||||
files:
|
||||
- haproxy-conf
|
||||
- haproxy_entrypoint
|
||||
# {% if percona.tls.enabled %}
|
||||
- ca.pem
|
||||
- server-key.pem
|
||||
- server-cert.pem
|
||||
# {% endif %}
|
||||
dependencies:
|
||||
- etcd
|
||||
command: "/opt/ccp/bin/haproxy_entrypoint.py daemon"
|
||||
@ -67,6 +77,11 @@ service:
|
||||
- entrypoint
|
||||
- mycnf
|
||||
- galera-checker
|
||||
# {% if percona.tls.enabled %}
|
||||
- ca.pem
|
||||
- server-key.pem
|
||||
- server-cert.pem
|
||||
# {% endif %}
|
||||
dependencies:
|
||||
- etcd
|
||||
command: /opt/ccp/bin/entrypoint.py
|
||||
@ -90,3 +105,22 @@ files:
|
||||
path: /opt/ccp/bin/haproxy_entrypoint.py
|
||||
content: haproxy_entrypoint.py
|
||||
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"
|
||||
# Cant use it right now, 'cos of the file creation order
|
||||
dhparams.pem:
|
||||
path: /var/lib/mysql/dhparams.pem
|
||||
content: dhparams.pem.j2
|
||||
perm: "0400"
|
||||
# {% endif %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user