2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LinuxサーバーでダイナミックDNSを使う方法(MyDNS.JP編)

2
Last updated at Posted at 2025-12-23

MyDNS.JPを使おう!

本記事は、LinuxサーバーでダイナミックDNSを使う方法(Duck DNS編)の後続編となります。ダイナミックDNSとはなんぞや?という方はまずDuck DNS編からお読みください。(サラッと前記事の宣伝:sweat_smile:)
Duck DNSは簡単に利用できるのが売りのダイナミックDNSサービスですが、その反面高度な設定はできず、また筆者の実感としてはパフォーマンスもイマイチ良くない気がします。
そこで、筆者はMyDNS.JPをメインのダイナミックDNSとして利用しています。

MyDNS.JPとは

MyDNS.JPは無料で利用できるダイナミックDNSサービスです。名前通り日本発の老舗ダイナミックDNSサービスで、速度・安定性ともに定評がありさらにIPv6にも完全対応しています。また、IP通知はメールの受信またはログインページへアクセスによって行うため、他のダイナミックDNSサービスのように独自のプロトコルを必要としないのも特徴の一つです。

MyDNS.JPの利用方法

アカウント作成

まずはhttps://www.mydns.jpへアクセスして、アカウントを作成します。

  1. MyDNS.JPのWebサイトにアクセスして「Log In」をクリックします
    MyDNS-top.png
  2. 右上の「JOIN US」をクリックします。
    MyDNS-join.png
  3. 必要事項を入力して登録します。
    MyDNS-register.png

これでMyDNS.JPのアカウントが作成できました。登録が完了するとMaster IDとそのパスワードが発行されメールで送られてきます。

ドメインの登録

アカウントが作成できたらMaster IDとパスワードでMyDNS.JPにログインします。
そして、「DOMAIN INFO」の画面でドメインの情報を登録します。サブドメインは最大14個まで登録できます。
メールサーバーを動かしているならここでMXレコードも指定します。
MyDNS-domain.png

IP通知設定

ここからは自宅サーバー側の作業となります。
今回は、IP通知にはログインページへのアクセスによる方法を用います。

IP通知スクリプトの作成

つぎにIP通知用のスクリプトを作成します。

※スクリプトが結構なボリュームになってきたので、コピペが面倒くさいという方のためにGitHubにスクリプト一式を公開しました。よろしければこちらもご利用ください。

https://github.com/kenichyan/mydns
/usr/local/bin/mydns-update.sh
#!/bin/bash

# --- Load Configuration ---
CONF_FILE="/etc/mydns/mydns.conf"
[[ ! -f "$CONF_FILE" ]] && echo "Error: $CONF_FILE not found." >&2 && exit 1
source "$CONF_FILE"

# Prepare cache directory
mkdir -p "$CACHE_DIR"

log_message() {
    local target_log="${LOG_FILE:-/var/log/mydns_update.log}"
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$target_log"
}

# Function to fetch current global IP address
get_current_ip() {
    local url=$1
    curl -s -m "$TIMEOUT" --connect-timeout "$CONN_TIMEOUT" "$url" | tr -d '[:space:]'
}

update_dns() {
    local cred=$1
    local url=$2
    local mode=$3
    local current_ip=$4
    local id_only="${cred%%:*}"
    local cache_file="${CACHE_DIR}/${id_only}_${mode}.lastip"
    local force_update="no"

    # --- Update Determination Logic ---
    
    # 1. Force update if cache does not exist (Initial execution)
    if [[ ! -f "$cache_file" ]]; then
        force_update="yes"
        local reason="Initial execution"
    else
        local last_ip=$(cat "$cache_file")
        
        # 2. Force update if IP has changed
        if [[ "$current_ip" != "$last_ip" ]]; then
            force_update="yes"
            local reason="IP changed (${last_ip} -> ${current_ip})"
        
        # 3. Force update if 24 hours have passed even without IP change
        # find -mmin +1440 checks if the file was modified more than 1440 minutes (24h) ago
        elif [[ -n $(find "$cache_file" -mmin +1440) ]]; then
            force_update="yes"
            local reason="24 hours elapsed since last update"
        fi
    fi

    # Exit if no update is required
    if [[ "$force_update" == "no" ]]; then
        return 0
    fi

    # --- Execute Update ---
    response=$(curl -s -u "${cred}" -A "${USER_AGENT}" -m "${TIMEOUT}" \
        --connect-timeout "${CONN_TIMEOUT}" --fail --globoff "$url" 2>&1)
    
    local exit_code=$?

    if [[ $exit_code -eq 0 ]]; then
        log_message "[$mode] Success: $reason. ID $id_only updated."
        # Update cache file (using touch to refresh mtime even if IP is identical)
        echo "$current_ip" > "$cache_file"
        touch "$cache_file"
    elif [[ $exit_code -eq 22 ]]; then
        log_message "[$mode] Auth Error (401): ID $id_only."
    else
        log_message "[$mode] Error (Code: $exit_code): ID $id_only. Reason: $reason"
    fi
}

# --- Main Process ---

# 1. Fetch current global IP addresses
[[ "$ENABLE_IPV4" == "yes" ]] && CURRENT_IPV4=$(get_current_ip "$CHECK_IPV4_URL")
[[ "$ENABLE_IPV6" == "yes" ]] && CURRENT_IPV6=$(get_current_ip "$CHECK_IPV6_URL")

# 2. Iterate through credentials and execute updates
for entry in "${MYDNS_CREDENTIALS[@]}"; do
    if [[ "$ENABLE_IPV4" == "yes" && -n "$CURRENT_IPV4" ]]; then
        update_dns "$entry" "$IPV4_URL" "IPv4" "$CURRENT_IPV4"
    fi

    if [[ "$ENABLE_IPV6" == "yes" && -n "$CURRENT_IPV6" ]]; then
        update_dns "$entry" "$IPV6_URL" "IPv6" "$CURRENT_IPV6"
    fi
done

exit 0

このスクリプトでは、MyDNS.JPへ負荷をかけないように、自宅サーバーのIPアドレスが変化したときにだけ、MyDNS.JPに通知を行うようにしています。
また、IPアドレスが変わっていない場合でも、24時間に1回はIP通知を行うようにしています。(MyDNS.JPの仕様で24時間に一度は通知することが推奨されているため。)

スクリプトのパーミッションを設定する

このスクリプトファイルに実行許可を与えます。

shell
$ sudo chmod +x /usr/local/bin/mydns-update.sh

設定ファイルの作成

つぎに、認証情報などを格納した設定ファイルを作成します。

/etc/mydns/mydns.conf
# ==========================================
# MyDNS.JP Configuration
# ==========================================

# 認証情報: ("ID:Password" "ID:Password" ...)
MYDNS_CREDENTIALS=(
   # mydns123456:Password1
   # mydns123457:Password2
)

# 通知有効化設定 (yes/no)
ENABLE_IPV4="yes"
ENABLE_IPV6="yes"

# 通知先URL
IPV4_URL="http://ipv4.mydns.jp/login.html"
IPV6_URL="http://ipv6.mydns.jp/login.html"

# IP確認用URL (通知前に現在の外向きIPを知るための外部サービス)
# MyDNS自身に負荷をかけないよう、軽量なAPIを利用します
CHECK_IPV4_URL="https://ipv4.icanhazip.com"
CHECK_IPV6_URL="https://ipv6.icanhazip.com"

# タイムアウト設定(秒)
TIMEOUT=15
CONN_TIMEOUT=10

# 実行環境設定
USER_AGENT="MyDNS-Update-Script/1.4"
LOG_FILE="/var/log/mydns_update.log"

# キャッシュディレクトリ (IDごとの前回IPを保存)
CACHE_DIR="/var/cache/mydns"

ここで、IDPasswordは各自のものに書き換えてください。
また、このスクリプトでは複数アカウントに対応しています。複数のアカウントを管理している場合は、上記の例のようにそれぞれのIDとPasswordを対にして列挙してください。

設定ファイルのパーミッション設定

設定ファイルにはパスワード情報が含まれているので、root以外は読めないようにします。

$ sudo chmod 600 /etc/mydns/mydns.conf

これで、IP通知スクリプトの設置は完了です。

サービスの登録

これをそのままcronで回してもいいのですが、今回はより現代的なsystemdを利用する方法をとりました。
まずは以下のようなサービスファイルを作成します。

/etc/systemd/system/mydns-update.service
[Unit]
Description=MyDNS.jp IP Update Service
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/mydns-update.sh
User=root
Group=root

[Install]
WantedBy=multi-user.target

これは単純にIP通知スクリプトをサービス化しただけです。

次にタイマーファイルを作成し、登録したIP通知サービスをタイマーに登録します。

/etc/systemd/system/mydns-update.timer
[Unit]
Description=Run MyDNS.jp IP Update every 5 minutes

[Timer]
OnBootSec=45sec
OnUnitActiveSec=5min
Persistent=true

[Install]
WantedBy=timers.target

ここでは5分ごとにIP通知サービスを走らせるようにしています。

ブート時にはシステムが完全に起動するまで45秒間の「待ち」を入れています。これがないとシステム(特にネットワーク周り)が起動し切っていないうちにIP通知スクリプトが実行されてしまい、ブート時のIP通知が失敗します。
(45秒間というのはあくまで筆者の環境での値なので、上手くいかないようであれば各自で調整してください。)

タイマーの有効化

最後に、登録したタイマーを有効化します。

shell
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now mydns-update.timer

これで、5分に1回、MyDNS.JPへIP通知がされるようになります。
タイマーがきちんと動いているかどうか確認するには、

shell
$ systemctl list-timers mydns-update

とするとmydns-updateタイマーの現在の実行状況が確認できます。

まとめ

これでめでたくMyDNS.JPを使って固定したドメイン名で自宅サーバーへアクセスできるようになりました。
MyDNS.JPは複数のサブドメインに対して様々なレコードを指定することができて非常に高機能です。さらに、MyDNS.JPへのIP通知はログインページへアクセスするだけというとてもシンプルなものです。おまけに完全に無料で利用できるのですから、自宅サーバーを立てているならぜひとも使って頂きたいダイナミックDNSサービスだと思います。この記事がその一助になれば幸いです。(決して筆者はMyDNS.JPの回し者ではありません。:sweat_smile:
それではよい自宅サーバーライフを♪

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?