Masteries

技術的なことや仕事に関することを書いていきます.

EdgeRouter Xに, 自宅の外からpingする

今住んでいるマンションは無料でインターネット回線が提供されているのですが, 時間帯によっては余りにも遅くなる(夜23時頃になると, 下りが1Mbpsとかになる)ことがあり, 余りにも人権がなく限界を感じたので, 別に敷設されている有料のケーブルテレビによるインターネット回線(既に敷設されているので, 割引などが効いて初期費用無料/月額3000円くらいで使える)を契約しました.

そのオプションとして, 無料でグローバルIPを1つもらえたので, そろそろEdgeRouter Xを整備するか... となり, 最近EdgeRouter Xをいろいろ触っていたのでした.

自宅の外からpingする

...で, 結論から言えば, EdgeRouter Xは, デフォルトでは外から来る通信は全て弾いています. その為, 初期状態では自宅の外のネットワークからは, グローバルIP経由でEdgeRouter Xに対してpingすら打つことができません.

最初, 何をやってもEdgeRouter Xと疎通が出来ず, 「一体何が...?」と混乱しまくっていました(流石にpingくらいは通るでしょ, と思い込んでいました...).

自宅の外からのpingできるようにする

ブラウザでEdgeRouter Xの管理画面に行き, 「Firewall/NAT」から「Filewall Policies」を選び, 「WAN_LOCAL」の「Actions」から, 「Edit Ruleset」を選びます.

f:id:papix:20171021112009p:plain

すると, このような画面になります(このスクリーンショットは, 既にいろいろ設定した後のものです. 最初は, 「Allow established/related」と, 「Drop invalid state」のみ設定されています).

f:id:papix:20171021112734p:plain

「Add New Rules」を選び, 「Action」は「Accept」に, 「Protocol」は「Choose a protocol by name」から「icmp」を選びます.

f:id:papix:20171021112356p:plain

「Save」を押して保存し, この作られたルールをドラッグして, 最初からあった「Allow established/related」と「Drop invalid state」の間に移動して, 最後に「Save Rule Order」をクリックすればOK.

これでめでたく自宅の外からEdgeRouter Xに対してpingを打つことができます.

10月31日に「はてなエンジニアが贈るはじめてのMackerel」という発表をすることになりました

supporterzcolab.com

代表取締役の自宅が, 自宅から徒歩1分圏内にあることが最近発覚したサポーターズさんに, いろいろな縁があってお声がけ頂いて, 「はてなエンジニアが贈るはじめてのMackerel」というイベントをやることになりました. 10月31日です.

「参加者が増えねェ...!」と嘆いていたところ, なんとMackerelのブログでもご紹介頂きました. ブログの公開後, 参加者が(少なくとも)3人増えていて, 本当にありがたい気持ちでいっぱいでした.

mackerel.io

どんな話をするの?

前にMackerel Drink Up #6で話したような, はてなブログチームでのMackerel活用術なども織り交ぜながら, Mackerelの基礎から応用までを, さっくり紹介してみる... という内容を予定しています.

papix.hatenablog.com

Mackerelに興味がある方, 或いははてな社内でのMackerel活用術に興味がある方は, 是非参加してみてください. お待ちしています.

あと, あれですね. これから, 資料作りも, 頑張ります...*1

*1: 資料については, きっとMackerelチームが誇るCREの id:a-know さんや id:Soudai さんの熱いレビューが入ると思うので, 良いものが出来上がると信じています! 頑張ります!!!

Perlで雑なスクリプトを書く時の個人的な三種の神器

日常の中で複雑な作業をしたい時, Perlで雑なスクリプトを書いて実現することがあります. そういった時によく使うCPANモジュール達を紹介しようと思います.

Path::Tiny

metacpan.org

ファイルの読み書きはもちろん, ファイルやディレクトリの存在確認, ディレクトリからのファイルの走査, 一時的なファイル/ディレクトリを用意... などなど, ファイルやディレクトリ操作に関するあらゆることがこのモジュール1つで実現できて便利です.

Data::Printer (DDP)

metacpan.org

便利で見やすいData::Dumper. 雑なスクリプトを作る時は, とにかくData::Printerで途中結果を表示しながら試行錯誤しています.

papix.hatenablog.com

過去にこういう紹介記事を書いていました.

papix.hatenablog.com

或いはこういう活用事例も書いていましたね.

Capture::Tiny

metacpan.org

systemで適当なコマンドを実行して, その標準出力や標準出力を元にして更に処理をする... という時に便利なコマンドです.

use strict;
use warnings;

use Capture::Tiny qw/ capture /;

my ($stdout, $stderr) = capture {
    system('ls');
};

print $stdout;

こういう感じにしてあげれば, captureで囲った部分のコード(この場合, systemlsを実行している)の標準出力が$stdoutに, 標準エラー出力が$stderrに格納されます.

まとめ

何かしらの作業をまとめてスクリプトにするとき, だいたいシェルスクリプトで書こうとするものの, 途中で分岐が増えてきて「アバーッ!!!」となり, Perlで書き直す... という事が多いです. というわけで, 今回はそういう時によく使うモジュール達を紹介しました.

「自分はこれ使うことが多い」, 「これも便利!」といった情報, お待ちしております.

Dockerコンテナの中でいい感じにCartonしたい

Dockerで建てたコンテナの上でPerlのWebサービスを開発している場合, 例えばテストを実行するとき等はコンテナ上で実行する必要があります. そういった時, 皆さんはどうしていますか?

例えばdocker-composeでコンテナ群を立ち上げていて, PerlのWebサービスがappというコンテナで動いている時, 次のような選択肢があると思います:

  • docker-compose exec app carton ...する
  • docker-compose exec app /bin/shでコンテナの中に入り, carton ...する

...これでも全然良いのですけれど, とはいえ個人的には面倒という気持ちがあります. やはり, 無意識にこれまで通りcartonでコマンドを実行をすると, 自動的にDockerコンテナの中で実行されて欲しい!!!

...と考えた結果, このようなスクリプトが生まれました.

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;

my $cmd;
my $argv = join ' ', @ARGV;

if ($ENV{'DISABLE_DOCKER'}) {
    $cmd = sprintf(q{$(plenv which carton) %s}, $argv);
} else {
    my $plack_env = $ENV{'PLACK_ENV'} || 'local';
    my $env       = join ' ', map { sprintf('%s=%s', $_, $ENV{$_}) } grep { $_ =~ /^PLACK_ENV$/ } keys %ENV;

    my @commands = 'carton';

    unshift @commands, $env if $env;
    push @commands, $argv if $argv;

    $cmd = sprintf(q{PLACK_ENV=%s docker-compose exec app /bin/sh -c '%s'}, $plack_env, join(' ', @commands));
    print "exec: $cmd\n";
}

exec $cmd;

あとはこのスクリプトをcartonとして呼び出せるようにしてあげればOKで, 例えばcarton exec prove tとすると,

PLACK_ENV=local docker-compose exec app /bin/sh -c 'PLACK_ENV=local carton exec prove t'

というコマンドが実行されます. もしDockerコンテナの中で実行したくないならば, DISABLE_DOCKER=1を付けて実行すればOK.

...ね, 簡単でしょう?


ちなみに, Dockerを使っている時だけこのcartonのラッパースクリプトを使いたい, という時はdirenvを使うと便利です. 例えば, このスクリプトが /path/to/script に設置されていて, /path/to/script/carton で使えるようになっているなら,

export PATH=/path/to/script:$PATH

という感じで.envrcを設置しれあげれば, そのディレクトリ下でのみ, cartonのラッパースクリプトが使われるようになります.

papix.hatenablog.com

EdgeRouter Xで/etc/hostsを変更する

EdgeRouter Xにはdnsmasqが載っています. dnsmasqは, /etc/hostsに書かれたルールに従ってDNSクエリに反応してくれるので, つまりEdgeRouter Xの/etc/hostsを書き換えれば, 家庭内ネットワークにある端末の名前解決をすることができます.

※そのためにはもちろん, LAN内における端末のIPを固定する必要があります. その辺りの手順はこちらのページが参考になります:

yabe.jp

/etc/hostsを変更する

EdgeRouter Xの/etc/hostsを書き換えたい場合, 直接/etc/hostsを変更するのではなく, 次のようにstatic-host-mappingコマンドで設定する必要があります: コマンド > configure > system - EdgeOS 日本語Wiki [非公式]

# set system static-host-mapping host-name [host] inet [ip addr]

例えば, test.homeというホスト名を192.168.1.10というIPで登録したい場合, 次のようにします.

$ configure
# set system static-host-mapping host-name test.home inet 192.168.1.10
# commit
# save

こうすることで, /etc/hostsにも設定が追加され, LAN内にある端末から, test.home192.168.1.10というIPアドレスを引くことができるようになります.

現在の設定を確認する/削除する

setではなく, showとすることで, 現在のstatic-host-mappingの設定を見ることができます.

# show system static-host-mapping

また, deleteで既存の設定を削除することができます.

# delete system static-host-mapping host-name [host]

参考にしたページ

qiita.com