88 lines
2.9 KiB
Python
88 lines
2.9 KiB
Python
#!/usr/bin/env python3
|
|
import sys
|
|
import os
|
|
import configparser
|
|
import argparse
|
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
from cryptography.hazmat.primitives import serialization
|
|
|
|
CONFIG_PATH = "/etc/pyarc/milter.conf"
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Schlüsselgenerator für den Custom ARC Milter")
|
|
parser.add_argument("domain", help="Die Domain, für die ein ARC-Schlüsselpaar generiert werden soll")
|
|
args = parser.parse_args()
|
|
|
|
domain = args.domain.lower().strip()
|
|
config = configparser.ConfigParser()
|
|
|
|
if not os.path.exists(CONFIG_PATH):
|
|
print(f"Fehler: Konfigurationsdatei {CONFIG_PATH} nicht gefunden.", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
config.read(CONFIG_PATH)
|
|
|
|
if not config.has_section(domain):
|
|
print(f"Fehler: Domain '{domain}' ist nicht in der {CONFIG_PATH} eingetragen.", file=sys.stderr)
|
|
print("Bitte lege zuerst die Sektion für die Domain in der Config an. Beispiel:", file=sys.stderr)
|
|
print(f"\n[{domain}]\nselector = arc2026\nprivate_key_path = /etc/pyarc/certs/{domain}.private.key\n", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
selector = config.get(domain, "selector", fallback="arc2026")
|
|
key_path = config.get(domain, "private_key_path")
|
|
|
|
if os.path.exists(key_path):
|
|
print(f"Abbruch: Key-Datei existiert bereits unter: {key_path}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
print(f"Generiere 2048-Bit RSA Schlüssel für {domain}...")
|
|
|
|
try:
|
|
private_key = rsa.generate_private_key(
|
|
public_exponent=65537,
|
|
key_size=2048
|
|
)
|
|
|
|
log_dir = os.path.dirname(key_path)
|
|
if log_dir:
|
|
os.makedirs(log_dir, exist_ok=True)
|
|
|
|
pem = private_key.private_bytes(
|
|
encoding=serialization.Encoding.PEM,
|
|
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
|
encryption_algorithm=serialization.NoEncryption()
|
|
)
|
|
|
|
with open(key_path, "wb") as f:
|
|
f.write(pem)
|
|
|
|
os.chmod(key_path, 0o640)
|
|
|
|
if os.path.exists("/etc/pyarc"):
|
|
stat_info = os.stat("/etc/pyarc")
|
|
os.chown(key_path, stat_info.st_uid, stat_info.st_gid)
|
|
|
|
print(f"✔ Private Key erfolgreich gespeichert unter: {key_path}")
|
|
|
|
public_key = private_key.public_key()
|
|
pub_pem = public_key.public_bytes(
|
|
encoding=serialization.Encoding.PEM,
|
|
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
|
)
|
|
|
|
pub_lines = pub_pem.decode('utf-8').splitlines()
|
|
pub_key_clean = "".join(pub_lines[1:-1])
|
|
|
|
print("\n" + "="*60)
|
|
print(f"DEIN DNS-TXT-RECORD FÜR {domain}:")
|
|
print("="*60)
|
|
print(f"{selector}._domainkey.{domain}. IN TXT \"v=DKIM1; k=rsa; p={pub_key_clean}\"")
|
|
print("="*60 + "\n")
|
|
|
|
except Exception as e:
|
|
print(f"Ein unerwarteter Fehler ist aufgetreten: {e}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|