Skip to main content

系统地址配置指引

概览

目标

  • 在安全隔离场景下,实现内网管理端发布问卷时显示外网答题链接和二维码
  • 通过系统地址配置,确保答题页面通过外网域名访问,管理页面通过内网访问

核心原理

  • 问卷发布页面默认读取当前页面的 origin 生成答题链接
  • 配置系统地址后,优先使用配置的外网域名生成答题链接
  • 通过 Nginx 配置实现内外网访问隔离

配置位置

  • 基础设置 → 配置管理 → 界面配置 → 系统地址配置

    1758605957376

使用场景

  • 内网访问管理页面,外网访问答题页面
  • 确保答题链接和二维码显示外网地址,便于外部用户访问

快速配置

快速配置目标

  • 快速完成系统地址配置,实现内外网访问隔离

步骤

  1. 配置系统地址

    • 登录管理后台(通过内网域名:https://admin.survey.example.com
    • 进入"基础设置 → 配置管理 → 界面配置 → 系统地址配置"
    • 在"系统地址"字段填入外网域名:https://survey.example.com
    • 保存配置
  2. 验证配置生效

    • 进入任意问卷的"问卷设置 → 发布"页面
    • 检查答题链接和二维码是否显示外网域名
    • 如仍显示内网域名,请清理浏览器缓存或重新发布

验证结果

  • 答题链接前缀显示为配置的外网域名
  • 外网域名可正常访问答题页面
  • 管理后台仍通过内网访问

详细配置步骤

详细配置目标

  • 完成系统地址配置并同步调整外网 Nginx 配置,实现安全隔离

前置条件

  • 已完成外网域名 DNS 解析
  • 具备外网 Nginx 配置文件编辑权限

配置步骤

  1. 配置系统地址

    • 登录管理后台(通过内网域名:https://admin.survey.example.com
    • 进入"基础设置 → 配置管理 → 界面配置 → 系统地址配置"
    • 在"系统地址"字段填入外网域名:https://survey.example.com
    • 保存配置
  2. 验证发布页展示

    • 打开任意问卷的发布页面
    • 确认答题链接和二维码显示外网域名
    • 如仍显示内网域名,清理浏览器缓存后重新发布
  3. 配置外网 Nginx

    • 根据前端路由配置,只允许答题相关页面通过外网访问
    • 禁止管理后台接口外网访问

Nginx 配置

Nginx 配置目标

  • 根据前端路由配置,生成对应的 Nginx 配置,实现安全隔离

配置说明

  • 双域名架构:外网域名用于答题页面,内网域名用于管理后台
  • 安全隔离:外网只允许答题相关页面访问,内网提供完整管理功能
  • 严格拒绝:外网非目标路径直接拒绝访问(403 Forbidden)
  • 访问控制:通过不同的 server_name 实现严格的访问控制
  • SSL 加密:两个域名都支持 HTTPS 访问
  • 静态资源优化:保持原有的缓存策略

完整配置示例

# 外网访问配置 - 只允许答题相关页面
server {
listen 443 ssl;
server_name survey.example.com; # 外网域名
root /var/www/surveyking;

# SSL 配置
ssl_certificate /path/to/your/certificate.crt;
ssl_certificate_key /path/to/your/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

# 只允许答题相关页面访问
location ~ ^/(e|s|t|redeem)/ {
try_files $uri $uri/ /index.html;
}

# 处理根路径重定向到首页
location = / {
try_files $uri $uri/ /index.html;
}

# 单独处理 HTML 文件的缓存策略
location ~* \.(html|htm)$ {
# 禁用缓存
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
# 可选:添加版本标识
add_header X-Version $date_gmt;
}

# 静态资源可以长期缓存(因为文件名带 hash)
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}

# 二维码代理
location /captcha {
# 修改为实际后端端口
proxy_pass http://localhost:1991/captcha;
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 30m;
proxy_http_version 1.1;
proxy_set_header Connection close;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_send_timeout 1800;
proxy_read_timeout 1800;
proxy_connect_timeout 1800;
}

# 允许答题相关接口外网访问
location /admin-api/survey/ {
# 修改为实际后端端口
proxy_pass http://localhost:1991/admin-api/survey/;
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 30m;
proxy_http_version 1.1;
proxy_set_header Connection close;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_send_timeout 1800;
proxy_read_timeout 1800;
proxy_connect_timeout 1800;
}

# 允许抽奖相关接口外网访问
location /admin-api/lottery/ {
# 修改为实际后端端口
proxy_pass http://localhost:1991/admin-api/lottery/;
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 30m;
proxy_http_version 1.1;
proxy_set_header Connection close;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_send_timeout 1800;
proxy_read_timeout 1800;
proxy_connect_timeout 1800;
}

# 允许认证接口外网访问
location /system/auth/ {
# 修改为实际后端端口
proxy_pass http://localhost:1991/system/auth/;
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 30m;
proxy_http_version 1.1;
proxy_set_header Connection close;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_send_timeout 1800;
proxy_read_timeout 1800;
proxy_connect_timeout 1800;
}

# 禁止其他管理后台接口外网访问
location /admin-api {
deny all;
}

# 禁止其他所有路径访问 - 直接拒绝
location / {
deny all;
}
}

# 内网访问配置 - 管理后台
server {
listen 443 ssl;
server_name admin.survey.example.com; # 内网域名
root /var/www/surveyking;

# SSL 配置
ssl_certificate /path/to/your/certificate.crt;
ssl_certificate_key /path/to/your/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

# 允许所有管理后台页面访问
location / {
try_files $uri $uri/ /index.html;
}

# 单独处理 HTML 文件的缓存策略
location ~* \.(html|htm)$ {
# 禁用缓存
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
# 可选:添加版本标识
add_header X-Version $date_gmt;
}

# 静态资源可以长期缓存(因为文件名带 hash)
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}

# 二维码代理
location /captcha {
# 修改为实际后端端口
proxy_pass http://localhost:1991/captcha;
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 30m;
proxy_http_version 1.1;
proxy_set_header Connection close;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_send_timeout 1800;
proxy_read_timeout 1800;
proxy_connect_timeout 1800;
}

# 后端接口代理
location /admin-api {
# 修改为实际后端端口
proxy_pass http://localhost:1991/admin-api;
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 30m;
proxy_http_version 1.1;
proxy_set_header Connection close;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_send_timeout 1800;
proxy_read_timeout 1800;
proxy_connect_timeout 1800;
}
}

# HTTP 重定向到 HTTPS
server {
listen 80;
server_name survey.example.com admin.survey.example.com;
return 301 https://$server_name$request_uri;
}

支持的路由说明

外网允许访问的路径:

  • /e/:id - 360 评价页面
  • /s/:id - 答卷页面
  • /t/:id - 练习页面
  • /t/:id/:answerId - 练习页面查看结果
  • /s/:id/result/:resultId - 公开查询
  • /s/:id/exam-result/:answerId - 考试结果与解析
  • /s/:id/dimension/:answerId - 考试结果与解析
  • /s/:id/exam-certificate/:answerId - 考试证书
  • /s/:id/lottery/:answerId - 抽奖页面
  • /s/:id/red-packet-wheel/:answerId - 红包转盘页面
  • /s/:id/:answerId - 查看问卷答案
  • /s/:id/print/:answerId/:printId - 打印报表
  • /s/:id/vote-rank - 投票排行榜
  • /redeem/:projectId - 兑奖页面
  • /captcha - 验证码接口
  • / - 根路径(重定向到首页)

外网允许访问的接口:

  • /admin-api/survey/* - 问卷相关接口(提交答案、获取问卷等)
  • /admin-api/lottery/* - 抽奖相关接口(抽奖、兑奖等)
  • /system/auth - 认证接口(登录、验证等)

外网拒绝访问的路径:

  • /admin-api - 其他管理后台接口(403 Forbidden)
  • 任何其他路径 - 直接拒绝(403 Forbidden)

域名配置要求

  • 外网域名survey.example.com - 用于答题页面访问
  • 内网域名admin.survey.example.com - 用于管理后台访问
  • DNS 解析:确保两个域名都正确解析到服务器 IP
  • SSL 证书:两个域名都需要配置 SSL 证书

安全说明

  • 严格访问控制:外网域名只允许访问答题相关页面和必要的接口,其他路径都会被直接拒绝
  • 必要接口开放:允许问卷、抽奖、认证等必要接口外网访问,确保答题功能正常
  • 拒绝策略:使用 deny all 而不是 return 404,确保非授权访问被明确拒绝
  • 管理功能隔离:核心管理功能只能通过内网域名访问,确保数据安全
  • 攻击防护:外网拒绝访问可以有效防止恶意扫描和攻击尝试

工作原理

工作原理目标

  • 说明系统地址配置如何影响答题链接生成及内外网访问隔离

核心机制

  1. 链接生成逻辑

    • 默认:读取当前页面 window.location.origin
    • 配置后:优先使用系统地址配置的外网域名
    • 适用于:答题链接、二维码、分享链接等
  2. 安全隔离架构

    • 内网:管理后台、系统配置、数据统计
    • 外网:答题页面、兑奖页面、公开查询
    • 通过 Nginx 配置实现访问控制

配置生效流程

验证方法

  • 浏览器控制台执行:console.log(window.location.origin)
  • 对比发布页面显示的答题链接域名
  • 确认外网域名可正常访问答题页面

故障排查

常见问题

  1. 答题链接仍显示内网域名

    • 检查系统地址配置是否正确保存
    • 清理浏览器缓存后重新发布
    • 确认配置的域名格式正确(包含协议)
  2. 外网无法访问答题页面

    • 检查 Nginx 配置是否正确
    • 确认域名 DNS 解析正常
    • 验证后端服务端口配置
  3. 外网访问非目标路径被拒绝

    • 这是正常的安全行为,外网只允许访问答题相关页面和必要接口
    • 如需访问管理功能,请使用内网域名:https://admin.survey.example.com
    • 确认访问的路径是否在允许列表中
  4. 外网答题功能异常

    • 检查问卷相关接口 /admin-api/survey/* 是否可正常访问
    • 检查抽奖相关接口 /admin-api/lottery/* 是否可正常访问
    • 检查认证接口 /system/auth 是否可正常访问
    • 确认后端服务端口配置正确
  5. 管理后台无法访问

    • 确认通过内网域名访问管理后台
    • 检查内网 Nginx 配置是否正常