Создаем свой ddns

Основная идея ddns в том, чтобы предоставлять доступ к домашней сети/компьютеру если нет "белого ip". Конечно можно купить у своего интернет провайдера ip адрес и прописать его в А записи DNS своего домена.

Но как часто бывает - жаба душит. Итак задача - оперативно менять ip адрес на поддомене/домене для доступа к домашней сети.

Для того, чтобы автоматически менять ip в DNS нужен api у dns хостера. А еще желательно и бесплатно. Самое первое что гуглится это Yandex Connect, вот его api.

Чтобы его использовать, нужно:

  1. делегировать домен на yandex connect
  2. получить токен

Теперь нужно узнать текущий внешний ip адрес, для этого можно использовать сторонние сервисы, либо написать небольшой скрипт и разместить его на хостинге в интернете.

<?php
function getUserIP() {
    $ipaddress = '';
    if (isset($_SERVER['HTTP_CLIENT_IP']))
        $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
    else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
        $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
    else if(isset($_SERVER['HTTP_X_FORWARDED']))
        $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
    else if(isset($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']))
        $ipaddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
        $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
    else if(isset($_SERVER['HTTP_FORWARDED']))
        $ipaddress = $_SERVER['HTTP_FORWARDED'];
    else if(isset($_SERVER['REMOTE_ADDR']))
        $ipaddress = $_SERVER['REMOTE_ADDR'];
    else
        $ipaddress = 'UNKNOWN';
    return $ipaddress;
}
echo getUserIP();

Для примера можно использовать мой скрипт https://afinogen.ru/ip.php

Все данные есть, можно вручную через curl отправить пару запросов в api яндекса (Примеры с curl есть в доментации).

Для автоматизации я написал небольшой sh скрипт.

#!/usr/bin/env bash
TOKEN=123456789ABCDEF0000000000000000000000000000000000000
DOMAIN="afinogen.ru"
RECORD_ID=1000000
#curl -H "PddToken: $TOKEN" "https://pddimp.yandex.ru/api2/admin/dns/list?domain=$DOMAIN"
IP=$(curl -s 'https://afinogen.ru/ip.php')
OLD_IP=$(cat ip.txt)
echo $IP > ip.txt
#echo $OLD_IP
if [ "$IP" != "$OLD_IP" ]; then
echo "IP is change" >> /root/logs/change-ip-$(date +%d.%m.%Y).log 2>&1
curl -s -H "PddToken: $TOKEN" -d "domain=$DOMAIN&record_id=$RECORD_ID&subdomain=test&ttl=900&content=$IP" 'https://pddimp.yandex.ru/api2/admin/dns/edit' >> /root/logs/change-ip-$(date +%d.%m.%Y).log 2>&1
fi

Переменные:

  • TOKEN - токен доступа к API
  • DOMAIN - домен на котором будут обновляться записи
  • RECORD_ID - id изменяемой записи, для ее получения нужно запустить закоментированную строку. В json ответе будет список всех записей, нужно выбрать id изменяемой записи.

В моем примере меняется ip у поддомена test.afinogen.ru. Так ip адрес может меняться довольно часто, данный скрипт лучше всего повесить в крон и запускать раз в час. Чтобы не дергать каждый час яндекс - добавлена проверка на изменение ip.

0 * * * * bash /root/change-ip.sh


У меня скрипт запускается от рута, но это не обязательно. При размещении в других папках нужно будет изменить пути в кроне и в скрипте для логирования. Либо убрать запись в лог. Она нужна для удобства отладки.


Комментарии