Skip to content

Commit

Permalink
feat: 🎸 failover support
Browse files Browse the repository at this point in the history
  • Loading branch information
monlor committed Aug 26, 2024
1 parent 64355ff commit 4309e1c
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 17 deletions.
4 changes: 2 additions & 2 deletions media-unlock/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
FROM ubuntu:latest

LABEL MAINTAINER [email protected]
LABEL VERSION 1.0.0
LABEL VERSION 1.1.0

RUN apt update && apt install dnsmasq -y && apt clean
RUN apt update && apt install dnsmasq bash curl -y && apt clean

COPY media.txt /tmp

Expand Down
6 changes: 5 additions & 1 deletion media-unlock/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ docker run -d --name media-unlock -e SNI_IP=x.x.x.x -p 53:53 monlor/media-unlock

## 环境变量

`MEDIA_DOMAIN_URL`: 支持指定远程的流媒体域名列表地址
`MEDIA_DOMAIN_URL`: 支持指定远程的流媒体域名列表地址

`SNI_IPS`: SNI IP列表,用逗号分隔

`TEST_INTERVAL`: IP可用性测试间隔,默认60
93 changes: 79 additions & 14 deletions media-unlock/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,53 @@
#!/bin/sh
#!/bin/bash

set -eu

# Configuration file for dnsmasq
CONFIG_FILE=/etc/dnsmasq.conf

cat > ${CONFIG_FILE} <<EOF
# Define a list of SNI_IPs, separated by commas
IFS=',' read -r -a IP_LIST <<< "$SNI_IPS" # Split the string into an array

# Set the interval for testing (in seconds)
# Default to 60 seconds if not set
INTERVAL=${TEST_INTERVAL:-60}

# Variable to hold the current IP
current_ip=""

# Function to test the current IP address
test_current_ip() {
if [ -n "$current_ip" ] && curl -s --connect-timeout 5 "http://$current_ip:80" > /dev/null; then
return 0
else
echo "$current_ip is not reachable."
return 1
fi
}

# Function to switch to the next available IP
switch_ip() {
for ip in "${IP_LIST[@]}"; do
if curl -s --connect-timeout 5 "http://$ip:80" > /dev/null; then
echo "Switching to $ip."
current_ip="$ip"
return 0
fi
done
echo "No available IP found."
return 1
}

# Function to generate dnsmasq configuration for all domains using a specified IP
generate_dnsmasq_config() {
local ip="$1"
local config_file="$2"

# Clear the existing configuration file
: > "$config_file"

# Write common dnsmasq settings
cat >> "$config_file" <<EOF
domain-needed
bogus-priv
no-resolv
Expand All @@ -17,16 +60,38 @@ local-ttl=60
interface=*
EOF

if [ -n "${MEDIA_DOMAIN_URL:=}" ]; then
echo "Downloading domain list from ${MEDIA_DOMAIN_URL}"
curl -L "${MEDIA_DOMAIN_URL}" | grep -v '^#' | grep -v '^$' | while read -r domain; do
echo "address=/$domain/${SNI_IP}" >> "${CONFIG_FILE}"
done
else
echo "Using domain list from /tmp/media.txt"
grep -h -v '^#' /tmp/media.txt | grep -v '^$' | while read -r domain; do
echo "address=/$domain/${SNI_IP}" >> "${CONFIG_FILE}"
done
fi
# Download domain list or use local file
if [ -n "${MEDIA_DOMAIN_URL:=}" ]; then
echo "Downloading domain list from ${MEDIA_DOMAIN_URL}"
while read -r domain; do
echo "address=/$domain/$ip" >> "$config_file"
done <<< "$(curl -L "${MEDIA_DOMAIN_URL}" | grep -v '^#' | grep -v '^$')"
else
echo "Using domain list from /tmp/media.txt"
while read -r domain; do
echo "address=/$domain/$ip" >> "$config_file"
done < /tmp/media.txt
fi
}

# Initialize with the first available IP
switch_ip || exit 1

# Generate the initial dnsmasq configuration
generate_dnsmasq_config "$current_ip" "$CONFIG_FILE"

# Start dnsmasq in the background
dnsmasq -d &

# Periodically test the current IP and switch if necessary
while true; do
if ! test_current_ip; then
switch_ip || exit 1 # Switch to a new IP if the current one is not reachable

# Update the dnsmasq configuration with the new reachable IP
generate_dnsmasq_config "$current_ip" "$CONFIG_FILE"
fi

dnsmasq -d
# Sleep for the specified interval before the next test
sleep "$INTERVAL"
done

0 comments on commit 4309e1c

Please sign in to comment.