value-domainのDDNS更新を使わずになるべく安全に更新したい

DDNS更新は固定IPを持たない自分としてはとても便利なのだけど、

value-domainDDNS更新はhttp通信のため、DDNS更新用のパスワード情報を傍受される可能性がある。

これは非常によろしくないので、セキュアに通信する方法を考える。

(結構当たり前のように使われてる理由がわからない...自分も今まで使ってたけど。)

DDNS更新はhttpsでは行えないが、通常のログインして色々操作できる画面経由のDNS更新はhttpsで行える。

これを利用して、WWW::Mechanize(要IO::Socket::SSL, Crypt::SSLeay)に頑張ってもらいます。



先に以下のスクリプトは欠点として、

  • value-domainのログインアカウントが必要
    • 読み取り権限を0700にしてくだし...
  • 更新失敗を検知できない
    • これは更新後に「正常に変更されました。」ってメッセージが出ることを確認して更新できたかどうか判断すればよさそう。
  • サイトのURLや部品のname値が変わると使えなくなるとか、セキュアじゃなくなる可能性がある(途中でhttpになっちゃうとかいう仕様変更があるかもしれない!)

とかあるけども、value-domainは結構長い間こんな感じなので、多分大丈夫でしょう

#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use WWW::Mechanize;
use constant TYPE_VALUE_DOMAIN => 'value-domain';

my $new_ip = "123.45.67.89";

my %domain_config = (
    "rying.net" => {
        type => TYPE_VALUE_DOMAIN,
        login => {
            username => 'XXXXXXXX',
            password => 'XXXXXXXX',
        },
        form => {
            records => trim(qq{
                a @ $new_ip
                a www $new_ip
                a test $new_ip
            })
        },
    },
);


update_dns(%domain_config);

sub update_dns{
    my %config = @_;
    while(my ($domain, $param) = each(%config)){
        if ($param->{type} eq TYPE_VALUE_DOMAIN){
            update_dns_value_domain($domain, $param);
        }else{
            die "not supported type: $param->{type}"
        }
    }
}

# records:
# ttl:
sub update_dns_value_domain{
    my $domain = shift;
    my $param = shift;
    my $login = $param->{login};
    my $form = $param->{form};
    
    my $mech = WWW::Mechanize->new();
    
    ### Login
    $mech->get('https://www.value-domain.com/login.php');
    
    $mech->form_name('formMAIN');
    $mech->field('username', $login->{username});
    $mech->field('password', $login->{password});
    $mech->click_button(name => 'Submit');
    
    ### Update
    $mech->get('https://www.value-domain.com/moddns.php?action=moddns2&domainname='. $domain);
    
    $mech->form_name('formMAIN');
    while(my($key, $value) = each(%$form)){
        $mech->field($key, $value);
    }
    $mech->click_button(name => 'Submit');
    
    print $mech->content();
}

sub trim{
    my $string = shift;
    $string =~ s/^[\r?\n]+$//mg;
    $string =~ s/^\s+//mg;
    $string =~ s/\s+$//mg;
    return $string;
}

れがしーすぎる。