create_certificate script provided

This commit is contained in:
Davte 2020-04-19 00:06:05 +02:00
parent d131688794
commit 5eb3d9d874
3 changed files with 139 additions and 23 deletions

View File

@ -60,40 +60,30 @@ python -m filebridging.client --help
## Generating SSL certificates ## Generating SSL certificates
You may use `filebridging.create_certificate.py` script or use openssl from the command line.
###Via script
```bash
python -m filebridging.create_certificate --name example --domain example.com --force
```
### Via command line
Store configuration in file `mycert.csr.cnf` and run the following command to generate a self-signed SSL certificate. Store configuration in file `mycert.csr.cnf` and run the following command to generate a self-signed SSL certificate.
```bash ```bash
openssl req -newkey rsa:2048 -nodes -keyout ./mycert.key \ openssl req -newkey rsa:4096 -nodes -keyout ./mycert.key \
-x509 -days 365 -out ./mycert.crt \ -x509 -days 365 -out ./mycert.crt \
-config <( cat mycert.csr.cnf ) -config mycert.csr.cnf
``` ```
**mycert.csr.cnf** **mycert.csr.cnf**
```text ```text
[req] [ req ]
default_bits = 2048 default_bits = 4096
prompt = no prompt = no
default_md = sha256 default_md = sha256
distinguished_name = dn distinguished_name = dn
req_extensions = v3_req
subjectAltName = @alt_names
[ v3_req ] [ dn ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[dn]
C=US
ST=YourState
L=YourTown
O=FileBridging
OU=filebridging
emailAddress=filebridging@yourdomain.com
CN = yourdomain.com CN = yourdomain.com
[ alt_names ]
DNS.1 = yourdomain.com
DNS.2 = 1.111.111.11
``` ```

View File

@ -13,6 +13,6 @@ __author__ = "Davide Testa"
__email__ = "davide@davte.it" __email__ = "davide@davte.it"
__credits__ = [] __credits__ = []
__license__ = "GNU General Public License v3.0" __license__ = "GNU General Public License v3.0"
__version__ = "0.0.6" __version__ = "0.0.7"
__maintainer__ = "Davide Testa" __maintainer__ = "Davide Testa"
__contact__ = "t.me/davte" __contact__ = "t.me/davte"

View File

@ -0,0 +1,126 @@
"""Create a SSL certificate.
Requirements: OpenSSL.
"""
import argparse
import logging
import os
import subprocess
def get_paths(path):
""""""
return [
os.path.abspath(path) + string
for string in (".crt", ".key", "csr.cnf")
]
def main():
# noinspection SpellCheckingInspection
log_formatter = logging.Formatter(
"%(asctime)s [%(module)-15s %(levelname)-8s] %(message)s",
style='%'
)
root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
console_handler.setFormatter(log_formatter)
console_handler.setLevel(logging.DEBUG)
root_logger.addHandler(console_handler)
cli_parser = argparse.ArgumentParser(description='Create SSL certificate',
allow_abbrev=False)
cli_parser.add_argument('-n', '--name',
type=str,
default=None,
required=False,
help='Certificate, key and configuration file name')
cli_parser.add_argument('-d', '--domain',
type=str,
default=None,
required=False,
help='Server domain (e.g. example.com)')
cli_parser.add_argument('-f', '--force', '--overwrite',
action='store_true',
help='Overwrite certificate and key if they exist')
arguments = vars(cli_parser.parse_args())
name = arguments['name']
if name is None:
try:
from config import name
except ImportError:
name = None
while not name or not os.access(os.path.dirname(os.path.abspath(name)),
os.W_OK):
try:
name = input(
"Enter a valid file name for certificate, key and "
"configuration file. Directory must be writeable.\n"
"\t\t"
)
except KeyboardInterrupt:
print()
logging.error("Aborting...")
return
certificate_path, key_path, configuration_path = get_paths(
name
)
if not os.access(os.path.dirname(certificate_path), os.W_OK):
logging.error(f"Invalid path `{certificate_path}`!")
return
if any(
os.path.isfile(path)
for path in (certificate_path, key_path, configuration_path)
) and not arguments['force'] and not input(
"Do you want to overwrite existing certificate, key and "
"configuration file?"
"\n[Y]es or [N]o\t\t\t\t"
).lower().startswith('y'):
logging.error("Interrupted. Provide a different --name.")
return
domain = arguments['domain']
if domain is None:
try:
from config import domain
except ImportError:
domain = None
while not domain:
domain = input("Enter server domain (e.g. example.com)\n\t\t")
with open(configuration_path, 'w') as configuration_file:
logging.info("Writing configuration file...")
configuration_file.write(
"[req]\n"
"default_bits = 4096\n"
"prompt = no\n"
"default_md = sha256\n"
"distinguished_name = dn\n"
"\n"
"[dn]\n"
f"CN = {domain}\n"
)
logging.info("Generating certificate and key...")
subprocess.run(
[
f"openssl req -newkey rsa:4096 -nodes "
f"-keyout \"{key_path}\" -x509 -days 365 "
f"-out \"{certificate_path}\" "
f"-config \"{configuration_path}\""
],
capture_output=True,
text=True,
shell=True
)
with open(certificate_path, 'r') as certificate_file:
logging.info(
"Certificate:\n\n{certificate}".format(
certificate=''.join(certificate_file.readlines())
),
)
logging.info("Done!")
if __name__ == '__main__':
main()