MikrotikOSでYandex DNSのdDNSクライアントを作成します

最近、友人とDynDNSおよび同様のサービスについて会話しました。YandexがDNSホスティングを管理するために提供するAPIに基づいてアナログを実装したいとずっと思っていたことを思い出しました。 ここ数年、私は素晴らしいMikrotik RB750GL鉄所有しており 、レコードを更新するものになりたかったのです。

しかし、MikroTikはHTTP経由でのみファイルをダウンロードでき、Yandex APIはHTTPS経由でのみ機能するため、最近までこれは不可能でした。 そして、 Wiki Mikrotikに行くと、切望されたエントリが見つかりました。

FetchはHTTPSプロトコルをサポートするようになりました。 デフォルトでは証明書チェックは行われませんが、check-certificateをyesに設定すると、ローカル証明書ストアからの信頼チェーン検証が有効になります。 CRLチェックは行われません。




スクリプトは、Mikrotik RouterOSのバージョンが6.0rc14の場合でも書き込みを開始し、リリースバージョン6.0で継続しました

さて、今スクリプト自体:



スクリプトの最初の部分はセットアップです。 スクリプト自体の本文に必要なすべてのパラメーターをローカル変数として示します。 これは、ドメイン名、トークン、およびレコードIDです。 インターフェイスのプロパティから現在のIPを取得し、その名前を指定します。

トークンはペンでのみ取得でき、IDの受信は自動化できますが、必要ありませんでした。 DNS APIドキュメントで読むことができます:



:local YaDNSdomain "domain.ru" :local YaDNStoken "132456789012345678901234567890" :local YaDNSrecordid "1234567" :local YaDNSTTL "300" :local YaDNSInterfaceName "PPPoE_NBN" :global YaDNSForceUpdateOnce :global YaDNSPreviousIP
      
      





2つのグローバル変数がありますが、それらについては後で詳しく説明します。



スクリプトの2番目の部分は、インターフェイスから現在のIPを取得することです。 変数$ YaDNSCurrentIPでIPアドレスを取得します。どこかにエラーがある場合、スクリプトはログに説明を書き込んで終了します。

 # get the current IP address from the interface :if ([:len [/interface find name=$YaDNSInterfaceName]] = 0 ) do={ :log info "UpdateYaDNS: No interface named $YaDNSInterfaceName , please check configuration." :error "UpdateYaDNS: No interface named $YaDNSInterfaceName , please check configuration." } :local YaDNSYaDNSCurrentIPMask [ /ip address get [/ip address find interface=$YaDNSInterfaceName] address ] :local YaDNSCurrentIP [:pick $YaDNSYaDNSCurrentIPMask 0 [:find $YaDNSYaDNSCurrentIPMask "/"]] :if ([ :typeof $YaDNSCurrentIP ] = "nothing" ) do= { :log info "UpdateDynDNS: No ip address present on $YaDNSInterfaceName, please check." :error "UpdateDynDNS: No ip address present on $YaDNSInterfaceName, please check." }
      
      







さまざまな「以前の」IPについて少し説明します。 私はそれらの2つを持っています:



 :if ([:typeof $YaDNSPreviousIP] = "nothing" ) do={ :global YaDNSPreviousIP 0.0.0.0 } :local YaDNSsrcpath1 ( "nsapi/get_domain_records.xml\?token=" . $YaDNStoken . "&domain=" . $YaDNSdomain ) :local YaDNSAPI [:resolve "pddimp.yandex.ru"] /tool fetch mode=https address="$YaDNSAPI" host="pddimp.yandex.ru" src-path=$YaDNSsrcpath1 dst-path="/YaDNSGetDomainRecord.txt" :local Result1 [/file get YaDNSGetDomainRecord.txt contents] :local Result2 [:pick $Result1 ([:find $Result1 "id=\"$YaDNSrecordid"]) ([:find $Result1 "id=\"$YaDNSrecordid"]+42) ] :set YaDNSDomainRecord [:pick $Result2 ([:find $Result2 ">"] + 1) ( [:find $Result2 "<"] ) ]
      
      







そして、このスクリプトの一部とその理由について説明します。

 :local YaDNSAPI [:resolve "pddimp.yandex.ru"] /tool fetch mode=https address="$YaDNSAPI" host="pddimp.yandex.ru" src-path=$YaDNSsrcpath1 dst-path="/YaDNSGetDomainRecord.txt"
      
      





まず、次のように/ tool fetch呼び出しを使用しました。

 /tool fetch mode=https address="pddimp.yandex.ru" src-path=$YaDNSsrcpath dst-path="/YaDNS.txt"
      
      





しかし、スクリプトから呼び出すこのオプションでは、コマンドは約4分の1のケースで機能し、この時点でスクリプトは単純に中断しました。 長い間、私はそれができませんでした。 Yandexが404エラーを返すことがあるのに気づくまで、コンソールからこのスクリプトを何度も実行しましたが、なぜ理解できなかったのですか。 Mikrotikのテクニカルサポートと話をしたところ、最初にIP APIを解決してからIP経由でアクセスするという次のような考えに至りました。 このオプションは私のために働いた。



そして、スクリプトの最後の部分、更新自体。 無駄にならないように、現在のIPが以前のIPのいずれかと一致しない場合にのみYandexが更新されます。 変数$ YaDNSForceUpdateOnceは、スクリプトがどのような場合でも機能する必要がある場合に残されます。適切と思われる場合は使用します。trueに設定する別のスクリプトがあります。

 :if (($YaDNSForceUpdateOnce or ($YaDNSCurrentIP != $YaDNSPreviousIP) or ($YaDNSCurrentIP != $YaDNSDomainRecord)) = true) do={ :log info "UpdateYaDNS: Try Update" :log info "UpdateYaDNS: YaDNSForceUpdateOnce = $YaDNSForceUpdateOnce" :log info "UpdateYaDNS: YaDNSPreviousIP = $YaDNSPreviousIP" :log info "UpdateYaDNS: YaDNSCurrentIP = $YaDNSCurrentIP" :log info "UpdateYaDNS: YaDNSDomainRecord = $YaDNSDomainRecord" :local YaDNSsrcpath2 ( "nsapi/edit_a_record.xml\?token=" . $YaDNStoken . "&domain=" . $YaDNSdomain . "&record_id=" . $YaDNSrecordid . "&ttl=" . $YaDNSTTL . "&content=" . $YaDNSCurrentIP ) :local YaDNSAPI [:resolve "pddimp.yandex.ru"] /tool fetch mode=https address="$YaDNSAPI" host="pddimp.yandex.ru" src-path=$YaDNSsrcpath2 dst-path="/YaDNS.txt" :local result [/file get YaDNS.txt contents] :global YaDNSResult [:pick $result ([:find $result "<error>"]+7) [:find $result "</error>"]] :if ( $YaDNSResult = "ok" ) do={ :set YaDNSForceUpdateOnce false :set YaDNSPreviousIP $YaDNSCurrentIP :log info "UpdateYaDNS: Update Success" } :log info "UpdateYaDNS: Result: $YaDNSResult" }
      
      







取り除くことができなかった短所:





スクリプトを使用するには、スケジューラに追加し、間隔を5分に設定します。

/システムスクリプトの実行UpdateYaDNS



PasteBinでスクリプトの全文をダウンロードできます



UPD

ペーストビン

ローカル変数が追加されました

 :local YaDNSsubdomain "xxx.domain.ru"
      
      





名前が示すように、サブドメインです。 ドメイン自体のレコードを更新する必要がある場合は、この変数を$ YaDNSdomainに指定する必要があります



All Articles