generate_tls_certs.sh•5.49 kB
#!/bin/bash
# MemOS TLS证书生成脚本
# 为个人场景生成自签名证书
set -e
MEMOS_DIR="/home/qqinshu/视频/MemOS"
TLS_DIR="$MEMOS_DIR/memos_data/qdrant_tls"
CERT_VALIDITY_DAYS=365
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
log_info() {
echo -e "${BLUE}ℹ️ $1${NC}"
}
log_success() {
echo -e "${GREEN}✅ $1${NC}"
}
log_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
log_error() {
echo -e "${RED}❌ $1${NC}"
}
# 检查openssl是否可用
check_openssl() {
if ! command -v openssl &> /dev/null; then
log_error "openssl未安装,请先安装: sudo apt install openssl"
exit 1
fi
log_success "openssl可用"
}
# 生成CA私钥和证书
generate_ca() {
log_info "生成CA私钥和证书..."
cd "$TLS_DIR"
# 生成CA私钥
openssl genrsa -out ca-key.pem 4096
# 生成CA证书
openssl req -new -x509 -days $CERT_VALIDITY_DAYS -key ca-key.pem -sha256 -out ca.pem -subj "/C=CN/ST=Local/L=Local/O=MemOS/OU=Personal/CN=MemOS-CA"
log_success "CA证书生成完成"
}
# 生成服务器证书
generate_server_cert() {
log_info "生成Qdrant服务器证书..."
cd "$TLS_DIR"
# 生成服务器私钥
openssl genrsa -out server-key.pem 4096
# 生成证书签名请求
openssl req -subj "/C=CN/ST=Local/L=Local/O=MemOS/OU=Personal/CN=localhost" -sha256 -new -key server-key.pem -out server.csr
# 创建扩展文件
cat > server-extfile.cnf << EOF
subjectAltName = DNS:localhost,IP:127.0.0.1,IP:0.0.0.0
extendedKeyUsage = serverAuth
EOF
# 生成服务器证书
openssl x509 -req -days $CERT_VALIDITY_DAYS -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -out server-cert.pem -extfile server-extfile.cnf -CAcreateserial
# 清理临时文件
rm server.csr server-extfile.cnf
log_success "服务器证书生成完成"
}
# 生成客户端证书
generate_client_cert() {
log_info "生成客户端证书..."
cd "$TLS_DIR"
# 生成客户端私钥
openssl genrsa -out client-key.pem 4096
# 生成证书签名请求
openssl req -subj "/C=CN/ST=Local/L=Local/O=MemOS/OU=Personal/CN=memos-client" -new -key client-key.pem -out client.csr
# 创建扩展文件
cat > client-extfile.cnf << EOF
extendedKeyUsage = clientAuth
EOF
# 生成客户端证书
openssl x509 -req -days $CERT_VALIDITY_DAYS -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -out client-cert.pem -extfile client-extfile.cnf -CAcreateserial
# 清理临时文件
rm client.csr client-extfile.cnf
log_success "客户端证书生成完成"
}
# 设置文件权限
set_permissions() {
log_info "设置证书文件权限..."
cd "$TLS_DIR"
# 设置私钥文件权限(仅所有者可读)
chmod 600 *-key.pem
# 设置证书文件权限(所有者可读写,组和其他用户可读)
chmod 644 *.pem
# 设置目录权限
chmod 755 "$TLS_DIR"
log_success "文件权限设置完成"
}
# 验证证书
verify_certificates() {
log_info "验证生成的证书..."
cd "$TLS_DIR"
# 验证CA证书
if openssl x509 -in ca.pem -text -noout > /dev/null 2>&1; then
log_success "CA证书验证通过"
else
log_error "CA证书验证失败"
exit 1
fi
# 验证服务器证书
if openssl verify -CAfile ca.pem server-cert.pem > /dev/null 2>&1; then
log_success "服务器证书验证通过"
else
log_error "服务器证书验证失败"
exit 1
fi
# 验证客户端证书
if openssl verify -CAfile ca.pem client-cert.pem > /dev/null 2>&1; then
log_success "客户端证书验证通过"
else
log_error "客户端证书验证失败"
exit 1
fi
}
# 显示证书信息
show_certificate_info() {
log_info "证书信息摘要:"
cd "$TLS_DIR"
echo ""
echo "📁 证书文件位置: $TLS_DIR"
echo "📋 生成的文件:"
ls -la *.pem | while read -r line; do
echo " $line"
done
echo ""
echo "🔒 证书有效期: $CERT_VALIDITY_DAYS 天"
echo "📅 CA证书到期时间:"
openssl x509 -in ca.pem -noout -enddate | sed 's/notAfter=/ /'
echo ""
log_warning "注意: 这些是自签名证书,仅适用于个人开发环境"
log_info "生产环境请使用由受信任CA签发的证书"
}
# 主函数
main() {
echo "🔐 MemOS TLS证书生成脚本"
echo "========================"
# 创建TLS目录
mkdir -p "$TLS_DIR"
# 检查是否已存在证书
if [ -f "$TLS_DIR/ca.pem" ]; then
log_warning "检测到已存在的证书文件"
read -p "是否要重新生成?(y/N): " choice
if [[ ! "$choice" =~ ^[Yy]$ ]]; then
log_info "保持现有证书"
show_certificate_info
exit 0
fi
log_info "清理现有证书文件..."
rm -f "$TLS_DIR"/*.pem "$TLS_DIR"/*.srl
fi
check_openssl
generate_ca
generate_server_cert
generate_client_cert
set_permissions
verify_certificates
show_certificate_info
echo ""
log_success "TLS证书生成完成!"
log_info "下一步: 更新docker-compose.yml配置以启用TLS"
}
# 运行主函数
main "$@"