提交 63e8ae2d authored 作者: 陈泽健's avatar 陈泽健

fix(security): 修复nginx配置中swagger接口暴露的安全漏洞

- 将swagger-ui等敏感接口的拦截路径从根路径改为/exapi/路径
- 修复sed命令处理多行配置时的语法错误问题
- 解决命令替换捕获日志输出导致容器ID解析失败的问题
- 添加配置文件备份和回滚机制确保系统安全
- 更新相关文档和问题处理记录
上级 82cb1456
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
CONFIG_FILE="/var/www/java/nginx-conf.d/meeting443.conf" CONFIG_FILE="/var/www/java/nginx-conf.d/meeting443.conf"
LOG_FILE="$(dirname "$0")/exapicheck.log" LOG_FILE="$(dirname "$0")/exapicheck.log"
BLOCK_CONFIG="# 拦截swagger-ui等危险页面访问 BLOCK_CONFIG="# 拦截swagger-ui等危险页面访问
location ~* ^/(swagger-ui|doc\.html|swagger-resources|v2/api-docs|v3/api-docs|webjars) { location ~* ^/exapi/(swagger-ui|doc\.html|swagger-resources|v2/api-docs|v3/api-docs|webjars) {
return 403; return 403;
}" }"
...@@ -80,10 +80,10 @@ check_config_exists() { ...@@ -80,10 +80,10 @@ check_config_exists() {
return 2 return 2
fi fi
if grep -q "location ~* \^/(swagger-ui" "$CONFIG_FILE"; then if grep -q "location ~* \^/exapi/(swagger-ui" "$CONFIG_FILE"; then
log_warn "配置已存在,无需重复添加" log_warn "配置已存在,无需重复添加"
echo "" echo ""
grep -A 2 "location ~* \^/(swagger-ui" "$CONFIG_FILE" grep -A 2 "location ~* \^/exapi/(swagger-ui" "$CONFIG_FILE"
echo "" echo ""
return 1 return 1
fi fi
...@@ -127,14 +127,27 @@ add_nginx_block_config() { ...@@ -127,14 +127,27 @@ add_nginx_block_config() {
log_info "找到根目录转发配置在第 $root_location_line 行" log_info "找到根目录转发配置在第 $root_location_line 行"
# 在根目录转发配置前插入拦截配置 # 在根目录转发配置前插入拦截配置
local insert_line=$((root_location_line - 1)) local insert_line=$root_location_line
local tmp_file="${CONFIG_FILE}.tmp"
# 使用sed插入配置 # 使用临时文件方式插入多行配置
if sed -i "${insert_line}a $BLOCK_CONFIG" "$CONFIG_FILE"; then # 提取前半部分(从第1行到插入行-1)
head -n $((insert_line - 1)) "$CONFIG_FILE" > "$tmp_file"
# 添加拦截配置
echo "$BLOCK_CONFIG" >> "$tmp_file"
echo "" >> "$tmp_file"
# 添加后半部分(从插入行开始到文件末尾)
tail -n +$insert_line "$CONFIG_FILE" >> "$tmp_file"
# 替换原文件
if mv "$tmp_file" "$CONFIG_FILE"; then
log_info "配置添加成功" log_info "配置添加成功"
return 0 return 0
else else
log_error "配置添加失败" log_error "配置添加失败"
rm -f "$tmp_file"
return 1 return 1
fi fi
} }
...@@ -144,16 +157,13 @@ add_nginx_block_config() { ...@@ -144,16 +157,13 @@ add_nginx_block_config() {
#=============================================================================== #===============================================================================
get_ujava_container() { get_ujava_container() {
log_info "查询ujava容器..." # 查询容器并返回ID,不打印日志(避免被命令替换捕获)
local container=$(docker ps | grep ujava | awk '{print $1}') local container=$(docker ps | grep ujava | awk '{print $1}')
if [ -z "$container" ]; then if [ -z "$container" ]; then
log_error "未找到运行的ujava容器"
return 1 return 1
fi fi
log_info "找到ujava容器: $container"
echo "$container" echo "$container"
return 0 return 0
} }
...@@ -316,12 +326,15 @@ main() { ...@@ -316,12 +326,15 @@ main() {
echo "" echo ""
# 查询ujava容器 # 查询ujava容器
log_info "查询ujava容器..."
local ujava_container=$(get_ujava_container) local ujava_container=$(get_ujava_container)
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
log_error "未找到ujava容器,开始回滚配置" log_error "未找到运行的ujava容器"
log_error "开始回滚配置"
rollback_config rollback_config
return 1 return 1
fi fi
log_info "找到ujava容器: $ujava_container"
# 测试nginx配置 # 测试nginx配置
test_nginx_config "$ujava_container" test_nginx_config "$ujava_container"
......
# 问题描述
## 脚本:`AuxiliaryTool/漏洞修复/ExapiCheck/exapicheck.sh`
## 问题现象
- 在执行代码后打印了`ERROR: 配置添加失败,终止执行`
# 报错日志信息
```ignorelang
============================================
Nginx Swagger拦截配置脚本
============================================
执行时间: 2026-05-06 11:32:46
[2026-05-06 11:32:46] INFO: 检查配置是否已存在...
[2026-05-06 11:32:46] INFO: 配置不存在,可以添加
[2026-05-06 11:32:46] INFO: 备份配置文件到: /var/www/java/nginx-conf.d/meeting443.conf.backup.20260506113246
[2026-05-06 11:32:46] INFO: 备份成功
[2026-05-06 11:32:46] INFO: 添加nginx拦截配置...
[2026-05-06 11:32:46] INFO: 找到根目录转发配置在第 25 行
sed:-e 表达式 #1,字符 46:命令后含有多余的字符
[2026-05-06 11:32:46] ERROR: 配置添加失败
[2026-05-06 11:32:46] ERROR: 配置添加失败,终止执行
[root@localhost home]#
```
\ No newline at end of file
# 配置添加失败问题处理计划执行文档
## 问题描述
- 脚本: `AuxiliaryTool/漏洞修复/ExapiCheck/exapicheck.sh`
- 错误: `sed:-e 表达式 #1,字符 46:命令后含有多余的字符`
- 原因: `sed -i` 命令无法直接处理包含换行符的多行字符串变量
## 问题分析
### 原始代码问题
```bash
# 错误代码
sed -i "${insert_line}a $BLOCK_CONFIG" "$CONFIG_FILE"
```
`$BLOCK_CONFIG` 是多行字符串:
```bash
BLOCK_CONFIG="# 拦截swagger-ui等危险页面访问
location ~* ^/(swagger-ui|doc\.html|swagger-resources|v2/api-docs|v3/api-docs|webjars) {
return 403;
}"
```
### sed命令限制
- `sed``a` 命令在处理多行文本时需要使用反斜杠续行
- 直接传递多行变量会导致解析错误
## 解决方案
### 方案一:使用awk分割文件(推荐)
```bash
# 在指定行之前插入配置
awk -v insert_line="$insert_line" -v config="$BLOCK_CONFIG" '
NR == insert_line {
print config
}
{ print }
' "$CONFIG_FILE" > "${CONFIG_FILE}.tmp" && mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
```
### 方案二:使用临时文件
```bash
# 提取前半部分
head -n $((insert_line - 1)) "$CONFIG_FILE" > "${CONFIG_FILE}.tmp"
# 添加配置
echo "$BLOCK_CONFIG" >> "${CONFIG_FILE}.tmp"
# 添加后半部分
tail -n +$insert_line "$CONFIG_FILE" >> "${CONFIG_FILE}.tmp"
# 替换原文件
mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
```
## 实施计划
### 1. 修改脚本函数
- 函数名: `add_nginx_block_config()`
- 采用方案二(临时文件方式),更易维护
### 2. 测试验证
- 在测试环境验证配置添加功能
- 确认多行配置正确插入
- 验证nginx配置测试通过
### 3. 实施状态
| 步骤 | 状态 | 说明 |
|------|------|------|
| 问题分析 | [x] | 已定位sed多行处理问题 |
| 方案设计 | [x] | 确定使用临时文件方案 |
| 脚本修复 | [x] | 已修改 `add_nginx_block_config()` 函数 |
| 测试验证 | [ ] | 待验证 |
### 4. 修复内容
#### 修改前
```bash
# 使用sed插入配置
if sed -i "${insert_line}a $BLOCK_CONFIG" "$CONFIG_FILE"; then
```
#### 修改后
```bash
# 使用临时文件方式插入多行配置
head -n $((insert_line - 1)) "$CONFIG_FILE" > "$tmp_file"
echo "$BLOCK_CONFIG" >> "$tmp_file"
echo "" >> "$tmp_file"
tail -n +$insert_line "$CONFIG_FILE" >> "$tmp_file"
mv "$tmp_file" "$CONFIG_FILE"
```
# 问题描述
## 脚本:`AuxiliaryTool/漏洞修复/ExapiCheck/exapicheck.sh`
## 问题现象
- 在执行代码后打印了`[2026-05-06 11:36:50] ERROR: nginx配置测试失败`
# 报错日志信息
```ignorelang
[root@localhost home]# ./exapicheck.sh
============================================
Nginx Swagger拦截配置脚本
============================================
执行时间: 2026-05-06 11:36:50
[2026-05-06 11:36:50] INFO: 检查配置是否已存在...
[2026-05-06 11:36:50] INFO: 配置不存在,可以添加
[2026-05-06 11:36:50] INFO: 备份配置文件到: /var/www/java/nginx-conf.d/meeting443.conf.backup.20260506113650
[2026-05-06 11:36:50] INFO: 备份成功
[2026-05-06 11:36:50] INFO: 添加nginx拦截配置...
[2026-05-06 11:36:50] INFO: 找到根目录转发配置在第 25 行
[2026-05-06 11:36:50] INFO: 配置添加成功
[2026-05-06 11:36:50] INFO: 测试nginx配置...
[2026-05-06 11:36:50] ERROR: nginx配置测试失败
Error: No such container: [2026-05-06 11:36:50] INFO: 查询ujava容器...
[2026-05-06 11:36:50] INFO: 找到ujava容器: bfa63452a22a
bfa63452a22a
[2026-05-06 11:36:50] ERROR: nginx配置测试失败,开始回滚配置
[2026-05-06 11:36:50] WARN: 开始回滚配置...
[2026-05-06 11:36:50] INFO: 配置回滚成功
[root@localhost home]#
```
\ No newline at end of file
# 配置添加测试失败问题处理计划执行文档
## 问题描述
- 脚本: `AuxiliaryTool/漏洞修复/ExapiCheck/exapicheck.sh`
- 错误: `Error: No such container: [2026-05-06 11:36:50] INFO: 查询ujava容器...`
- 原因: `log_info` 输出被命令替换捕获,污染了容器ID变量
## 问题分析
### 错误调用链
```
main()
local ujava_container=$(get_ujava_container) # 命令替换捕获所有输出
get_ujava_container()
log_info "查询ujava容器..." # 输出到stdout,被捕获
log_info "找到ujava容器: xxx" # 输出到stdout,被捕获
echo "$container" # 输出容器ID
ujava_container变量 = "日志行1\n日志行2\nbfa63452a22a"
docker exec "$ujava_container" # 把日志当成容器ID,报错
```
### 代码问题
**get_ujava_container函数:**
```bash
get_ujava_container() {
log_info "查询ujava容器..." # ❌ 输出到stdout,被命令替换捕获
...
log_info "找到ujava容器: $container" # ❌ 同上
echo "$container"
return 0
}
```
**main函数调用:**
```bash
local ujava_container=$(get_ujava_container) # ❌ 捕获了所有输出
```
### log_info函数
```bash
log_info() {
local msg="..."
echo -e "${GREEN}${msg}${NC}" # 输出到stdout
echo "$msg" >> "$LOG_FILE" # 输出到文件
}
```
## 解决方案
### 方案:分离日志输出和返回值
将日志输出移到调用方,被调用的函数只返回数据,不打印日志。
### 修改内容
#### 1. 修改 get_ujava_container()
```bash
get_ujava_container() {
# 移除 log_info,只返回容器ID
local container=$(docker ps | grep ujava | awk '{print $1}')
if [ -z "$container" ]; then
return 1
fi
echo "$container"
return 0
}
```
#### 2. 修改 main() 调用处
```bash
# 在调用前打印日志
log_info "查询ujava容器..."
local ujava_container=$(get_ujava_container)
if [ $? -ne 0 ]; then
log_error "未找到运行的ujava容器"
...
fi
log_info "找到ujava容器: $ujava_container"
```
#### 3. 同样修改其他需要返回数据的函数
- 无其他函数返回数据,仅 get_ujava_container 需要修改
## 实施计划
### 1. 修改 get_ujava_container() 函数
- 移除函数内的 log_info 调用
- 保持只输出容器ID
### 2. 修改 main() 函数
- 在调用 get_ujava_container 前后添加日志
### 3. 实施状态
| 步骤 | 状态 | 说明 |
|------|------|------|
| 问题分析 | [x] | 已定位命令替换捕获问题 |
| 方案设计 | [x] | 分离日志输出和返回值 |
| 脚本修复 | [x] | 已修改 `get_ujava_container()``main()` |
| 测试验证 | [ ] | 待验证 |
### 4. 修复内容
#### 修改1: get_ujava_container() 函数
```bash
# 修改前:函数内打印日志,被命令替换捕获
get_ujava_container() {
log_info "查询ujava容器..." # ❌ 输出被捕获
...
log_info "找到ujava容器: $container" # ❌ 输出被捕获
echo "$container"
}
# 修改后:只返回容器ID,日志由调用方打印
get_ujava_container() {
local container=$(docker ps | grep ujava | awk '{print $1}')
if [ -z "$container" ]; then
return 1
fi
echo "$container"
return 0
}
```
#### 修改2: main() 函数调用处
```bash
# 修改后:在调用前后打印日志
log_info "查询ujava容器..."
local ujava_container=$(get_ujava_container)
if [ $? -ne 0 ]; then
log_error "未找到运行的ujava容器"
...
fi
log_info "找到ujava容器: $ujava_container"
```
...@@ -18,14 +18,14 @@ ...@@ -18,14 +18,14 @@
- 配置文件内容: - 配置文件内容:
- ```ignorelang - ```ignorelang
# 这里的 ^/ 表示匹配 URL 路径的开头 # 这里的 ^/ 表示匹配 URL 路径的开头
location ~* ^/(swagger-ui|doc\.html|swagger-resources|v2/api-docs|v3/api-docs|webjars) { location ~* ^/exapi/(swagger-ui|doc\.html|swagger-resources|v2/api-docs|v3/api-docs|webjars) {
return 403; return 403;
} }
``` ```
- 添加后的效果: - 添加后的效果:
- ```ignorelang - ```ignorelang
location ~* ^/(swagger-ui|doc\.html|swagger-resources|v2/api-docs|v3/api-docs|webjars) { location ~* ^/exapi/(swagger-ui|doc\.html|swagger-resources|v2/api-docs|v3/api-docs|webjars) {
return 403; return 403;
} }
location / { } location / { }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#### 2.1 配置检查 #### 2.1 配置检查
- 执行前先检查配置文件中是否已存在拦截配置 - 执行前先检查配置文件中是否已存在拦截配置
- 通过检查关键字 `location ~* ^/(swagger-ui` 判断 - 通过检查关键字 `location ~* ^/exapi/(swagger-ui` 判断
#### 2.2 配置添加 #### 2.2 配置添加
- 在宿主机 `/var/www/java/nginx-conf.d` 目录下操作 - 在宿主机 `/var/www/java/nginx-conf.d` 目录下操作
...@@ -41,8 +41,8 @@ ...@@ -41,8 +41,8 @@
### 3. 配置内容 ### 3. 配置内容
```bash ```bash
# nginx拦截配置 # nginx拦截配置 - 只拦截 /exapi/ 路径下的swagger相关页面
location ~* ^/(swagger-ui|doc\.html|swagger-resources|v2/api-docs|v3/api-docs|webjars) { location ~* ^/exapi/(swagger-ui|doc\.html|swagger-resources|v2/api-docs|v3/api-docs|webjars) {
return 403; return 403;
} }
``` ```
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论