ヤマハ・RTXルーターのluaからDDNS更新

はじめに

テスト・開発用サーバーを適宜,起動・停止させるようにした為,連続停止が1週間ほど続いた場合に,ddnsサービスからddnsの更新が無いと警告が来るようになった。そのまま放置するとアカウントが停止するので,強制的にddns更新をさせる必要がある。
今まではサーバーに入れたddns更新ソフト(Dice,DeNSuke)で更新していたが,サーバー停止中なので更新できない。常時稼働中のルーターからddnsを更新する仕組みを検討・構築した。

DDNS:「ダイナミックドメインネームシステム (Dynamic Domain Name System、ダイナミックDNS、DDNS)」

方針

サーバーからの更新は,MyDNSを利用していたが,これも見直したいと思っている。
レジストラ(お名前.com)のネームサーバーを直接更新したいが,ddnsの詳細な技術情報が公開されておらずDNSクライアントソフトを使用しての更新の為,技術的に難しい。
リセラ(販売業者:バリュードメイン)のネームサーバーは更新できそうなので,一部のドメインの更新に利用したい。
残りのドメインはお名前.comのネームサーバー更新をあきらめて,従来通りのMyDNSのネームサーバーを更新するように設定する。特殊技でお名前.comのネームサーバーを使用する方法もあるようだが,特殊な設定なので今回は見送る。

方策検討

ヤマハのルーターはluaスクリプト(ルアスクリプト)で書かれたコードを登録して実行させる。
ヤマハのHPにはluaスクリプトの設定例が記載されているが,ddnsの更新については見たところ記載されていない。ネット検索したらいくつか情報が見つかった。

ルーターでのluaの実行について,おおまかに下記の二通りがある。
 ① 常時稼働でipアドレス変更監視をさせて変更時に更新させる方法
 ② スケジュールにて,ipアドレス変更有無に関わらず定期的に変更させる方法

 コードは複雑になるが①で設定する。
 ipアドレス変更時と定期的にipアドレスを強制更新するluaスクリプトを作成する。
 丁度思い通りのコードが見つかったので,有難く参考にさせてもらう。_(._.)_

luaスクリプト作成

ddnsの更新先はvalue-domainとMyDNSの二か所なので,それぞれのひな形を作成してみた。
value-domainはアカウント用とは別にddns更新用パスワードが設定されており,コードをそれに対応するようにカスタマイズした。それを元にMyDNS用を作成した。

HTTP リクエスト送信のAPIで「 rt.httprequest(TABLE)」の auth_typeオプションは_RT_LUA_VERSION が “1.08” 以上で指定可能なので,RTX1210(1.08)以降でないと指定できない。また,”https://”指定もVer:1.08以上で指定可能で,”http://hoge.com:443/”指定ではエラーになる。BASIC認証不要であれば,「auth_type_op」「auth_username」「auth_password」はnil指定する。
MyDNSのpop3での更新もテストしてみた。MyDNS側ではメールを受け付けてもらえないので,SYSLOGにリトライメッセージが記録され,戻り値のメール送信結果が「false:送信失敗」となる。MyDNSのHPで
※実際にはメールを送信することはできません。メールの受信チェック=IPアドレスの通知、です。」と記載されている。luaスクリプトで受信のみ設定できればよいのだが。
裏技としてSMTPサーバーを自分のメールサーバーにして,「smtp_auth_name」,「smtp_auth_password」を記載し,自分のメールアドレスへ送信させる。受信はMyDNSのPOPサーバー「ipv4.mydns.jp or ipv6.mydns.jp」を指定して「pop_before_smtp」をtrueで行えば戻り値のメール送信結果が「true:送信成功」となり,ddnsの更新もされる。
ipアドレスの更新が行われた事をメールで確認できるので,一石二鳥かな。

value-domain用

hoge.comのipアドレスをddnsサービスのバリュードメインに通知する。
設定箇所 (網掛け行)
ddns更新ドメイン名「hoge.com」,更新用パスワード「DDNSPASS」,ddnsサービスホスト名「dyn.value-domain.com」,luaバージョンは1.08なのでUpTypeは「https」

--[[

DDNSのIPアップデート   value_ddns-update.lua    hoge.com >>>> dyn.value-domain.com

*** YAMAHAルーター専用 ***

PPPoEで設定されたlocal側のIPアドレスを取得し、既存IPアドレスと異なれば取得したIPアドレスでDDNSを更新する。
IPアドレスが同じであれば更新はしない。WatchInterval * UpdateInterval(秒)で設定された期間更新されない場合、
強制的にIPアドレスを更新する。

※下記サンプルはdyn.value-domain.com バリュードメイン用に記述した。
 他のDDNSサービスに使用する場合は、サービスに応じたUpType/UpHost/UpUrlパラメータを記述すること。
 value-domainはddns更新用パスがauth用と別に必要で,汎用性を持たせるため,authとddnsを記載してある。

]]

----------------------## 設定 ここから ##----------------
-- debug(tru | false で指定) 本番稼働はtru
debug    = tru

----------------------## DDNSサービスに応じた変更箇所 ##----------------
-- DDNS service user account others   auth_typeがbasicの場合はauth_userとpass必須
method_op     = "GET"    --   "GET" | "HEAD" | "POST"  通常は"GET"
auth_type_op  = ""     --   "" | "basic"  ""はデフォルト(none),"basic"は“1.08” 以降
auth_username = ""     -- BASIC認証・POP認証用ユーザー名
auth_password = ""     -- BASIC認証・POP認証用パスワード
ddns_username = ""     -- URLパラメーター指定ユーザー名
ddns_password = "DDNSPASS"     -- URLパラメーター指定パスワード
host = "*"             --   "" | "*" | "www" ホスト名が必要時指定
domain = "hoge.com"    -- ddns更新ドメイン名
UpHost = "dyn.value-domain.com"    -- ddnsサービスホスト名
ipvn   = "ipv4"    --   "ipv4" | "ipv6"   MyDNS用

---------------------## ルーターのLUAバージョン毎の設定
-- _RT_LUA_VERSION が “1.08” 以降は"https" , "1.07"以前はhttpを指定
UpType = "https"    --   "http" | "https"
UpPort = ""    --   "" | ":80" | ":443"  通常は指定なし

-- DDNS update api address ##### ddnsサービスのホスト名設定
-- HTTP(s)-BASIC URL   mydns用
basic_url = UpType .. "://" .. ipvn .. ".mydns.jp/login.html"

-- HTTP(s)-DIRECT URL   value-domain用 mydns用
-- UpUrl の末尾にIPが自動付加されるので末尾に更新用IPアドレスを指定。
if (UpHost == "dyn.value-domain.com") then
  UpUrl  = UpType .. "://" .. UpHost .. UpPort .. "/cgi-bin/dyn.fcg?d=" .. domain .. "&p=" .. ddns_password .. "&h=" .. host .. "&i="
else
 IPVN = string.upper(ipvn) 
 UpUrl  = UpType .. "://" .. UpHost .. UpPort .. "/directip.html?MID=" .. ddns_username .. "&PWD=" .. ddns_password .. "&" .. IPVN .. "ADDR="
end

-- mail (POP3)   「mydns」にメールで更新する場合
update_type         = ""          --   "" | "mail"  メールでの更新時は"mail"指定
SMTP_ADDRESS        = "hoge.com"      -- 自分のメールサーバー
SMTP_PORT           = "587"           --  "25" | "587"
SMTP_AUTH_NAME      = "hogehogee@hoge.com"   -- 自分のメールサーバーアカウント
SMTP_AUTH_PASSWORD  = "smtp_pass"  -- 自分のメールサーバーパスワード
POP_BEFORE_SMTP     = true
POP_PROTOCOL        = "pop3"
POP_ADDRESS         = ipvn .. ".mydns.jp"
POP_AUTH_NAME       = auth_username
POP_AUTH_PASSWORD   = auth_password
FROM                = auth_username .. "@mydns.jp"
TO                  = "hogehoge@hoge.com"          -- 自分のメールアドレス
SUBJECT             = "MyDNS.JP IpInfo Update from MAIL"

----------------------## DDNSサービスに応じた変更箇所 おわり##----------------

-- IP取得するPP番号
pp_num   = 1

-- 実行指定時間(hh:mm)    強制updateの時刻
schedule = "01:00"

-- 実行間隔秒数と強制アップデート実施カウンターのしきい値
--
-- IP取得リトライ回数と間隔(秒数)
interval_retrypp = 3
interval_timespp = 10

-- syslogwatch time 86400/day, max 864000(10days)
-- interval_watch * interval_update   1週間update無しで警告がでるサービスもあり。「毎日1時update」
interval_watch  = 86400
interval_update = 1

-- syslogwatch タイマー誤差の補正値(NVR500の実績でNVR700Wでは不要の模様)RTXでは不要? 動作に影響なし
-- for NVR500 (-90秒)
--correction_time = -90
-- for NVR700W (補正不要)
correction_time = 0

----------------------## 設定 ここまで ##----------------


------------------------------------------------------------
-- syslog出力関数 --
------------------------------------------------------------
function putSyslog(msg)
  rt.syslog("info", "[LUA] ddns-update.lua DDNS " .. msg)
end

------------------------------------------------------------
-- 指定した時間までの秒数を返す関数 --
------------------------------------------------------------
function getDiffTime(t_dest)
  local t_adjust, t_diff
  local tmp  = {string.split(t_dest, /:/)}
  local now  = os.time()
  local time = os.date("*t", now)

  time.hour = tmp[1]
  time.min  = tmp[2]
  time.sec  = 0

  tmp = os.time(time)

  if os.difftime(tmp, now) <= 60 then
    time = os.date("*t", tmp + interval_watch)
  end

  t_diff   = os.difftime(os.time(time), now)
  t_adjust = (t_diff * correction_time) / interval_watch

  return (t_diff + t_adjust)
end

------------------------------------------------------------
-- 指定されたPPの local IP 取得関数 --
------------------------------------------------------------
function getLocalIp(id)
  local rtn, str, ipadr
  local cmd = "show status pp " .. tostring(id)
  local ptn = "PP IP Address Local:%s+(%d+%.%d+%.%d+%.%d+)"

  rtn, str = rt.command(cmd)

  if (rtn) and (str) then
    ipadr = str:match(ptn)

    if (ipadr == nil) then
      rtn   = false
      ipadr = "PPP not linked up"
    end
  else
    rtn   = false
    ipadr = cmd .. "Can not obtain IPaddr (command exec failure: " .. cmd .. ")\r\n"
  end

  return rtn, ipadr
end

------------------------------------------------------------
-- IPアドレスの変化検出関数 --
------------------------------------------------------------
function isNew(ip)
  local blip
  blip = os.getenv("GLOBALIP")

  if (blip) then
    if (blip == ip) then
      return false
    else
      rt.command("set GLOBALIP=" .. ip)
      return true
    end
  else
    rt.command("set GLOBALIP=" .. ip)
    return true
  end
end

------------------------------------------------------------
-- DDNS Update 関数 --
------------------------------------------------------------
function UpdateDDNS(ip)
  if (update_type == "mail") then
    mail_table = {
     smtp_address        = SMTP_ADDRESS,
     smtp_port           = SMTP_PORT,
     smtp_auth_name      = SMTP_AUTH_NAME,
     smtp_auth_password  = SMTP_AUTH_PASSWORD,
     pop_before_smtp     = POP_BEFORE_SMTP,
     pop_address         = POP_ADDRESS,
     pop_protocol        = POP_PROTOCOL,
     pop_auth_name       = POP_AUTH_NAME,
     pop_auth_password   = POP_AUTH_PASSWORD,
     from                = FROM,
     to                  = TO,
     subject             = SUBJECT,
     text                = domain .. " - detected new ip and update (old/new ip): " .. oldip .. "/" .. ip
     }
    mail_resp = rt.mail(mail_table)     -- メール(POP3)更新用
     if (not mail_resp) then
       putSyslog("mail update failed - " .. "return code-> " .. tostring(mail_resp) )
     else
       putSyslog("new IP = " .. ip)
       oldip = ip
     end

  else
     if (auth_type_op == "basic") then
        puturl = basic_url
        req_table = {
        url       = puturl,
        method    = method_op,
        auth_type = auth_type_op,
        auth_name = auth_username,
        auth_pass = auth_password
        }
     else
        puturl = UpUrl .. ip
        req_table = {
        url       = puturl,
        method    = method_op,
        }
     end

   putSyslog("update url = " .. puturl)
   resp_table = rt.httprequest(req_table)

     if (resp_table.rtn1) then
       putSyslog("new IP = " .. ip)
       oldip = ip
     else
      putSyslog("update failed - " .. "\nrtn1-> " .. tostring(resp_table.rtn1) .. "\nrtn2-> " .. tostring(resp_table.rtn2) .. "\nerr-> " .. tostring(resp_table.err) .. "\ncode-> " .. tostring(resp_table.code) .. "\nheader-> " .. tostring(resp_table.header) .. "\nbody-> " .. tostring(resp_table.body))
     end
  end

end

------------------------------------------------------------
-- main --
------------------------------------------------------------
local rtn, str, lip, cnt, sec
cnt = 0

putSyslog("updater starting (lua = " .. _RT_LUA_VERSION .. " , using " .. UpType .. ") ...")
rtn, str = getLocalIp(pp_num)

-- IP取得できない場合(リンクアップ待ち、等)は指定の回数・間隔でリトライ
if (not rtn) then
  cnt = interval_retrypp

  repeat
    putSyslog("try to specify target ... retry " .. math.abs(cnt - interval_retrypp - 1))
    rt.sleep(interval_timespp)
    rtn, str = getLocalIp(pp_num)
    cnt = cnt - 1
  until (rtn or cnt < 1)
end

if (rtn) then
  putSyslog("target is (if = " .. string.format("PP[%02d]:", pp_num) .. str .. ")")
  lip = str
  oldip = str

  if (isNew(lip)) then
    if (not debug) then UpdateDDNS(lip) else print("-- UpdateDDNS(lip)") end
  end
else
  putSyslog("target specify failure. aborted: " .. str)
  os.exit(1)
end

cnt = 0
sec = getDiffTime(schedule)
putSyslog("next ip-check is after " .. sec .. " seconds")

while (true) do
  local rtn, str, lip, gip
  rtn, str = rt.syslogwatch(string.format("PP%%[%02d%%]", pp_num) .. " PPP/IPCP up%s+%(Local:%s+(%d+%.%d+%.%d+%.%d+)", 1, sec)

  if (rtn == 0) then
    gip = os.getenv("GLOBALIP") or ""
    cnt = cnt + 1

    if (cnt == interval_update) then
      cnt = 0
      putSyslog("force update, new ip = " .. gip)

      if (not debug) then
        UpdateDDNS(gip)
      else
        print("Skip counter = " .. tostring(interval_update) .. ", DDNS update ip = " .. gip)
      end
    end
  else
    lip = string.match(str[rtn], "Local:%s+(%d+%.%d+%.%d+%.%d+)")
    putSyslog("detected new ip and update (old/new ip): " .. oldip .. "/" .. lip)

    if (isNew(lip)) then
      if (not debug) then
        UpdateDDNS(lip)
      else
        print("DDNS update called in while loop\n")
      end

      cnt = 0
    end
  end

  sec = getDiffTime(schedule)
  putSyslog("next ip-check is after " .. sec .. " seconds")

end

 

MyDNS用

冒頭の設定部分だけ記載した。後の部分は上のvalue-domain用と同じ。
hoge.jpのipアドレスをddnsサービスのMyDNSに通知する。
設定箇所 (網掛け行)
BASIC認証指定,auth_user「mydns123456」,auth_pass「mydnspass」,ddns更新ドメイン名「hoge.jp」,ddnsサービスホスト名「www.mydns.jp」,ipアドレスは「ipv4」,luaバージョンは1.08なのでUpTypeは「https」

--[[

DDNSのIPアップデート   ddns-update.lua   hoge.jp >>>> www.mydns.jp

*** YAMAHAルーター専用 ***

PPPoEで設定されたlocal側のIPアドレスを取得し、既存IPアドレスと異なれば取得したIPアドレスでDDNSを更新する。
IPアドレスが同じであれば更新はしない。WatchInterval * UpdateInterval(秒)で設定された期間更新されない場合、
強制的にIPアドレスを更新する。

※下記サンプルはdyn.value-domain.com バリュードメイン用に記述したものをMyDNS用に書き換えた。
 他のDDNSサービスに使用する場合は、サービスに応じたUpType/UpHost/UpUrlパラメータを記述すること。
 value-domainはddns更新用パスがauth用と別に必要で,汎用性を持たせるため,authとddnsを記載してある。

]]

----------------------## 設定 ここから ##----------------
-- debug(tru | false で指定) 本番稼働はtru
debug    = tru

----------------------## DDNSサービスに応じた変更箇所 ##----------------
-- DDNS service user account others   auth_typeがbasicの場合はauth_userとpass必須
method_op     = "GET"    --   "GET" | "HEAD" | "POST"  通常は"GET"
auth_type_op  = "basic"     --   "" | "basic"  ""はデフォルト(none),"basic"は“1.08” 以降
auth_username = "mydns123456"     -- BASIC認証・POP認証用ユーザー名
auth_password = "mydnspass"     -- BASIC認証・POP認証用パスワード
ddns_username = ""     -- URLパラメーター指定ユーザー名
ddns_password = ""     -- URLパラメーター指定パスワード
host = "*"             --   "" | "*" | "www" ホスト名が必要時指定
domain = "hoge.jp"    -- ddns更新ドメイン名
UpHost = "www.mydns.jp"    -- ddnsサービスホスト名
ipvn   = "ipv4"    --   "ipv4" | "ipv6"   MyDNS用

---------------------## ルーターのLUAバージョン毎の設定
-- _RT_LUA_VERSION が “1.08” 以降は"https" , "1.07"以前はhttpを指定
UpType = "https"    --   "http" | "https"
UpPort = ""    --   "" | ":80" | ":443"  通常は指定なし

-- DDNS update api address ##### ddnsサービスのホスト名設定
-- HTTP(s)-BASIC URL   mydns用
basic_url = UpType .. "://" .. ipvn .. ".mydns.jp/login.html"

-- HTTP(s)-DIRECT URL   value-domain用 mydns用
-- UpUrl の末尾にIPが自動付加されるので末尾に更新用IPアドレスを指定。
if (UpHost == "dyn.value-domain.com") then
  UpUrl  = UpType .. "://" .. UpHost .. UpPort .. "/cgi-bin/dyn.fcg?d=" .. domain .. "&p=" .. ddns_password .. "&h=" .. host .. "&i="
else
 IPVN = string.upper(ipvn) 
 UpUrl  = UpType .. "://" .. UpHost .. UpPort .. "/directip.html?MID=" .. ddns_username .. "&PWD=" .. ddns_password .. "&" .. IPVN .. "ADDR="
end

-- mail (POP3)   「mydns」にメールで更新する場合
update_type         = ""          --   "" | "mail"  メールでの更新時は"mail"指定
SMTP_ADDRESS        = "hoge.com"      -- 自分のメールサーバー
SMTP_PORT           = "587"           --  "25" | "587"
SMTP_AUTH_NAME      = "hogehoge@hoge.com"   -- 自分のメールサーバーアカウント
SMTP_AUTH_PASSWORD  = "smtp_pass"  -- 自分のメールサーバーパスワード
POP_BEFORE_SMTP     = true
POP_PROTOCOL        = "pop3"
POP_ADDRESS         = ipvn .. ".mydns.jp"
POP_AUTH_NAME       = auth_username
POP_AUTH_PASSWORD   = auth_password
FROM                = auth_username .. "@mydns.jp"
TO                  = "hogehoge@hoge.com"          -- 自分のメールアドレス
SUBJECT             = "MyDNS.JP IpInfo Update from MAIL"

----------------------## DDNSサービスに応じた変更箇所 おわり##----------------


-- ######以下はvalue-domain用と同じ

メール更新用

MyDNSにメールで更新する場合は,メール設定箇所に追加修正する。
POP認証用ユーザー名・パスワードは上記で指定済なので,それ以外のメール情報を指定する。下記網掛け箇所

-- mail (POP3)   「mydns」にメールで更新する場合
update_type         = "mail"          --   "" | "mail"  メールでの更新時は"mail"指定
SMTP_ADDRESS        = "hoge.com"      -- 自分のメールサーバー
SMTP_PORT           = "587"           --  "25" | "587"
SMTP_AUTH_NAME      = "hogehoge@hoge.com"   -- 自分のメールサーバーアカウント
SMTP_AUTH_PASSWORD  = "smtp_pass"  -- 自分のメールサーバーパスワード
POP_BEFORE_SMTP     = true
POP_PROTOCOL        = "pop3"
POP_ADDRESS         = ipvn .. ".mydns.jp"
POP_AUTH_NAME       = auth_username
POP_AUTH_PASSWORD   = auth_password
FROM                = auth_username .. "@mydns.jp"
TO                  = "hogehoge@hoge.com"          -- 自分のメールアドレス
SUBJECT             = "MyDNS.JP IpInfo Update from MAIL"

luaスクリプトの登録

luaスクリプトをルーターに登録

作成したluaスクリプトをusbメモリーに「ddns-update.lua」の名前でluaフォルダーを新規作成して保存。
telnetでルーターのコンソール画面からusbメモリーの「/lua」フォルダーをコピーする。

※RTX1200で「/lua」フォルダー毎コピーした際,このluaファイルではないのだがファイル名が短い(3~4文字)ファイルが大文字に変換されてコピーされた。ファイル単位でコピーすれば小文字でコピーされる。luaをコマンドで起動する際には大文字小文字を区別するので重要な点だ。

C:\WINDOWS\system32>telnet 192.168.***.***
Password:    <<<< パスワードは表示されない

RTX1210 Rev.14.01.41 (Mon Jun 13 15:33:27 2022)
Copyright (c) 1994-2022 Yamaha Corporation. All Rights Reserved.
To display the software copyright statement, use 'show copyright' command.
00:00:00:00:00:00, 00:00:00:00:00:00, 00:00:00:00:00:00
Memory 256Mbytes, 3LAN, 1BRI
> ad
> administrater    <<<<自動変換される
Password:    <<<< パスワードは表示されない

# copy usb1:/lua /lua
# show file list / all
[ / ]
2022/XX/XX 21:55:15 <DIR>           ap_config
2022/XX/XX 14:10:13 <DIR>           dashboard
2022/XX/XX 15:56:18 <DIR>           lanmap
2022/XX/XX 10:57:13 <DIR>           lua
2022/XX/XX 18:24:28            6863 wol.html

[ /lua ]
2022/XX/XX 10:57:13            6548 ddns-update.lua

ルーター環境設定

ルーターに登録したluaスクリプト「ddns-update.lua」を実行させるスケジュールをconfigで設定。
ルーター起動時にスタートさせ,その後は常時起動しながらipアドレスの変更を監視させる。
「schedule at 1」でNTPの更新スケジュールが既に登録されているのでluaスクリプトは「schedule at 2」とする。

#ddns更新スケジュール
schedule at 2 startup * lua /lua/ddns-update.lua

 

動作確認

動作確認はルーターのコンソール画面からとSYSLOGで確認する。
ルーターを再起動させて,「ddns-update.lua」をスケジュール起動させる。
コンソール画面から「show status lua」コマンドで確認  問題なく動作している。

# show status lua
Luaライブラリバージョン:        Lua 5.1.5
Luaスクリプト機能バージョン:    1.08

[running]
LuaタスクID (状態):  1  (WATCH)
走行トリガー:        スケジュールによる実行
コマンドライン:      lua /lua/ddns-update.lua
スクリプトファイル:  /lua/ddns-update.lua
監視文字列:          "PP%[01%] PPP/IPCP up%s+%(Local:%s+(%d+%.%d+%.%d+%.%d+)"
開始日時:            2022/XX/XX 11:06:13
経過時間:            27秒

[history]
過去の走行履歴はありません
# 

 

ルーターSYSLOG

ルーターのSYSLOG確認  PP1を切断-接続してIPアドレスを変化させてMyDNSの更新を確認。MyDNSのlogでも確認。

# pp select 1
pp1# 
pp1# disconnect pp 1
pp1# connect pp 1
pp1# 
起動時
2022/XX/XX 19:50:54: [LUA] created Lua Task(1)
2022/XX/XX 19:50:54: [LUA] ddns-update.lua DDNS updater starting (lua = 1.08 , using https) ...
2022/XX/XX 19:50:54: [LUA] Task(1) executed rt.command("show status pp 1"): true
2022/XX/XX 19:50:54: [LUA] ddns-update.lua DDNS target is (if = PP[01]:100.***.***.001)
2022/XX/XX 19:50:54: [LUA] Task(1) executed rt.command("set GLOBALIP=100.***.***.001"): true
2022/XX/XX 19:50:54: [LUA] ddns-update.lua DDNS update url = https://www.mydns.jp/directip.html?MID=mydns123456&PWD=mydnspass&IPV4ADDR=100.***.***.001
2022/XX/XX 19:50:54: [LUA] Task(1) started rt.httprequest
2022/XX/XX 19:51:09: [LUA] Task(1) completed rt.httprequest
2022/XX/XX 19:51:09: [LUA] ddns-update.lua DDNS new IP = 100.***.***.001
2022/XX/XX 19:51:09: [LUA] ddns-update.lua DDNS next ip-check is after 18531 seconds
2022/XX/XX 19:51:09: [LUA] Task(1) started rt.syslogwatch

ipアドレス変更時
2022/XX/XX 20:03:11: [LUA] Task(1) completed rt.syslogwatch
2022/XX/XX 20:03:11: [LUA] ddns-update.lua DDNS detected new ip and update (old/new ip): 100.***.***.001/200.***.***.002
2022/XX/XX 20:03:11: [LUA] Task(1) executed rt.command("set GLOBALIP=200.***.***.002"): true
2022/XX/XX 20:03:11: [LUA] ddns-update.lua DDNS update url = https://www.mydns.jp/directip.html?MID=mydns123456&PWD=mydnspass&IPV4ADDR=200.***.***.002
2022/XX/XX 20:03:11: [LUA] Task(1) started rt.httprequest
2022/XX/XX 20:03:11: [LUA] Task(1) completed rt.httprequest
2022/XX/XX 20:03:11: [LUA] ddns-update.lua DDNS new IP = 200.***.***.002
2022/XX/XX 20:03:11: [LUA] ddns-update.lua DDNS next ip-check is after 17809 seconds
2022/XX/XX 20:03:11: [LUA] Task(1) started rt.syslogwatch

定時更新時
2022/XX/XX 01:00:00: [LUA] Task(1) detected time out in rt.syslogwatch
2022/XX/XX 01:00:00: [LUA] ddns-update.lua DDNS force update, new ip = 200.***.***.002
2022/XX/XX 01:00:00: [LUA] ddns-update.lua DDNS update url = https://www.mydns.jp/directip.html?MID=mydns123456&PWD=mydnspass&IPV4ADDR=200.***.***.002
2022/XX/XX 01:00:00: [LUA] Task(1) started rt.httprequest
2022/XX/XX 01:00:01: [LUA] Task(1) completed rt.httprequest
2022/XX/XX 01:00:01: [LUA] ddns-update.lua DDNS new IP = 200.***.***.002
2022/XX/XX 01:00:01: [LUA] ddns-update.lua DDNS next ip-check is after 86399 seconds
2022/XX/XX 01:00:01: [LUA] Task(1) started rt.syslogwatch

MyDNS LOG

BASIC認証のLOG

2022/XX/XX 21:30:59 JST	DNS UPDATE : hohe.jp
2022/XX/XX 21:30:59 JST	IPv4 UPDATE : mydns123456 ***.***.***.*** (***-***-***-***.nnnnn.abcde.or.jp), http, ny02

POP3更新のメール連絡

RTX810でPOP3更新のテストをしてみた。
更新後に送信される自分宛のメールにルーターの情報が記載されている。あまり頻繁に更新されないのであれば,これも有かも。

バリュードメインのDDNS設定

バリュードメイン側のDDNS設定は,HPにユーザーズガイドが記載されている。

考察

とりあえず,ルーターからDDNS更新が出来るようになった。サーバーが停止していても更新してくれるので,1週間以上長期停止してのサーバーメンテナンスも安心して行える。
LUAのバージョンが最新(1.08)でないとSSL通信出来ないので,URLパラメーターにユーザーIDとパスワードを指定しているのが気になる。しかし今までのDICEもSSLでなかったので変わらなのか。
利点としては,今までの更新ツールはipアドレス監視は5分毎に行っており,アクセスのタイミングによってはipアドレスの変更に重なると最大5分間アクセス出来ないのだが,今回の方式ではluaで常時監視して変更と同時にddnsのupdateに行くのでそれは皆無になった。
メールのpopアドレスを自分のメールサーバーにして,mail条件のif文をコメントにするなどすれば,自分宛に更新連絡のメールが来るように出来る。というか単純にメール更新にすれば良いだけだが。

TOPに戻る

しばらく運用しての問題

ルーターの起動直後や回線・プロバイダーのメンテナンス等でグローバルIPアドレスを一定時間(30秒)に一定回数(3回)取得出来なかった場合はLUAが終了する。

2023/04/01 15:02:43: [LUA] ddns-update.lua DDNS updater starting (lua = 1.08 , using https) ...
2023/04/01 15:02:43: [LUA] ddns-update.lua DDNS try to specify target ... retry 1
2023/04/01 15:02:53: [LUA] ddns-update.lua DDNS try to specify target ... retry 2
2023/04/01 15:03:03: [LUA] ddns-update.lua DDNS try to specify target ... retry 3
2023/04/01 15:03:13: [LUA] ddns-update.lua DDNS target specify failure. aborted: PPP not linked up

回避する方法は下記の設定値を修正する方法があるが,メンテナンス等で長時間停止の場合は,復旧後にルーターを再起動する方法が手っ取り早い。ルーター起動時のIPアドレス取得失敗対策は値を大きくする。
「例:30秒3回 → 5分10回」

-- IP取得リトライ回数と間隔(秒数)
interval_retrypp = 3  → 10
interval_timespp = 10 → 30