|
| 1 | +# This script will only edit the config.xml file. |
| 2 | +# It will not do anything else. Copying or moving the certificates is done by a seperate script. |
| 3 | +# You are free to use or modify this for whatever purpose. Just let me know how much time it saved you :) |
| 4 | +import base64 |
| 5 | +import xmltodict |
| 6 | +import secrets |
| 7 | +import argparse |
| 8 | + |
| 9 | +parser = argparse.ArgumentParser() |
| 10 | +parser.add_argument("--publickey", help = "Specify the location of the public key file", required=True) |
| 11 | +parser.add_argument("--privatekey", help= " Specify the location the private key file", required=True) |
| 12 | +parser.add_argument("--config", help = 'Specify the location of the downloaded pfSense config', required=True) |
| 13 | +args = parser.parse_args() |
| 14 | + |
| 15 | +pf_config_file = args.config |
| 16 | +pub_key_file = args.publickey |
| 17 | +priv_key_file = args.privatekey |
| 18 | + |
| 19 | +def read_files(): |
| 20 | + """Load in pf config file and TLS pub and priv keys""" |
| 21 | + with open(pf_config_file, 'r', encoding='utf-8') as conf_file: |
| 22 | + r_xml = conf_file.read() |
| 23 | + with open(pub_key_file, 'r', encoding='utf-8') as pk: |
| 24 | + public_key = pk.read() |
| 25 | + with open(priv_key_file, 'r', encoding='utf-8') as pk: |
| 26 | + private_key = pk.read() |
| 27 | + return r_xml, public_key, private_key |
| 28 | + |
| 29 | +def update_config(certs, public_key, private_key): |
| 30 | + """Update the pf config file with new TLS certs. Also change the cert the web configurator uses.""" |
| 31 | + gen_refid = secrets.token_hex(13)[:13] |
| 32 | + if type(certs) == dict: |
| 33 | + |
| 34 | + # Just incase our originally generated cert id already exist. |
| 35 | + while gen_refid == pf_conf['pfsense']['cert']['refid']: |
| 36 | + gen_refid = secrets.token_hex(13)[:13] |
| 37 | + |
| 38 | + pf_conf['pfsense']['cert'] = [pf_conf['pfsense']['cert']] |
| 39 | + |
| 40 | + # This is our new certificate. We wont delete the old ones. |
| 41 | + # Maybe in the future we will. |
| 42 | + pf_conf['pfsense']['cert'].append({ |
| 43 | + 'refid': gen_refid, |
| 44 | + 'descr': f'LE - {gen_refid}', |
| 45 | + 'crt': base64.b64encode(public_key.encode('utf-8')).decode('utf-8'), |
| 46 | + 'prv': base64.b64encode(private_key.encode('utf-8')).decode('utf-8') |
| 47 | + }) |
| 48 | + else: |
| 49 | + # Get list of existing cert ids |
| 50 | + cert_ids = [cert['refid'] for cert in certs] |
| 51 | + |
| 52 | + while gen_refid in cert_ids: |
| 53 | + gen_refid = secrets.token_hex(13)[:13] |
| 54 | + pf_conf['pfsense']['cert'].append({ |
| 55 | + 'refid': gen_refid, |
| 56 | + 'descr': f'LE - {gen_refid}', |
| 57 | + 'crt': base64.b64encode(public_key.encode('utf-8')).decode('utf-8'), |
| 58 | + 'prv': base64.b64encode(private_key.encode('utf-8')).decode('utf-8') |
| 59 | + }) |
| 60 | + |
| 61 | + # Finally, we tell pfsense that it should use our new TLS certificate for the web configurator. |
| 62 | + pf_conf['pfsense']['system']['webgui']['ssl-certref'] = gen_refid |
| 63 | + |
| 64 | + |
| 65 | +r_xml, public_key, private_key = read_files() |
| 66 | + |
| 67 | +pf_conf = xmltodict.parse(r_xml) |
| 68 | + |
| 69 | +update_config(pf_conf['pfsense']['cert'], public_key, private_key) |
| 70 | + |
| 71 | +# Convert the dict to xml and write to disk. |
| 72 | +xml_format = xmltodict.unparse(pf_conf, pretty=True) |
| 73 | +with open(pf_config_file, 'w', encoding='utf-8') as new_xml: |
| 74 | + new_xml.write(xml_format) |
0 commit comments