ラベル 調査 の投稿を表示しています。 すべての投稿を表示
ラベル 調査 の投稿を表示しています。 すべての投稿を表示

2018-11-12

WSLでMozcで日本語入力

できるの・・・?

WSL(Windows Subsystem for Linux/旧Bash on Ubuntu on Windows)でGUIアプリ使う場合に気になること。GUIでLinuxのアプリを動かすのはXサーバを起動して環境変数DISPLAYを0:0とかに設定、というのはssh -XでGUIを引っ張ってくる時もやるので同じスキームでできそうだなという見当は付くものの、この方法でいっつも引っかかるのは

  • クリップボード経由のコピペ
  • 日本語入力(IMを経由した入力)

という定番があり、アルファベットだけで生きていけない言語話者としては常用するにあたりクリティカルな問題として常に横たわっていました。
が、どうもググるとWSLでMozc使って日本語入力が可能っぽいということで、作業ログ及びご紹介です。
尚、WSL用のターミナルはWSL Terminalを使っています。

WSL側で準備

関連パッケージのインストール

WSL側でフォント、X関連含めてインストール。インストールするフォントはお好みで。
# apt-get install fcitx-mozc
# apt-get install fonts-vlgothic fonts-mmcedar fonts-motoya-l-cedar fonts-motoya-l-maruberi
# apt-get install dbus-x11 x11-xserver-utils

実行準備

実行ユーザのUUIDを書き込み。
$ sudo sh -c "dbus-uuidgen > /var/lib/dbus/machine-id"
(これしないとエラーが出ます
dbus[4934]: D-Bus library appears to be incorrectly set up: see the manual page for dbus-uuidgen to correct this issue. (Failed to open "/var/lib/dbus/machine-id": No such file or directory; UUID file '/etc/machine-id' should contain a hex string of length 32, not length 0, with no other text)

環境変数設定

必要な環境変数をまとめたファイル~/.xenvをWSL側のホームディレクトリに作成(本当は~/.profileに書きたいのだけどWSL Terminalからbash起動した場合に~/.profileを読み込まないため。--loginを付けてbashを起動すればいいらしいのだけどそうじゃないだろと…)
export DISPLAY=localhost:0.0
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export DefaultIMModule=fcitx
今回だけ手動読み込み(次回以降WSLログインで読み込み)
$ . .xenv

尚、次回以降の起動用に~/.bashrcの末尾に.コマンドを追記。これで次回以降は気にする必要なし。
. ~/.xenv

Windows側でXサーバ/VcXsrvのインストール

vcxsrv-64.1.20.1.3.installer.exeでインストールしました。デフォルトのままFullで。
インストール後、デスクトップにできたXLaunchを実行、Select display settingsはデフォルトのMultiple windowsを選択し次へ、Select how to start clientsもデフォルトのStart no client。Extra settingsもデフォルトのままClipboardとNative openglで。タスクトレイにアイコン表示で起動。

WSL側でFcitx起動・設定

$ fcitx-autostart
毎回GUI起動時に実行しなければならないが.profileに書いてしまうとXサーバがいない場合.profileを抜けないらしいのでとりあえず手動で実行することにします。
諸々表示されますがecho $?して0なら問題なし。ならない場合はXサーバが起動されてるか確認。
問題なければ
$ fcitx-config-gtk3
fcitx-autostartを実行しない場合は空で表示されるので閉じてfcitx-autostart。ここにMozcを追加するので左下の+をクリック。
Mozc選んでOK。
Global Configを選んでとりあえずTrigger Input Methodを変えます。何か色々安定しないので全角半角以外、Ctrl+SpaceはEclipseの補完入力と被るので普段使わないキーバインディングに変えます。変え終わったら閉じ。

文字入力の出来るアプリを適当に実行して確認します。私の場合普段がMATE使いなのでPlumaとかCajaとかで。
とりあえずうまくいったことにします。

Mozcの設定(任意)

Xサーバが起動している状態で、徐に以下を実行。
$ /usr/lib/mozc/mozc_tool --mode=config_dialog
私の場合はATOKキーマップが一番いいのでMS-IMEから変更します。

fcitx-autostart実行設定を.xenvに追記

Windows側でVcXsrvが起動してたらログイン時(WSL Terminal実行時)にfcitx-autostartコマンドを実行するようにします。
Xサーバの死活監視ってどうやればいいかな?6000番からTCPでnetstat開いてるか見るかな?とも思ったんですが、Build14951以降のWSLではWSLからWindowsプログラムを実行できるようになってるので、これを利用して「VcXsrvが起動してるかどうかをtasklistコマンドで確認して動いてればfcitx-autostartを実行」を書いてしまおうと思います。

~/.xenvに以下を追記
if [ $(/mnt/c/Windows/System32/tasklist.exe | grep vcxsrv | wc -l) -gt 0 ] ; then
        echo "vcxsrv exists. fcitx-autostart execute."
        fcitx-autostart
else
        echo "vcxsrv does not exist. do nothing."
fi
色々と力づくなのは承知しており、以下の懸念があるのは言わずもがなです。
  • tasklistコマンドの位置がWindows/System32の下にあることが将来的に保証されない
  • tasklistコマンドで表示した場合のVcXsrvプロセスが小文字のvcxsrv.exeであることが将来的に保証されない
  • VcXsrv以外のプログラムで「vcxsrv」を含むプロセスがwindowsで動作していると誤検知する
ただ、手軽にさっとできるのはこの程度とは思っています。変更があれば修正したいですね。
また、fcitx-autostartの出力が邪魔という場合は > /dev/null 2>&1を後ろにつけてもいいと思います。

まとめ

  • WSL側で必要パッケージをインストール
  • VcXsrvをインストール
  • WSL側で環境変数、実行プログラム等準備
  • Have a Happy Mozc on WSL Life!

補足

何か調子がおかしい場合
  • 入力中のGUIアプリを保存して閉じて、fcitx-autostartを実行する
  • fcitx-config-gtk3を実行して、Mozcがある(一番上にある)事を確認
  • どうしてもおかしかったらXサーバを再起動してfcitx-autostartからやり直す
  • fcitx-config-gtk3の中でKeyboard-EnglishがあってIM切り替えでMozcを外した時にEnglishに切り替わる場合、キーボードレイアウトが英語キーボードになるっぽいのでいっそ消した方が幸せかもしれない

2018-04-08

LMDEからの卒業(予定)

もうかれこれ数年に渡って愛用しているLinuxディストロであるLMDE/Linux Mint Debian Editionですが、些細なきっかけにより今後使用するディストロから外れていく可能性が高くなりました。

2015-05-09

X.Orgの設定を探る

今まで有耶無耶にググって使えるようにしてきたX.Orgの設定ですが、LMDE2 Betsyのインストール時にノウハウが違ってたのでどう解決したもんかなと思いちょっと調べたので、今回備忘がてら書き残しておこうかと。

xorg.confはmanがあった
「あれが動かないんだけどどうすればいいの?」という疑問は基本的にRTFM問題だったというオチであります。
なんで、疑問を持ったらman 5 xorg.confしてからという話なんですが、やっぱりというかなんと言うかそもそもmanが長いのも確かで、掻い摘んで設定ファイルをどこから読むのかなーというところを見ても、一般ユーザーの場合
  • /etc/X11/<cmdline>
  • /usr/etc/X11/<cmdline>
  • /etc/X11/$XORGCONFIG
  • /usr/etc/X11/$XORGCONFIG
  • /etc/X11/xorg.conf
  • /etc/xorg.conf
  • /usr/etc/X11/xorg.conf.<hostname>
  • /usr/etc/X11/xorg.conf
  • /usr/lib/X11/xorg.conf.<hostname>
  • /usr/lib/X11/xorg.conf
追加configファイルは
  • /etc/X11/<cmdline>
  • /etc/X11/xorg.conf.d

rootユーザーの場合
  • <cmdline>
  • /etc/X11/<cmdline>
  • /usr/etc/X11/<cmdline>
  • $XORGCONFIG
  • /etc/X11/$XORGCONFIG
  • /usr/etc/X11/$XORGCONFIG
  • /etc/X11/xorg.conf
  • /etc/xorg.conf
  • /usr/etc/X11/xorg.conf.<hostname>
  • /usr/etc/X11/xorg.conf
  • /usr/lib/X11/xorg.conf.<hostname>
  • /usr/lib/X11/xorg.conf
追加configファイルは
  • <cmdline>
  • /etc/X11/<cmdline>
  • /etc/X11/xorg.conf.d
それでもって、ベンダ提供とかサードパーティーとかローカル管理者がファイルを置くべきディレクトリは
  • /usr/share/X11/xorg.conf.d
と書かれているので、実は割とどこにあっても読み込んでくれそうだなぁという感覚でFHSに則るとより良いかなというのがmanを読んだ後の感想です。

で、LMDEではどこに置けばいいの?
先週LMDEをクリーンインストールした時に置いた場所は/usr/share/X11/xorg.conf.dなんですが[1]、「ローカル管理者が置くファイル」に該当するのでここにしたというのと、DebianのWiki[2]でもここになってたからというのが理由です。

かつてのDebianではどうなっていたのか?
ところが、「ThinkPad トラックポイント Linux」とかで探すと/usr/share/X11/xorg.conf.dに置いてる記事が(日本語では)1件もなかったので、昔は違ったんだろうなぁという事情が見えてきます。
件のDebianのWikiの「TrackPoint scrolling on Squeeze and later」を見ると、gpointing-device-settingsパッケージを入れる記述がありますが、lenny以降はorphanで2011年の更新が最後になっている状態です。
xinputパッケージを使う場合は~/.xsessionrcにコマンドを書いておく方法が書かれています。
lennyでは/etc/X11/xorg.confの中のConfigured Mouseセクションに書き足す方法が書かれています。

設定値はどうやれば探れるのか?
20-thinkpad.confに記述する値はIdentifierとかMatchProductとかMatchDevicePathとかがいきなりしれっと書かれていますが、これらの値は本当はどうやって見つけるべきなのか。
DebianのWikiにコマンドが書かれています。
# dmidecode -t 21
# dmidecode 2.12
SMBIOS version fixup (2.33 -> 2.3).
SMBIOS 2.3 present.

Handle 0x002E, DMI type 21, 7 bytes
Built-in Pointing Device
    Type: Track Point
    Interface: PS/2
    Buttons: 3
# cat /proc/bus/input/devices
(snip)
I: Bus=0011 Vendor=0002 Product=000a Version=0000
N: Name="TPPS/2 IBM TrackPoint"
P: Phys=isa0060/serio1/input0
S: Sysfs=/devices/platform/i8042/serio1/input/input7
U: Uniq=
H: Handlers=mouse0 event7
B: PROP=0
B: EV=7
B: KEY=70000 0 0 0 0 0 0 0 0
B: REL=3
(snip)
これらの値を持ってくるのが正解というところでしょうか。
dmidecodeコマンドを初めて知ったんですが、type(-t/--type)で0(BIOS)から42(Management Controller Host Interface)まで情報が見えるのでこれから使ってみようかなと思います。

[1] http://utimukat55.blogspot.jp/2015/05/lmde-2-betsythinkpad.html
[2] https://wiki.debian.org/InstallingDebianOn/Thinkpad/Trackpoint のTrackpoint Scrolling on Wheezy or Jessie

2015-05-06

LMDE 2 Betsyを新しくないThinkPadに入れてみた

概要
今までLMDE UP8を入れていたThinkPad X40に先頃リリースされたLMDE 2 Betsy(MATE)をクリーンインストールしました。
apt-get dist-upgradeで更新できるかなと思ってトライはしてみたんですが、更新後PCを再起動したらGRUBの後kernel起動ができなくなってしまったので、あえなくクリーンインストールとなりました。
インストール自体はISOイメージをUSBメモリ(4GB)にddで焼いて、USBメモリから起動、起動後にHDDへインストールの手順で行いました。手順はこちらを参考に。[1]
インストールしたのは今回もMATEで、結構古いPCに入れるというのと軽快さを重視しての選択です。アーキテクチャはPentiumMなので選択肢は必然的に32bitのみ。

インストール後にすること
いろいろとインストール後にすることはあるんですが、今まで弊blogに書いてきたことがそのまま今回も使えたりしたので、参照するだけのところは基本的にはリンクを貼るだけにします。
  • aptの参照ミラーを日本に切り替える
  • 日本語入力できるようにする(fcitx) [2]
  • ネットワーク(無線LAN)を使えるようにする
  • sudoではなくsuでrootユーザになれるようにする [3] ※ただし、usermodでsudoグループから削除できなくなってた
  • デスクトップ/ダウンロード/テンプレート/公開/ドキュメント/音楽/画像/ビデオディレクトリをDesktop/Download/Template/Public/Document/Music/Pictures/Videosディレクトリに変更する
  • ThinkPadのトラックポイントのスクロールを有効にする
  • MintUpdateの自動起動を無効にする
  • スワップファイルをファイルシステム上に作る [4]
  • 日本語フォントとしてVLゴシック、モトヤ2種、Ricty Diminishedをインストール
  • ChromiumブラウザとPPAPI版のFlashのインストール(Flashのインストールについて[5])

aptの参照ミラーを日本に切り替える
Betsyのデフォルトのapt-lineは/etc/apt/sources.list.d/official-package-repositories.listに記載されていて、そのままでもこれといって問題はないんですがパッケージの取得の効率化のためにミラーを日本に切り替えます。diffは以下。
--- official-package-repositories.list.org    2015-04-07 02:02:43.000000000 +0900
+++ official-package-repositories.list    2015-05-05 10:22:31.050908564 +0900
@@ -1,7 +1,7 @@
 deb http://packages.linuxmint.com betsy main upstream import

-deb http://ftp.us.debian.org/debian jessie main contrib non-free
-deb http://ftp.us.debian.org/debian jessie-updates main contrib non-free
+deb http://ftp.jp.debian.org/debian jessie main contrib non-free
+deb http://ftp.jp.debian.org/debian jessie-updates main contrib non-free
 deb http://security.debian.org jessie/updates main contrib non-free

 deb http://www.deb-multimedia.org jessie main non-free
各パッケージの取得前に一度apt-get update、apt-get upgradeしておきましょう。

ネットワーク(無線LAN)を使えるようにする
デフォルトの状態で無線LANアダプタを認識していたので、ドライバのインストールとかは必要ありませんでした。
デスクトップ右下がこんな感じになっているので、クリックするとアクセス可能なSSID一覧が表示されます。
こんな感じのダイアログがでるので、PSKとかを入力して接続完了。

デスクトップ/ダウンロード/テンプレート/公開/ドキュメント/音楽/画像/ビデオディレクトリをDesktop/Download/Template/Public/Document/Music/Pictures/Videosディレクトリに変更する
ロケールに合わせて日本語でディレクトリ作ってくれるんですが、ターミナルからcdで移動するときにIME切り替えないといけないのが超絶めんどくさいので、以下のコマンドで変更します。
$ LANG=C xdg-user-dirs-gtk-update
コマンド実行後、ダイアログが表示されるので適切に操作して完了。

ThinkPadのトラックポイントのスクロールを有効にする
デフォルトでは左右ボタンと中ボタン(貼り付け)は機能しますが中ボタンドラッグのスクロールができないので、/usr/share/X11/xorg.conf.d/20-thinkpad.conf というファイルを作って以下の内容を記述します。
 Section "InputClass"
     Identifier "Trackpoint Wheel Emulation"
     MatchProduct       "TPPS/2 IBM TrackPoint|DualPoint Stick|Synaptics Inc. Composite TouchPad / TrackPoint|ThinkPad USB Keyboard with TrackPoint|ThinkPad Compact USB Keyboard with TrackPoint|USB Trackpoint pointing device"
     MatchDevicePath    "/dev/input/event*"
     Option             "EmulateWheel"          "true"
     Option             "EmulateWheelButton"    "2"
     Option             "Emulate3Buttons"       "false"
     Option             "XAxisMapping"          "6 7"
     Option             "YAxisMapping"          "4 5"
 EndSection
詳細は別途エントリにて。


MintUpdateの自動起動を無効にする
LinuxMintの特徴の一つでもあるMintUpdateですが、更新タイミングとかが気に食わなかったので自動起動を停止しました。
デスクトップ左下Menu→設定→自動起動するアプリ を選ぶと以下の画面になるので、
 「自動起動するプログラム」タブの中のMintUpdateのチェックを外して閉じます。

日本語フォントとしてVLゴシック、モトヤ2種、Ricty Diminishedをインストール
これまでのスクリーンショットの日本語フォントで大丈夫な方は作業不要です。
個人的には見やすさ重視のVLゴシック、改まったところで使うモトヤ、エディタとかで使うRicty Diminishedを使う予定なので、これらをインストールします。
ただし、Ricty DiminishedはDebian GNU/Linuxのjessieには入らなかったので、パッケージを直接ダウンロード[6]してdpkgコマンドでインストールしました。
# apt-get install fonts-vlgothic fonts-motoya-l-cedar fonts-motoya-l-maruberi
# dpkg -i /home/user/Downloads/fonts-ricty-diminished_3.2.4-1_all.deb
また、Rictyフォントのインストールはこちら[7]で紹介しています(今回検証していません)

Chromiumブラウザのインストール
BetsyはデフォルトでFirefoxがインストールされています。Chromiumはメモリ使用量がきついのですが一応インストールしています。
# apt-get install chromium
てなわけで、インストール後に最低限必要な手順を備忘を兼ねて書き出しました。
今までLMDE UP8使ってて今回Betsyにした感じだと、正直何が変わったのか体感できてないんですが(汗)、動作は軽快だし今のところ悪いところは見つかってないです。
きっとCinnamonの方だと色々と変わってるんじゃないかなーという気はします。
何よりアップデートが掛からないと使うことができないというのが更新の理由ですね。

[1] http://www.tecmint.com/linux-mint-debian-edition-betsy-cinnamon-installation-customization/
[2] http://utimukat55.blogspot.jp/2014/06/lmde-up8matefcitx.html
[3] http://utimukat55.blogspot.jp/2013/10/sudo.html
[4] http://utimukat55.blogspot.jp/2014/05/linuxswapswap.html
[5] http://utimukat55.blogspot.jp/2014/06/debianchromiumflash.html
[6] https://packages.debian.org/stretch/all/fonts-ricty-diminished/download
[7] http://utimukat55.blogspot.jp/2014/01/ricty.html 

2014-06-28

DebianのChromiumでFlashを見る

Flashという障壁
いつもセキュリティホールが見つかる対象として諸悪の根源的な扱いも受けることの多いFlashですが、それでもあったほうが便利な状況は未だに多く、特にデスクトップ用途ではその傾向が顕著です。
また、GNU/Linux上での扱い方もコロコロ変わったりするんですが、Debianで扱う[1]上で今の時点で一番筋の良さそうな方法を記載します。前提は以下。

  • ChromiumブラウザでFlashを使う
  • アーキテクチャはi386/amd64

Chromium上でのFlashの扱い
(Chromeではない)Chromiumを使う場合、ブラウザにFlashが同梱されていないため、手動で導入する必要があります。(ChromeにはPPAPI版のFlashが同梱されているので、このエントリの手順は必要ありません)
Flashの導入はパッケージとしてaptからできますが、NPAPI版[2]とPPAPI版[3]のパッケージがあります。詳細な違いは把握してませんが、NPAPIは古いアーキテクチャでメンテナンスが大変らしい、基本的にChromeはNPAPIのサポートをやめる方向、バイナリをadobeからダウンロードしてくる。PPAPIは新しいアーキテクチャで、GoogleがメンテしていてバイナリもGoogleからダウンロードしてくる。という違いはあるようなので、ここではPPAPI版[4]の導入をすることにします。

パッケージのインストール
# apt-get install pepperflashplugin-nonfree
インストールは以上で、パッケージのインストールの場合はバイナリを落としてきてインストールまでやってくれるみたいです。

普段のメンテナンス
pepperflashplugin-nonfreeパッケージ自体はflashのバイナリを含んでいるわけではなく、update-pepperflashplugin-nonfreeコマンドの実行によってバイナリが更新されているかを判断するようです(NPAPI版のflash-plugin-nonfreeと同じ)
# update-pepperflashplugin-nonfree
Usage:
  update-pepperflashplugin-nonfree --install
  update-pepperflashplugin-nonfree --uninstall
  update-pepperflashplugin-nonfree --status
Additional options:
  --verbose
  --quiet
ということなので、--statusを付けてアップデートがあるかチェック、あれば--installで更新ということになります。(更新があるかどうかを自動的に確認する方法は無さそうです。)
ちなみに、現在の状況は
# update-pepperflashplugin-nonfree --status
Flash Player version installed on this system  : 14.0.0.125
Flash Player version available on upstream site: 14.0.0.125

導入されているバージョンは、Chromiumから「chrome://plugins/」を開くことでも確認が可能です。

[1] https://wiki.debian.org/FlashPlayer
[2] https://packages.debian.org/jessie/flashplugin-nonfree
[3] https://packages.debian.org/jessie/pepperflashplugin-nonfree
[4] https://wiki.debian.org/PepperFlashPlayer

2014-06-21

LMDE UP8(MATE)での日本語入力にfcitxを使う

以前のエントリ[1]の内容を新しいPCでやってみるとできないことに気づいたので、LMDE UP8(MATE)を新規インストールした際の設定方法を確認しました。
LMDEでの設定方法ですが、他のdistro(特にDebian系)でも応用できるのではないかと思います。

関連パッケージのインストール
パッケージをインストールします。
# apt-get install im-config fcitx fcitx-mozc fcitx-frontend-gtk2 fcitx-frontend-gtk3 fcitx-frontend-qt4 fcitx-frontend-qt5 fcitx-ui-classic fcitx-config-gtk mozc-utils-gui
im-configコマンドでfcitxを指定します。(以前の手順ではコンソールから選びましたが、-nオプションでinput method nameを指定するとコマンドだけで変えれるみたいです。
$ im-config -n fcitx
Xをログアウトしてもう一度ログインし、「設定」→「Fcitx設定」を開きます(メニュー開いて右上の「すべてのアプリケーション」を選択しておいてください。)

「入力メソッド」タブにmozcが追加されてるのを確認して、「全体の設定」で入力メソッドのオンオフを変えたりします。



今度はメニューから「設定」→「Mozcの設定」。


「一般」タブでキー設定の選択をATOKに。


「辞書」タブに「Unicode6絵文字変換」というのがあったので選んでみました。


以上。

余談
パッケージを大量にインストールしてますが、こんなにちまちま指定しなくてもLinux Mint Japanが提供する「mint-gnome-ja」パッケージをインストールすると色々ひっくるめてインストールできます。
ですが、とにかく以下の点があり(個人的に)お勧めできません。

  • ibus入れてくる[2]
  • takaoフォント入れてくる[3]
  • 他にも使うかどうかわからないパッケージ色々入れてくる

これでもいいという方はmint-gnome-jaを入れるほうが楽なので、入れ方をググってもいいと思います。

[1] http://utimukat55.blogspot.jp/2013/10/ibusfcitx.html
[2] ibus使い続けて問題なければfcitxユーザーこんなに増えてないよね
[3] 画面表示はVLゴシックの方が見やすいし、改まったゴシックならモトヤLシーダ(fonts-motoya-l-cedar)/モトヤLマルベリ(fonts-motoya-l-maruberi)使えばいいかなというのと、takaoフォントの優先度がむちゃくちゃ高いのが嫌なので

2014-02-10

特定のMACアドレスに対してIPv6アドレスを設定するDHCPv6サーバを構築した(4)-DHCPv6サーバの設定再び

前回までのあらすじ

  • DHCPv6サーバはISCのものにパッチを当てたものをパッケージとして作ってインストール
  • DHCPv6クライアントはISCのものを使って、クライアントを手動実行
  • クライアントから送るDHCPv6 soliciteが期待通りにならない(DUIDが)
サーバ側の設定を変更
/etc/dhcp/dhclient.confに記載したDUIDは例のwide_mkduid.plで生成したもので、Hardware typeが6(IEEE802)となっていたのだけど、ISCのdhclientは1(Ethernet)としてDUIDを作るので、こっちに寄せることにしてファイルの内容を変更[1]。最終的には以下。

default-lease-time 2592000;
preferred-lifetime 604800;
option dhcp-renewal-time 3600;
option dhcp-rebinding-time 7200;
allow leasequery;
option dhcp6.info-refresh-time 21600;
dhcpv6-lease-file-name "/var/lib/dhcp/dhcpd6.leases";
# RAとか範囲とか(うちの場合はRTX1100で配っているRA)
subnet6 fd00:dead:beef::/64 {
 # 1000からffffまでをDHCPで配る対象にする
 range6 fd00:dead:beef::1000 fd00:dead:beef::ffff;
 # 固定IPアドレス
 host kurobox-t4 {
  host-identifier option dhcp6.client-id 00:03:00:01:00:16:01:xx:yy:zz;
  # 固定で振るIPv6アドレス
  fixed-address6 fd00:dead:beef::100;
 }
}
DHCPサーバを再起動。
# /etc/init.d/isc-dhcp-server restart
DHCPv6クライアント側はDUIDタイプはdhclientのmanを注意深く読んだ結果、引数「-D LL」を指定することでLLを強制的に指定できそうだったので、/var/lib/dhcp/dhclient6.leasesの中身を空にして[2]、起動方法を以下の引数へ変更して実行。
# dhclient -6 -D LL -cf /etc/dhcp/dhclient.conf eth0 -v
一応これで当初望んでいた「fd00:dead:beef::100」は設定されるようになったので「特定のMACアドレスに対して固定IPv6アドレスをDHCPv6で設定する」は達成できたと思いますが、いくつか条件付きなのはここまで記載したとおり。
  • DHCPv6サーバがデフォルトだと扱いづらい
  • dhclientの起動方法が手動
  • DUIDがLLのみ(LL+Tだと対応できない)
サーバ側もクライアント側も結局一筋縄でいかないのは間違いないと思うので、できるだけ早いとここの辺が解決するといいなぁと思っています。

[1] 00:03:00:06から00:03:00:01へ
[2] 空にしないと、取得済みのアドレスを載せたDHCPv6 confirmを送り続けます

特定のMACアドレスに対してIPv6アドレスを設定するDHCPv6サーバを構築した(3)-DHCPv6クライアントの設定

DHCPv6クライアントの設定
クライアント側パッケージはisc-dhcp-clientを使います。サーバ側をisc-dhcp-serverにしたからというだけですが、一応バージョンはdebianの4.2.4-7[1]を使いました。これより前のバージョンでも動くかもしれません。
で、いろんなサイトを見ながら設定を探しつつ…とりあえず[2]の設定がよさげかなぁと思ってこれをベースに。
以下の2行を/etc/dhcp/dhclient.confに書き足して。
send dhcp6.oro 3,23,24,31;
send dhcp6.rapid-commit;
NIC再起動すりゃこの設定したdhclientがDHCPv6 solicite投げるだろjk…
# /etc/init.d/networking restart
……パケット取ってるwiresharkに一向にDHCPv6パケットが流れてこない……

DHCPv6クライアントを手動で実行する
まさかの手動実行ですよ。何か設定が間違ってるのかもしれませんが小職のスキルでは悪いところが見つけられませんでした。

で、とりあえずman dhclientしてみて、dhclient --helpしてみて、それっぽい引数を探します。
# dhclient --help
Internet Systems Consortium DHCP Client 4.2.4
Copyright 2004-2012 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/
Usage: dhclient [-4|-6] [-SNTP1dvrx] [-nw] [-p <port>] [-D LL|LLT]
                [-s server-addr] [-cf config-file] [-lf lease-file]
                [-pf pid-file] [--no-pid] [-e VAR=val]
                [-sf script-file] [interface]
ふむ。とりあえずDHCPv6クライアントとして実行する場合は-6と、最後のinterfaceは指定したほうがよさそう。ついでに一応設定ファイルを-cfで明示的に指定してみよう。あとは動きを確認するために-v(よくあるverbose)。

# dhclient -6 -cf /etc/dhcp/dhclient.conf eth0 -v
実行結果。
Internet Systems Consortium DHCP Client 4.2.4
Copyright 2004-2012 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/
Bound to *:546
Listening on Socket/eth0
Sending on   Socket/eth0
PRC: Soliciting for leases (INIT).
XMT: Forming Solicit, 0 ms elapsed.
'send dhcp6.oro' syntax is deprecated, please use the 'request' syntax ("man dhclient.conf").
XMT:  X-- IA_NA 01:96:49:2b
XMT:  | X-- Request renew in  +3600
XMT:  | X-- Request rebind in +5400
XMT: Solicit on eth0, interval 1060ms.
RCV: Advertise message on eth0 from fe80::213:e8ff:fexx:yyzz.
RCV:  X-- IA_NA 01:96:49:2b
RCV:  | X-- starts 1391264700
RCV:  | X-- t1 - renew  +3600
RCV:  | X-- t2 - rebind +7200
RCV:  | X-- [Options]
RCV:  | | X-- IAADDR fd00:dead:beef::c7e5
RCV:  | | | X-- Preferred lifetime 604800.
RCV:  | | | X-- Max lifetime 2592000.
RCV:  X-- Server ID: 00:01:00:01:1a:7f:8d:59:00:13:e8:xx:yy:zz
RCV:  Advertisement recorded.
PRC: Selecting best advertised lease.
PRC: Considering best lease.
PRC:  X-- Initial candidate 00:01:00:01:1a:7f:8d:59:00:13:e8:xx:yy:zz (s: 153, p: 0).
XMT: Forming Request, 0 ms elapsed.
'send dhcp6.oro' syntax is deprecated, please use the 'request' syntax ("man dhclient.conf").
XMT:  X-- IA_NA 01:xx:yy:zz
XMT:  | X-- Requested renew  +3600
XMT:  | X-- Requested rebind +5400
XMT:  | | X-- IAADDR fd00:dead:beef::c7e5
XMT:  | | | X-- Preferred lifetime +7200
XMT:  | | | X-- Max lifetime +7500
XMT:  V IA_NA appended.
XMT: Request on eth0, interval 960ms.
RCV: Reply message on eth0 from fe80::213:e8ff:fexx:yyzz.
RCV:  X-- IA_NA 01:xx:yy:zz
RCV:  | X-- starts 1391264702
RCV:  | X-- t1 - renew  +3600
RCV:  | X-- t2 - rebind +7200
RCV:  | X-- [Options]
RCV:  | | X-- IAADDR fd00:dead:beef::c7e5
RCV:  | | | X-- Preferred lifetime 604800.
RCV:  | | | X-- Max lifetime 2592000.
RCV:  X-- Server ID: 00:01:00:01:1a:7f:8d:59:00:13:e8:xx:yy:zz
PRC: Bound to lease 00:01:00:01:1a:7f:8d:59:00:13:e8:xx:yy:zz.
お。動いてる[3]。動いているが。DHCPv6サーバから振られているアドレスが「fd00:dead:beef::c7e5」である。前に書いたとおり動いていれば振られるアドレスは「fd00:dead:beef::100」になるはずなのであるが。一応ifconfigでも確認。
# ifconfig
eth0      Link encap:イーサネット  ハードウェアアドレス 00:16:01:xx:yy:zz
          inetアドレス:192.168.1.33 ブロードキャスト:192.168.1.255  マスク:255.255.255.0
          inet6アドレス: fd00:dead:beef:0:216:1ff:fexx:yyzz/64 範囲:グローバル
          inet6アドレス: fe80::216:1ff:fexx:yyzz/64 範囲:リンク
          inet6アドレス: fd00:dead:beef::c7e5/64 範囲:グローバル
うむやはり。c7e5はDHCPv6サーバからリースする範囲(1000からffff)の範囲には入っているので、DHCPv6サーバ自体は機能してそう。
サーバ側のログを見てみると。
Feb  1 23:25:36 lmdecfy7 dhcpd: Solicit message from fe80::216:1ff:fexx:yyzz port 546, transaction ID 0x792D6600
Feb  1 23:25:36 lmdecfy7 dhcpd: Picking pool address fd00:dead:beef::c7e5
Feb  1 23:25:36 lmdecfy7 dhcpd: Sending Advertise to fe80::216:1ff:fexx:yyzz port 546
Feb  1 23:25:37 lmdecfy7 dhcpd: Request message from fe80::216:1ff:fexx:yyzz port 546, transaction ID 0xA4A60600
Feb  1 23:25:37 lmdecfy7 dhcpd: Wrote 0 deleted host decls to leases file.
Feb  1 23:25:37 lmdecfy7 dhcpd: Wrote 0 new dynamic host decls to leases file.
Feb  1 23:25:37 lmdecfy7 dhcpd: Wrote 0 leases to leases file.
Feb  1 23:25:37 lmdecfy7 dhcpd: Sending Reply to fe80::216:1ff:fexx:yyzz port 546
ということで、どうも適当に在庫からアドレスを拾ってきていてそれがc7e5ということらしい。うーむ。色々がんばったつもりなんだが。
パケットを見てみると、どうやらDHCPv6 soliciteの中にクライアントから送られるDUIDが含まれているらしいということを知る。
DUID type: link-layer address plus time (1)
Hardware type: Ethernet (1)
Time: Feb  1, 2014 23:25:00 JST
Link-layer address: 00:16:01:xx:yy:zz
マジかよ。とりあえず2つおかしい。
  1. DUIDタイプがLL+T(MACアドレスと時刻)になっている
  2. Hardware typeがEthernetになっている
DUIDタイプは時刻がいつになるかわからない時点で知ったこっちゃないので、LLになるといいなぁと思っていたので、正直参る。

このエントリはここまで。

[1] http://packages.debian.org/ja/jessie/isc-dhcp-client
[2] https://wikispaces.psu.edu/display/ipv6/DHCPv6#DHCPv6-ISCdhclient4.1.0
[3] MACアドレス該当部はぼかしています

2014-02-05

特定のMACアドレスに対してIPv6アドレスを設定するDHCPv6サーバを構築した(2)-DHCPv6サーバの設定(1)

(今のところ)isc-dhcp-serverはdaemonとしてハンドリングしづらい
いきなりブチ切れに近い感じで。

  • 今回DHCPv6サーバにするのはLinux(Debian GNU/Linux)
  • ざっと持ち合わせてる知識だとwide-dhcpv6-server[1]かisc-dhcp-server[2]が良さそうなのだけど、wideの方はupstreamを見ても最後の更新が2009年なので使うのに気が引けてしまう(今はdibblerなのかな?)
  • かと言ってisc-dhcp-serverがDHCPv6サーバとしてハンドリングしやすいかと言えばそんな事は全くなく、パッチをあてる[3]のが一番てっとり早そうという泥沼
という事で、普通のDHCP(v4)サーバみたくハンドリングできるようにソースパッケージにパッチをあててビルドしますorz。

isc-dhcp-serverをビルド、インストール
まず、当てたいパッチが4.2.4向けなので、現状4.2.4なtesting/jessieまたはsidをapt-get sourceできるように以下の行をapt-lineに追加します。

deb-src http://ftp.jp.debian.org/debian/ jessie main non-free contrib
# apt-get update
# apt-get build-dep isc-dhcp=4.2.4-7
# apt-get install devscripts

# exit
$ mkdir build_isc
$ cd build_isc/
$ apt-get source isc-dhcp=4.2.4-7
で、[3]のMessage142のisc-dhcp-server-ipv6.patchをダウンロードしてきます。ここでは~/Downloadsに保存したものとして、
$ patch -u -p0 < ~/Downloads/isc-dhcp-server-ipv6.patch
(patching file・・・がずらずらーっと出ればOK)

$ cd isc-dhcp-4.2.4/
$ debuild -uc -us
$ su
$ cd ..
# dpkg -i isc-dhcp-server_4.2.4-7_amd64.deb isc-dhcp-common_4.2.4-7_amd64.deb
でビルドしたパッケージのインストールは完了。

isc-dhcp-serverの設定項目
今回はDHCP(v4)サーバは設定せず、DHCPv6サーバだけ動かすので、そのように書き換えます。/etc/default/isc-dhcp-serverの以下の場所を書き換え。
  • V4_ENABLED="true"を"false"へ
  • V6_ENABLED="false"を"true"へ
  • INTERFACES_V6=の行を"wlan0"へ(今回はwlan0でDHCPv6dを動かすので)
# touch /var/lib/dhcp/dhcpd6.leases

/etc/dhcp/dhcpd6.confを必要に応じて書き換える。
default-lease-time 2592000;
preferred-lifetime 604800;
option dhcp-renewal-time 3600;
option dhcp-rebinding-time 7200;
allow leasequery;
option dhcp6.info-refresh-time 21600;
dhcpv6-lease-file-name "/var/lib/dhcp/dhcpd6.leases";
# RAとか範囲とか(うちの場合はRTX1100で配っているRA)
subnet6 fd00:dead:beef::/64 {
 # 1000からffffまでをDHCPで配る対象にする
 range6 fd00:dead:beef::1000 fd00:dead:beef::ffff;
 # 固定IPアドレス
 host kurobox-t4 {
  host-identifier option dhcp6.client-id 00:03:00:06:00:16:01:xx:yy:zz;
  # 固定で振るIPv6アドレス
  fixed-address6 fd00:dead:beef::100;
 }
}
ここで固定アドレスを振る対象の行の最後のパラメータですが(最後3オクテットをぼかしてますが)、これが弊ブログの別エントリで触れているDUIDになります。
この時点では生成をミスるとまずいと思ったので、wide_mkduid.plというスクリプトを使って生成しました。端的に書くと、MACアドレスの前に「00:03:00:06:」を付与したDUID-LL(hardware typeは6(IEEE 802 Networks))です。まぁ後々これでも不味かったことを思い知るわけですが。
なお、dhcpd6.confの書き方は[4]を参考にさせていただきました。

このエントリはここまで。


[1] http://packages.qa.debian.org/w/wide-dhcpv6.html
[2] http://packages.qa.debian.org/i/isc-dhcp.html
[3] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=592539

特定のMACアドレスに対してIPv6アドレスを設定するDHCPv6サーバを構築した(1)-序章

やる前は1エントリで済むと思ってたんですが実際やってみるとすげー大変だったのでいくつかに分けます。
現状&やりたいこと
我が家では部分的にIPv6を導入していて、VPN(L2TP)ルータとしてヤマハのRTX1100を使っています。また、RAもRTX1100からLAN側に流していて、ステートレスなIPv6アドレス設定はできている状態です。


ですが、ご存知の通りIPv6アドレスは長い事、ステートレスに生成するIPv6アドレスは128bitぶんのアドレスを使い切る(0ではない)ので、LAN内のサーバにも頻繁にアクセスするには辛いアドレス(手入力したくない)が設定されます。[1]
そこで、IPv4では家庭用のブロードバンドルータでもできるような「特定のMACアドレスに特定のMACアドレスを配布する」をIPv6で実現しようと思いました。よく言うDHCPv6によるステートフルなIPv6アドレス割り振り(しかも固定アドレス)です[2]。

せっかくヤマハルータあるんだからコマンドいくつか流しこめば出来るんじゃないかと思ったんですが、現状のヤマハルータではRTX1100に限らずこの機能が提供されていません。


なので、LAN内のPCをDHCPv6サーバにしてみようというのが今回のスタート地点です。

今回の記事の全容は以下になります。

  1. 序章←今ここ
  2. DHCPv6サーバの設定(1)
  3. DHCPv6クライアントの設定
  4. DHCPv6サーバの設定(2)
RTX1100の設定はこんな感じです。

  • LAN1がLAN
  • 配布するRAのprefixはfd00:dead:beef::/64
  • DHCPv6使うのでRAのMフラグは立てる

具体的には

  • # ipv6 prefix 1 fd00:dead:beef::/64
  • # ipv6 lan1 prefix fd00:dead:beef::/64
  • # ipv6 lan1 rtadv send 1 m_flag=on
このエントリはここまで。


[1] AAAAレコードを返すDNSサーバを置いても解決できる問題ではありますが
[2] ステートフルの定義を理解できてないかもしれないので間違っていたら教えてください

2014-02-01

DHCPv6について(DUID)

DHCPv6で(各ホスト上の手動設定ではなく)静的にアドレスを振る方法について調べていて、DUIDというものに辿り着いた。忘れないように書きだす。

DUIDとは
色々世の中にはIDを振る方法があるのだけど、DHCPの仕組みで使われる(と思われる)IDの振り方。DHCP Unique Identifierの略。

RFC3315で定義されているDUID
RFC3315(DHCP for IPv6)[1]のSection-9で定義されているDUIDは3つ。

  • DUID-LLT(DUID Based on Link-layer Address Plus Time)
  • DUID-EN(DUID Assigned by Vendor Based on Enterprise Number)
  • DUID-LL(DUID Based on Link-layer Address)

DUID-LLTとDUID-LLに書かれている「Link-layer Address」は日本語でいう物理アドレス、いわゆるMACアドレスのことで、LLTの方はMACアドレスと時刻から導出、LLはMACアドレスから導出という事らしい。
一方でDUID-ENはIANAがメンテしているPrivate Enterprise Numberに各ベンダが持っているIDを振っていく形式のようだ。
これら3つのIDのオフセットはRFC3315を参照。

RFC6355で定義されているDUID
それでいて、RFC6355(DUID-UUID)[2]でもDUIDが定義されている。
DUID-UUIDはRFC4122で定義されているUUIDをそのまま使う(正確にはDUID-Typeである4の後ろにDUID128bitを繋げる144bit)ということ。UUIDはあんまり重複しないのでこれの方が手軽という事なんだろうか。

もうちょっとだけ続くんじゃ(2014/02/04追記)
元々あるDUID-LLTとDUID-LLについて、dhclientがデフォルトで投げるDUIDがDUID-LLTになっているので、何で似たようなものが2つあるのかdhclientのデフォルト設定について調べていたらバグとして報告されていた[3]。
その中でComment21に
> So it seems like we all agree that DUID-LL is the way to go...
AFAIK even the RFC agrees :).
と書いてあり、それならと思って改めてRFC3315を読んでみると、まずDUID-LLTがある理由は

  • DHCPv6クライアントとDHCPv6サーバとの間で重複しないIDが必要
  • NICを機器の間で付け替えたとしても、別々のIDになるようにする
ために、MACアドレスと時刻を複合キーのように扱ってIDとして使う。との事。
ではDUID-LLが定義されている理由は。

This type of DUID consists of two octets containing the DUID type 3,
a two octet network hardware type code, followed by the link-layer
address of any one network interface that is permanently connected to
the client or server device.  For example, a host that has a network
interface implemented in a chip that is unlikely to be removed and
used elsewhere could use a DUID-LL.
要は、「NICを取り外し不可能なプロダクトに限ってDUID-LLを使ってもいいよー」的なノリで書かれているので、デフォルトはDUID-LLみたいな事になっているようだ(RFC3315を書いた時のノリでは)。

それと、DUID-LLTとDUID-LLの3〜4オクテット目に使われるhardware typeはIANAでメンテされていて[4]、どういう風に識別されているかはDUIDを生成するDHCPv6クライアント次第であることにも注意が必要である。(DHCPv6サーバ側でDUIDを元にした処理をする場合があるので。)
具体的には、6(IEEE 802 Networks)かと思ったら1(Ethernet (10Mb))だったりするので。

[1] http://tools.ietf.org/html/rfc3315#section-9
[2] http://tools.ietf.org/html/rfc6355
[3] https://bugzilla.redhat.com/show_bug.cgi?id=560361
[4] http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml#arp-parameters-2

2014-01-26

Dockerを使ってみる(2)-操作ひと通り

前回のエントリでDebian GNU Linux/jessieのDockerコンテナが出来上がってるので、それをいじりまわす感じで。
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
utimukat55/debian   jessie              583d969ed337        4 minutes ago       153.3 MB
dockerのインストールが終わっていると、ホスト側にdocker0というNICが追加されますが、どうもここをルーティングする形でゲストから外に通信をするようです。
ルーティング設定と反映のコマンドを実行します。
/etc/sysctlの以下の行をアンコメント。
net.ipv4.ip_forward=1
以下のコマンドを実行して即時有効化
# sysctl -p
net.ipv4.ip_forward = 1

とりあえず起動する
docker images実行結果のIMAGE IDをイメージに指定、シェルを起動するよう引数に指定してコマンドを実行。
# docker run -t -i 583d969ed337 /bin/bash
root@ed7307934a79:/#
 今の状態だとifconfigもないなど色々扱いづらい(個人的に)なので、必要なパッケージを入れます。
# apt-get install net-tools openssh-server vim
vimを入れたので、/etc/apt/sources.listを必要であれば書き換えてミラーを変更します(USになっているので)

commitする!
起動しているbashを抜けると保存されずに終了してしまうので、別のターミナルを開いて、以下のコマンドを実行します。
# docker ps -a
CONTAINER ID        IMAGE                      COMMAND             CREATED             STATUS              PORTS               NAMES
ed7307934a79        utimukat55/debian:jessie   /bin/bash           23 minutes ago      Up 23 minutes                           lonely_euclid
 CONTAINER IDを引数に指定してcommitします。-mでコミットログも付けれるみたいですが未確認。
# docker commit ed7307934a79 utimukat55/debian:jessie
f86c3830f454c1ed1e217b86f09c47df41e2ed1bed22038813b478d1514283cc
commitが終わったら実行してた方を閉じます。exitでいいみたいです(Ctrl-dでも抜けれますがステータスが130になって正常終了じゃないみたいです。詳細不明)

色々と未整理なこと
コンテナを起動して終了すると、状態を記録した?ファイルが増えていきます。確認は以下のコマンドで可能です。
# docker ps -a
CONTAINER ID        IMAGE                      COMMAND             CREATED             STATUS              PORTS               NAMES
b12d2c3979c6        utimukat55/debian:jessie   /bin/bash           19 seconds ago      Exit 130                                boring_albattani  
84883288b0e9        utimukat55/debian:jessie   /bin/bash           About an hour ago   Exit 0                                  insane_shockley  
449810a25bd0        utimukat55/debian:jessie   /bin/bash           About an hour ago   Exit 0                                  grave_darwin        
この中から必要のないものがある場合、docker rmコマンドで削除可能です。引数はCONTAINER IDを指定します。
# docker rm b12d2c3979c6
いろんなコンテナを使っている場合、コンテナの一覧は以下のコマンドで確認できます。(既に出てきていますが)
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
utimukat55/debian   jessie              583d969ed337        23 minutes ago      153.3 MB
base                latest              b750fe79269d        10 months ago       175.3 MB
base                ubuntu-12.10        b750fe79269d        10 months ago       175.3 MB
base                ubuntu-quantal      b750fe79269d        10 months ago       175.3 MB
base                ubuntu-quantl       b750fe79269d        10 months ago       175.3 MB
必要のないコンテナを削除する場合、docker rmiコマンドを使います。引数はIMAGE IDを指定します。
# docker rmi b750fe79269d
まだまだわかってない事のほうが遥かに多いですがとりあえずここまで。

ここまでやったイメージ
セントラルリポジトリ?にアップロードしました。
使う場合は以下のコマンドでどうぞ。
# docker pull  utimukat55/docker_jessie

Dockerを使ってみる(1)-導入

Dockerとは
いわゆる仮想化ソリューションですが、OSごと仮想化するような感じではなく、カーネル等は共通のものを使いながらユーザーランドを分離するSolarisコンテナみたいなもののようです。今回はいつもどおりDebian GNU/Linux(amd64)で導入します。今のところamd64でしか動作しないようです(Raspberry PIに移植してる人はいるみたいなので将来的にはアーキテクチャ非依存になるかもしれません)。

パッケージの導入
公式サイト[1]を参考にしつつ例によってsudo使わないのでこんな感じ。パッケージ自体はUbuntu用のものがそのまま使えています。
# wget -qO- https://get.docker.io/gpg | apt-key add -  
OK
# echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list
# apt-get update
# apt-get install lxc-docker
よくわからなかったのでとりあえずデフォルトのまま。パッケージのインストールはこれで完了。

自前でイメージを作成
Dockerのイメージとして公式のもの[2]もありますが、今回はtesting(今はjessie)のイメージを作りたかったので、自分で作ることにします。Debianの場合はシェルが用意されています。docker searchコマンドで所望のイメージが見つかる場合はこの手順は必要ありません。

https://github.com/dotcloud/docker-debian/blob/master/contrib/mkimage-debian.sh

Rawを右クリックしてリンク先保存。ターミナルでダウンロードしてきた場所に移動して
$ chmod +x mkimage-debian.sh
$ su
# ./mkimage-debian.sh utimukat55/debian jessie
問題なく終われば、
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
utimukat55/debian   jessie              583d969ed337        4 minutes ago       153.3 MB
みたいな感じでイメージができているはず。このエントリはここまで。

[1] http://docs.docker.io/en/latest/installation/ubuntulinux/
[2] https://index.docker.io/popular Officialと書かれているものは多分安全

2014-01-08

Rictyフォントを生成する

元にしているフォントのライセンス都合上導入に手間のかかるRictyフォント[1]ですが手元のDebian環境で生成してみました。
というのも、Rictyフォントの生成にはfontforgeと2つのフォントが必要ですが、Debianだとパッケージで用意されてるみたいなので手間削減できるかなぁと思い・・・
Rictyフォントの生成
まずはfontforgeとベースとなるフォント(InconsolataとMigu 1M)のDebianパッケージをインストール
# apt-get install fonts-inconsolata fonts-migmix fontforge
次いで生成シェルをダウンロード。githubからgit cloneでもいいんでしょうが、ちょっと手間を惜しんで。
ブラウザで https://github.com/yascentur/Ricty/blob/3.2.2/ricty_generator.sh へ移動
「raw」を右クリック→保存
ターミナル開いてダウンロードしたディレクトリに移動
$ chmod +x ricty_generator.sh
$ ./ricty_generator.sh auto
で、問題がなければシェルが正常終了します。
Ricty-Bold.ttfとRicty-Regular.ttfが実行した場所に生成されるので、フォント追加します。[2]

$ mkdir ~/.fonts
$ cp -f Ricty-{Bold,Regular}.ttf ~/.fonts/
システムワイドに追加したい場合は/usr/local/share/fonts/にコピーすると良いでしょう。
$ fc-cache -vf
追加されたことを確認したい場合は $ fc-list | grep Ricty で確認するといいでしょう。
と思ったものの!!
生成に必要なフォントのうち、Migu 1Mが古いです(Debianのパッケージが)。
単にパッケージングしてないだけかぁと思いつつBTS見てみたら、どうもライセンスが変わったけどどうするのこれ的なの[3]が見つかりうーん。
なお、フォントが古い事が明らかになってしまったので上記手順自体あまりおすすめできなくなってしまいましたが補足。
Rictyの生成手順で書かれている「(MigMixではありません)」をぶっちぎってfonts-migmix[4]をインストールしていますが、migu-1m-regular.ttfとmigu-1m-bold.ttfが20120411版と同じことは確認済みです。

[1] http://save.sys.t.u-tokyo.ac.jp/~yusa/fonts/ricty.html
[2] https://wiki.debian.org/Fonts#Adding_fonts
[3] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=680036
[4] http://packages.qa.debian.org/f/fonts-migmix.html

2013-10-30

sudoを使わない理由

概要
弊ブログを見て戴いている方には
「なんでこの人はLinux使っているのにsudo使ってないんだろう」
という疑問を持つ方がいるかもしれない。
このエントリは、そんな疑問を持った人に対する私なりの回答である。

sudoとは
sudoというのは、最近のLinuxディストリビューションではかなりデフォルト導入率の高い[1]、「他のユーザとしてコマンドを実行する」ためのコマンドである。
また、他のユーザとしてコマンドを実行する時に【自ユーザのパスワードをcredentialとして使用する】のも大きな特徴。

古くからUNIXでは、su(substitute user)というコマンドで、ターミナル上での実行ユーザの切り替えを行ってきたが、最近ではAndroidでroot権限が必要な場合にsuをインストールする手順があるので、こっち経由で知っている人も多いかもしれない。
sudoを使うと、sudo以降にタイプしたコマンドを、(suでユーザ変更することなく)自分以外のユーザで実行できるということである。

sudoが嫌いな理由
ここからは自分がsudoを使わずにsuを使う理由を並べていく。
  • 毎回sudoって打つのが面倒
使い勝手の面ではこれが最大の嫌いな理由である。例えば「あーaptで更新したいなー」と思った時に
$ sudo apt-get update
[sudo] password for hogehoge:
$ sudo apt-get upgrade
必要なステップは3つ。ただし事前に認証済みで、認証が残っていればパスワードは聞かれないので2つ。この2つだったり3つだったり感。
一方で、普通にsuして同じコマンドを実行する場合は
$ su -
パスワード:
# apt-get update
# apt-get upgrade
必要なステップは常に3つ(パスワード入力を1とするなら4つ)だが、コマンド打ってる途中にパスワードを入れるという混乱が起こらないのでこっちのがいいなぁ。

  • 一般ユーザのパスワードに他ユーザの履歴が混じって記録される
いまどきのインタラクティブシェルは大概コマンドの履歴を保持する機能を持っていて、すぼらなユーザが「あの時どんな引数使ったかなぁ」なんて時にhistoryコマンドで実行履歴を参照されるので、最近実行したコマンドは引数含めて確認が簡単にできる。
のはいいのだが、sudo使うとsudoコマンドの履歴も一般ユーザのhistoryに残るので、root権限の必要なコマンドが一般ユーザの履歴に残る。更に、【sudoは認証に自ユーザのパスワードを使うので、どんなに重要なコマンドであってもそのユーザが実行できてしまう】状態になる。個人的にはセキュリティ考えると一般ユーザでログインされた時点で全部クラックされたも同然なのでなんで問題にならないんだろうと前から思っているのだが。

sudoを使うメリット
では、sudoを使うメリットとは何なんだろうか。
  • 実行履歴をロギングできる
sudo自体は2通りのロギングの仕組みを持っている。syslogのファシリティを設定することでsyslogに渡す事もできるし、sudo自体のログ機構も使うことができる。特に大事な設定を変更する場合は監査目的で保持したほうが良い場合があるので、そういった場面ではコマンド履歴をロギングできるというのは非常に有用であると思う。[2]

なので、企業内でsudoを使うというのは妥当な理由があると思う。そもそもsudoを使わないとできない操作はchrootとか使えばいくらでも代替できるので、クリティカルなサーバでは存在しないのではないかとも思うが。

sudoを使うメリット?
sudoの使い方と合わせて合理的っぽい理由として書かれている利点に

  • ssh/telnetでrootログインされる心配がない
というのがあるが、これ本当だろうか。心配がないというのは本当なんだが、(インターネット経由での)telnet自体はもう使われないとしてsshログインに話を限定すると、

  • 大抵の場合、sshdはデフォルトでrootログインを許可していない(PermitRootLoginの設定)
  • 外部公開する場合、sshdは公開鍵認証にするのが普通なので、それが破れている時点でrootを破られてもsudoersされてる一般ユーザを破られても大して変わらないのではないか
  • sshdの脆弱性を突かれる可能性はあるが、opensshとsudoだとsudoの方がセキュリティパッチ当たる頻度が高いのでsudo使うほうが危なくないか

というのが個人的な意見である。

sudoじゃなくてsuでrootユーザになれるようにする
最近のLinuxディストリビューションでは、インストール時にも一般ユーザの設定しかしないし、実際にインストール後にsu -しようとしてもパスワードが一致しない。これは設定されていないrootのパスワードに合わせる方法が存在しないからである。ということで、rootのパスワードを設定することでsuからrootになれるようにするのが、インストール後最近一番最初にやることになっている。
でもどうやって?sudoを使って。

rootユーザのパスワードを設定するのはroot権限が必要。でもrootユーザのパスワードが設定されていないのでsu - rootができない。ならばsudoを使うしかない。
$ sudo passwd root
New UNIX password:
Retype new UNIX password:
んで、sudoグループに入っているとsudoが使えてしまう(sudoersの設定による)ので、sudoグループから抜ける。
まずはどのグループに入ってるか確認
$ id -a
uid=1000(hogehoge) gid=1000(hogehoge) groups=1000(hogehoge),27(sudo),111(fuse),122(kvm),123(libvirt)
rootになってusermod。
$ su - root
# usermod -G hogehoge,fuse,kvm,libvirt hogehoge
C-dで戻って
$ id -a
uid=1000(hogehoge) gid=1000(hogehoge) groups=1000(hogehoge),111(fuse),122(kvm),123(libvirt)
sudoできなくなったことを確認
$ sudo apt-get update
[sudo] password for hogehoge: 
hogehoge は sudoers ファイル内にありません。この事象は記録・報告されます。
以上。


[1] Ubuntuがデフォルトで使っていたからという理由が一番大きそうだが
[2] ちゃんと活用できれば、の話だが

2011-12-15

Google Calendar APIが更新された

ものすごい勢いで書くのをサボっていた弊blogだが、サボっている間に調査中だったCalendar APIが更新されていた[1]。かなり大胆に変更されたようなので、新しいAPIを使って色々試したいと思う。

[1] http://code.google.com/p/google-api-java-client/wiki/APIs

2011-10-03

プログラムからGoogleカレンダーを操作する


Googleカレンダーを初めとしたGoogleサービスは、「Google Data Protocol」として外部から利用できるようになっており、同じく公開されている「Google Data API」[1]をプログラムから呼び出すことで、操作する事が可能である。

Googleカレンダーをプログラムから操作する場合、「Google Calendar Data API」を呼び出すのがよさそうである。プログラム言語はJava/.NET/PHP/Python/JavaScript/Objective-C、他のAPIとしてはCalDAVからアクセスする方法もあるようだ[2]。ここでは、JavaのAPIを使って操作することとする。


実行に当たっての準備は、ライブラリとして以下のファイルを依存ライブラリとして設定し、実行を確認している。
  • gdata-calendar-1.0.jar
  • gdata-client-1.0.jar
  • mail.jar
なぜかJavaMailのjarであるmail.jarが必要である。これらが公式な説明として必要とされているが、mavenのセントラルリポジトリから取得できたため、以下にPOMのdependencyを記載する。「java mail」「google calendar」で検索した結果から得られたものである。

  <dependencies>
  	<dependency>
  		<groupId>org.codemonkey.simplejavamail</groupId>
  		<artifactId>simple-java-mail</artifactId>
  		<version>2.0</version>
  	</dependency>
  	<dependency>
  		<groupId>com.google.api.client</groupId>
  		<artifactId>google-api-data-calendar-v2</artifactId>
  		<version>1.0.10-alpha</version>
  	</dependency>
  	<dependency>
  		<groupId>org.openengsb.wrapped</groupId>
  		<artifactId>com.google.gdata</artifactId>
  		<version>1.41.5.w1</version>
  		<type>bundle</type>
  	</dependency>
  </dependencies>


まずは、自分のカレンダーの全エントリを取得するプログラム。このプログラムでは、以下のmainクラスの他に、Constantsというクラスを定義しており、以下のデータを定数として定義している。

  • String loginAddr(gmailのアカウント@gmail.com)
  • String loginPassword(アカウントのパスワード)
  • URL url("http://www.google.com/calendar/feeds/default/private/full")

import java.io.IOException;
import java.util.List;

import com.google.gdata.client.calendar.CalendarQuery;
import com.google.gdata.client.calendar.CalendarService;
import com.google.gdata.data.calendar.CalendarEventEntry;
import com.google.gdata.data.calendar.CalendarEventFeed;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;

public class SampleMain {

	public static void main(String[] args) throws IOException, ServiceException {
		Constants.setUrl();
		
		CalendarService service = getMyCalendar();
		
		List<CalendarEventEntry> eventList = getEverySchedules(service);
		
		displaySchedule(eventList);
	}
	
	public static CalendarService getMyCalendar() throws AuthenticationException
	{
		CalendarService service = new CalendarService("gmail-sample-1.0");
		service.setUserCredentials(Constants.loginAddr, Constants.loginPassword);
		System.out.println("CalendarService Created.");
		return service;
	}
	
	public static List<CalendarEventEntry> getEverySchedules(CalendarService service) throws IOException, ServiceException
	{
		CalendarQuery query = new CalendarQuery(Constants.url);
		CalendarEventFeed results = service.query(query, CalendarEventFeed.class);
		List<CalendarEventEntry> result = results.getEntries();
		System.out.println("Result get success.");
		return result;
	}
	
	public static void displaySchedule(List<CalendarEventEntry> entries)
	{
		System.out.println("=== BEGIN All schedules ===");
		for (CalendarEventEntry entry : entries)
		{
			System.out.println("== schedule begin ==");
			System.out.println("Title:[" + entry.getTitle().getPlainText() + "]");
			System.out.println("Start Date:[" + entry.getTimes().get(0).getStartTime() + "]");
			System.out.println("End Date:[" + entry.getTimes().get(0).getEndTime() + "]");
			System.out.println("Summary:[" + entry.getSummary() + "]");
			System.out.println("Place:[" + entry.getLocations().get(0).getValueString() + "]");
			System.out.println("== schedule end ==");
		}
		System.out.println("=== END All schedules ===");
	}
}

あらかじめ予定が入れてある場合、以下のような実行結果が得られる。

=== BEGIN All schedules ===
== schedule begin ==
Title:[適当な未来の予定]
Start Date:[2011-08-20T10:30:00.000+09:00]
End Date:[2011-08-20T11:30:00.000+09:00]
Summary:[null]
Place:[日本武道館]
== schedule end ==
== schedule begin ==
Title:[適当な過去の予定]
Start Date:[2011-08-18T09:00:00.000+09:00]
End Date:[2011-08-18T10:00:00.000+09:00]
Summary:[null]
Place:[埼玉スーパーアリーナ]
== schedule end ==
=== END All schedules ===

次に、単一ユーザで複数のカレンダーを持っている場合に、カレンダーの一覧を取得するサンプル。このサンプルでも、以下の値をConstantsクラスに別途定義している。


  • String loginAddr(gmailのアカウント@gmail.com)
  • String loginPassword(アカウントのパスワード)
  • URL url("http://www.google.com/calendar/feeds/default/allcalendars/full")
このとき、urlに"http://www.google.com/calendar/feeds/default/owncalendars/full"を指定すると、ユーザが所有するもののみ取得になる(allcalendarsでは、自分が所有していないカレンダーでも取得対象となる)

import com.google.gdata.client.calendar.CalendarService;
import com.google.gdata.data.calendar.CalendarEntry;
import com.google.gdata.data.calendar.CalendarFeed;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;


public class TestMain {

	/**
	 * @param args
	 * @throws ServiceException 
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException, ServiceException {
		// TODO Auto-generated method stub

		CalendarService service = getMyCalendar();
		
		CalendarFeed feeds = service.getFeed(Constants.allCalendarUrl, CalendarFeed.class);
		
		List<CalendarEntry> entries = feeds.getEntries();
		
		for (CalendarEntry entry : entries)
		{
			System.out.println(entry.getTitle().getPlainText());
		}
		
	}

	private static CalendarService getMyCalendar() throws AuthenticationException {
		CalendarService ret = new CalendarService("example");
		ret.setUserCredentials(Constants.loginAddr, Constants.loginPassword);
		
		return ret;
	}

}

同じく、複数のカレンダーを保持するようにしている場合、実行結果は以下のようになる。

1つめのカレンダー(デバッグ用)
2番目のカレンダー(デバッグ用)
最初のカレンダー(デバッグ用)
4つ目のカレンダー(デバッグ用)
日本の祝日
連絡先の誕生日と予定

そして、上記2つの事ができるならば、「自分が保持しているカレンダーの下にぶら下がっている全ての予定を取得」することも可能ではないかと考えがち(というか、自分も考えた)だが、一筋縄ではいかない。方法はあるにはあるのだが、オフィシャルに公開されている方法でないし、いつまでも同じ方法でできるとも限らない。ともかく長くなってしまったので、このエントリはここまでとする。