Files
nginxserver/IMPLEMENTATION_PLAN.md
2026-07-16 13:03:11 +08:00

271 lines
8.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Nginx域名转发管理平台 - 实现方案文档
版本: 1.0 | 日期: 2026-06-09 | 状态: 已完成部署
---
## 一、项目概述
开发一个可视化管理平台,实现对 Nginx 反向代理规则的增删改查及 HTTPS 证书管理功能。
### 核心流程
```
用户 -> Vue.js前端(:3002) -> Spring Boot(:4002) -> Python API(10.1.1.160:5000) -> Nginx
|
v
MySQL(10.1.1.122:3306)
```
---
## 二、技术架构
| 层级 | 技术 | 版本 | 端口 | 部署位置 |
|------|------|------|------|----------|
| 前端 | Vue.js 3 + Element Plus | Vite 8 | 3002 | 独立部署 |
| 后端 | Spring Boot + Maven | 3.2.0 + JDK 17 | 4002 | 独立部署 |
| 数据库 | MySQL | 8.0.29 | 3306 | 10.1.1.122 |
| Nginx API | Python Flask + Gunicorn | Flask 2.0.3 | 5000 | 10.1.1.160 |
| 代理服务器 | Nginx | 1.14.1 | 80/443 | 10.1.1.160 |
### 关键设计决策
1. 三层架构 - 前端不直接调用 Python API通过 Spring Boot 中间层统一管理
2. 数据双写 - Python API 操作 Nginx 配置Spring Boot 同步写入 MySQL 作为持久化
3. 内部 CA - 内网域名无法使用 Let's Encrypt采用自建 CA 自动签发证书
4. 前后端直连 - 前端通过环境变量配置后端地址,不使用 Vite 代理
---
## 三、服务端点总览
### 3.1 Python API - 10.1.1.160:5000
| 方法 | 路径 | 功能 |
|------|------|------|
| GET | /api/nginx/health | 健康检查 |
| GET | /api/nginx/rules | 获取所有转发规则 |
| GET | /api/nginx/rules/<domain> | 获取单个规则 |
| POST | /api/nginx/rules | 新增转发规则 |
| PUT | /api/nginx/rules/<domain> | 修改转发规则 |
| DELETE | /api/nginx/rules/<domain> | 删除转发规则 |
| POST | /api/nginx/reload | 重载 Nginx 配置 |
### 3.2 Spring Boot - 端口 4002
| 方法 | 路径 | 功能 |
|------|------|------|
| GET | /api/rules | 获取规则列表MySQL |
| POST | /api/rules | 新增规则调Python -> 存MySQL -> 重载) |
| PUT | /api/rules/{id} | 修改规则 |
| DELETE | /api/rules/{id} | 删除规则 |
| POST | /api/rules/reload | 手动重载 Nginx |
| GET | /api/rules/status | Nginx 运行状态 |
### 3.3 Vue.js 前端 - 端口 3002
- 布局: 左侧深色菜单栏 + 顶部标题栏 + 内容区
- 菜单: Nginx转发管理
- 功能: 规则列表展示、新增/修改/删除弹窗、HTTPS 自动提示
- 环境切换: .env.development / .env.production 配置不同后端地址
---
## 四、Nginx 转发规则逻辑
### HTTP 规则
```
用户访问 http://test1.mokee.com
-> Nginx 80端口匹配 server_name test1.mokee.com
-> proxy_pass 转发到目标地址(如 http://10.1.1.11:8080
-> 透传 Host/X-Real-IP/X-Forwarded-For 头
```
### HTTPS 规则
```
用户访问 https://test1.mokee.com
-> Nginx 80端口返回 301 跳转到 https://
-> Nginx 443端口匹配 server_name使用 SSL 证书
-> proxy_pass 转发到目标地址
```
### 生成的 Nginx 配置
#### HTTP 转发
```nginx
server {
listen 80;
server_name test1.mokee.com;
location / {
proxy_pass http://10.1.1.11:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
#### HTTPS 转发
```nginx
# HTTP 自动跳转 HTTPS
server {
listen 80;
server_name test1.mokee.com;
return 301 https://$host$request_uri;
}
# HTTPS 转发
server {
listen 443 ssl;
server_name test1.mokee.com;
ssl_certificate /etc/nginx/ssl/test1.mokee.com.pem;
ssl_certificate_key /etc/nginx/ssl/test1.mokee.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://10.1.1.11:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
---
## 五、HTTPS 证书方案
### 5.1 内部自建 CA
- 首次启动 Python API 时自动生成根 CA
- CA 证书: /etc/nginx/ssl/ca/ca.crt有效期 10 年)
- CA 私钥: /etc/nginx/ssl/ca/ca.key权限 600
- 不占用 80/443/5000 端口
### 5.2 自动签发流程
```
选择 HTTPS -> SSLService.ensure_certificate(domain)
-> 检查 /etc/nginx/ssl/<domain>.pem 是否存在且未过期
-> 有效 -> 复用
-> 无效/不存在 -> 使用内部 CA 签发新证书有效期365天
```
### 5.3 客户端信任
内网用户浏览器需导入 ca.crt 为受信任的根证书颁发机构:
```bash
# 下载 CA 证书
scp root@10.1.1.160:/etc/nginx/ssl/ca/ca.crt .
```
---
## 六、数据库设计
### forwarding_rules 表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGINT PK | 主键 |
| domain | VARCHAR(255) UNIQUE | 域名 |
| protocol | VARCHAR(10) | http/https |
| target | VARCHAR(500) | 转发目标 |
| config_file | VARCHAR(500) | Nginx配置文件路径 |
| ssl_cert | VARCHAR(500) | SSL证书路径 |
| ssl_key | VARCHAR(500) | SSL私钥路径 |
| status | TINYINT | 0-已删除 1-正常 |
| created_at | DATETIME | 创建时间 |
| updated_at | DATETIME | 更新时间 |
### certificates 表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGINT PK | 主键 |
| domain | VARCHAR(255) UNIQUE | 域名 |
| cert_path | VARCHAR(500) | 证书文件路径 |
| key_path | VARCHAR(500) | 私钥文件路径 |
| issue_date | DATETIME | 签发日期 |
| expire_date | DATETIME | 过期日期 |
| status | VARCHAR(20) | active/expired/revoked |
| created_at | DATETIME | 创建时间 |
| updated_at | DATETIME | 更新时间 |
---
## 七、项目文件结构
```
nginxServer/
├── nginx-python-api/ # Python Flask API 源码
│ ├── app.py # 主入口7个API端点
│ ├── services/
│ │ ├── nginx_service.py # Nginx配置CRUD + reload
│ │ └── ssl_service.py # 内部CA + 证书签发
│ ├── requirements.txt # flask + gunicorn
│ ├── gunicorn_config.py # 生产环境配置
│ └── deploy.sh # 一键部署脚本
├── nginx-manager-backend/ # Spring Boot 源码
│ ├── pom.xml
│ └── src/main/java/com/mokee/nginx/
│ ├── NginxManagerApplication.java
│ ├── controller/
│ │ ├── ForwardingRuleController.java
│ │ └── GlobalExceptionHandler.java
│ ├── service/
│ │ ├── ForwardingRuleService.java
│ │ └── PythonApiClient.java
│ ├── entity/ForwardingRule.java
│ ├── repository/ForwardingRuleRepository.java
│ ├── dto/RuleRequest.java
│ ├── dto/ApiResponse.java
│ └── config/RestTemplateConfig.java
├── nginx-manager-frontend/ # Vue.js 3 前端
│ ├── .env.development # 开发环境变量
│ ├── .env.production # 生产环境变量
│ ├── vite.config.js # Vite配置端口3002
│ └── src/
│ ├── App.vue # 根组件
│ ├── layout/MainLayout.vue # 左侧菜单布局
│ ├── views/NginxForwarding.vue # 转发管理页面
│ ├── api/nginxApi.js # API请求封装
│ └── router/index.js # 路由配置
├── sql/init.sql # MySQL建库建表脚本
├── IMPLEMENTATION_PLAN.md # 本文档 - 实现方案
└── DEPLOYMENT.md # 部署文档 - 含全部命令
```
---
## 八、启动命令
```bash
# === 10.1.1.160 服务器(已配置开机自启)===
systemctl start nginx-api # Python API (5000)
systemctl start nginx # Nginx (80/443)
# === Spring Boot 后端 ===
cd nginx-manager-backend
mvn spring-boot:run # 开发模式端口4002
# === Vue.js 前端 ===
cd nginx-manager-frontend
npm run dev # 开发模式端口3002读.env.development
npm run build # 生产构建(读.env.production
```