Initial commit
This commit is contained in:
86
pushcert-mikrotik
Executable file
86
pushcert-mikrotik
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env python3
|
||||
# dlitz 2025
|
||||
|
||||
import os
|
||||
import shlex
|
||||
import subprocess
|
||||
import tempfile
|
||||
from argparse import ArgumentParser
|
||||
from pathlib import Path
|
||||
|
||||
from pkcs12_export import PKCS12Exporter
|
||||
|
||||
|
||||
def generate_random_passphrase():
|
||||
return os.urandom(64).hex()
|
||||
|
||||
|
||||
def make_arg_parser():
|
||||
parser = ArgumentParser(
|
||||
description="push TLS privkey & certificate to MikroTik RouterOS router"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-k", "--privkey", type=Path, required=True, help="private key file"
|
||||
)
|
||||
parser.add_argument("--cert", type=Path, required=True, help="certificate file")
|
||||
parser.add_argument(
|
||||
"--chain", type=Path, help="separate certificate chain file (optional)"
|
||||
)
|
||||
parser.add_argument("--ssh-host", required=True, help="target ssh host")
|
||||
return parser
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = make_arg_parser()
|
||||
args = parser.parse_args()
|
||||
assert ":" not in args.ssh_host
|
||||
return args, parser
|
||||
|
||||
|
||||
def main():
|
||||
args, parser = parse_args()
|
||||
|
||||
# TODO: Check certificate serial number before attempting to copy cert, and at end.
|
||||
|
||||
privkey_data = args.privkey.read_text()
|
||||
cert_data = args.cert.read_text()
|
||||
chain_data = args.chain.read_text() if args.chain is not None else None
|
||||
|
||||
key_passphrase = generate_random_passphrase()
|
||||
|
||||
pkcs12_data = PKCS12Exporter().export_pkcs12(
|
||||
privkey_data=privkey_data,
|
||||
cert_data=cert_data,
|
||||
chain_data=chain_data,
|
||||
passphrase=key_passphrase,
|
||||
)
|
||||
|
||||
with tempfile.NamedTemporaryFile(dir="/dev/shm") as tf:
|
||||
tf.write(pkcs12_data)
|
||||
tf.flush()
|
||||
|
||||
ssh_options = [
|
||||
"-oBatchMode=yes",
|
||||
"-oControlMaster=no",
|
||||
]
|
||||
|
||||
cmd = ["scp", *ssh_options, "-q", tf.name, f"{args.ssh_host}:/cert-pusher-data.p12"]
|
||||
# print("executing:", shlex.join(cmd))
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
# ros_command = f'/certificate import name=www_ssl_cert file-name=cert-pusher-data.p12 no-key-export=yes passphrase="{key_passphrase}"'
|
||||
ros_command = f'/certificate import name=www_ssl_cert file-name=cert-pusher-data.p12 no-key-export=yes passphrase="{key_passphrase}"; /file remove [/file find name=cert-pusher-data.p12]'
|
||||
cmd = [
|
||||
"ssh",
|
||||
*ssh_options,
|
||||
args.ssh_host,
|
||||
ros_command,
|
||||
]
|
||||
result = subprocess.check_output(cmd, text=True)
|
||||
assert " files-imported: 1" in result
|
||||
# print(result)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user