150 lines
5.2 KiB
Markdown
Executable File
150 lines
5.2 KiB
Markdown
Executable File
# 动态IP情况下如何绑定域名
|
||
[toc]
|
||
## 使用场景
|
||
|
||
主要是用在家庭宽带等每次重启都会自动获取动态IP的场景下。这时候,如果需要访问我们的NAS或者内部服务器,则需要实时的将IP与域名重新绑定。
|
||
|
||
## 使用工具
|
||
|
||
1. 域名在cloudflare上。如果不在那个上面,则需要重新写脚本;
|
||
2. 获取到域名的global key;我们在[5.v2ray和trojan的翻墙配置](:/e80ad79f492c4c3d91bd85aa014bfc78)里也提到了这一点;
|
||
3. 一台在内部的服务器/电脑,linux系统。
|
||
|
||
## 开始制作
|
||
|
||
1. 获取你在cloudflare上面的key,在这个链接里找:https://www.cloudflare.com/a/account/my-account ,大概是这样子的:c8729fd0febf3f59a0102a047558ac07f1d51
|
||
2. 确保内部电脑可以正常上网;下载脚本:
|
||
3. 打开脚本,填入参数:
|
||
```bash
|
||
#!/usr/bin/env bash
|
||
set -o errexit
|
||
set -o nounset
|
||
set -o pipefail
|
||
# API key, see https://www.cloudflare.com/a/account/my-account,
|
||
# incorrect api-key results in E_UNAUTH error
|
||
CFKEY="cc729fd0febf3f59a0102a047558aa07f1d51" #这是你的global key,
|
||
# Username, eg: user@example.com
|
||
CFUSER="maxwellxzy@gmail.com" #你在cloudflare的账号
|
||
# Zone name, eg: example.com
|
||
CFZONE_NAME="disbaidu.com" #你要更新的域名的主域名,根域名,不带www
|
||
# Hostname to update, eg: homeserver.example.com
|
||
CFRECORD_NAME="read.disbaidu.com" #这是你要更新的dns的域名
|
||
# Record type, A(IPv4)|AAAA(IPv6), default IPv4
|
||
CFRECORD_TYPE=A #ipv4是这个
|
||
# Cloudflare TTL for record, between 120 and 86400 seconds
|
||
CFTTL=3600
|
||
# Ignore local file, update ip anyway
|
||
FORCE=false
|
||
WANIPSITE="http://ipv4.icanhazip.com"
|
||
|
||
# Site to retrieve WAN ip, other examples are: bot.whatismyipaddress.com, https://api.ipify.org/ ...
|
||
if [ "$CFRECORD_TYPE" = "A" ]; then
|
||
:
|
||
elif [ "$CFRECORD_TYPE" = "AAAA" ]; then
|
||
WANIPSITE="http://ipv6.icanhazip.com"
|
||
else
|
||
echo "$CFRECORD_TYPE specified is invalid, CFRECORD_TYPE can only be A(for IPv4)|AAAA(for IPv6)"
|
||
exit 2
|
||
fi
|
||
|
||
# get parameter
|
||
while getopts k:u:h:z:t:f: opts; do
|
||
case ${opts} in
|
||
k) CFKEY=${OPTARG} ;;
|
||
u) CFUSER=${OPTARG} ;;
|
||
h) CFRECORD_NAME=${OPTARG} ;;
|
||
z) CFZONE_NAME=${OPTARG} ;;
|
||
t) CFRECORD_TYPE=${OPTARG} ;;
|
||
f) FORCE=${OPTARG} ;;
|
||
esac
|
||
done
|
||
|
||
# If required settings are missing just exit
|
||
if [ "$CFKEY" = "" ]; then
|
||
echo "Missing api-key, get at: https://www.cloudflare.com/a/account/my-account"
|
||
echo "and save in ${0} or using the -k flag"
|
||
exit 2
|
||
fi
|
||
if [ "$CFUSER" = "" ]; then
|
||
echo "Missing username, probably your email-address"
|
||
echo "and save in ${0} or using the -u flag"
|
||
exit 2
|
||
fi
|
||
if [ "$CFRECORD_NAME" = "" ]; then
|
||
echo "Missing hostname, what host do you want to update?"
|
||
echo "save in ${0} or using the -h flag"
|
||
exit 2
|
||
fi
|
||
|
||
# If the hostname is not a FQDN
|
||
if [ "$CFRECORD_NAME" != "$CFZONE_NAME" ] && ! [ -z "${CFRECORD_NAME##*$CFZONE_NAME}" ]; then
|
||
CFRECORD_NAME="$CFRECORD_NAME.$CFZONE_NAME"
|
||
echo " => Hostname is not a FQDN, assuming $CFRECORD_NAME"
|
||
fi
|
||
|
||
# Get current and old WAN ip
|
||
WAN_IP=`curl -s ${WANIPSITE}`
|
||
WAN_IP_FILE=$HOME/.cf-wan_ip_$CFRECORD_NAME.txt
|
||
if [ -f $WAN_IP_FILE ]; then
|
||
OLD_WAN_IP=`cat $WAN_IP_FILE`
|
||
else
|
||
echo "No file, need IP"
|
||
OLD_WAN_IP=""
|
||
fi
|
||
|
||
# If WAN IP is unchanged an not -f flag, exit here
|
||
if [ "$WAN_IP" = "$OLD_WAN_IP" ] && [ "$FORCE" = false ]; then
|
||
echo "WAN IP Unchanged, to update anyway use flag -f true"
|
||
exit 0
|
||
fi
|
||
|
||
# Get zone_identifier & record_identifier
|
||
ID_FILE=$HOME/.cf-id_$CFRECORD_NAME.txt
|
||
if [ -f $ID_FILE ] && [ $(wc -l $ID_FILE | cut -d " " -f 1) == 4 ] \
|
||
&& [ "$(sed -n '3,1p' "$ID_FILE")" == "$CFZONE_NAME" ] \
|
||
&& [ "$(sed -n '4,1p' "$ID_FILE")" == "$CFRECORD_NAME" ]; then
|
||
CFZONE_ID=$(sed -n '1,1p' "$ID_FILE")
|
||
CFRECORD_ID=$(sed -n '2,1p' "$ID_FILE")
|
||
else
|
||
echo "Updating zone_identifier & record_identifier"
|
||
CFZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$CFZONE_NAME" -H "X-Auth-Email: $CFUSER" -H "X-Auth-Key: $CFKEY" -H "Content-Type: application/json" | grep -Po '(?<="id":")[^"]*' | head -1 )
|
||
CFRECORD_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CFZONE_ID/dns_records?name=$CFRECORD_NAME" -H "X-Auth-Email: $CFUSER" -H "X-Auth-Key: $CFKEY" -H "Content-Type: application/json" | grep -Po '(?<="id":")[^"]*' | head -1 )
|
||
echo "$CFZONE_ID" > $ID_FILE
|
||
echo "$CFRECORD_ID" >> $ID_FILE
|
||
echo "$CFZONE_NAME" >> $ID_FILE
|
||
echo "$CFRECORD_NAME" >> $ID_FILE
|
||
fi
|
||
|
||
# If WAN is changed, update cloudflare
|
||
echo "Updating DNS to $WAN_IP"
|
||
|
||
RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$CFZONE_ID/dns_records/$CFRECORD_ID" \
|
||
-H "X-Auth-Email: $CFUSER" \
|
||
-H "X-Auth-Key: $CFKEY" \
|
||
-H "Content-Type: application/json" \
|
||
--data "{\"id\":\"$CFZONE_ID\",\"type\":\"$CFRECORD_TYPE\",\"name\":\"$CFRECORD_NAME\",\"content\":\"$WAN_IP\", \"ttl\":$CFTTL}")
|
||
|
||
if [ "$RESPONSE" != "${RESPONSE%success*}" ] && [ "$(echo $RESPONSE | grep "\"success\":true")" != "" ]; then
|
||
echo "Updated succesfuly!"
|
||
echo $WAN_IP > $WAN_IP_FILE
|
||
exit
|
||
else
|
||
echo 'Something went wrong :('
|
||
echo "Response: $RESPONSE"
|
||
exit 1
|
||
fi
|
||
```
|
||
|
||
4. 接下来,就要让它执行:
|
||
```
|
||
$sudo chmod +x cf-v4-ddns.sh
|
||
```
|
||
|
||
5. 加入定时任务:
|
||
```
|
||
sudo crontab -e
|
||
```
|
||
|
||
```ini
|
||
5 * * * * bash /opt/cf-ddns/cf-v4-ddns.sh >> /var/log/cf-ddns.log
|
||
``` |