2020-03-12 23:06:05 +00:00
|
|
|
import os
|
2020-04-22 17:33:31 +00:00
|
|
|
import confluent.collective.manager as collective
|
2019-08-05 20:16:42 +00:00
|
|
|
from os.path import exists
|
2018-12-11 18:51:46 +00:00
|
|
|
import shutil
|
|
|
|
import socket
|
2020-04-22 17:33:31 +00:00
|
|
|
import eventlet.green.subprocess as subprocess
|
2018-12-11 18:51:46 +00:00
|
|
|
import tempfile
|
|
|
|
|
|
|
|
def get_openssl_conf_location():
|
2019-08-05 20:16:42 +00:00
|
|
|
if exists('/etc/pki/tls/openssl.cnf'):
|
|
|
|
return '/etc/pki/tls/openssl.cnf'
|
2020-02-03 20:37:20 +00:00
|
|
|
elif exists('/etc/ssl/openssl.cnf'):
|
2019-08-05 20:16:42 +00:00
|
|
|
return '/etc/ssl/openssl.cnf'
|
|
|
|
else:
|
|
|
|
raise Exception("Cannot find openssl config file")
|
2018-12-11 18:51:46 +00:00
|
|
|
|
|
|
|
def get_ip_addresses():
|
|
|
|
lines = subprocess.check_output('ip addr'.split(' '))
|
2020-03-16 13:27:34 +00:00
|
|
|
if not isinstance(lines, str):
|
|
|
|
lines = lines.decode('utf8')
|
2018-12-11 18:51:46 +00:00
|
|
|
for line in lines.split('\n'):
|
|
|
|
if line.startswith(' inet6 '):
|
|
|
|
line = line.replace(' inet6 ', '').split('/')[0]
|
|
|
|
if line == '::1':
|
|
|
|
continue
|
|
|
|
elif line.startswith(' inet '):
|
|
|
|
line = line.replace(' inet ', '').split('/')[0]
|
|
|
|
if line == '127.0.0.1':
|
|
|
|
continue
|
|
|
|
if line.startswith('169.254.'):
|
|
|
|
continue
|
|
|
|
else:
|
|
|
|
continue
|
|
|
|
yield line
|
|
|
|
|
2020-04-22 17:33:31 +00:00
|
|
|
def create_certificate(outdir):
|
|
|
|
keyout = os.path.join(outdir, 'key.pem')
|
|
|
|
certout = os.path.join(outdir, 'cert.pem')
|
2018-12-11 18:51:46 +00:00
|
|
|
shortname = socket.gethostname().split('.')[0]
|
|
|
|
longname = socket.getfqdn()
|
|
|
|
subprocess.check_call(
|
2020-04-22 17:33:31 +00:00
|
|
|
['openssl', 'ecparam', '-name', 'secp384r1', '-genkey', '-out',
|
|
|
|
keyout])
|
2018-12-11 18:51:46 +00:00
|
|
|
san = ['IP:{0}'.format(x) for x in get_ip_addresses()]
|
2020-03-12 23:06:05 +00:00
|
|
|
# It is incorrect to put IP addresses as DNS type. However
|
|
|
|
# there exists non-compliant clients that fail with them as IP
|
|
|
|
san.extend(['DNS:{0}'.format(x) for x in get_ip_addresses()])
|
2018-12-11 18:51:46 +00:00
|
|
|
san.append('DNS:{0}'.format(shortname))
|
|
|
|
san.append('DNS:{0}'.format(longname))
|
|
|
|
san = ','.join(san)
|
|
|
|
sslcfg = get_openssl_conf_location()
|
|
|
|
tmpconfig = tempfile.mktemp()
|
|
|
|
shutil.copy2(sslcfg, tmpconfig)
|
2020-03-12 23:06:05 +00:00
|
|
|
try:
|
|
|
|
with open(tmpconfig, 'a') as cfgfile:
|
|
|
|
cfgfile.write('\n[SAN]\nsubjectAltName={0}'.format(san))
|
2020-04-22 17:33:31 +00:00
|
|
|
subprocess.check_call([
|
|
|
|
'openssl', 'req', '-new', '-x509', '-key', keyout, '-days',
|
|
|
|
'7300', '-out', certout, '-subj', '/CN={0}'.format(longname),
|
|
|
|
'-extensions', 'SAN', '-config', tmpconfig
|
|
|
|
])
|
2020-03-12 23:06:05 +00:00
|
|
|
finally:
|
|
|
|
os.remove(tmpconfig)
|
2020-04-22 17:33:31 +00:00
|
|
|
fname = '/var/lib/confluent/public/site/tls/{0}.cert'.format(
|
|
|
|
collective.get_myname())
|
|
|
|
shutil.copy2(certout, fname)
|
|
|
|
hv = subprocess.check_output(
|
|
|
|
['openssl', 'x509', '-in', certout, '-hash', '-noout'])
|
|
|
|
if not isinstance(hv, str):
|
|
|
|
hv = hv.decode('utf8')
|
|
|
|
hv = hv.strip()
|
|
|
|
hashname = '/var/lib/confluent/public/site/tls/{0}.0'.format(hv)
|
|
|
|
certname = '{0}.cert'.format(collective.get_myname())
|
|
|
|
for currname in os.listdir('/var/lib/confluent/public/site/tls/'):
|
|
|
|
currname = os.path.join('/var/lib/confluent/public/site/tls/', currname)
|
|
|
|
if currname.endswith('.0'):
|
|
|
|
try:
|
|
|
|
realname = os.readlink(currname)
|
|
|
|
if realname == certname:
|
|
|
|
os.unlink(currname)
|
|
|
|
except OSError:
|
|
|
|
pass
|
|
|
|
os.symlink(certname, hashname)
|
2018-12-11 18:51:46 +00:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2020-04-22 17:33:31 +00:00
|
|
|
create_certificate(os.getcwd())
|