421 lines
12 KiB
Markdown
421 lines
12 KiB
Markdown
# GoWVP + ZLMediaKit 访问超时排查手册
|
||
|
||
> **适用场景**: 浏览器访问 `http://192.168.3.108` 超时 / 无法打开
|
||
> **排查原则**: 从"服务层→端口层→防火墙层→网络层"逐层验证
|
||
|
||
---
|
||
|
||
## 第一步:确认容器是否正常运行
|
||
|
||
```bash
|
||
# 1. 查看容器状态
|
||
docker-compose -f /opt/owl-zlmediakit/docker-compose.yml ps
|
||
|
||
# 预期输出:两个容器都显示 Up
|
||
# NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||
# gowvp gospace/gowvp:latest "/opt/owl/owl-server" gowvp 10 minutes ago Up 10 minutes
|
||
# zlmediakit zlmediakit/zlmediakit:master "/bin/sh -c 'cd /op…'" zlmediakit 10 minutes ago Up 10 minutes
|
||
```
|
||
|
||
**如果状态不是 `Up`,说明容器启动失败:**
|
||
|
||
```bash
|
||
# 查看容器退出原因
|
||
docker logs zlmediakit --tail 50
|
||
docker logs gowvp --tail 50
|
||
|
||
# 常见错误:
|
||
# - "port is already allocated" → 端口被占用(见第二步)
|
||
# - "Permission denied" → SELinux限制(见第四步)
|
||
# - "exec format error" → 镜像架构不对(x86_64镜像跑在ARM64上)
|
||
```
|
||
|
||
---
|
||
|
||
## 第二步:确认端口是否在监听
|
||
|
||
```bash
|
||
# 方法1: 使用 ss 命令(推荐)
|
||
ss -tlnp | grep -E ':80|:15123'
|
||
|
||
# 方法2: 使用 netstat
|
||
netstat -tlnp | grep -E ':80|:15123'
|
||
|
||
# 方法3: 直接测试端口连通性
|
||
curl -I http://127.0.0.1:80
|
||
curl -I http://127.0.0.1:15123
|
||
|
||
# 方法4: 查看ZLMediaKit实际监听的端口
|
||
docker exec zlmediakit netstat -tlnp
|
||
```
|
||
|
||
**预期输出示例:**
|
||
```
|
||
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
|
||
LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("MediaServer",pid=1,fd=25))
|
||
LISTEN 0 128 0.0.0.0:15123 0.0.0.0:* users:(("owl-server",pid=1,fd=18))
|
||
```
|
||
|
||
> **关键点**: `Local Address` 必须显示 `0.0.0.0:80` 或 `:::80`,如果显示 `127.0.0.1:80`,说明服务只监听了本地回环,外部无法访问。
|
||
> 但在 `network_mode: host` 模式下,服务通常会自动监听 `0.0.0.0`,除非程序自身配置限制了。
|
||
|
||
**如果端口未监听:**
|
||
|
||
```bash
|
||
# 检查端口是否被其他程序占用
|
||
ss -tlnp | grep :80
|
||
lsof -i :80
|
||
|
||
# 如果有其他程序占用了80端口(如nginx、apache)
|
||
# 方案A: 停止占用程序
|
||
sudo systemctl stop nginx
|
||
|
||
# 方案B: 修改ZLMediaKit端口(不推荐,很多配置依赖80端口)
|
||
# 编辑 data/zlm-config.ini 将 [http] 下的 port=80 改为 port=8080
|
||
```
|
||
|
||
---
|
||
|
||
## 第三步:测试服务器本机访问
|
||
|
||
```bash
|
||
# 在服务器上测试,确认服务本身是否正常
|
||
curl -I http://127.0.0.1
|
||
curl -I http://192.168.3.108
|
||
curl http://192.168.3.108/index/api/getApiList
|
||
|
||
# 测试GoWVP
|
||
curl -I http://127.0.0.1:15123
|
||
curl -I http://192.168.3.108:15123
|
||
```
|
||
|
||
**如果 `127.0.0.1` 能访问但 `192.168.3.108` 不能:**
|
||
- 说明服务正常,但绑定在了 `127.0.0.1` 而不是 `0.0.0.0`
|
||
- 需要检查程序启动参数或配置
|
||
|
||
**如果两者都不能访问:**
|
||
- 服务本身有问题,查看容器日志
|
||
|
||
---
|
||
|
||
## 第四步:检查防火墙
|
||
|
||
统信UOS 1070军事版默认可能开启防火墙,这是超时最常见的原因!
|
||
|
||
```bash
|
||
# ===== 检查 firewalld =====
|
||
sudo firewall-cmd --state
|
||
sudo firewall-cmd --list-all
|
||
sudo firewall-cmd --list-ports
|
||
|
||
# 如果 firewalld 运行中,放行端口
|
||
sudo firewall-cmd --permanent --add-port=80/tcp
|
||
sudo firewall-cmd --permanent --add-port=15123/tcp
|
||
sudo firewall-cmd --permanent --add-port=15060/tcp
|
||
sudo firewall-cmd --permanent --add-port=15060/udp
|
||
sudo firewall-cmd --reload
|
||
|
||
# ===== 检查 iptables =====
|
||
sudo iptables -L -n | grep -E '80|15123'
|
||
|
||
# 如果 iptables 有DROP规则,添加ACCEPT
|
||
sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT
|
||
sudo iptables -I INPUT -p tcp --dport 15123 -j ACCEPT
|
||
sudo iptables -I INPUT -p tcp --dport 15060 -j ACCEPT
|
||
sudo iptables -I INPUT -p udp --dport 15060 -j ACCEPT
|
||
|
||
# ===== 检查 ufw (Debian/Ubuntu系列) =====
|
||
sudo ufw status
|
||
sudo ufw allow 80/tcp
|
||
sudo ufw allow 15123/tcp
|
||
|
||
# ===== 统信UOS特有: 安全中心/安全加固 =====
|
||
# 1070军事版可能启用了额外的安全策略
|
||
# 检查是否有应用层防火墙或白名单机制
|
||
sudo cat /etc/security/limits.conf
|
||
cat /etc/hosts.allow
|
||
cat /etc/hosts.deny
|
||
```
|
||
|
||
> ⚠️ **统信UOS 1070军事版特殊提示**:
|
||
> 军事版通常有更严格的默认安全策略,可能:
|
||
> 1. 默认拒绝所有入站连接
|
||
> 2. 开启了额外的安全审计/访问控制
|
||
> 3. SELinux 处于 Enforcing 模式
|
||
>
|
||
> 如果上述防火墙命令执行后仍无法访问,请联系系统管理员确认是否有额外的网络安全策略。
|
||
|
||
---
|
||
|
||
## 第五步:检查 SELinux
|
||
|
||
```bash
|
||
# 查看SELinux状态
|
||
getenforce
|
||
# 可能输出: Enforcing / Permissive / Disabled
|
||
|
||
# 如果为 Enforcing,尝试临时设置为 Permissive(仅用于测试)
|
||
sudo setenforce 0
|
||
|
||
# 测试访问是否恢复
|
||
# 如果恢复,说明是SELinux限制,需要添加策略而不是永久关闭
|
||
|
||
# 查看SELinux审计日志(确认是否是SELinux拦截)
|
||
sudo cat /var/log/audit/audit.log | grep -i denied | tail -20
|
||
sudo ausearch -m avc -ts recent
|
||
|
||
# 如果是SELinux问题,为Docker添加权限
|
||
sudo setsebool -P container_manage_cgroup on
|
||
```
|
||
|
||
> **注意**: 军事环境可能不允许关闭 SELinux,请先确认安全策略要求。
|
||
|
||
---
|
||
|
||
## 第六步:检查网络连通性
|
||
|
||
```bash
|
||
# 1. 确认IP地址正确
|
||
ip addr show | grep 192.168.3.108
|
||
|
||
# 2. 从服务器ping网关,确认网络正常
|
||
ping 192.168.3.1
|
||
|
||
# 3. 从其他机器ping服务器
|
||
# 在另一台电脑上执行:
|
||
ping 192.168.3.108
|
||
|
||
# 如果ping不通,说明网络层有问题(网线、交换机、路由)
|
||
# 如果ping通但HTTP超时,说明传输层/应用层有问题(防火墙、服务未启动)
|
||
|
||
# 4. 从其他机器测试端口连通性
|
||
telnet 192.168.3.108 80
|
||
# 或
|
||
nc -vz 192.168.3.108 80
|
||
```
|
||
|
||
---
|
||
|
||
## 第七步:查看详细日志
|
||
|
||
```bash
|
||
# ZLMediaKit 实时日志
|
||
docker logs -f zlmediakit
|
||
|
||
# GoWVP 实时日志
|
||
docker logs -f gowvp
|
||
|
||
# 系统日志(查看Docker、网络相关错误)
|
||
sudo journalctl -u docker -n 100 --no-pager
|
||
sudo journalctl -n 50 --no-pager | grep -i -E 'firewall|denied|reject'
|
||
|
||
# 查看ZLMediaKit配置文件是否被正确加载
|
||
docker exec zlmediakit cat /opt/media/conf/config.ini | grep -E 'port|externIP'
|
||
```
|
||
|
||
**重点关注的日志关键词:**
|
||
- `bind failed` / `Address already in use` → 端口占用
|
||
- `Permission denied` → 权限/SELinux问题
|
||
- `listen failed` → 监听失败
|
||
- `accept failed` → 连接被拒绝
|
||
|
||
---
|
||
|
||
## 第八步:一键排查脚本
|
||
|
||
在服务器上执行以下脚本,自动检测常见问题:
|
||
|
||
```bash
|
||
cd /opt/owl-zlmediakit
|
||
sudo tee scripts/diagnose.sh > /dev/null << 'EOF'
|
||
#!/bin/bash
|
||
# GoWVP + ZLMediaKit 访问超时一键排查脚本
|
||
|
||
SERVER_IP="192.168.3.108"
|
||
|
||
echo "=========================================="
|
||
echo " 访问超时诊断脚本"
|
||
echo " 服务器IP: ${SERVER_IP}"
|
||
echo "=========================================="
|
||
|
||
# 1. 检查容器状态
|
||
echo -e "\n[1/8] 检查容器状态..."
|
||
if docker ps | grep -q zlmediakit; then
|
||
echo " ✓ ZLMediaKit 容器运行中"
|
||
else
|
||
echo " ✗ ZLMediaKit 容器未运行"
|
||
docker ps -a | grep zlmediakit
|
||
fi
|
||
|
||
if docker ps | grep -q gowvp; then
|
||
echo " ✓ GoWVP 容器运行中"
|
||
else
|
||
echo " ✗ GoWVP 容器未运行"
|
||
docker ps -a | grep gowvp
|
||
fi
|
||
|
||
# 2. 检查端口监听
|
||
echo -e "\n[2/8] 检查端口监听..."
|
||
for port in 80 15123; do
|
||
if ss -tlnp 2>/dev/null | grep -q ":${port} "; then
|
||
echo " ✓ 端口 ${port} 正在监听"
|
||
ss -tlnp | grep ":${port} " | head -1
|
||
else
|
||
echo " ✗ 端口 ${port} 未监听"
|
||
fi
|
||
done
|
||
|
||
# 3. 本机访问测试
|
||
echo -e "\n[3/8] 本机访问测试..."
|
||
if curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1 | grep -q "200\|302\|404"; then
|
||
echo " ✓ 127.0.0.1:80 可访问"
|
||
else
|
||
echo " ✗ 127.0.0.1:80 无法访问"
|
||
fi
|
||
|
||
if curl -s -o /dev/null -w "%{http_code}" http://${SERVER_IP} | grep -q "200\|302\|404"; then
|
||
echo " ✓ ${SERVER_IP}:80 可访问"
|
||
else
|
||
echo " ✗ ${SERVER_IP}:80 无法访问"
|
||
fi
|
||
|
||
# 4. 防火墙检查
|
||
echo -e "\n[4/8] 检查防火墙..."
|
||
if command -v firewall-cmd &> /dev/null; then
|
||
if firewall-cmd --state 2>/dev/null | grep -q "running"; then
|
||
echo " firewalld 运行中,已开放端口:"
|
||
firewall-cmd --list-ports | tr ' ' '\n' | grep -E '80|15123' | sed 's/^/ /'
|
||
else
|
||
echo " firewalld 未运行"
|
||
fi
|
||
fi
|
||
|
||
if command -v iptables &> /dev/null; then
|
||
IPTABLES_COUNT=$(iptables -L INPUT -n --line-numbers 2>/dev/null | grep -c -E 'dpt:80|dpt:15123' || true)
|
||
if [ "$IPTABLES_COUNT" -gt 0 ]; then
|
||
echo " iptables 相关规则:"
|
||
iptables -L INPUT -n --line-numbers | grep -E 'dpt:80|dpt:15123' | sed 's/^/ /'
|
||
else
|
||
echo " iptables 无80/15123相关规则"
|
||
fi
|
||
fi
|
||
|
||
# 5. SELinux检查
|
||
echo -e "\n[5/8] 检查SELinux..."
|
||
if command -v getenforce &> /dev/null; then
|
||
SELINUX_STATUS=$(getenforce)
|
||
echo " SELinux 状态: ${SELINUX_STATUS}"
|
||
if [ "${SELINUX_STATUS}" = "Enforcing" ]; then
|
||
echo " ⚠ SELinux 处于强制模式,可能拦截访问"
|
||
fi
|
||
else
|
||
echo " SELinux 未安装"
|
||
fi
|
||
|
||
# 6. 网络接口检查
|
||
echo -e "\n[6/8] 检查网络接口..."
|
||
ip addr show | grep "${SERVER_IP}" > /dev/null 2>&1
|
||
if [ $? -eq 0 ]; then
|
||
echo " ✓ IP ${SERVER_IP} 已绑定到网卡"
|
||
ip addr show | grep "${SERVER_IP}" | sed 's/^/ /'
|
||
else
|
||
echo " ✗ IP ${SERVER_IP} 未绑定到任何网卡"
|
||
echo " 可用IP地址:"
|
||
ip addr show | grep "inet " | sed 's/^/ /'
|
||
fi
|
||
|
||
# 7. 端口占用检查
|
||
echo -e "\n[7/8] 检查80端口占用..."
|
||
PORT_80_PID=$(ss -tlnp 2>/dev/null | grep ':80 ' | head -1)
|
||
if [ -n "$PORT_80_PID" ]; then
|
||
echo " 端口80被占用:"
|
||
echo " ${PORT_80_PID}"
|
||
else
|
||
echo " 端口80未被监听"
|
||
fi
|
||
|
||
# 8. Docker网络检查
|
||
echo -e "\n[8/8] 检查Docker网络配置..."
|
||
docker network ls | grep -q host
|
||
if [ $? -eq 0 ]; then
|
||
echo " ✓ host 网络模式可用"
|
||
else
|
||
echo " ✗ host 网络模式不可用"
|
||
fi
|
||
|
||
echo -e "\n=========================================="
|
||
echo " 诊断完成"
|
||
echo "=========================================="
|
||
EOF
|
||
|
||
sudo chmod +x scripts/diagnose.sh
|
||
sudo ./scripts/diagnose.sh
|
||
```
|
||
|
||
---
|
||
|
||
## 常见原因速查表
|
||
|
||
| 现象 | 最可能原因 | 解决方案 |
|
||
|------|-----------|----------|
|
||
| 浏览器超时,但服务器上`curl 127.0.0.1`正常 | **防火墙拦截** | 执行`firewall-cmd --add-port=80/tcp`或`iptables -I INPUT -p tcp --dport 80 -j ACCEPT` |
|
||
| 浏览器超时,`curl 127.0.0.1`也失败 | **服务未启动/端口未监听** | `docker logs zlmediakit`查看错误,可能是端口被占用 |
|
||
| `docker-compose ps`显示Exit | **容器启动失败** | 查看`docker logs`,可能是SELinux或镜像架构问题 |
|
||
| 能ping通但HTTP超时 | **防火墙或SELinux** | 检查防火墙规则 + `getenforce` |
|
||
| 连ping都ping不通 | **网络层问题** | 检查网线、交换机、IP配置 |
|
||
| `ss`显示端口监听在`127.0.0.1:80` | **服务绑定错误** | 检查程序配置,确保绑定到`0.0.0.0` |
|
||
|
||
---
|
||
|
||
## 统信UOS 1070军事版特有问题
|
||
|
||
### 1. 默认安全策略
|
||
|
||
1070军事版通常有严格的安全加固:
|
||
|
||
```bash
|
||
# 检查是否有额外的安全模块
|
||
lsmod | grep -E 'security|apparmor|selinux'
|
||
cat /proc/1/attr/current
|
||
|
||
# 检查TCP Wrappers
|
||
cat /etc/hosts.allow
|
||
cat /etc/hosts.deny
|
||
```
|
||
|
||
### 2. Docker在军事版上的特殊问题
|
||
|
||
```bash
|
||
# 检查Docker是否被安全策略限制
|
||
sudo auditctl -l | grep docker
|
||
sudo cat /var/log/audit/audit.log | grep -i docker | tail -20
|
||
|
||
# 检查cgroup配置(统信UOS可能有特殊配置)
|
||
cat /proc/self/cgroup
|
||
mount | grep cgroup
|
||
```
|
||
|
||
### 3. 如果所有排查都没问题
|
||
|
||
可能是军事版定制的内核或安全模块拦截了。尝试:
|
||
|
||
```bash
|
||
# 临时关闭所有防火墙(仅测试用,测试后恢复)
|
||
sudo systemctl stop firewalld
|
||
sudo iptables -F
|
||
sudo setenforce 0
|
||
|
||
# 测试访问
|
||
# 如果此时可以访问,说明确实是防火墙/安全策略问题
|
||
# 逐条恢复策略,定位具体是哪条规则导致的拦截
|
||
```
|
||
|
||
---
|
||
|
||
> 如果以上排查都未能解决问题,请提供以下信息以便进一步分析:
|
||
> 1. `docker-compose ps` 的输出
|
||
> 2. `ss -tlnp | grep -E ':80|:15123'` 的输出
|
||
> 3. `sudo firewall-cmd --list-all` 或 `sudo iptables -L -n` 的输出
|
||
> 4. `getenforce` 的输出
|
||
> 5. `docker logs zlmediakit --tail 30` 的输出
|