dnsmasqで複数N/Wそれぞれにdefault gatewayを設定する。

もともとdnsmasqサーバにのみアクセスさせる用途で使っていたのですが、他のネットワークにもアクセスする必要がでたので調べてみました。

ます、複数のNICを持つサーバで、dnsmasqを使ってDHCPサーバを立てる場合、払い出すNICとDHCPの範囲を指定します。

interface=eth1
interface=eth2
interface=eth3
interface=eth4
interface=eth5
interface=eth6

dhcp-range=10.0.0.10,10.0.0.250,30m
dhcp-range=10.0.1.10,10.0.1.250,30m
dhcp-range=10.0.2.10,10.0.2.250,30m
dhcp-range=10.0.3.10,10.0.3.250,30m
dhcp-range=10.0.4.10,10.0.4.250,30m
dhcp-range=10.0.5.10,10.0.5.250,30m

しかし、これだとデフォルトゲートウェイが設定されません。上記のネットワークはそれぞれ24bitなので、デフォルトゲートウェイも別々に設定したいですね。dhcp-optionで、option:routerを使うと一つのネットワークに対してデフォルトゲートウェイを設定できますが、そのままでは複数のネットワークに対して設定できません。そこで、tagを使います。tagでつける名前は任意の半角英数の文字列です。

dhcp-range=tag:eth1,10.0.0.10,10.0.0.250,30m
dhcp-range=tag:eth2,10.0.1.10,10.0.1.250,30m
dhcp-range=tag:eth3,10.0.2.10,10.0.2.250,30m
dhcp-range=tag:eth4,10.0.3.10,10.0.3.250,30m
dhcp-range=tag:eth5,10.0.4.10,10.0.4.250,30m
dhcp-range=tag:eth6,10.0.5.10,10.0.5.250,30m

dhcp-option=tag:eth1,option:router,10.0.0.1
dhcp-option=tag:eth2,option:router,10.0.1.1
dhcp-option=tag:eth3,option:router,10.0.2.1
dhcp-option=tag:eth4,option:router,10.0.3.1
dhcp-option=tag:eth5,option:router,10.0.4.1
dhcp-option=tag:eth6,option:router,10.0.5.1

あとはdnsmasqを再起動すれば、セグメント毎にデフォルトゲートウェイを設定できます。 dnsmasqのマニュアル には他の設定もいろいろ記載されています。コマンドラインで使うオプションを、設定ファイル(/etc/dnsmasq.conf)でそのまま使えるのが良いですね。

GitLabを導入してみた話。

ちょいと昨日、GitLabをUbuntu12.04に導入してみました。基本的には、 Install for stable version (recommended) の通りです。GitLabの現時点のstableはRuby 1.9.2を必要としますが、Ubuntu 12.04では、1.9.1どまりなので、Rubyについては、上記の手順どおりソースコードからビルドし、Ruby関連パッケージは全てGem経由でインストールしました。

一部、手順の 4. Install gitlab and configuration. Check status configuration. において、Gemに紛れて、

sudo pip install pygments

と、pygmentsをpipでインストールする手順があります。が、これはDebianパッケージがあり、バージョンの指定もないので、python-pygmentsパッケージをインストールしました。

この手順どおりに行うと、インストール後に表示されるGitリポジトリのURIのホストがlocalhostになってしまいます。インストール後に、/home/gitlab/gitlab/config/gitlab.ymlのサーバ絡みの変更すると、gitlite関連の手順がGitlab経由で行えません。gitlite絡みというのは、つまりユーザ作成後のSSHキーの登録であったり、ベアリポジトリの作成です。原因は、gitlab.yamlのホスト関連の情報をlocalhostからホスト名やIPアドレスに変更すると、インストール手順の中で行っていたgit clone先のホスト名と変わってしまうためと思われます。ですので、上記手順の CHECK: Logout & login again to apply git group to your user のうち、

sudo -u gitlab -H git clone git@localhost:gitolite-admin.git /tmp/gitolite-admin

は、localhostではなく、サーバのホスト名もしくはIPアドレスを指定し、前述の4の手順で

sudo -u gitlab cp config/gitlab.yml.example config/gitlab.yml

を行った直後に、gitlab.yamlのlocalhostの部分を変更しておく必要があると思います。「思います」と書いているのは、未確認だからです。私が実際にやったのは後からgitlab.yamlを修正した場合の手順。つまり、

  • ホストキーの再生成

$ sudo -H -u gitlab ssh-keygen -q -N '' -t rsa -f /home/gitlab/.ssh/id_rsa
  • setupの再実行

$ sudo -u git sh -c 'echo -e "PATH=\$PATH:/home/git/bin\nexport PATH" > /home/git/.profile'
$ sudo -u git -i -H /home/git/gitolite/src/gl-system-install
$ sudo cp /home/gitlab/.ssh/id_rsa.pub /home/git/gitlab.pub
$ sudo chmod 777 /home/git/gitlab.pub
$ sudo -u git -H sed -i 's/0077/0007/g' /home/git/share/gitolite/conf/example.gitolite.rc
$ sudo -u git -H sh -c "PATH=/home/git/bin:$PATH; gl-setup -q /home/git/gitlab.pub"
  • 手順4の再実行

$ sudo -u gitlab -H git clone git@repos.example.org:gitolite-admin.git /tmp/gitolite-admin
$ sudo rm -rf /tmp/gitolite-admin

を行って解決しました。ただし、「setupの再実行」のうち、gl-system-installスクリプトの実行は、下記の用にwarningが出るのでいらないかも。(これもまた未確認)

$ sudo -u git -i -H /home/git/gitolite/src/gl-system-install
-sh: 1: -e: not found
using default values for EUID=109:
/home/git/bin /home/git/share/gitolite/conf /home/git/share/gitolite/hooks

                ***** WARNING *****
/usr/bin precedes /home/git/bin in your $PATH,
and it *also* contains gl-setup.  This is almost certainly going to confuse
you or me later.

Since gl-setup MUST be run from the PATH (and not as src/gl-setup or such),
you must fix this before running gl-setup.  The simplest way is to add

    PATH=/home/git/bin:$PATH

to the end of your bashrc or similar file.  You can even simply run that
command manually each time you log in and want to run a gitolite command.

Run /home/git/gitolite/src/gl-system-install -h for a detailed usage message.

ReadOnlyでグローバルアクセスさせたいのだけど。

コードだけでなく、各種サーバのある設定ファイルの置き場として、ログインせずにHTTPでReadOnlyアクセスもできるようにしたかったのですが、Public repositories、これは今後も予定されてないみたいです。理由は、 GitLabの開発を行っている企業が目指しているのはプライベートなGitHubで、githubの競合になることは避けるためだとか 。 rejectされたみたいですが、 コメント欄での反応が割と良かったこんな pull request もあります。残念ながら導入したのがstableだったのですぐに試せず。

今回みたいな場合は Gitrious の方があってそうですねえ。見た目はGitLabの方がgithubに近いのでいいんですけどね。残念。

optparseからargparseに変更。 1

tonicdnscli のPython 3への対応をしようとした際、コマンドラインオプションに使用している optparseモジュールがPython 2.7 で廃止予定だということを知りました。そこで、optparseからargparseに変更することにしました。optparseでは、入力ファイルをJSON形式で表示させるためのオプションや、TonicDNSからレコードを取得して表示、レコードの登録、レコードの削除を行うのをオプションで行っていましたが、argparseに変更するタイミングで、これらをサブコマンドとして実装しなおしました。変更した結果が下記の表です。

機能

optparse

argparse

変換・表示

-o/–stdout

show

取得表示

-g/–retrieve

get

レコード登録

-c/–create

create

レコード削除

-d/–delete

delete

基本的には 公式ドキュメント を読めばoptparseでやっていたことをargparseに置き換えるのは問題なくできます。ちょいとハマったのが、サブコマンドのオプションを相互排他にする方法。メインパーサと、ArgementParserのadd_subparsers()メソッドで作成するサブパーサと、どちらにadd_mutually_exclusive_group()メソッドを使うのかとか、相互排他でどちらかを必須にするにはrequired=Trueをadd_mutually_exclusive_group()メソッドと、add_argument()メソッドのどちらの引数として渡すのか、といったあたりです。

結果は下記のとおり。(createの例)

# Create records
parser_create = subparsers.add_parser(
    'create', help='create records of specific zone')
parser_create.add_argument('infile', action='store',
                             help='pre-converted text file')
parser_create.add_argument('-s', dest='server', required=True,
                           help='specify TonicDNS hostname or IP address')
parser_create.add_argument('-u', dest='user', required=True,
                           help='TonicDNS username')
group_create = parser_create.add_mutually_exclusive_group(required=True)
group_create.add_argument('-p', dest='password',
                           help='TonicDNS password')
group_create.add_argument('-P', action='store_true',
                           help='TonicDNS password prompt')
parser_create.set_defaults(func=create)

argparseを使った場合のヘルプは下記のようになります。

$ tonicdnscli -h
usage: tonicdnscli [-h] [-v] {show,get,create,delete} ...

usage

positional arguments:
  {show,get,create,delete}
                        commands
    show                show converted JSON
    get                 retrieve records of specific zone
    create              create records of specific zone
    delete              delete records of specific zone

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit

サブコマンド毎のヘルプも表示できます。(createの場合)

$ tonicdnscli create -h
usage: command.py create [-h] -s SERVER -u USER (-p PASSWORD | -P) infile

positional arguments:
  infile       pre-converted text file

optional arguments:
  -h, --help   show this help message and exit
  -s SERVER    specify TonicDNS hostname or IP address
  -u USER      TonicDNS username
  -p PASSWORD  TonicDNS password
  -P           TonicDNS password prompt

“-p”と”-P”がサブコマンドで相互排他かつ入力必須というわけです。

入力が不完全な場合は、下記のように表示されます。まずはサブコマンドが無い場合。

$ tonicdnscli
usage: tonicdnscli [-h] [-v] {show,get,create,delete} ...
tonicdnscli: error: too few arguments

サブコマンドの引数が足りない場合。

$ tonicdnscli create
usage: tonicdnscli create [-h] -s SERVER -u USER (-p PASSWORD | -P) infile
tonicdnscli create: error: too few arguments

サブコマンドの引数が足りない場合。

$ tonicdnscli create examples/example.org.txt
usage: tonicdnscli create [-h] -s SERVER -u USER (-p PASSWORD | -P) infile
tonicdnscli create: error: argument -s is required

結構親切で便利です。optparseと違ってデフォルトでサブコマンドを作れることも考慮すると、もはやoptparseを使わず、argparseにした方が良いですね。

tonicdnscli/src/tonicdnscli/command.pyでの置き換えは Gistに上げておきました 。置き換え後が結構冗長ですね。

1

タイトルが間違ってました。 Vさん、ご指摘ありがとうございました。

第87回東京エリアDebian勉強会に参加してきた。

おまめちゃんの誕生があったので、1月以来で久々に参加してきました。今日のテーマはDebianでのnode.jsの話、AndroidデバイスでDebianを動かす話、月刊Debhelper。あと、今期のDebian JP Projectの会長に再選されたので、今期の所信表明をしてきました。node.jsの設計思想がいろいろアレゲで、Debianパッケージにするのは魔窟過ぎて泣けるなぁと思った次第です。(通常の)Debian勉強会への初参加の方も3人いらっしゃり、宴会も盛り上がって楽しかったです。

なお、来月のDebian勉強会は、おまめちゃんの世話で留守番のため不参加です。次の参加は 6/23の大統一Debian勉強会 ですね。

TonicDNS Clientを作成しました。

俺得シリーズ。 “TonicDNSでレコードの一括登録・削除するためのJSONを生成する。”でTonicDNS用にJSONを生成するツールを作成しましたが、これにTonicDNS API用のクライアント機能を実装しました。 Github および PyPI で公開しています。使い方は src/README.rst に記述していますが、現時点でできることは以下の通りです。

  • 半角空白文字区切りフォーマットのテキストファイルからJSONへの変換

  • TonicDNS API経由でのPowerDNSの操作

    • 指定ドメインのレコード情報の一括表示

    • 指定ドメインへのレコード一括登録

    • 指定ドメインからのレコード一括削除

登録 or 削除対象が100件を超える場合

コミット 7571109876 で実装したのですが、登録もしくは削除対象が100件を超える場合は、100件毎に処理するようにしています。例えば345件の登録を行う場合は、100, 100, 100, 45と、計4回処理します。コミットメッセージにも書いたのですが、これはHTTP PUTメソッド、もしくはDELETEメソッドで、送信するbodyサイズ、つまりJSONファイルのサイズが27,915byte以上、27,938byteより下の間が処理可能なサイズの境になっているためです。この送信可能なデータサイズの上限がどこで決められているのかは、現状ではまだ分かっていません。POSTメソッドならTonicDNSが実装されているPHPの場合は、php.iniの post_max_size で変更でき、デフォルト値は8MBになっていますが、PUTやDELETEの場合はありません。また、使用している環境に合わせ、PHP 5.3.2, TonicDNS develブランチの d4906df6 , Apache 2.2.14のソースコードを調べてみましたが、現時点ではPUTメソッドやDELETEメソッドでの送信データの上限に関わる値を決めているロジックは見当たりませんでした。

初めてのPythonパッケージ

今回、はじめてPythonパッケージを作成してみました。 公式ドキュメント と、Debianパッケージのメンテナンスをしているblockdiagを参考にして行ったら結構分かりやすかったです。これは、PythonツールのDebianパッケージ作成を行うときに実行する、

dh $@ --with python2

で行う処理が、

python setup.py sdist bdist

を実行しているのだな、と理解できるようになったことなど、Pythonパッケージの作成の処理が理解できるようになったのは、PythonのDebianパッケージをメンテナンスする上でも重要なので良かったなと思います。

Upstream = Debian パッケージメンテナ = オレ、ってあり?

tonicdnscliは、自分で作ったツールですが普段使う際、

$ sudo python setup.py install

でインストールはするのは割けたいところです。これだと/usr/local下にインストールされてしまうからです。なので、まだITPはしていませんがDebianパッケージを作成してインストールしています。Githubではdebian/ディレクトリ以下のファイルもリポジトリに追加しています。ITPをしていないので、debain/copyrightのBTS番号のみがテンプレートのままですが、手元でdebuildしてもパッケージを作成することはできます。さて、自分がUpstreamのソフトウェアを自分でITPしてパッケージメンテナになるのはアリなんでしょうか?

PowerDNS + TonicDNSのススメ。

現時点では処理対象のレコードが既に登録されているものがないかをチェックする機能を実装していません。また、レコード単位でのアップデートも現時点ではできず、一度対象のレコードを削除した後、再度まとめて登録するしかありませんが、この辺も近々対応する予定です。これを実装すれば、まあかなりtonicdnscliも使える感じになるかなと思っています。

また、TonicDNSとtonicdnscliや、PowerDNS GUI、ton-katsuさんの作成した novadns 1 とPowerDNS + MySQLの環境を活用するツールがだいぶ揃ってきた感じです。特にシステムの自動化を行っていく上でPowerDNSとTonicDNSの組み合わせはかなり便利です。まだDNSの運用を行っていたり、OpenStackでホスト名の登録とIPアドレスの紐付けをどうしようか検討している人もいると思います。そういう人にはうってつけです。TonicDNSは機能的に足りない部分やバグもまだありますが、開発速度も割と速い上、パッチ投げると内容によってはマージしてもらえますので、是非使ってみてはいかがでしょうか。

1

OpenStackのNovaではインスタンスを作成すると、ランダムにホスト名及びインスタンス名が作成されますが、novadnsは、このホスト名とインスタンス作成時に自動的に割り当てられるIPアドレスを使って、自動的にTonicDNS経由でPowerDNSにAレコードを登録するデーモンです。