この記事は、XServerのサブドメインにグローバルIPを反映させ、自宅サーバにアクセスできるようにしたい人向けの記事、および備忘録になります。

・X Serverでサブドメインを取得した。
・APIを使って自宅のグローバルIPをサブドメインに反映した。
・市販のDDNSサービス(mydnsなど)を使わず、自前ドメインのサブドメインで運用することで、怪しいURLにならず、信頼性の高いドメインで自宅サービスを公開できる!

XServerは2026年4月16日から「XServer API」の提供を開始し、色々できるようになったようです。
サブドメインに自宅のIPアドレスを設定し、家のサーバに接続に接続できるようになるのでは?と思ったので、一度試してみました。

Ubuntu 24.04.4 LTS (Lubuntu)
XServer レンタルサーバー

①XServerでドメインが無料でもらえるので、サブドメインを追加します。

今回はsub.xxxxx.comとして、追加します。

②XServerでAPIキーを取得し、メモっておきます。

「APIキー追加」から追加画面へ行きます。

APIキー名を入力し、権限は「カスタム」を選択します。

DNSレコード設定のみ「すべての操作」を選択し、それ以外は「利用不可」にします。
※今回はDNSだけ変更できればいいので。

確認画面に進み、APIキーが表示されたらメモっておきましょう。このタイミングでしかキーは表示されないようです。
追加後、APIキー一覧を確認し、対象サーバの項目の文字をメモっておきましょう。初期のドメイン名に該当します。(例:xs9999999.xsrv.jp)

③XServerのDNSレコード設定から更新したいサブドメインのDNSレコード設定を追加します。

「DNSレコード設定を追加」から追加画面へ行きます。

対象ドメインを選択し、ホスト名はサブドメインを入力します。内容には後でIPが更新されたことが分かるように、適当なIPアドレスを入力し、追加します。

④今回追加したDNSレコードのIDをターミナルから確認します。

curl -s \
"https://api.xserver.ne.jp/v1/server/{初期のドメイン名}/dns?domain={取得したドメイン名}" \
-H "Authorization: Bearer {APIキー}"
例)
curl -s \
"https://api.xserver.ne.jp/v1/server/xs9999999.xsrv.jp/dns?domain=xxxxx.com" \
-H "Authorization: Bearer xs_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

帰ってきた反応の一番最後に、今回追加したDNSレコードが表示されているので、IDを確認する。

{"id":123456789,"domain":"xxxxx.com","host":"sub.xxxxx.com","type":"A","content":"0.0.0.0","ttl":60,"priority":0}]}

⑤必要な情報をまとめます。
1.初期のドメイン名:例)xs9999999.xsrv.jp
2.取得したドメイン名:例)xxxxx.com
3.APIキー:例)xs_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
4.DNSレコードID:例)123456789

ここからは実作業用に、/opt/xserver-ddns に設定ファイルとスクリプトを分けて作る形で進めます。APIキーをスクリプト本体に直書きしない構成にします。
Ubuntu上で実際にスクリプトを作成 → 手動実行 → ログ確認 まで進める手順です

1.作業ディレクトリを作成

sudo mkdir -p /opt/xserver-ddns
sudo mkdir -p /var/lib/xserver-ddns

2.設定ファイルを作成
APIキーはここに入れます。

sudo vi /opt/xserver-ddns/xserver-ddns.conf

中身は以下の通りです。適宜書き換えてください。

XSERVER_API_KEY="xs_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
XSERVER_SERVERNAME="xs9999999.xsrv.jp"
DOMAIN="xxxxx.com"
TTL=60

RECORDS=(
"sub.xxxxx.com:123456789"
)

3.設定ファイルの権限を制限
APIキーが入るので、rootだけ読めるようにします

sudo chmod 600 /opt/xserver-ddns/xserver-ddns.conf
sudo chown root:root /opt/xserver-ddns/xserver-ddns.conf

4.更新スクリプトを作成

sudo vi /opt/xserver-ddns/update_xserver_dns.sh

中身は下記を貼り付けてください。

#!/usr/bin/env bash
set -euo pipefail

CONFIG_FILE="/opt/xserver-ddns/xserver-ddns.conf"
STATE_DIR="/var/lib/xserver-ddns"
IP_FILE="${STATE_DIR}/last_ipv4.txt"
LOG_FILE="/var/log/xserver-ddns.log"

if [[ ! -f "$CONFIG_FILE" ]]; then
echo "ERROR: 設定ファイルがありません: $CONFIG_FILE"
exit 1
fi

# 設定読み込み
source "$CONFIG_FILE"

mkdir -p "$STATE_DIR"

log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') $*" | tee -a "$LOG_FILE"
}

if [[ -z "${XSERVER_API_KEY:-}" ]]; then
log "ERROR: XSERVER_API_KEY が未設定です"
exit 1
fi

if [[ -z "${XSERVER_SERVERNAME:-}" ]]; then
log "ERROR: XSERVER_SERVERNAME が未設定です"
exit 1
fi

if [[ -z "${DOMAIN:-}" ]]; then
log "ERROR: DOMAIN が未設定です"
exit 1
fi

if [[ ${#RECORDS[@]} -eq 0 ]]; then
log "ERROR: RECORDS が空です"
exit 1
fi

# 現在のグローバルIPv4を取得
CURRENT_IP="$(curl -4 -fsS https://api.ipify.org || true)"

if [[ -z "$CURRENT_IP" ]]; then
log "ERROR: グローバルIPv4を取得できませんでした"
exit 1
fi

# IPv4形式チェック
if ! [[ "$CURRENT_IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
log "ERROR: 取得した値がIPv4形式ではありません: $CURRENT_IP"
exit 1
fi

# 0〜255の範囲チェック
IFS='.' read -r o1 o2 o3 o4 <<< "$CURRENT_IP"
for octet in "$o1" "$o2" "$o3" "$o4"; do
if (( octet < 0 || octet > 255 )); then
log "ERROR: IPv4の範囲外です: $CURRENT_IP"
exit 1
fi
done

LAST_IP=""
if [[ -f "$IP_FILE" ]]; then
LAST_IP="$(cat "$IP_FILE")"
fi

if [[ "$CURRENT_IP" == "$LAST_IP" ]]; then
log "OK: IP変更なし: $CURRENT_IP"
exit 0
fi

log "INFO: IP変更検出: ${LAST_IP:-なし} -> $CURRENT_IP"

for item in "${RECORDS[@]}"; do
HOST="${item%%:*}"
DNS_ID="${item##*:}"

log "INFO: DNS更新開始: ${HOST} -> ${CURRENT_IP}"

RESPONSE="$(curl -fsS \
-X PUT \
"https://api.xserver.ne.jp/v1/server/${XSERVER_SERVERNAME}/dns/${DNS_ID}" \
-H "Authorization: Bearer ${XSERVER_API_KEY}" \
-H "Content-Type: application/json" \
-d "{
\"domain\": \"${DOMAIN}\",
\"host\": \"${HOST}\",
\"type\": \"A\",
\"content\": \"${CURRENT_IP}\",
\"ttl\": ${TTL}
}" 2>&1)" || {
log "ERROR: DNS更新失敗: ${HOST}"
log "ERROR: ${RESPONSE}"
exit 1
}

log "OK: DNS更新完了: ${HOST}"
done

echo "$CURRENT_IP" > "$IP_FILE"
log "OK: 全レコード更新完了: $CURRENT_IP"

5.実行権限を付与

sudo chmod 700 /opt/xserver-ddns/update_xserver_dns.sh
sudo chown root:root /opt/xserver-ddns/update_xserver_dns.sh

6.サブドメインに適応させたい、現在のIPを確認します。

curl -4 https://api.ipify.org

7.手動実行

sudo /opt/xserver-ddns/update_xserver_dns.sh

初回は、おそらくこういうログになります。

2026-05-05 21:37:08 INFO: IP変更検出: なし -> 123.45.678.9
2026-05-05 21:37:08 INFO: DNS更新開始: sub.xxxxx.com -> 123.45.678.9
2026-05-05 21:37:09 OK: DNS更新完了: sub.xxxxx.com
2026-05-05 21:37:09 OK: 全レコード更新完了: 123.45.678.9

2回目に実行すると、

OK: IP変更なし: 123.45.678.9

これが出れば、前回IPとの比較処理も正常です。

8.ログ確認

sudo tail -n 50 /var/log/xserver-ddns.log

9.DNS側の確認

XServerのDNSレコード設定から、追加したサブドメインの「内容」が確認したIPアドレスを同じになっていたら更新OKです。

「内容」の部分が、先に設定した適当なIPアドレスからグローバルIPに書き換わっていると思います。

9.cronで5分ごとに自動実行
手動実行が成功したら、cronに入れます。

sudo crontab -e

下記を追加します。

*/5 * * * * /opt/xserver-ddns/update_xserver_dns.sh >/dev/null 2>&1

保存後、登録確認します。

sudo crontab -l

10.cron実行後の確認
5分程度経ったあとに、下記を確認します。

sudo tail -n 20 /var/log/xserver-ddns.log

正常なら、下記のようなログが増えます。

OK: IP変更なし: 123.45.678.9

今回の構成まとめ

/opt/xserver-ddns/
├── xserver-ddns.conf
└── update_xserver_dns.sh

/var/lib/xserver-ddns/
└── last_ipv4.txt

/var/log/
└── xserver-ddns.log

DNSレコード設定で入力したIPを適当なものに変更し、ちゃんとIPが更新されているか改めてテストをします。
今回のスクリプトは 前回保存したIP /var/lib/xserver-ddns/last_ipv4.txt と現在IPを比較しています。
前回IPの記録を削除します。

sudo rm -f /var/lib/xserver-ddns/last_ipv4.txt

下記を実行し、last_ipv4.txt が無ければOKです。

sudo ls -la /var/lib/xserver-ddns/

スクリプトを手動実行します。

sudo /opt/xserver-ddns/update_xserver_dns.sh

X serverのDNSレコード設定の画面を更新し、IPが更新されていればOKです。

今回無事にサブドメインを使い、家のサーバにアクセスできる環境をテスト的に整えてみました。
慣れない作業で苦戦しましたが、とりあえず目的は達成したと思います。
細かい設定、数値などは各々で調整してもらえたらと思います。

※自宅サーバーを公開する際は、ルーターのポート開放(ポートフォワーディング)設定などが必要です。
 またネットワークの知識がない状態で自宅サーバ公開などをすればセキュリティ上問題がでます。

自己責任でお試しください♪