节点在线、应用在线、配置在线使用令牌查询
大石头 authored at 2021-12-16 19:49:30
7.55 KiB
Stardust
# 星尘发布自动开放防火墙端口 ## 功能概述 从 v3.7 开始,星尘发布支持自动检测应用监听端口并开放防火墙规则,免去手动配置防火墙的繁琐步骤。 该功能在应用部署启动后自动执行,支持 Windows 和 Linux 多种防火墙系统。 ## 功能特点 1. **自动检测**:自动识别系统防火墙类型和可用性 2. **智能提取**:从应用配置文件自动提取监听端口 3. **多平台支持**:支持 Windows 和主流 Linux 防火墙 4. **无侵入设计**:配置失败不影响应用正常部署 5. **详细日志**:完整记录检测和配置过程 ## 支持的防火墙类型 ### Windows 平台 - **Windows Firewall**(Windows 防火墙) - 使用 `netsh advfirewall` 命令 - 自动创建入站规则 - 规则命名格式:`{应用名}-{端口}` ### Linux 平台 - **firewalld**(CentOS/RHEL/Fedora) - 主流企业 Linux 发行版默认防火墙 - 永久开放端口,重启后保持 - 自动重载配置 - **ufw**(Ubuntu/Debian) - Ubuntu 和 Debian 系列默认防火墙 - 简单易用的防火墙管理工具 - 自动处理重复规则 - **iptables**(通用) - 传统 Linux 防火墙 - 兼容大多数 Linux 发行版 - 自动尝试保存规则 ## 端口检测机制 系统会自动从以下配置文件中提取监听端口: ### 1. Nginx 配置文件 从 `*.conf` 或 `*.nginx` 文件中提取 `listen` 指令: ```nginx server { listen 80; listen 443 ssl; # 自动提取:80, 443 } ``` ### 2. ASP.NET Core 配置 从 `appsettings*.json` 文件中提取端口: **方式一:urls 配置** ```json { "urls": "http://localhost:5000;https://localhost:5001" // 自动提取:5000, 5001 } ``` **方式二:Kestrel 配置** ```json { "Kestrel": { "Endpoints": { "Http": { "Url": "http://localhost:5000" }, "Https": { "Url": "https://localhost:5001" } } } // 自动提取:5000, 5001 } ``` ### 3. IIS 配置 从 `web.config` 文件中提取绑定端口: ```xml <configuration> <system.applicationHost> <sites> <site name="Default Web Site" id="1"> <bindings> <binding protocol="http" bindingInformation="*:8080:" /> <binding protocol="https" bindingInformation="*:8443:" /> <!-- 自动提取:8080, 8443 --> </bindings> </site> </sites> </system.applicationHost> </configuration> ``` ## 部署日志示例 ### Windows 平台 ``` 检测到防火墙类型:WindowsFirewall 检测到 2 个端口需要开放: 80, 443 已开放端口 80 (规则: MyWebApp-80) 已开放端口 443 (规则: MyWebApp-443) ``` ### Linux (firewalld) ``` 检测到防火墙类型:Firewalld 检测到 2 个端口需要开放: 5000, 5001 已开放端口 5000 (firewalld) 已开放端口 5001 (firewalld) ``` ### Linux (ufw) ``` 检测到防火墙类型:Ufw 检测到 1 个端口需要开放: 8080 已开放端口 8080 (ufw) ``` ### 无防火墙或无权限 ``` 未检测到可用的防火墙或无权限访问,跳过端口开放 ``` ## 权限要求 ### Windows 平台 - 需要**管理员权限**才能配置 Windows 防火墙 - StarAgent 服务应以管理员身份运行 - 如果权限不足,会跳过防火墙配置但不影响应用部署 ### Linux 平台 - 需要 **root 权限**或具有 sudo 权限的用户 - 建议 StarAgent 以 root 用户运行 - 或配置 sudoers 允许 StarAgent 用户执行防火墙命令 #### 配置 sudoers(可选) 如果不想以 root 运行 StarAgent,可以配置 sudoers: ```bash # 编辑 sudoers 文件 sudo visudo # 添加以下行(根据实际防火墙类型选择) staragent ALL=(ALL) NOPASSWD: /usr/bin/firewall-cmd staragent ALL=(ALL) NOPASSWD: /usr/sbin/ufw staragent ALL=(ALL) NOPASSWD: /usr/sbin/iptables ``` ## 技术实现 ### 防火墙检测流程 ``` 1. Windows 系统 └─ 执行 netsh advfirewall show currentprofile └─ 成功 → WindowsFirewall └─ 失败 → 无可用防火墙 2. Linux 系统 ├─ 执行 firewall-cmd --state │ └─ running → Firewalld ├─ 执行 ufw status │ └─ active → Ufw └─ 执行 iptables -L -n └─ 成功 → Iptables └─ 失败 → 无可用防火墙 ``` ### Windows 命令示例 ```powershell # 检测防火墙 netsh advfirewall show currentprofile # 检查规则是否存在 netsh advfirewall firewall show rule name="MyApp-80" # 添加入站规则 netsh advfirewall firewall add rule name="MyApp-80" dir=in action=allow protocol=TCP localport=80 ``` ### Linux firewalld 命令示例 ```bash # 检测防火墙状态 firewall-cmd --state # 查询端口是否已开放 firewall-cmd --query-port=80/tcp # 永久开放端口 firewall-cmd --permanent --add-port=80/tcp # 重载配置 firewall-cmd --reload ``` ### Linux ufw 命令示例 ```bash # 检测防火墙状态 ufw status # 开放端口(自动处理重复) ufw allow 80/tcp ``` ### Linux iptables 命令示例 ```bash # 查看规则 iptables -L -n # 检查规则是否存在 iptables -C INPUT -p tcp --dport 80 -j ACCEPT # 添加规则 iptables -A INPUT -p tcp --dport 80 -j ACCEPT # 保存规则(CentOS/RHEL) service iptables save # 保存规则(Ubuntu/Debian) iptables-save > /etc/iptables/rules.v4 ``` ## 故障排查 ### 防火墙未检测到 **症状**:日志显示"未检测到可用的防火墙" **可能原因**: 1. 系统未安装防火墙服务 2. 防火墙服务未运行 3. StarAgent 无执行权限 **解决方法**: ```bash # CentOS/RHEL - 安装并启动 firewalld sudo yum install firewalld sudo systemctl start firewalld sudo systemctl enable firewalld # Ubuntu/Debian - 启用 ufw sudo ufw enable ``` ### 端口开放失败 **症状**:日志显示"端口 XX 开放失败" **可能原因**: 1. 权限不足 2. 防火墙服务异常 3. 端口号无效 **解决方法**: 1. 确认 StarAgent 有足够权限 2. 手动执行防火墙命令测试 3. 检查日志中的错误详情 ### 端口未自动提取 **症状**:日志显示"未检测到需要开放的端口" **可能原因**: 1. 配置文件格式不标准 2. 配置文件不在工作目录 3. 端口配置使用了变量 **解决方法**: 1. 检查配置文件是否存在于部署目录 2. 确认配置文件格式符合标准 3. 手动开放端口: ```bash # Windows netsh advfirewall firewall add rule name="MyApp-80" dir=in action=allow protocol=TCP localport=80 # Linux (firewalld) sudo firewall-cmd --permanent --add-port=80/tcp sudo firewall-cmd --reload ``` ## 注意事项 1. **自动化程度**:仅支持从配置文件提取端口,动态端口(如随机端口)需要手动配置 2. **安全考虑**: - 仅开放 TCP 入站规则 - 不修改现有防火墙规则 - 支持检查规则是否已存在,避免重复添加 3. **兼容性**: - 需要系统已安装相应防火墙服务 - Windows 需要 Windows Firewall 服务运行 - Linux 至少需要一种防火墙(firewalld/ufw/iptables) 4. **性能影响**: - 防火墙配置在应用启动后异步执行 - 配置失败不会阻塞或中断应用部署 - 每个端口配置耗时通常在 100ms 以内 ## 后续规划 - [ ] 支持 UDP 协议端口开放 - [ ] 支持从启动参数提取端口 - [ ] 支持端口范围配置 - [ ] 支持自定义规则优先级 - [ ] 支持云平台安全组自动配置(阿里云、腾讯云等) ## 相关链接 - [星尘发布架构](/NewLife/Stardust/Blob/master/Doc/星尘发布架构.md) - [StarAgent 远程部署](/NewLife/Stardust/Blob/master/Doc/StarAgent远程部署.md) - [远程命令执行安全方案](/NewLife/Stardust/Blob/master/Doc/远程命令执行安全方案.md)