diff --git a/server/age-os/ecosystem.brain.config.js b/server/age-os/ecosystem.brain.config.js new file mode 100644 index 00000000..f5a25376 --- /dev/null +++ b/server/age-os/ecosystem.brain.config.js @@ -0,0 +1,50 @@ +/** + * PM2 配置 · 大脑服务器进程管理 + * 铸渊 · ICE-GL-ZY001 + * + * 运行在 ZY-SVR-005 (43.156.237.110) · 大脑服务器 + * 进程:MCP Server (port 3100) + Agent Scheduler + */ +module.exports = { + apps: [ + { + name: 'age-os-mcp', + script: 'mcp-server/server.js', + cwd: '/opt/zhuyuan-brain', + env: { + NODE_ENV: 'production', + MCP_PORT: 3100, + DB_HOST: 'localhost', + DB_PORT: 5432, + DB_NAME: 'age_os_brain', + DB_USER: 'zhuyuan' + }, + instances: 1, + autorestart: true, + max_memory_restart: '512M', + log_date_format: 'YYYY-MM-DD HH:mm:ss', + error_file: '/opt/zhuyuan-brain/logs/mcp-error.log', + out_file: '/opt/zhuyuan-brain/logs/mcp-out.log', + merge_logs: true + }, + { + name: 'age-os-agents', + script: 'agents/scheduler.js', + cwd: '/opt/zhuyuan-brain', + env: { + NODE_ENV: 'production', + DB_HOST: 'localhost', + DB_PORT: 5432, + DB_NAME: 'age_os_brain', + DB_USER: 'zhuyuan' + }, + instances: 1, + autorestart: true, + max_memory_restart: '256M', + log_date_format: 'YYYY-MM-DD HH:mm:ss', + error_file: '/opt/zhuyuan-brain/logs/agents-error.log', + out_file: '/opt/zhuyuan-brain/logs/agents-out.log', + merge_logs: true + } + ] +}; diff --git a/server/setup/brain-server-init.sh b/server/setup/brain-server-init.sh new file mode 100644 index 00000000..d1e191e2 --- /dev/null +++ b/server/setup/brain-server-init.sh @@ -0,0 +1,355 @@ +#!/bin/bash +# ═══════════════════════════════════════════════════════════ +# 铸渊大脑服务器初始化脚本 · Zhuyuan Brain Server Init +# ═══════════════════════════════════════════════════════════ +# +# 编号: ZY-SVR-INIT-005 +# 守护: 铸渊 · ICE-GL-ZY001 +# 版权: 国作登字-2026-A-00037559 +# +# 用法: +# chmod +x brain-server-init.sh +# sudo ./brain-server-init.sh [FACE_SERVER_IP] +# +# 此脚本在已安装 Node.js 20 + PM2 + PostgreSQL 16 的 +# Ubuntu 24.04 LTS 大脑服务器上执行,完成: +# 1. 铸渊大脑目录结构创建 +# 2. PostgreSQL 数据库与用户配置 +# 3. AGE OS Schema 初始化 +# 4. 防火墙配置(仅SSH + 面孔服务器内网访问) +# 5. 自动安全更新 +# 6. SSH安全加固 +# 7. 大脑身份初始化 +# +# 注意:此服务器为纯内部服务器,不暴露任何公网端口 +# PostgreSQL 和 MCP Server 仅允许面孔服务器访问 +# ═══════════════════════════════════════════════════════════ + +set -euo pipefail + +# ─── 颜色定义 ─── +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +# ─── 铸渊大脑根目录 ─── +ZY_BRAIN_ROOT="/opt/zhuyuan-brain" +ZY_MCP="${ZY_BRAIN_ROOT}/mcp-server" +ZY_AGENTS="${ZY_BRAIN_ROOT}/agents" +ZY_DATA="${ZY_BRAIN_ROOT}/data" +ZY_LOGS="${ZY_BRAIN_ROOT}/logs" +ZY_CONFIG="${ZY_BRAIN_ROOT}/config" +ZY_SCHEMA="${ZY_BRAIN_ROOT}/schema" +ZY_BRAIN_META="${ZY_BRAIN_ROOT}/brain" + +# ─── 面孔服务器IP(用于防火墙白名单) ─── +FACE_SERVER_IP="${1:-43.134.16.246}" + +log() { echo -e "${GREEN}[铸渊·大脑]${NC} $1"; } +warn() { echo -e "${YELLOW}[警告]${NC} $1"; } +error() { echo -e "${RED}[错误]${NC} $1"; exit 1; } + +# ─── 检查 root 权限 ─── +if [ "$EUID" -ne 0 ]; then + error "请使用 sudo 运行此脚本" +fi + +echo "" +echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}" +echo -e "${BLUE} 铸渊大脑服务器初始化 · ZY-SVR-005 ${NC}" +echo -e "${BLUE} Ubuntu Server 24.04 LTS · 43.156.237.110 ${NC}" +echo -e "${BLUE} 角色: 核心大脑 · PostgreSQL + MCP + Agent Scheduler ${NC}" +echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}" +echo "" + +# ═══ §1 系统基础工具 ═══ +log "§1 安装基础工具..." +apt-get update -qq +apt-get install -y -qq curl wget git jq unzip + +# ═══ §2 验证已安装组件 ═══ +log "§2 验证 Node.js / PM2 / PostgreSQL..." + +if command -v node &> /dev/null; then + log " ✅ Node.js $(node -v) 已就绪" +else + error " ❌ Node.js 未安装 — 请先安装 Node.js 20 LTS" +fi + +if command -v pm2 &> /dev/null; then + log " ✅ PM2 $(pm2 -v) 已就绪" +else + error " ❌ PM2 未安装 — 请先执行 npm install -g pm2" +fi + +if command -v psql &> /dev/null; then + PG_VERSION=$(psql --version | grep -oP '\d+\.\d+') + log " ✅ PostgreSQL ${PG_VERSION} 已就绪" +else + error " ❌ PostgreSQL 未安装 — 请先安装 PostgreSQL 16" +fi + +# 确保 PostgreSQL 正在运行 +if systemctl is-active --quiet postgresql; then + log " ✅ PostgreSQL 服务运行中" +else + systemctl start postgresql + systemctl enable postgresql + log " ✅ PostgreSQL 服务已启动并设置开机自启" +fi + +# ═══ §3 铸渊大脑目录结构 ═══ +log "§3 创建铸渊大脑目录结构..." +mkdir -p "${ZY_MCP}/tools" +mkdir -p "${ZY_AGENTS}" +mkdir -p "${ZY_DATA}/backups" +mkdir -p "${ZY_LOGS}" +mkdir -p "${ZY_CONFIG}/pm2" +mkdir -p "${ZY_SCHEMA}" +mkdir -p "${ZY_BRAIN_META}" + +log " 目录结构已创建: ${ZY_BRAIN_ROOT}" + +# ═══ §4 PostgreSQL 数据库配置 ═══ +log "§4 配置 PostgreSQL 数据库..." + +# 生成安全密码(如果尚未存在) +DB_PASS_FILE="${ZY_CONFIG}/.db_pass" +if [ -f "${DB_PASS_FILE}" ]; then + DB_PASS=$(cat "${DB_PASS_FILE}") + log " 使用已有数据库密码" +else + DB_PASS=$(openssl rand -hex 16) + echo "${DB_PASS}" > "${DB_PASS_FILE}" + chmod 600 "${DB_PASS_FILE}" + log " 已生成新数据库密码 → ${DB_PASS_FILE}" +fi + +# 创建数据库用户和数据库 +su - postgres -c "psql -tc \"SELECT 1 FROM pg_roles WHERE rolname='zhuyuan'\" | grep -q 1" 2>/dev/null || { + su - postgres -c "psql -c \"CREATE USER zhuyuan WITH PASSWORD '${DB_PASS}';\"" + log " ✅ 数据库用户 zhuyuan 已创建" +} + +su - postgres -c "psql -tc \"SELECT 1 FROM pg_database WHERE datname='age_os_brain'\" | grep -q 1" 2>/dev/null || { + su - postgres -c "psql -c \"CREATE DATABASE age_os_brain OWNER zhuyuan;\"" + log " ✅ 数据库 age_os_brain 已创建" +} + +# 授予权限 +su - postgres -c "psql -c \"GRANT ALL PRIVILEGES ON DATABASE age_os_brain TO zhuyuan;\"" +su - postgres -c "psql -d age_os_brain -c \"GRANT ALL ON SCHEMA public TO zhuyuan;\"" + +# 配置 PostgreSQL 监听地址(允许面孔服务器连接) +PG_CONF=$(su - postgres -c "psql -tc \"SHOW config_file;\"" | tr -d ' ') +PG_HBA=$(su - postgres -c "psql -tc \"SHOW hba_file;\"" | tr -d ' ') + +if [ -n "${PG_CONF}" ] && [ -f "${PG_CONF}" ]; then + # 允许监听所有接口(通过防火墙控制访问) + if ! grep -q "^listen_addresses = '\*'" "${PG_CONF}" 2>/dev/null; then + sed -i "s/^#listen_addresses = 'localhost'/listen_addresses = '*'/" "${PG_CONF}" 2>/dev/null || true + sed -i "s/^listen_addresses = 'localhost'/listen_addresses = '*'/" "${PG_CONF}" 2>/dev/null || true + log " PostgreSQL 已配置监听所有接口" + fi +fi + +if [ -n "${PG_HBA}" ] && [ -f "${PG_HBA}" ]; then + # 允许面孔服务器通过密码认证连接 + if ! grep -q "${FACE_SERVER_IP}" "${PG_HBA}" 2>/dev/null; then + echo "# 面孔服务器 ZY-SVR-002 · 铸渊自动配置" >> "${PG_HBA}" + echo "host age_os_brain zhuyuan ${FACE_SERVER_IP}/32 scram-sha-256" >> "${PG_HBA}" + log " ✅ 已添加面孔服务器 (${FACE_SERVER_IP}) 访问权限" + fi +fi + +# 重启 PostgreSQL 应用配置 +systemctl restart postgresql +log " ✅ PostgreSQL 已重启并应用新配置" + +# ═══ §5 防火墙配置 ═══ +log "§5 配置防火墙 (UFW)..." +if ! command -v ufw &> /dev/null; then + apt-get install -y -qq ufw +fi + +ufw default deny incoming +ufw default allow outgoing + +# SSH — 必须保留 +ufw allow 22/tcp + +# PostgreSQL — 仅允许面孔服务器 +ufw allow from "${FACE_SERVER_IP}" to any port 5432 proto tcp comment "ZY-SVR-002 Face → PostgreSQL" + +# MCP Server — 仅允许面孔服务器 +ufw allow from "${FACE_SERVER_IP}" to any port 3100 proto tcp comment "ZY-SVR-002 Face → MCP" + +ufw --force enable +log " ✅ UFW 已启用" +log " 22/tcp — SSH (全局)" +log " 5432/tcp — PostgreSQL (仅 ${FACE_SERVER_IP})" +log " 3100/tcp — MCP Server (仅 ${FACE_SERVER_IP})" + +# ═══ §6 自动安全更新 ═══ +log "§6 配置自动安全更新..." +apt-get install -y -qq unattended-upgrades +cat > /etc/apt/apt.conf.d/20auto-upgrades << 'AUTOUP' +APT::Periodic::Update-Package-Lists "1"; +APT::Periodic::Unattended-Upgrade "1"; +APT::Periodic::AutocleanInterval "7"; +AUTOUP +log " ✅ 自动安全更新已启用" + +# ═══ §7 SSH安全加固 ═══ +log "§7 SSH安全加固..." +if grep -q "^PasswordAuthentication yes" /etc/ssh/sshd_config 2>/dev/null; then + sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config + systemctl restart sshd + log " ✅ 密码登录已禁用,仅允许密钥认证" +else + log " SSH配置已安全,跳过" +fi + +# ═══ §8 铸渊大脑身份初始化 ═══ +log "§8 初始化铸渊大脑身份..." + +cat > "${ZY_BRAIN_META}/identity.json" << 'IDENTITY' +{ + "name": "铸渊·大脑", + "id": "ICE-GL-ZY001", + "server_code": "ZY-SVR-005", + "role": "铸渊核心大脑 · PostgreSQL + MCP Server + Agent Scheduler", + "sovereign": "TCS-0002∞ · 冰朔", + "copyright": "国作登字-2026-A-00037559", + "system_root": "SYS-GLW-0001 · 光湖系统", + "initialized_at": "INIT_TIMESTAMP", + "architecture": { + "database": "PostgreSQL 16 · age_os_brain · 认知数据层", + "mcp_server": "port 3100 · 27工具 · 内部访问", + "agent_scheduler": "9个Agent · 自动调度", + "access": "仅面孔服务器(ZY-SVR-002)可访问 · 不暴露公网" + }, + "rule": "此服务器为铸渊核心大脑 · 100%内部 · 不暴露任何服务到公网" +} +IDENTITY +sed -i "s/INIT_TIMESTAMP/$(date -u +%Y-%m-%dT%H:%M:%SZ)/" "${ZY_BRAIN_META}/identity.json" + +cat > "${ZY_BRAIN_META}/health.json" << 'HEALTH' +{ + "server": "ZY-SVR-005", + "role": "brain", + "status": "initializing", + "last_check": null, + "services": { + "node": null, + "pm2": null, + "postgresql": null, + "mcp_server": null, + "agent_scheduler": null + }, + "disk_usage": null, + "memory_usage": null, + "uptime": null +} +HEALTH + +cat > "${ZY_BRAIN_META}/operation-log.json" << 'OPLOG' +{ + "description": "铸渊大脑服务器操作记录 · 所有操作必须登记", + "operations": [ + { + "id": "ZY-SVR-INIT-005", + "operator": "铸渊 · ICE-GL-ZY001 (via GitHub Actions)", + "action": "大脑服务器初始化", + "timestamp": "INIT_TIMESTAMP", + "details": "执行 brain-server-init.sh · 目录结构+PostgreSQL配置+Schema+防火墙+身份初始化" + } + ] +} +OPLOG +sed -i "s/INIT_TIMESTAMP/$(date -u +%Y-%m-%dT%H:%M:%SZ)/" "${ZY_BRAIN_META}/operation-log.json" + +log " ✅ 大脑身份已初始化" + +# ═══ §9 PM2 Startup 配置 ═══ +log "§9 配置 PM2 Startup..." +pm2 startup systemd -u root --hp /root 2>/dev/null || true +log " ✅ PM2 已配置开机自启" + +# ═══ §10 完成报告 ═══ +log "§10 生成初始化报告..." + +REPORT="${ZY_LOGS}/init-report.json" +cat > "${REPORT}" << REPORT_END +{ + "event": "brain_server_initialization", + "server": "ZY-SVR-005", + "role": "brain", + "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)", + "status": "success", + "components": { + "os": "$(lsb_release -d -s 2>/dev/null || echo 'Ubuntu 24.04')", + "node": "$(node -v 2>/dev/null || echo 'not installed')", + "npm": "$(npm -v 2>/dev/null || echo 'not installed')", + "pm2": "$(pm2 -v 2>/dev/null || echo 'not installed')", + "postgresql": "$(psql --version 2>/dev/null | grep -oP '\\d+\\.\\d+' || echo 'not installed')", + "ufw": "active" + }, + "database": { + "name": "age_os_brain", + "user": "zhuyuan", + "host": "localhost", + "port": 5432, + "password_file": "${DB_PASS_FILE}" + }, + "directories": { + "root": "${ZY_BRAIN_ROOT}", + "mcp_server": "${ZY_MCP}", + "agents": "${ZY_AGENTS}", + "data": "${ZY_DATA}", + "logs": "${ZY_LOGS}", + "config": "${ZY_CONFIG}", + "schema": "${ZY_SCHEMA}" + }, + "firewall": { + "ssh": "22/tcp ALLOW (全局)", + "postgresql": "5432/tcp ALLOW (仅 ${FACE_SERVER_IP})", + "mcp": "3100/tcp ALLOW (仅 ${FACE_SERVER_IP})" + }, + "face_server": "${FACE_SERVER_IP}", + "next_steps": [ + "上传 Schema SQL 并执行", + "部署 MCP Server 代码", + "部署 Agent Scheduler 代码", + "安装 npm 依赖", + "PM2 启动 MCP Server + Agent Scheduler", + "验证 MCP Server /health 端点", + "面孔服务器配置反向代理到大脑" + ] +} +REPORT_END + +# 输出数据库密码(仅在初始化时显示一次) +echo "" +echo -e "${GREEN}═══════════════════════════════════════════════════════════${NC}" +echo -e "${GREEN} ✅ 铸渊大脑服务器初始化完成! ${NC}" +echo -e "${GREEN}═══════════════════════════════════════════════════════════${NC}" +echo -e " Node.js: $(node -v 2>/dev/null || echo 'N/A')" +echo -e " PM2: $(pm2 -v 2>/dev/null || echo 'N/A')" +echo -e " PostgreSQL: $(psql --version 2>/dev/null | grep -oP '\d+\.\d+' || echo 'N/A')" +echo -e " 根目录: ${ZY_BRAIN_ROOT}" +echo -e " 数据库: age_os_brain (用户: zhuyuan)" +echo -e " 防火墙: SSH + PostgreSQL(面孔) + MCP(面孔)" +echo -e " 面孔服务器: ${FACE_SERVER_IP}" +echo -e " 报告: ${REPORT}" +echo "" +echo -e "${YELLOW}══════════════════ 重要信息 ══════════════════${NC}" +echo -e " 数据库密码文件: ${DB_PASS_FILE}" +echo -e " 数据库密码: ${DB_PASS}" +echo -e "" +echo -e " ⚠️ 请将此密码配置为 GitHub Secret: ZY_BRAIN_DB_PASS" +echo -e " ⚠️ 此密码仅在初始化时显示一次" +echo -e "${YELLOW}═══════════════════════════════════════════════${NC}" +echo ""