支持ipv6

This commit is contained in:
qaq
2025-06-25 12:05:59 +08:00
parent 30fc503731
commit c05f847f1b
+195 -321
View File
@@ -27,326 +27,191 @@ check_docker() {
echo "检测到 Docker 命令:$DOCKER_CMD"
}
# 检查Docker IPv6支持的多种方法
check_docker_ipv6_support() {
echo "🔍 验证Docker IPv6支持..."
# 方法1: 检查daemon.json配置文件
if [ -f "/etc/docker/daemon.json" ]; then
if grep -q '"ipv6".*true' /etc/docker/daemon.json 2>/dev/null; then
echo "✅ daemon.json配置检查通过"
return 0
fi
fi
# 方法2: 尝试创建IPv6测试网络
echo "🧪 尝试创建IPv6测试网络..."
if docker network create --ipv6 --subnet=2001:db8:test::/64 ipv6-test-net 2>/dev/null; then
echo "✅ IPv6网络创建成功"
# 清理测试网络
docker network rm ipv6-test-net >/dev/null 2>&1
return 0
fi
# 方法3: 检查docker info的详细输出
if docker info 2>/dev/null | grep -i ipv6 | grep -q true; then
echo "✅ docker info IPv6检查通过"
return 0
fi
# 方法4: 检查Docker版本和配置
DOCKER_VERSION=$(docker version --format '{{.Server.Version}}' 2>/dev/null)
if [ -n "$DOCKER_VERSION" ]; then
echo "ℹ️ Docker版本: $DOCKER_VERSION"
# 对于新版本Docker,配置可能需要更多时间生效
echo "⏳ 等待Docker配置生效..."
sleep 5
# 再次尝试网络创建
if docker network create --ipv6 --subnet=2001:db8:test2::/64 ipv6-test-net2 2>/dev/null; then
echo "✅ 延迟检查IPv6网络创建成功"
docker network rm ipv6-test-net2 >/dev/null 2>&1
return 0
fi
fi
echo "⚠️ IPv6支持验证失败,但配置可能已生效"
echo "ℹ️ 建议手动验证: docker network create --ipv6 --subnet=2001:db8:test::/64 test-net"
return 1
}
# 检查IPv6支持
# 检测系统是否支持 IPv6
check_ipv6_support() {
echo "🔍 检查IPv6支持..."
echo "🔍 检测 IPv6 支持..."
# 检查内核是否支持IPv6
if [ ! -f /proc/net/if_inet6 ]; then
echo "⚠️ 警告:系统内核不支持IPv6"
# 检查是否有 IPv6 地址(排除 link-local 地址)
if ip -6 addr show | grep -v "scope link" | grep -q "inet6"; then
echo "✅ 检测到系统支持 IPv6"
return 0
elif ifconfig 2>/dev/null | grep -v "fe80:" | grep -q "inet6"; then
echo "✅ 检测到系统支持 IPv6"
return 0
else
echo "⚠️ 未检测到 IPv6 支持"
return 1
fi
# 检查Docker是否支持IPv6
if ! check_docker_ipv6_support; then
echo "⚠️ Docker守护进程未启用IPv6支持,正在自动配置..."
# 自动配置Docker daemon.json
configure_docker_ipv6
# 重新检查
if ! check_docker_ipv6_support; then
echo "❌ Docker IPv6配置失败,请手动检查"
return 1
fi
fi
echo "✅ IPv6支持检查通过"
return 0
}
# 配置Docker IPv6支持
# 配置 Docker 启用 IPv6
configure_docker_ipv6() {
echo "🔧 正在配置Docker IPv6支持..."
echo "🔧 配置 Docker IPv6 支持..."
DAEMON_JSON_PATH="/etc/docker/daemon.json"
# 检查操作系统类型
OS_TYPE=$(uname -s)
# 检查是否有写入权限
if [ ! -w "/etc/docker" ] && [ ! -w "$DAEMON_JSON_PATH" ]; then
echo "⚠️ 需要管理员权限来配置Docker"
echo "🔐 正在请求sudo权限..."
if [[ "$OS_TYPE" == "Darwin" ]]; then
# macOS 上 Docker Desktop 已默认支持 IPv6
echo "✅ macOS Docker Desktop 默认支持 IPv6"
return 0
fi
# 备份现有配置
if [ -f "$DAEMON_JSON_PATH" ]; then
sudo cp "$DAEMON_JSON_PATH" "$DAEMON_JSON_PATH.backup.$(date +%Y%m%d_%H%M%S)" 2>/dev/null || {
echo "❌ 无法备份daemon.json文件,请检查权限"
return 1
}
echo "✅ 已备份现有daemon.json配置"
# Docker daemon 配置文件路径
DOCKER_CONFIG="/etc/docker/daemon.json"
# 检查是否需要 sudo
if [[ $EUID -ne 0 ]]; then
SUDO_CMD="sudo"
else
SUDO_CMD=""
fi
# 创建或更新daemon.json
if [ -f "$DAEMON_JSON_PATH" ]; then
# 文件存在,检查是否已配置IPv6
if grep -q '"ipv6".*true' "$DAEMON_JSON_PATH" 2>/dev/null; then
echo "ℹ️ daemon.json已配置IPv6支持"
# 检查 Docker 配置文件
if [ -f "$DOCKER_CONFIG" ]; then
# 检查是否已经配置了 IPv6
if grep -q '"ipv6"' "$DOCKER_CONFIG"; then
echo "✅ Docker 已配置 IPv6 支持"
else
echo "🔧 更新现有daemon.json配置..."
# 尝试多种方式更新JSON
JSON_UPDATED=false
echo "📝 更新 Docker 配置以启用 IPv6..."
# 备份原配置
$SUDO_CMD cp "$DOCKER_CONFIG" "${DOCKER_CONFIG}.backup"
# 方法1: 使用jq
# 使用 jq 或 sed 添加 IPv6 配置
if command -v jq &> /dev/null; then
if sudo jq '. + {"ipv6": true, "fixed-cidr-v6": "2001:db8:1::/64"}' "$DAEMON_JSON_PATH" > /tmp/daemon.json.tmp 2>/dev/null && \
sudo mv /tmp/daemon.json.tmp "$DAEMON_JSON_PATH" 2>/dev/null; then
JSON_UPDATED=true
echo "✅ 使用jq更新JSON配置"
fi
fi
# 方法2: 使用Python3
if [ "$JSON_UPDATED" = false ] && command -v python3 &> /dev/null; then
if sudo python3 -c "
import json
try:
with open('$DAEMON_JSON_PATH', 'r') as f:
config = json.load(f)
except:
config = {}
config['ipv6'] = True
config['fixed-cidr-v6'] = '2001:db8:1::/64'
with open('$DAEMON_JSON_PATH', 'w') as f:
json.dump(config, f, indent=2)
print('JSON updated successfully')
" 2>/dev/null; then
JSON_UPDATED=true
echo "✅ 使用Python3更新JSON配置"
fi
fi
# 方法3: 手动创建新文件(简单覆盖)
if [ "$JSON_UPDATED" = false ]; then
echo "⚠️ 无法解析现有JSON,将创建新的配置文件"
read -p "这将覆盖现有的daemon.json配置,是否继续?(y/N): " confirm
if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
sudo tee "$DAEMON_JSON_PATH" > /dev/null <<EOF
{
"ipv6": true,
"fixed-cidr-v6": "2001:db8:1::/64"
}
EOF
JSON_UPDATED=true
echo "✅ 创建新的daemon.json配置"
else
echo "❌ 用户取消操作"
return 1
fi
fi
if [ "$JSON_UPDATED" = false ]; then
echo "❌ 无法更新daemon.json,请手动配置"
return 1
fi
fi
else
# 文件不存在,创建新的
echo "🆕 创建新的daemon.json配置..."
sudo mkdir -p /etc/docker 2>/dev/null || {
echo "❌ 无法创建/etc/docker目录"
return 1
}
sudo tee "$DAEMON_JSON_PATH" > /dev/null <<EOF
{
"ipv6": true,
"fixed-cidr-v6": "2001:db8:1::/64"
}
EOF
fi
echo "✅ Docker IPv6配置完成"
echo "🔄 重启Docker服务..."
# 重启Docker服务
if command -v systemctl &> /dev/null; then
if sudo systemctl restart docker 2>/dev/null; then
echo "⏳ 等待Docker服务启动..."
sleep 5
if sudo systemctl is-active docker &> /dev/null; then
echo "✅ Docker服务重启成功"
$SUDO_CMD jq '. + {"ipv6": true, "fixed-cidr-v6": "fd00::/80"}' "$DOCKER_CONFIG" > /tmp/daemon.json && $SUDO_CMD mv /tmp/daemon.json "$DOCKER_CONFIG"
else
echo "❌ Docker服务启动失败"
sudo systemctl status docker --no-pager -l
return 1
# 如果没有 jq,使用 sed
$SUDO_CMD sed -i 's/^{$/{\n "ipv6": true,\n "fixed-cidr-v6": "fd00::\/80",/' "$DOCKER_CONFIG"
fi
echo "🔄 重启 Docker 服务..."
if command -v systemctl &> /dev/null; then
$SUDO_CMD systemctl restart docker
elif command -v service &> /dev/null; then
$SUDO_CMD service docker restart
else
echo "⚠️ 请手动重启 Docker 服务"
fi
else
echo "❌ 无法重启Docker服务"
return 1
fi
elif command -v service &> /dev/null; then
if sudo service docker restart 2>/dev/null; then
sleep 5
echo "✅ Docker服务重启完成"
else
echo "❌ 无法重启Docker服务"
return 1
fi
else
echo "⚠️ 无法自动重启Docker服务,请手动重启:"
echo " sudo systemctl restart docker"
echo " 或者: sudo service docker restart"
return 1
# 创建新的配置文件
echo "📝 创建 Docker 配置文件..."
$SUDO_CMD mkdir -p /etc/docker
echo '{
"ipv6": true,
"fixed-cidr-v6": "fd00::/80"
}' | $SUDO_CMD tee "$DOCKER_CONFIG" > /dev/null
echo "🔄 重启 Docker 服务..."
if command -v systemctl &> /dev/null; then
$SUDO_CMD systemctl restart docker
elif command -v service &> /dev/null; then
$SUDO_CMD service docker restart
else
echo "⚠️ 请手动重启 Docker 服务"
fi
sleep 5
fi
return 0
}
# 配置IPv6网络
configure_ipv6_network() {
if [[ "$ENABLE_IPV6" == "true" ]]; then
echo "🌐 配置IPv6网络..."
# 检查IPv6支持
if ! check_ipv6_support; then
echo "❌ IPv6支持检查失败"
echo ""
echo "📋 您有以下选择:"
echo "1. 继续安装(仅使用IPv4网络)"
echo "2. 取消安装,手动配置IPv6后重试"
echo ""
read -p "请选择 (1/2): " ipv6_choice
case $ipv6_choice in
1)
echo "ℹ️ 继续安装,将使用IPv4网络"
ENABLE_IPV6=false
echo "✅ 网络配置完成(仅IPv4)"
echo "ℹ️ IPv4子网: 172.20.0.0/16"
return 0
;;
2)
echo "❌ 安装已取消"
echo "ℹ️ 请参考以下步骤手动配置IPv6:"
echo " 1. 确保系统内核支持IPv6"
echo " 2. 编辑 /etc/docker/daemon.json 添加:"
echo ' {"ipv6": true, "fixed-cidr-v6": "2001:db8:1::/64"}'
echo " 3. 重启Docker服务: sudo systemctl restart docker"
echo " 4. 重新运行此安装脚本"
echo "ℹ️ 脚本会自动选择不冲突的IPv6子网"
exit 1
;;
*)
echo "❌ 无效选择,安装已取消"
exit 1
;;
esac
fi
# 创建支持IPv6的docker-compose.yml配置
echo "🔧 正在创建IPv6网络配置..."
# 检查文件是否已包含IPv6配置
if grep -q "enable_ipv6: true" docker-compose.yml && (grep -q "2001:db8:1::/64" docker-compose.yml || grep -q "2001:db8:2::/64" docker-compose.yml); then
EXISTING_IPV6_SUBNET=$(grep -o "2001:db8:[0-9]::/64" docker-compose.yml)
echo "✅ IPv6配置已存在"
echo "✅ IPv6网络配置完成"
echo "ℹ️ IPv6子网: $EXISTING_IPV6_SUBNET"
echo "ℹ️ IPv4子网: 172.20.0.0/16"
else
# 安全地添加IPv6配置,只修改networks部分
echo "⚙️ 正在添加IPv6网络支持..."
# 检测daemon.json中的IPv6子网,选择不冲突的子网
IPV6_SUBNET="2001:db8:2::/64" # 默认使用2号子网
if [ -f "/etc/docker/daemon.json" ]; then
if grep -q "2001:db8:2::/64" /etc/docker/daemon.json 2>/dev/null; then
IPV6_SUBNET="2001:db8:3::/64" # 如果2号被占用,使用3号
fi
fi
echo "ℹ️ 将使用IPv6子网: $IPV6_SUBNET"
# 创建临时文件来安全修改
cp docker-compose.yml docker-compose.yml.backup
# 使用awk来精确修改networks部分
awk -v ipv6_subnet="$IPV6_SUBNET" '
/^networks:/ { in_networks = 1 }
/^[a-zA-Z]/ && !/^networks:/ && in_networks { in_networks = 0 }
/^ gost-network:/ && in_networks { in_gost_network = 1 }
/^ [a-zA-Z]/ && !/^ gost-network:/ && in_gost_network { in_gost_network = 0 }
/^ driver: bridge$/ && in_gost_network && !ipv6_added {
print $0
print " enable_ipv6: true"
ipv6_added = 1
next
}
/^ - subnet: 172\.20\.0\.0\/16$/ && in_gost_network && !subnet_added {
print $0
print " - subnet: " ipv6_subnet
subnet_added = 1
next
}
{ print }
' docker-compose.yml.backup > docker-compose.yml
# 验证修改是否成功
if grep -q "enable_ipv6: true" docker-compose.yml && grep -q "$IPV6_SUBNET" docker-compose.yml; then
echo "✅ IPv6网络配置添加成功"
rm -f docker-compose.yml.backup
echo "✅ IPv6网络配置完成"
echo "ℹ️ IPv6子网: $IPV6_SUBNET"
echo "ℹ️ IPv4子网: 172.20.0.0/16"
else
echo "❌ IPv6网络配置添加失败"
echo "🔍 请检查docker-compose.yml文件"
if [ -f docker-compose.yml.backup ]; then
echo "📁 备份文件: docker-compose.yml.backup"
fi
fi
fi
else
echo "ℹ️ 跳过IPv6网络配置,仅使用IPv4网络"
echo "✅ 网络配置完成(仅IPv4)"
echo "ℹ️ IPv4子网: 172.20.0.0/16"
fi
# 更新 docker-compose.yml 以支持 IPv6
update_compose_for_ipv6() {
echo "🔧 更新 docker-compose.yml 配置 IPv6..."
# 创建支持 IPv6 的 docker-compose.yml
cat > docker-compose.yml.ipv6 <<'EOF'
services:
mysql:
image: mysql:5.7
container_name: gost-mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
TZ: Asia/Shanghai
volumes:
- mysql_data:/var/lib/mysql
- ./gost.sql:/docker-entrypoint-initdb.d/init.sql:ro
command: >
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
--max_connections=1000
--innodb_buffer_pool_size=256M
networks:
- gost-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
timeout: 10s
retries: 10
backend:
image: bqlpfy/springboot-backend:latest
container_name: springboot-backend
restart: unless-stopped
environment:
DB_HOST: mysql
DB_NAME: ${DB_NAME}
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
JWT_SECRET: ${JWT_SECRET}
LOG_DIR: /app/logs
SERVER_ADDR: ${SERVER_HOST}
JAVA_OPTS: "-Xms256m -Xmx512m -Dfile.encoding=UTF-8 -Duser.timezone=Asia/Shanghai"
ports:
- "${BACKEND_PORT}:6365"
- "[::]:${BACKEND_PORT}:6365"
volumes:
- backend_logs:/app/logs
depends_on:
mysql:
condition: service_healthy
networks:
- gost-network
healthcheck:
test: ["CMD", "sh", "-c", "wget --no-verbose --tries=1 --spider http://localhost:6365/flow/test || exit 1"]
interval: 30s
timeout: 10s
retries: 5
start_period: 90s
frontend:
image: bqlpfy/vue-frontend:latest
container_name: vue-frontend
restart: unless-stopped
ports:
- "${FRONTEND_PORT}:80"
- "[::]:${FRONTEND_PORT}:80"
depends_on:
backend:
condition: service_healthy
networks:
- gost-network
volumes:
mysql_data:
driver: local
backend_logs:
driver: local
networks:
gost-network:
driver: bridge
enable_ipv6: true
ipam:
config:
- subnet: 172.20.0.0/16
- subnet: fd00:dead:beef::/48
EOF
mv docker-compose.yml.ipv6 docker-compose.yml
echo "✅ docker-compose.yml 已更新为支持 IPv6"
}
# 显示菜单
@@ -386,25 +251,6 @@ get_config_params() {
read -p "后端端口(默认 6365): " BACKEND_PORT
BACKEND_PORT=${BACKEND_PORT:-6365}
# 询问是否开启IPv6支持
echo ""
echo "🌐 IPv6 支持配置"
echo "开启IPv6可以让容器支持IPv6网络连接"
echo "ℹ️ 注意事项:"
echo " - 需要系统内核支持IPv6"
echo " - 需要Docker守护进程启用IPv6支持"
echo " - 如果Docker未启用IPv6,请先配置Docker后再安装"
echo ""
read -p "是否开启IPv6支持?(y/N): " ENABLE_IPV6
if [[ "$ENABLE_IPV6" == "y" || "$ENABLE_IPV6" == "Y" ]]; then
ENABLE_IPV6=true
echo "✅ 已选择开启IPv6支持"
echo "ℹ️ 将根据系统配置自动选择合适的IPv6子网"
else
ENABLE_IPV6=false
echo "ℹ️ 未开启IPv6支持,使用IPv4网络"
fi
DB_NAME=$(generate_random)
DB_USER=$(generate_random)
DB_PASSWORD=$(generate_random)
@@ -423,8 +269,12 @@ install_panel() {
curl -L -o gost.sql "$GOST_SQL_URL"
echo "✅ 下载完成"
# 配置IPv6网络
configure_ipv6_network
# 自动检测并配置 IPv6 支持
if check_ipv6_support; then
echo "🚀 系统支持 IPv6,自动启用 IPv6 配置..."
configure_docker_ipv6
update_compose_for_ipv6
fi
cat > .env <<EOF
DB_NAME=$DB_NAME
@@ -434,7 +284,6 @@ JWT_SECRET=$JWT_SECRET
SERVER_HOST=$SERVER_HOST_PORT
FRONTEND_PORT=$FRONTEND_PORT
BACKEND_PORT=$BACKEND_PORT
ENABLE_IPV6=$ENABLE_IPV6
EOF
echo "🚀 启动 docker 服务..."
@@ -449,7 +298,18 @@ EOF
echo "SERVER_HOST=$SERVER_HOST_PORT"
echo "FRONTEND_PORT=$FRONTEND_PORT"
echo "BACKEND_PORT=$BACKEND_PORT"
echo "ENABLE_IPV6=$ENABLE_IPV6"
# 如果启用了 IPv6,显示额外信息
if check_ipv6_support; then
echo ""
echo "📡 IPv6 访问信息:"
# 获取系统的 IPv6 地址
IPV6_ADDR=$(ip -6 addr show | grep -v "fe80" | grep -v "::1" | grep "inet6" | head -n1 | awk '{print $2}' | cut -d'/' -f1)
if [[ -n "$IPV6_ADDR" ]]; then
echo " 前端访问: http://[$IPV6_ADDR]:$FRONTEND_PORT"
echo " 后端访问: http://[$IPV6_ADDR]:$BACKEND_PORT"
fi
fi
}
# 更新功能
@@ -461,7 +321,21 @@ update_panel() {
curl -L -o docker-compose.yml "$DOCKER_COMPOSE_URL"
echo "✅ 下载完成"
# 检查当前是否已启用 IPv6(通过检查网络配置)
CURRENT_IPV6_ENABLED=false
if [[ -f "docker-compose.yml" ]] && grep -q "enable_ipv6: true" docker-compose.yml; then
CURRENT_IPV6_ENABLED=true
fi
# 如果之前启用了 IPv6 或系统支持 IPv6,自动启用
if [[ "$CURRENT_IPV6_ENABLED" == "true" ]]; then
echo "🔍 检测到当前配置已启用 IPv6,保持 IPv6 支持..."
update_compose_for_ipv6
elif check_ipv6_support; then
echo "🚀 系统支持 IPv6,自动启用 IPv6 配置..."
configure_docker_ipv6
update_compose_for_ipv6
fi
echo "🛑 停止当前服务..."
$DOCKER_CMD down
@@ -814,4 +688,4 @@ main() {
}
# 执行主函数
main
main