カテゴリー別アーカイブ: その他

IIJmioファミリーシェアプランに追加する形でDoCoMo SIMから転入

個人的にIIJmioタイプDファミリーシェアプランを一人で使っていたのですが、音声用に長年DoCoMoの契約を続けていました。ちょうど更新月に入ったのでこの機会にMNP転出することにしました。ファミリーシェアプランが追加のSIMを頼めるようになっていたので、MNPの転出先としてそちらを選んでみました。この時どのメニューから選択すると正しく申し込めるのかが分かりづらかったので記録しておきます。

  •  会員専用ページ(https://www.iijmio.jp/member/)の「SIMカード追加」(https://www.iijmio.jp/service/setup/hdd/addsim/confirm.do)を選択
  • 遷移したページでサービスコードがファミリーシェアプランになっていることを確認
  • SIMカードの追加を選択
    • 機能から「音声通話機能つき」を選択
    • 「MNP転入」という項目が選べるようになるので選択
    • MNP転入に必要な情報を入力

会員トップページの「ご購入お申し込み」から選択してしまうと新規プラン追加になってしまうので、気をつける必要がありました。

今後MNPする機会はそうそう無いとは思いますが、忘れないよう記録しておきます。

そもそもDoCoMo FOMA以前はNTTパーソナルのPHSをずっと使っていたのですが、2004年あたりで「端末料金3万円OFF」と引き換えに乗り換えを行いました。当時5万円程度したモトローラM1000を2万円程度で購入できたのですが、電話番号を変える作業は結構大変でした。今思えば、もっと粘ればPHSからのMNPができたのでそのほうが楽だったかもしれません。

秋葉原でREVIVE USBを組み立てた

以前からやってみたいことの一つとして、PCから操作可能なUSB HIDデバイスを使って何かしらの操作をする、ということがありました。

実現する手段はいくつか考えられます。一つはBadUSBと呼ばれるデバイスの応用です。これは一般的に販売されているUSBデバイスの一部に一般ユーザーが書き換え可能なファームウェアが搭載されていて、任意のUSBデバイスとして動作させることができるものです。キーロガーなど悪用される可能性があるということで広く問題になりました。この方法で利用可能なデバイスが現在でも手に入るかどうかわからなかったので、この方法はあきらめました。

電子工作界隈では、V-USBというマイコンで動作するUSBターゲット用のオープンソースなファームウェアがあります。オリジナルのV-USBはAVR用となっていますが、Arduinoで動くArduino USBというものもあります。

今回はHIDデバイスという明確にターゲットが決まっていたので、REVIVE USBというキットを使いました。Amazonや秋葉原の三月兎などで購入できます。私ははキットの方を三月兎で購入しました。ほかに配線済みの完成品も販売されているのですが、千円ぐらい値段が違います。

REVIVE USB 表
REVIVE USB 表

自力で組み立てる必要があるわけですが、自宅は狭いうえに整理がなされていなくてあまりはんだ付けなどの作業には向いていない環境です。たまたま秋葉原のガード下を見ていたところ、Assemblageという電子工作スペースがあることに気付いたので、そちらを利用してみました。休日は1時間200円ほどで利用できます。

秋葉原 ASSEMBLAGE
秋葉原 ASSEMBLAGE

はんだ付け作業は10年ぶりぐらいでしたが、45分ほどかけてなんとか完成しました。

REVIVE USB 裏
REVIVE USB 裏

できあがったデバイスをLinuxマシンに差すと、USB ID 22ea:0006とでます。linux-usb/usb.idsには該当するデータがないようです。ともあれ無事認識したので、これで何かしら作ってみたいと思います。

gensimでLDA(Latent Dirichlet Allocation)

トピックモデルを試そうとgensimのLdaModelを使ってみたのですが、参考にした記事「LSIやLDAを手軽に試せるGensimを使った自然言語処理入門」は対象とするgensimのバージョンが古いようだったので、現状にあうようアレンジして試してみました。この記事で使ったgensimのバージョンは0.11.1です。

過去のgensimと今のものとでは、メソッド名等の命名規則が変わっています。旧来はcamel caseでしたが、今は小文字とアンダースコアの組み合わせになっています。たとえばnumTopicsという名前付き引数はnum_topicsに変わっています。

それ以外にも多少の違いはあるのですが、yuku_tさんのgistのコードを今のバージョンのgensimで動くように修正したのが以下になります。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import logging
import sys
import os.path
import bz2

from gensim.corpora import WikiCorpus
from gensim.corpora.wikicorpus import filter_wiki
import MeCab

logger = logging.getLogger('jawikicorpus')
logger.setLevel(logging.INFO)

tagger = MeCab.Tagger()

DEFAULT_DICT_SIZE = 100000
ARTICLE_MIN_CHARS = 500

def jatokenize(text):
    node = tagger.parseToNode(text.encode('utf-8')).next
    while node:
        if node.feature.split(',')[0] == '名詞':
            yield node.surface.lower()
        node = node.next

def tokenize(content):
    return [token for token in jatokenize(content) if not token.startswith('_')]

class JaWikiCorpus(WikiCorpus):
    def getArticles(self, return_raw=False):
        articles, articles_all = 0, 0
        intext, positions = False, 0
        for lineno, line in enumerate(bz2.BZ2File(self.fname)):
            if line.startswith('      <text'):
                intext = True
                line = line[line.find('>') + 1 : ]
                lines = [line]
            elif intext:
                lines.append(line)
            pos = line.find('</text>') # can be on the same line as <text>
            if pos >= 0:
                articles_all += 1
                intext = False
                if not lines:
                    continue
                lines[-1] = line[:pos]
                text = filter_wiki(''.join(lines))
                if len(text) > ARTICLE_MIN_CHARS: # article redirects are pruned here
                    articles += 1
                    if return_raw:
                        result = text
                    else:
                        result = tokenize(text) # text into tokens here
                        positions += len(result)
                    yield result

        logger.info("finished iterating over Wikipedia corpus of %i documents with %i positions"
                     " (total %i articles before pruning)" %
                     (articles, positions, articles_all))
        self.numDocs = articles # cache corpus length

if __name__ == '__main__':
    logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s')
    logging.root.setLevel(level=logging.INFO)
    logging.info("running %s" % ' '.join(sys.argv))
    program = os.path.basename(sys.argv[0])
    if len(sys.argv) < 3:
        #print globals()['__doc__'] % locals()
        sys.exit(1)
    input, output = sys.argv[1:3]
    wiki = JaWikiCorpus(input)
    wiki.dictionary.save_as_text(output + "_wordids.txt")
    from gensim.corpora import MmCorpus
    MmCorpus.serialize(output + "_bow.mm", wiki)
    #del wiki
    from gensim.corpora import Dictionary
    id2token = Dictionary.load_from_text(output + '_wordids.txt')
    mm = MmCorpus(output + '_bow.mm')
    from gensim.models import TfidfModel
    tfidf = TfidfModel(mm, id2word=id2token, normalize=True)
    MmCorpus.save_corpus(output + '_tfidf.mm', tfidf[mm], progress_cnt=10000)
    logging.info("finished running %s" % program)

WikiCorpusクラスにはsaveAsTextと等価なメソッドが今は存在しないので、個別にDictionaryとCorpusをファイルに出力しています。

生成されたモデルをもとにLSI, LDAモデルを作成する流れは、メソッド名等を(たとえばPrintTopic→print_topic)書き換える点以外は元記事とほぼ変わりません。

また、LDAモデルの生成をマルチコアで実施するgensim.corpura.LdaMulticoreというクラスも用意されています。worker=2等とワーカースレッド数を指定できる点以外はLdaModelクラスと同じです。しかし、あまりよくスケールするわけではないようで、CPU論理コア数8の環境でworker=7としてみても対して速度が上がることはないようです(参考:Multicore LDA in Python: from over-night to over-lunch)。一応workerプロセスは指定しただけ起動はするのですけど。加えてマルチコアで処理した場合、出力されるログが少なくなって進捗状況がわかりづらくなるようです。

ところで以前書いたword2vecの記事でgensimのword2vecでのマルチスレッド動作について書いていなかったので、同様にworkerスレッド数を指定できることを追記しておきました。

また、Google C言語実装のword2vecのマルチスレッド処理について一つだけ気になるところがありました。それは、単純にファイルをバイト単位でスレッド数に分割し、処理している点です。単語の区切りを一切考慮しないので、その箇所がたまたま単語の途中であってもお構いなしに処理を進めてしまいます。

もっとも、出現頻度の少ない単語は捨てられるので、実用上問題になることはほとんどないはずではあります。運悪くUTF-8の途中で切られてしまい、なおかつ語彙として記録されてしまうと、gensimで読み込もうとするときにInvalidUnicodeErrorが発生してしまうので、その点だけは気を付ける必要があります。

日本語も扱える文章チェッカーLanguageTool(実用レベルとはいっていない)

以前から注目しているソフトウェアとして、LanguageToolがあります。Javaで書かれた文法チェッカーで、コマンドラインやFirefoxアドオン、Libre/OpenOfficeのプラグインとして動作します。

以前簡単な紹介をおこなったり、使い方をDoc-ja Wikiに書いたりしてみました。このころはversion 2.6でしたが、現在の最新版は2.9です。

残念ながら、日本語の対応状況については今も芳しくありません。日本語のルールの数はslideshareの資料では23種類でしたが、version 2.9の段階では43種類と増えてはいるものの、まだまだ不足している状態です。

$ cd LanguageTool-2.9
$ grep 'rule id=' ./org/languagetool/rules/ja/grammar.xml|wc -l
43

単語ベースでのルールも少ないのですが、コードベースで対応すべきケースについては現状皆無です(https://github.com/languagetool-org/languagetool/blob/master/languagetool-language-modules/ja/src/main/java/org/languagetool/language/Japanese.java)。

先日、こちらにコードを追加しないと対応できなさそうな実例が出てきたので、それを考えてみようと思います。

以前grammer.xmlのプルリクエストを送った時は、パッケージ全体をビルドする必要がなかったので、ビルド環境がそろっていなかったことに気付いていませんでした。

ビルドにはmavenが必要なので、Debian wheezy上でapt-get install mavenを行ってbuild.shをたたいてみたのですが…

$ ./build.sh languagetool-standalone clean package |& tee log
Running: mvn --projects languagetool-standalone --also-make clean package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] languagetool-parent
[INFO] LanguageTool Style and Grammar Checker Core
[INFO] English module for LanguageTool
[INFO] Persian module for LanguageTool
[INFO] French module for LanguageTool
(略)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.308s
[INFO] Finished at: Fri Apr 17 16:07:19 JST 2015
[INFO] Final Memory: 10M/112M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.2:compile (default-compile) on project languagetool-core: Fatal error compiling: 1.7 は無効な VM バージョンです。 -> [Help 1]
[ERROR]

JVMが古すぎると怒られてしまいました。ということでsid環境で試したところ、無事ビルドできました。続きは明日の東京エリアDebian勉強会でもやってみようと思います。

KAKASIの写経とバグ修正

ここのところKAKASIのコードをいじっています。昔から再実装したいと考えていたのですが、コードを十分理解していない部分もあったので、目視でソースを見ながらエディタで書き写す「写経」的なことをやってみました。

写経の過程でいくつかの潜在的なバグが発見でき、本体にコミットすることもできました。内容は以下です。

それ以外にもいくつかコミットがありますが、直接的なバグではないもの(即値の代入、不適切なマクロ定数の利用、実害のないロジックミス)ばかりです。

それ以外にも問題はありましたが、それらは修正に関して検討が必要なものだったので、Tracにチケットを作る程度にとどめています。

写経したKAKASIのコードも一応gitにおいてあります。ただし動作検証は行っていません。あくまで実験として行ったものです。環境変数で辞書のディレクトリを指定すればおそらく動作はするはずです。

作業に関して、ソースの可読性を高めるため以下のことを念頭に行いました。

  • K&Rスタイルの廃止
  • 単純なマクロ定義だった定数をいくつかenum化
  • 配列定数として埋め込んでいたいくつかのテーブルを外部ファイル化
  • 文字エンコーディング定数でマジックナンバーだったものをマクロ化(dict.cのみ)
  • CMakeの採用

特に文字エンコーディングがらみはかなりわかりやすくなったのではないかと思います。旧来のコードの一部を引用してみます。

    while(*p != '\0') {
        if (*p == '\033') {
            if ((p[1] == '$') &&
                ((p[2] == '@') || (p[2] == 'B'))) {
                kanji = 1;
                p += 2;

ESC $ BというのはISO-2022-JPでG0をJIS X 0208に指定するためのエスケープシーケンスですが、これをマクロで以下のように書き換えました。

    while (*p != NULLCHAR) {
        if (*p == ESCAPE) {     /* ESC (0x1b) */
            if ((p[1] == G0_JISX0208_1ST) &&
                ((p[2] == G0_JISC6226_2ND) || (p[2] == G0_JISX0208_2ND))) {
                kanji = 1;
                p += 2;

コメントがなくても意味が理解しやすくなったと思っています。まだ道半ばではありますが、ゆくゆくはfrom scratchなコードを起こしたいと思っています。

安価なBluetoothヘッドフォン

ずいぶん前にAmazonで購入したBluetoothヘッドホンを長らく使っていました。MM-BTSH24と同等品だったと思うのですが、当時2500円ぐらいで購入した記憶があります。

メーカー純正品は結構高価なのですが、同等品が当時と同じぐらいの値段で売られているようです。

長く使っていたせいか、耳あて部分の片方が若干痛んできています。先週末にあきばお~でBSHSBE19(白)が税別1999円で販売されていたので、この機会に買ってみました。Amazonでも3000円程度で購入できるようです。

違いはいろいろありますが、どちらにも一長一短があります。BSHSBE19は新しい製品なので、以下のポイントが個人的に良いと思っています。

  • Bluetooth 4.0対応
  • マルチポイント(2デバイス対応)
  • ノイズキャンセリング搭載
  • microUSBによる給電

一方MM-BTSH24の方がよかったなあ、と思う点は以下です。

クリップ型

個人的に耳は小さい方なので、カナル型よりもクリップ型である点は好みでした。必然的にノイズキャンセリング機能は載せられなくなってしまいますが、自分の用途だと主にジムで運動しながらというシチュエーションが多いので、むしろ環境音も聞こえた方が都合が良いです。

操作ボタンが多い

物理的サイズが大きい分、搭載されている操作ボタンが電源・再生ボタン、ボリュームボタンx2、選曲ボタンx2と多くあります。一方BSHSBE19は電源(スライドスイッチ)、マルチファンクションボタン、ボリュームボタンx2となっています。ボリュームボタンを長押しすると選曲ができるのですが、選曲を含めたあらゆる機能に音声ガイドがついているため、何か操作するたびに喋るのがちょっと煩わしいところです。

MM-BTSH24も使えなくなったわけではないので、当面は両方を使い分けることになりそうです。

Internet ArchiveとDMCA改定

主にWebのアーカイブ(wayback machine)で有名なInternet Archiveが、MS-DOS用のゲームをブラウザ上でプレイできるよう公開した、というニュースがありました。

ねとらぼの記事(MS-DOSのゲーム約2400本がブラウザでプレイ可能に 海外サイト「InternetArchive」が公開)ではフェアユースの扱いという解説がありましたが、事態はもう少し複雑のようです。

Internet Archive、DMCAの改正を歓迎という記事で、Internet Archiveの行っていたソフトウェア、ビデオゲームのアーカイブが合法になったことについて触れています。

本家の声明Internet Archive Helps Secure Exemption To The Digital Millennium Copyright Act によると、「図書館のような公的機関に限って、もはや動作させることが困難な古い記録メディアや再生機器が必要な場合には、コピープロテクトなどを解除してアーカイブすることがゆるされる」という改正がなされたように読めます。Internet Archiveはアメリカの非営利公益法人であり、この対象となります。形体としては「インターネット図書館」と呼べるものです。

提供手段はWebブラウザ上での再生で、JSMESSというJavaScript実装のエミュレーターを利用しています。つまり誰でもゲームがプレイできる状態にあるわけですが、この点について法的にどうなのかという疑問を後藤さんがされていました。

単純にコピーを配布する、という話であれば確かに問題があると思います。とはいえ、DMCAは先頭のDがデジタルであり、YouTubeのようなWeb上での配付に当たらない公開についての取り決めであったとなんとなく記憶していたので、改めて原文を確認してみました。

原文(pdf)には”webcasting”という表現がありました。Wikipediaの解説によると”Webcasting is the distribution of media files through the internet.”ということで、”distribution”の定義が問題になりそうです。訳としては配布もありますが、頒布と訳されることもあります。 個人的な見解としては、Webブラウザ上に限定して再生できる状況はYouTubeと形体としては近いものだと思います。日本の法解釈であればビデオゲームは映画と同じ分類(cf.パックマン訴訟)でもあります。 とはいえ、ブラウザに送信されたゲームのデータをキャプチャして第三者に配布するなどといったことは当然禁止されることでしょう。Internet Archiveが非営利法人であったからこそできたことでもあると思います。

こちらの後藤さんツイートはねとらぼの記事を読んだ直後のものなので誤解もあると思うのですが、さすがにそういう意図をInternet Archiveはしていないと思います。Internet ArchiveはかつてはWebの収集しかしていませんでしたが、今では動画音声画像電子書籍などといったものも広く収集、公開しています。Amazon S3 互換APIも用意されており、第三者からの提供も受け付けています。

最近壊したもの

昨年は本厄年で、今年は後厄を迎えているのですが、ここ2か月ぐらいでかなりの勢いでモノを壊してしまったので、記録として残しておきます。

Bluetoothキーボード

以前購入した「ELECOM Bluetoothフルキーボード ゲーム用82キー 9台切替 ブラック TK-GMFBP043BK」です。ちょっと引っかけてしまい、キートップが一つとれてしまいました。このキーボードはパンタグラフタイプです。

対処

エレコムのサポートに問い合わせたところ、サポート期間半年以内であれば対応とのことで、新品を送ってきてくれました。故障したものと購入を証明できるものを送り返してくれとのこと。神様のような対応です。

Playstation VITA(初代3Gモデル)

ジップロックに包んで水場で使っていたのですが、口をしっかりと締めていなかったため、するりとジップロックから本体がこぼれおち、がっつり水没させてしまいました。 1週間ほど陰干ししていたのですが、結局復帰することはありませんでした。

対処

水没に関しては通常修理対応しないということなので、中古で新しいモデルのWiFi版を購入しました。目下の課題は、壊れた本体とPS3との紐づけを外すことです。一応、サポートセンター経由でできるようです(未実施)。

Nintendo 3DS LL

ジムで運動しているときに、うっかり落としてしまいました。LEDがついている右側のヒンジ部分を強打してしまい、破損してしまいました。上部液晶は通電はしているものの、映像は移りません。

対処

取り急ぎ、中古の本体を購入しました。現在修理依頼をしているところです。直ったら、最悪一人すれ違い用にしようと思っています。

Nexus 5

路上にて、胸ポケットにいれるつもりが位置を外してしまい、そのままアスファルトの地面に落下し、表面ガラスが大きく破損しました。液晶表示およびタッチ部分に問題はありませんでしたが、通知部にひびが集中して見づらい状況でした。

対処

LGモバイルサポートセンターに修理として出しました。修理中はしまっていたGalaxy Nexusを引っ張り出して我慢しましたが、今となってはほぼ使い物にならないレベルでした(メモリ、CPU不足)。 修理費用は2万9千円程度になりました。白ロムのNexus5 32GBが4万円程度で流通しているようですが、修理してもらうことにしました。1週間程度で修理は完了し、現在はソフトケースを取り付けて利用しています。

LCD-10000VH2

外でもECS Livaの開発に使えるようなディスプレイが欲しい、ということでUSB給電で動作する小型のLCDパネル「センチュリー 10.1インチHDMIマルチモニター PLUS ONE HDMI LCD-10000VH2」を購入しました。 いい加減に保管していたら、ディスプレイ部に荷重がかかりすぎてしまい液晶が割れてしまいました。

対処

修理に出すことを検討していますが、まだアクションは起こしていません。正直いろんなものが集中して壊れすぎてこちらの精神まで壊れそうです。

まとめ

あらためてまとめてみると不幸続きにもほどがあることを実感できます。適切な取り扱いや、自衛対策をより進めてゆきます。

Windowsの証明書自動更新と認証proxyの罠(CryptoAPI)

過去にCentOS/RHEL5にてGlobalSignのルート証明書が期限切れとなる事態が起きました(参考: RHEL5/CentOS5でGlobalSignのルート証明書が有効期限切れで大騒ぎ)。一般的なGNU/Linuxディストリビューションでは、SSLのルート証明書等をパッケージとして配布しています。たとえばDebianではca-certificatesパッケージがそれに該当します。

かたやWindowsは、XPまではWindows Updateで最新の証明書セットを配布していました。しかしVista以降はマイクロソフトが各種証明局と連携して、自動的に更新する仕組みを導入しています。しかし、システムが利用するhttp proxyがユーザー認証つきの場合、これが動作しないということに最近気付きましたので、記録として残しておきます。

CryptoAPI

SSL証明書の自動更新は、CryptoAPIのサービス、Cryptographic Servicesが行います。管理ツールのサービス一覧を見ると、このサービスが動作しているのがわかります。

まったく新規のWindows環境を用意して、台湾のVISA取得サービス(https://visawebapp.boca.gov.tw/BOCA_MRVWeb/subroot/MRVWeb0_form.jsp)にアクセスする場合を例示してみます。

新規のWindows環境では、台湾のルート証明書は古いものが搭載されています。前述のURLにアクセスすると、CryptoAPIサービスが新しい証明書(http://grca.nat.gov.tw/repository/CRL/CA.crl)を取得し、検証用のエンドポイント(http://gca.nat.gov.tw/cgi-bin/OCSP/ocsp_server.exe)で証明書が正しいことを確認した上で、OSの証明書ストアを新しいものに更新します。

困ったことに、CryptoAPIは認証つきhttp proxyを経由したアクセスをサポートしていません。これは仕様としてそうなっているようです。

したがって、認証つきhttp proxyしかない環境下では、SSL証明書の更新がうまく動作しません。

一つの対応策として、User-Agentが”Crypto-API”である場合に認証を不要とする方法があります。それ以外には、stone等を使って認証不要なhttp proxyをローカルに立ち上げるという手段も考えられます。

 

さくらVPSでLXCを使う(dummynet+bridge+proxy arp)

さくらインターネットの提供するVPSサービスではDebianが利用できます。VPSのホストはKVMで提供されているようです。VPSのインスタンス一つで別の仮想的な環境が欲しくなったので、LXCを使ってみました。
ループバックインターフェースを持つだけのホストは簡単に作れるのですが、VPSに割り当てられているNICインターフェースをブリッジにするわけにもゆきません。そこで今回はdummynetを利用してホストオンリーネットワークを構築してみました。

dummynetは物理NICとは結びつかない、完全なダミーのネットワークインターフェースを提供します。インターフェース名はdummy0などとなります。使うには単純にmodprobe dummy等としてdummy.koをロードするだけです。Debianで起動時に有効にするためには、/etc/modulesに一行”dummy”と追加しておけばよいです。

次にdummy0をLXCから使えるよう、ブリッジを作ります。
apt-get install bridge-utilsを実行してネットワークブリッジデバイスを扱うためのツール一式を入れておきます。次に/etc/network/interfacesに以下のような記述を追加します。

auto br0
iface br0 inet static
        bridge_ports dummy0
        address 172.23.186.1
        netmask 255.255.255.0
        bridge_stp off
        bridge_fd 0
        bridge_maxwait 0

IPアドレスやネットワークは、別途自分が普段使う範囲とバッティングしない、適当なプライベートネットワークを設定してください。

この状態でifup br0を実行すれば、dummy0デバイスに紐づいたブリッジデバイスbr0が作られます。auto br0を入れてあるので、再起動時にも自動的にbr0がifupします。

この状態で、lxc-create等を使ってLXCコンテナのインスタンスを作成します。ただ、Debian wheezyのlxcパッケージはかなりbuggyで、あんまり動作が信用なりません。私は個人的にsidのlxcをバックポートしたものを使っています。

以下は私の作ったlxcコンテナのconfigの一部です。

lxc.network.type = veth
lxc.network.flags = down
lxc.network.link = br0
lxc.network.name = eth0

私は、コンテナ側の/etc/network/interfacesにeth0のネットワーク設定を書いて設定しています。

基本的にはこれでホストオンリーな環境ができます。しかし、メンテナンス上コンテナ側でも毎日apt-getはしたいので、私の環境ではNAT(masquerade)をできるようにしています。

この時に問題になるのがarpとfowardingです。何も設定しない状態では、br0から外に出ることができません。

まずbr0でproxy arpを有効化します。設定方法はsysctlを使うか、echo 1 > /proc/sys/net/ipv4/conf/br0/proxy_arpを実行するかして有効化します。これでbr0から他のインターフェース(eth0等)へ届くようになります。起動時に有効にするためには、interfacesにさらなる設定を追加します。

auto br0
iface br0 inet static
        bridge_ports dummy0
        address 172.23.186.1
        netmask 255.255.255.0
        bridge_stp off
        bridge_fd 0
        bridge_maxwait 0
        up echo 1 > /proc/sys/net/ipv4/conf/br0/proxy_arp

次はforwardingです。これもprocでも設定できますが、私は以下の内容を書いたファイルを/etc/sysctl.d/ip_forward.confとしています。

net.ipv4.ip_forward = 1

最期にNATの設定です。/etc/iptables/rules.v4に以下のような行を書いておきます。コマンドであれば、iptables -A POSTROUTING -s 172.23.186.0/24 -o eth0 -j MASQUERADEという具合です。

-A POSTROUTING -s 172.23.186.0/24 -o eth0 -j MASQUERADE

これで、VPS上でも外部ネットワークに到達可能なLXCインスタンスを持つことができます。もちろん、静的NATを組み合わせれば、一部のポートをインターネット側で受けることもできます。