Merge pull request #209 from kevgliss/migrate_chain
Adding command to transparently rotate the chain on an ELB
This commit is contained in:
commit
c617a11c55
|
@ -11,8 +11,10 @@
|
||||||
"""
|
"""
|
||||||
from sqlalchemy import exc
|
from sqlalchemy import exc
|
||||||
from sqlalchemy.sql import and_, or_
|
from sqlalchemy.sql import and_, or_
|
||||||
|
from sqlalchemy.orm import make_transient
|
||||||
from sqlalchemy.orm.exc import NoResultFound
|
from sqlalchemy.orm.exc import NoResultFound
|
||||||
|
|
||||||
|
|
||||||
from lemur.extensions import db
|
from lemur.extensions import db
|
||||||
from lemur.exceptions import AttrNotFound, DuplicateError
|
from lemur.exceptions import AttrNotFound, DuplicateError
|
||||||
|
|
||||||
|
@ -254,6 +256,18 @@ def update_list(model, model_attr, item_model, items):
|
||||||
return model
|
return model
|
||||||
|
|
||||||
|
|
||||||
|
def clone(model):
|
||||||
|
"""
|
||||||
|
Clones the given model and removes it's primary key
|
||||||
|
:param model:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
db.session.expunge(model)
|
||||||
|
make_transient(model)
|
||||||
|
model.id = None
|
||||||
|
return model
|
||||||
|
|
||||||
|
|
||||||
def sort_and_page(query, model, args):
|
def sort_and_page(query, model, args):
|
||||||
"""
|
"""
|
||||||
Helper that allows us to combine sorting and paging
|
Helper that allows us to combine sorting and paging
|
||||||
|
|
|
@ -24,7 +24,11 @@ from lemur.certificates import service as cert_service
|
||||||
from lemur.sources import service as source_service
|
from lemur.sources import service as source_service
|
||||||
from lemur.notifications import service as notification_service
|
from lemur.notifications import service as notification_service
|
||||||
|
|
||||||
|
from lemur.certificates.models import get_name_from_arn
|
||||||
from lemur.certificates.verify import verify_string
|
from lemur.certificates.verify import verify_string
|
||||||
|
|
||||||
|
from lemur.plugins.lemur_aws import elb
|
||||||
|
|
||||||
from lemur.sources.service import sync
|
from lemur.sources.service import sync
|
||||||
|
|
||||||
from lemur import create_app
|
from lemur import create_app
|
||||||
|
@ -510,23 +514,66 @@ class RotateELBs(Command):
|
||||||
Rotates existing certificates to a new one on an ELB
|
Rotates existing certificates to a new one on an ELB
|
||||||
"""
|
"""
|
||||||
option_list = (
|
option_list = (
|
||||||
Option('-c', '--cert-name', dest='cert_name', required=True),
|
Option('-e', '--elb-list', dest='elb_list', required=True),
|
||||||
Option('-a', '--account-id', dest='account_id', required=True),
|
Option('-p', '--chain-path', dest='chain_path'),
|
||||||
Option('-e', '--elb-list', dest='elb_list', required=True)
|
Option('-c', '--cert-name', dest='cert_name'),
|
||||||
|
Option('-a', '--cert-prefix', dest='cert_prefix'),
|
||||||
|
Option('-d', '--description', dest='description')
|
||||||
)
|
)
|
||||||
|
|
||||||
def run(self, cert_name, account_id, elb_list):
|
def run(self, elb_list, chain_path, cert_name, cert_prefix, description):
|
||||||
from lemur.plugins.lemur_aws import elb
|
|
||||||
arn = "arn:aws:iam::{0}:server-certificate/{1}".format(account_id, cert_name)
|
|
||||||
|
|
||||||
for e in open(elb_list, 'r').readlines():
|
for e in open(elb_list, 'r').readlines():
|
||||||
for region in elb.get_all_regions():
|
elb_name, account_id, region, from_port, to_port, protocol = e.strip().split(',')
|
||||||
if str(region) in e:
|
|
||||||
name = "-".join(e.split('.')[0].split('-')[:-1])
|
if cert_name:
|
||||||
if name.startswith("internal"):
|
arn = "arn:aws:iam::{0}:server-certificate/{1}".format(account_id, cert_name)
|
||||||
name = "-".join(name.split("-")[1:])
|
|
||||||
elb.update_listeners(account_id, str(region), name, [(443, 7001, 'https', arn)], [443])
|
else:
|
||||||
sys.out.write("[+] Updated {0} to use {1} on 443\n".format(name, cert_name))
|
# if no cert name is provided we need to discover it
|
||||||
|
listeners = elb.get_listeners(account_id, region, elb_name)
|
||||||
|
|
||||||
|
# get the listener we care about
|
||||||
|
for listener in listeners:
|
||||||
|
if listener[0] == int(from_port) and listener[1] == int(to_port):
|
||||||
|
arn = listener[4]
|
||||||
|
name = get_name_from_arn(arn)
|
||||||
|
certificate = cert_service.get_by_name(name)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
sys.stdout.write("[-] Could not find ELB {0}".format(elb_name))
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not certificate:
|
||||||
|
sys.stdout.write("[-] Could not find certificate {0} in Lemur".format(name))
|
||||||
|
continue
|
||||||
|
|
||||||
|
dests = []
|
||||||
|
for d in certificate.destinations:
|
||||||
|
dests.append({'id': d.id})
|
||||||
|
|
||||||
|
nots = []
|
||||||
|
for n in certificate.notifications:
|
||||||
|
nots.append({'id': n.id})
|
||||||
|
|
||||||
|
new_certificate = database.clone(certificate)
|
||||||
|
|
||||||
|
if cert_prefix:
|
||||||
|
new_certificate.name = "{0}-{1}".format(cert_prefix, new_certificate.name)
|
||||||
|
|
||||||
|
new_certificate.chain = open(chain_path, 'r').read()
|
||||||
|
new_certificate.description = "{0} - {1}".format(new_certificate.description, description)
|
||||||
|
|
||||||
|
new_certificate = database.create(new_certificate)
|
||||||
|
database.update_list(new_certificate, 'destinations', Destination, dests)
|
||||||
|
database.update_list(new_certificate, 'notifications', Notification, nots)
|
||||||
|
database.update(new_certificate)
|
||||||
|
|
||||||
|
arn = new_certificate.get_arn(account_id)
|
||||||
|
|
||||||
|
elb.update_listeners(account_id, region, elb_name, [(from_port, to_port, protocol, arn)], [from_port])
|
||||||
|
|
||||||
|
sys.stdout.write("[+] Updated {0} to use {1}\n".format(elb_name, new_certificate.name))
|
||||||
|
|
||||||
|
|
||||||
class ProvisionELB(Command):
|
class ProvisionELB(Command):
|
||||||
|
@ -743,24 +790,6 @@ def publish_verisign_units():
|
||||||
requests.post('http://localhost:8078/metrics', data=json.dumps(metric))
|
requests.post('http://localhost:8078/metrics', data=json.dumps(metric))
|
||||||
|
|
||||||
|
|
||||||
@manager.command
|
|
||||||
def backfill_signing_algo():
|
|
||||||
"""
|
|
||||||
Will attempt to backfill the signing_algorithm column
|
|
||||||
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
from cryptography import x509
|
|
||||||
from cryptography.hazmat.backends import default_backend
|
|
||||||
from lemur.certificates.models import get_signing_algorithm
|
|
||||||
for c in cert_service.get_all_certs():
|
|
||||||
cert = x509.load_pem_x509_certificate(str(c.body), default_backend())
|
|
||||||
c.signing_algorithm = get_signing_algorithm(cert)
|
|
||||||
c.signing_algorithm
|
|
||||||
database.update(c)
|
|
||||||
print(c.signing_algorithm)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
manager.add_command("start", LemurServer())
|
manager.add_command("start", LemurServer())
|
||||||
manager.add_command("runserver", Server(host='127.0.0.1'))
|
manager.add_command("runserver", Server(host='127.0.0.1'))
|
||||||
|
|
Loading…
Reference in New Issue