Kamixitong/scripts/generate_ssl.py

187 lines
5.3 KiB
Python
Raw Permalink Normal View History

2025-12-12 11:35:14 +08:00
#!/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()