#!/usr/bin/env python3 """ SSL证书生成脚本 用于生成自签名证书(开发和测试)或为Let's Encrypt准备 """ import os import sys import subprocess from pathlib import Path def check_openssl(): """检查OpenSSL是否已安装""" try: result = subprocess.run(['openssl', 'version'], capture_output=True, text=True) print(f"✅ OpenSSL 已安装: {result.stdout.strip()}") return True except FileNotFoundError: print("❌ OpenSSL 未安装") print("\n请安装 OpenSSL:") print(" Ubuntu/Debian: sudo apt-get install openssl") print(" CentOS/RHEL: sudo yum install openssl") print(" macOS: brew install openssl") return False def generate_self_signed_cert(domain="localhost", days=365): """生成自签名SSL证书""" print(f"\n🔒 生成自签名SSL证书...") print(f" 域名: {domain}") print(f" 有效期: {days} 天") # 创建证书目录 cert_dir = Path('certs') cert_dir.mkdir(exist_ok=True) # 证书文件路径 key_file = cert_dir / f"{domain}.key" cert_file = cert_dir / f"{domain}.crt" csr_file = cert_dir / f"{domain}.csr" # 生成私钥 print("\n1. 生成私钥...") cmd_key = [ 'openssl', 'genrsa', '-out', str(key_file), '2048' ] try: subprocess.run(cmd_key, check=True, capture_output=True) print(f" ✅ 私钥已生成: {key_file}") except subprocess.CalledProcessError as e: print(f" ❌ 生成私钥失败: {e.stderr.decode()}") return False # 生成证书签名请求 print("\n2. 生成证书签名请求...") cmd_csr = [ 'openssl', 'req', '-new', '-key', str(key_file), '-out', str(csr_file), '-subj', f'/C=CN/ST=Beijing/L=Beijing/O=KaMiXiTong/CN={domain}' ] try: subprocess.run(cmd_csr, check=True, capture_output=True) print(f" ✅ 证书签名请求已生成: {csr_file}") except subprocess.CalledProcessError as e: print(f" ❌ 生成证书签名请求失败: {e.stderr.decode()}") return False # 生成自签名证书 print("\n3. 生成自签名证书...") cmd_cert = [ 'openssl', 'x509', '-req', '-in', str(csr_file), '-signkey', str(key_file), '-out', str(cert_file), '-days', str(days) ] try: subprocess.run(cmd_cert, check=True, capture_output=True) print(f" ✅ 自签名证书已生成: {cert_file}") except subprocess.CalledProcessError as e: print(f" ❌ 生成自签名证书失败: {e.stderr.decode()}") return False # 清理临时文件 csr_file.unlink() # 设置文件权限 key_file.chmod(0o600) cert_file.chmod(0o644) print("\n✅ SSL证书生成完成!") print(f"\n📁 文件位置:") print(f" 私钥: {key_file.absolute()}") print(f" 证书: {cert_file.absolute()}") print(f"\n⚠️ 安全提醒:") print(f" - 私钥文件权限已设置为600(仅所有者可读写)") print(f" - 自签名证书仅用于开发和测试") print(f" - 生产环境请使用 Let's Encrypt 或其他CA签发的证书") return True def generate_certbot_config(domain, email): """生成 Certbot 配置""" print(f"\n🔒 生成 Certbot 配置...") cert_dir = Path('certs') cert_dir.mkdir(exist_ok=True) config_content = f"""# Certbot 配置文件 # 申请 Let's Encrypt 证书 certbot certonly \\ --webroot \\ -w /var/www/html \\ -d {domain} \\ --email {email} \\ --agree-tos \\ --non-interactive \\ --keep-until-expiring # 证书自动续期(添加到 crontab) 0 12 * * * /usr/bin/certbot renew --quiet """ config_file = cert_dir / 'certbot.conf' with open(config_file, 'w') as f: f.write(config_content) print(f"✅ Certbot 配置已生成: {config_file}") print(f"\n📋 使用说明:") print(f" 1. 安装 Certbot: sudo apt-get install certbot python3-certbot-nginx") print(f" 2. 运行配置: sudo bash certbot.conf") print(f" 3. 证书自动续期: 每天12点检查") print(f" 4. 手动续期: sudo certbot renew") def main(): """主函数""" print("=" * 60) print("🔒 SSL证书生成工具") print("=" * 60) # 检查OpenSSL if not check_openssl(): sys.exit(1) # 获取用户输入 print("\n请选择证书类型:") print("1. 自签名证书(开发和测试)") print("2. Let's Encrypt 配置(生产环境推荐)") choice = input("\n请选择 (1/2): ").strip() if choice == '1': domain = input("\n请输入域名或IP地址 (默认: localhost): ").strip() or 'localhost' days = input("请输入有效期天数 (默认: 365): ").strip() days = int(days) if days.isdigit() else 365 generate_self_signed_cert(domain, days) elif choice == '2': domain = input("\n请输入域名: ").strip() email = input("请输入邮箱地址: ").strip() if not domain or not email: print("❌ 域名和邮箱不能为空") sys.exit(1) generate_certbot_config(domain, email) else: print("❌ 无效选择") sys.exit(1) print("\n" + "=" * 60) print("✅ 完成!") print("=" * 60) if __name__ == '__main__': main()