Repository navigation
Install and Deploy
中文 · English
AutoOps 堡垒机是「Python Flask 后端 + ant-design-pro 前端」,数据全部落在本地文件里(默认 SQLite),不需要先准备 MySQL/PostgreSQL。Windows 上可以完整开发调试,Linux 上按下面第五节做生产部署。
| 组件 | 版本 | 什么时候需要 |
|---|---|---|
| Python | ≥ 3.11(开发机实测 3.13) | 一直需要,后端与所有工具脚本都跑在它上面 |
| Node.js | 根 README.md 写 ≥ 20;前端 ant-design-pro/package.json 的 engines.node 声明 ≥ 22(开发机实测 v24.16.0) |
只在构建/开发前端时需要;后端单跑不需要 Node |
| npm | 随 Node 附带 | 同上 |
| 操作系统 | 目标平台 Linux;开发环境 Windows 亦可直接运行 | SSH 相关能力基于 paramiko 纯协议实现,不依赖系统 ssh 命令
|
两处 Node 版本口径并不一致。保险做法是直接用 Node 22 或更高,两个要求同时满足。
生产环境建议(Linux 生产部署一节的前提):Ubuntu 22.04+ / Debian 12+ / RHEL 9+,放行 5000(Web 与 API)与 2222(SSH 网关)两个端口。
开三个终端窗口,依次是「后端」「演示目标机」「前端」。
# 终端 1:后端(API + SSH 网关 + 网页终端)
cd bastion-backend
python -m pip install -r requirements.txt
python run.py
# API http://127.0.0.1:5000 (健康检查 GET /api/health)
# SSH 网关 0.0.0.0:2222
# 默认管理员 admin / admin123(首次登录强制改口令)
# 终端 2:演示目标机(一台真 SSH 协议栈的假 Linux,用来试手)
cd bastion-backend
python tools/demo_ssh_target.py
# 监听 127.0.0.1:2200,账号 root / s3cret
# 终端 3:前端
cd ant-design-pro
npm install
npm run dev
# http://localhost:8000后端起来后先自检:浏览器打开 http://127.0.0.1:5000/api/health,能看到 {"success": true, ...} 就说明 API 活着。
当前端跑在 http://localhost:8000 时,它把 /api/ 与 /socket.io/(含 WebSocket)都代理到 http://127.0.0.1:5000,所以后端必须先起来,否则登录会 502。后端不在本机时用 BASTION_API 覆盖代理目标:
set BASTION_API=http://192.168.1.10:5000 # Windows
export BASTION_API=http://192.168.1.10:5000 # Linux / macOS
npm run dev请用 npm run dev(等价于 MOCK=none);模板自带的 npm start 会开 Pro mock 服务,会把 /api/login/account 这类请求截走。
| 项目 | 值 |
|---|---|
| 默认管理员 |
admin / admin123
|
| 首次登录 | 强制改口令,改完才能进系统;SSH 网关同样强制 |
| 忘记口令 |
python run.py --reset-admin,按提示输入新口令 |
上线前必须改掉初始口令,并给运维人员建独立角色,日常不要拿超管账号干活。
后端的数据目录默认是 bastion-backend/instance/(可用 BASTION_INSTANCE_DIR 改),首次启动自动生成:
| 文件 | 说明 |
|---|---|
bastion.db |
SQLite 数据库 |
secret.key |
Flask SECRET_KEY 与 JWT_SECRET_KEY(丢失会导致所有 JWT 失效) |
fernet.key |
资产口令加密主密钥(丢失则已存资产口令无法解密) |
gateway_host_rsa.key |
SSH 网关主机私钥(RSA 2048) |
transcripts/<sid>.log |
每会话录像(JSON Lines,含命令、输出、放行/拦截) |
这个目录已在 .gitignore 里,但它是你的全部家底:备份就备份 instance/ 与 .env 里的三把密钥。请给它设 600 权限。
sudo useradd -r -m -d /opt/autoops -s /bin/bash bastion
sudo -iu bastion git clone git@github.com:sywdn-001/AutoOps.git /opt/autoops/appcd /opt/autoops/app/bastion-backend
python3 -m venv .venv
.venv/bin/python -m pip install -U pip
.venv/bin/python -m pip install -r requirements.txtcd /opt/autoops/app/ant-design-pro
npm ci
npm run build # 产物 dist/,后端启动时自动挂载产物由后端同端口直服,不需要额外装 Web 服务器。反过来说:没有 dist/ 时后端只会提供 API,前端页面是空的——所以顺序一定是「先 build,再起后端」。
| 变量 | 默认值 | 说明 |
|---|---|---|
BASTION_HOST / BASTION_PORT
|
0.0.0.0 / 5000
|
Web 与 API 监听地址、端口 |
BASTION_GATEWAY_HOST / BASTION_GATEWAY_PORT
|
0.0.0.0 / 2222
|
SSH 网关监听地址、端口(BASTION_GATEWAY_ENABLED=0 关掉整条网关) |
BASTION_ADMIN_USERNAME / BASTION_ADMIN_PASSWORD
|
admin / admin123
|
首次启动创建的管理员,上线前必须改(登录后也会强制改密) |
BASTION_INSTANCE_DIR |
bastion-backend/instance |
数据目录:SQLite 库、三把密钥、会话录像 |
BASTION_DB_URI |
sqlite:///<INSTANCE_DIR>/bastion.db |
换 PostgreSQL 等外部库时改这里(需自备驱动) |
BASTION_SECRET_KEY / BASTION_JWT_SECRET / BASTION_FERNET_KEY
|
首次启动随机生成并落盘 | 会话签名、JWT、资产口令加密;多实例部署必须显式给同一组值 |
BASTION_SERVE_FRONTEND / BASTION_FRONTEND_DIST
|
1 / 自动找 ant-design-pro/dist
|
关掉前端直服,或指定别处的构建产物 |
BASTION_TOKEN_HOURS |
12 |
登录令牌有效期(小时) |
BASTION_LOGIN_MAX_FAILURES / BASTION_LOGIN_LOCK_MINUTES
|
5 / 15
|
连续登录失败锁定策略 |
BASTION_SESSION_IDLE_TIMEOUT |
1800 |
会话空闲上限(秒) |
BASTION_COMMAND_TIMEOUT / BASTION_MAX_OUTPUT_BYTES
|
60 / 262144
|
单条命令超时与输出截断 |
BASTION_GATEWAY_MAX_SESSIONS |
5 |
单用户网关并发会话上限 |
DEEPSEEK_API_KEY / DEEPSEEK_BASE_URL / AI_MODEL
|
空 / https://api.deepseek.com / deepseek-flash
|
AI 运维助手模型凭据(AI_ENABLED=0 整体关闭) |
BASTION_CORS_ORIGINS |
* |
前后端分离部署时收紧到前端域名 |
变量名与默认值取自 bastion-backend/app/config.py;bastion-backend/.env.example 是 AI 相关键的模板。
/etc/systemd/system/autoops.service:
[Unit]
Description=AutoOps Bastion
After=network-online.target
[Service]
User=bastion
WorkingDirectory=/opt/autoops/app/bastion-backend
EnvironmentFile=/etc/autoops.env
ExecStart=/opt/autoops/app/bastion-backend/.venv/bin/python run.py --host 0.0.0.0 --port 5000 --gateway-port 2222
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now autoops
sudo systemctl status autoops
curl -fsS http://127.0.0.1:5000/api/health # {"success":true,...}- 浏览器开
http://<服务器IP>:5000,用初始管理员登录 → 立刻改密(登录后强制)。 - 「系统设置 → 系统参数」按需收紧并发数、空闲超时、命令超时;「身份与权限」给运维建角色与授权,不要日常拿超管账号干活。
- 备份
$BASTION_INSTANCE_DIR(SQLite + 三把密钥 + 录像)与.env里的三把密钥。密钥丢了,已存的资产口令就解不开。
Nginx 反代到 127.0.0.1:5000,必须透传 WebSocket,网页终端靠它:
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 3600s; # 网页终端是长连接
}SSH 网关不是 HTTP,用户直接 ssh -p 2222 <账号>@<服务器IP>;想走标准 22 端口,就用防火墙/端口转发把 22 转给 2222。
| 参数 | 默认 | 说明 |
|---|---|---|
--host / --port
|
0.0.0.0 / 5000
|
Web 与 API 监听地址、端口 |
--gateway-host / --gateway-port
|
0.0.0.0 / 2222
|
SSH 网关监听地址、端口 |
--no-gateway |
关 | 本次不启动 SSH 网关 |
--debug / --log-level
|
关 / info
|
调试模式与日志级别 |
--reset-admin |
— | 忘记管理员口令时重设(按提示输入) |
cd /opt/autoops/app
git pull
cd bastion-backend && .venv/bin/python -m pip install -r requirements.txt
cd ../ant-design-pro && npm ci && npm run build
sudo systemctl restart autoops数据库表结构由 ensure_schema() 在启动时只加不减地对齐,所以不写迁移脚本也不会丢数据。
| 现象 | 原因 / 处理 |
|---|---|
| 浏览器打开只有 API,没有界面 | 没先 npm run build(或 BASTION_SERVE_FRONTEND=0、BASTION_FRONTEND_DIST 指错);补 build 后重启后端 |
| 改了代码但行为没变 | 后端不会热加载,sudo systemctl restart autoops;改 gateway_host/gateway_port 尤其要重启 |
| 网页终端一直「连接中」 | 反代没透传 WebSocket,/socket.io/ 必须带 Upgrade、Connection 头 |
| 登录页报 502 / 接口 404 | 后端没起或端口不对;前端代理默认指向 127.0.0.1:5000
|
| 换了三把密钥后老资产连不上 | 密钥换了,已存的资产口令就解不开;要么恢复原密钥,要么重录账号口令 |
| 多实例部署行为不一致 | 多实例必须显式给同一组 BASTION_SECRET_KEY / BASTION_JWT_SECRET / BASTION_FERNET_KEY
|
| 换 Key / 改 AI 配置不生效 | 配置文件改动要重启进程 |
本页的命令、变量与默认值全部抄自
README.md与bastion-backend/README.md。以 README 与bastion-backend/app/config.py为准。
AutoOps is a Flask backend plus an ant-design-pro frontend, and it keeps all data in local files (SQLite by default). You do not need MySQL or PostgreSQL to get started. You can develop and debug the whole stack on Windows; follow section 5 for a production deployment on Linux.
| Component | Version | When you need it |
|---|---|---|
| Python | ≥ 3.11 (3.13 on the development machine) | Always — the backend and every tool script run on it |
| Node.js | The root README.md says ≥ 20; engines.node in ant-design-pro/package.json declares ≥ 22 (v24.16.0 tested) |
Only to develop or build the frontend; the backend alone does not need Node |
| npm | Ships with Node | Same as above |
| OS | Target platform is Linux; Windows works for development | The SSH features are built on paramiko's protocol implementation and do not shell out to the system ssh command |
The two Node figures disagree. Use Node 22 or newer and you satisfy both.
Suggested production platform (the premise of section 5): Ubuntu 22.04+ / Debian 12+ / RHEL 9+, with 5000 (web and API) and 2222 (SSH gateway) allowed through the firewall.
Open three terminals — backend, demo target, frontend.
# Terminal 1: backend (API + SSH gateway + web terminal)
cd bastion-backend
python -m pip install -r requirements.txt
python run.py
# API http://127.0.0.1:5000 (health check: GET /api/health)
# SSH gateway 0.0.0.0:2222
# default admin admin / admin123 (a password change is forced on first login)
# Terminal 2: demo target (a fake Linux with a real SSH stack, for practice)
cd bastion-backend
python tools/demo_ssh_target.py
# listens on 127.0.0.1:2200, account root / s3cret
# Terminal 3: frontend
cd ant-design-pro
npm install
npm run dev
# http://localhost:8000Verify the backend first: open http://127.0.0.1:5000/api/health and look for {"success": true, ...}.
While the frontend runs on http://localhost:8000, it proxies /api/ and /socket.io/ (WebSocket included) to http://127.0.0.1:5000, so start the backend first or login returns 502. Point the proxy elsewhere with BASTION_API:
set BASTION_API=http://192.168.1.10:5000 # Windows
export BASTION_API=http://192.168.1.10:5000 # Linux / macOS
npm run devUse npm run dev (it sets MOCK=none). The template's npm start enables Pro's mock server, which intercepts /api/login/account and friends.
| Item | Value |
|---|---|
| Default admin |
admin / admin123
|
| First login | You are forced to change the password, in the web UI and in the SSH gateway alike |
| Forgotten password |
python run.py --reset-admin and follow the prompt |
Change the initial password before going live, create separate roles for your operators, and do not use the super-admin account for daily work.
The backend data directory defaults to bastion-backend/instance/ (override with BASTION_INSTANCE_DIR) and is created on first start:
| File | Purpose |
|---|---|
bastion.db |
SQLite database |
secret.key |
Flask SECRET_KEY and JWT_SECRET_KEY (losing it invalidates every JWT) |
fernet.key |
master key for asset-password encryption (losing it makes stored asset passwords undecryptable) |
gateway_host_rsa.key |
SSH gateway host private key (RSA 2048) |
transcripts/<sid>.log |
per-session transcript (JSON Lines: commands, output, allow/deny) |
This directory is in .gitignore, but it is your entire estate: back up instance/ plus the three keys in .env, and set 600 permissions on it.
sudo useradd -r -m -d /opt/autoops -s /bin/bash bastion
sudo -iu bastion git clone git@github.com:sywdn-001/AutoOps.git /opt/autoops/appcd /opt/autoops/app/bastion-backend
python3 -m venv .venv
.venv/bin/python -m pip install -U pip
.venv/bin/python -m pip install -r requirements.txtcd /opt/autoops/app/ant-design-pro
npm ci
npm run build # produces dist/, mounted automatically when the backend startsThe backend serves that build on its own port, so no extra web server is required. Conversely, without dist/ the backend serves only the API and the UI is blank — build before you start.
| Variable | Default | Meaning |
|---|---|---|
BASTION_HOST / BASTION_PORT
|
0.0.0.0 / 5000
|
web and API listen address and port |
BASTION_GATEWAY_HOST / BASTION_GATEWAY_PORT
|
0.0.0.0 / 2222
|
SSH gateway listen address and port (BASTION_GATEWAY_ENABLED=0 disables the gateway) |
BASTION_ADMIN_USERNAME / BASTION_ADMIN_PASSWORD
|
admin / admin123
|
admin created on first start; change it before going live (the UI forces a change anyway) |
BASTION_INSTANCE_DIR |
bastion-backend/instance |
data directory: SQLite database, the three keys, session recordings |
BASTION_DB_URI |
sqlite:///<INSTANCE_DIR>/bastion.db |
switch to PostgreSQL and friends here (bring your own driver) |
BASTION_SECRET_KEY / BASTION_JWT_SECRET / BASTION_FERNET_KEY
|
random and persisted on first start | session signing, JWT, asset-password encryption; multi-instance deployments must set one identical set |
BASTION_SERVE_FRONTEND / BASTION_FRONTEND_DIST
|
1 / auto-detect ant-design-pro/dist
|
turn off frontend serving, or point at a build elsewhere |
BASTION_TOKEN_HOURS |
12 |
login token lifetime (hours) |
BASTION_LOGIN_MAX_FAILURES / BASTION_LOGIN_LOCK_MINUTES
|
5 / 15
|
consecutive-failure lockout policy |
BASTION_SESSION_IDLE_TIMEOUT |
1800 |
session idle cap (seconds) |
BASTION_COMMAND_TIMEOUT / BASTION_MAX_OUTPUT_BYTES
|
60 / 262144
|
per-command timeout and output truncation |
BASTION_GATEWAY_MAX_SESSIONS |
5 |
per-user concurrent gateway sessions |
DEEPSEEK_API_KEY / DEEPSEEK_BASE_URL / AI_MODEL
|
empty / https://api.deepseek.com / deepseek-flash
|
AI assistant model credential (AI_ENABLED=0 turns it off entirely) |
BASTION_CORS_ORIGINS |
* |
tighten to your frontend origin when you split frontend and backend |
Names and defaults come from bastion-backend/app/config.py; bastion-backend/.env.example templates the AI keys.
/etc/systemd/system/autoops.service:
[Unit]
Description=AutoOps Bastion
After=network-online.target
[Service]
User=bastion
WorkingDirectory=/opt/autoops/app/bastion-backend
EnvironmentFile=/etc/autoops.env
ExecStart=/opt/autoops/app/bastion-backend/.venv/bin/python run.py --host 0.0.0.0 --port 5000 --gateway-port 2222
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now autoops
sudo systemctl status autoops
curl -fsS http://127.0.0.1:5000/api/health # {"success":true,...}- Open
http://<server-ip>:5000, log in as the initial admin, and change the password immediately (it is forced). - Tighten concurrency, idle timeout and command timeout under System settings → System parameters, and create roles and grants for your operators instead of using the super-admin account daily.
- Back up
$BASTION_INSTANCE_DIR(SQLite + the three keys + recordings) and the three keys in.env. If a key is lost, stored asset passwords cannot be decrypted.
Proxy Nginx to 127.0.0.1:5000 and pass WebSocket through — the web terminal depends on it:
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 3600s; # the web terminal is a long-lived connection
}The SSH gateway is not HTTP: users run ssh -p 2222 <account>@<server-ip>. To use port 22, forward 22 to 2222 at the firewall.
| Option | Default | Meaning |
|---|---|---|
--host / --port
|
0.0.0.0 / 5000
|
web and API listen address and port |
--gateway-host / --gateway-port
|
0.0.0.0 / 2222
|
SSH gateway listen address and port |
--no-gateway |
off | do not start the SSH gateway this run |
--debug / --log-level
|
off / info
|
debug mode and log level |
--reset-admin |
— | reset the admin password (follow the prompt) |
cd /opt/autoops/app
git pull
cd bastion-backend && .venv/bin/python -m pip install -r requirements.txt
cd ../ant-design-pro && npm ci && npm run build
sudo systemctl restart autoopsensure_schema() aligns the database schema on startup with additive changes only (including backfilling protocol endpoints for the multi-protocol host model), so an upgrade without a migration script does not lose data.
| Symptom | Cause / fix |
|---|---|
| The browser shows the API but no UI | You never ran npm run build (or set BASTION_SERVE_FRONTEND=0 / a wrong BASTION_FRONTEND_DIST); build and restart |
| Code changes have no effect | The backend does not hot reload: sudo systemctl restart autoops (especially after changing gateway_host/gateway_port) |
| The web terminal stays at "connecting" | The reverse proxy drops WebSocket: /socket.io/ needs the Upgrade and Connection headers |
| Login returns 502 / the API 404s | The backend is not running or is on another port; the dev proxy targets 127.0.0.1:5000
|
| Assets fail after replacing the three keys | New keys cannot decrypt old asset passwords; restore the old keys or re-enter the credentials |
| Multiple instances behave differently | Set one identical BASTION_SECRET_KEY / BASTION_JWT_SECRET / BASTION_FERNET_KEY for every instance |
| A new API key or AI setting is ignored | Restart the process after editing the config |
Every command, variable and default on this page is copied from
README.mdandbastion-backend/README.md. Treat README andbastion-backend/app/config.pyas authoritative.
相关页面 / Related pages: Quick-Start · Settings · Home
很高兴认识你,陌生人! 我是一名初二学生,在中国新疆读初中。英语和写的代码都还在慢慢练,这份手册也还在补,请大家多多谅解,也欢迎直接指正。
Nice to meet you, stranger! I'm an eighth-grade student in Xinjiang, China. My English and my code are still a work in progress, and so is this manual — please bear with me (and tell me if you can).
AutoOps 堡垒机 · 使用手册
起步
资产与权限
干活
查账与维护
AutoOps Bastion · Manual
Getting started
Assets and permissions
Work
Audit and upkeep