第一次提交
This commit is contained in:
186
scripts/generate_ssl.py
Normal file
186
scripts/generate_ssl.py
Normal file
@@ -0,0 +1,186 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user