2台以上あるnetatalkサーバの1台目にしかアクセス出来ない [netatalk]
2台以上あるnetatalk 2.0.xの1台目にしかアクセス出来ない。
これはFAQです。何度も何度もあちこちでみかける話です。
この問題はnetatalk2.1.xで直っています。
hostidを生成するとき、localhostのIPアドレス127.0.0.1を使ってしまうと、netatalkが2台以上あったときに混乱するという話です。対処法は、/etc/hostsにちゃんとしたhostnameを書く事です。
悪い例
127.0.0.1 myhostname.mydomainname myhostname localhost.localdomain localhost
良い例
<some ip addr> myhostname.mydomainname myhostname 127.0.0.1 localhost.localdomain localhost
もうちょっと掘り下げます。
afpクライアントがafpサーバに接続するまでの手続きを説明します。
- NBP(AppleTalk)、SLP(TCP/IP)、Bonjour(TCP/IP)等でサーバの存在を知る。またはアドレスを既に知っている。
- サーバに対して、AppleTalkまたはTCP/IPで、どんなサーバなのか問い合わせする(GetStatus、別名GetSrvrInfo)。
- サーバから返答を受け取る。
- その情報を元に、接続する。
netatalkにはasip-status.plというコマンドが付属しています。これはサーバに対して問い合わせを行ない、返答の内容を表示するものです。次は、私の自宅サーバhatachanに対して問い合わせた結果です。
# asip-status.pl hatachan AFP reply from hatachan:548 Flags: 1 Cmd: 3 ID: 57005 Reply: DSIGetStatus Request ID: 57005 Machine type: Netatalk AFP versions: AFPVersion 1.1,AFPVersion 2.0,AFPVersion 2.1,AFP2.2,AFPX03,AFP3.1 UAMs: DHCAST128,Cleartxt Passwrd Flags: SupportsCopyFile,SupportsServerMessages,SupportsServerSignature,SupportsTCP/IP,SupportsOpenDirectory,SupportsUTF8Servername,SupportsSuperClient Server name: hatachan Signature: 01 01 c0 a8 01 01 c0 a8 01 01 c0 a8 01 01 c0 a8 ................ Network address: 192.168.1.1 (TCP/IP address) Network address: 42750.172 (ddp address) UTF8 Servername: hatachan
このServer nameがlocalhostになっていたり、Network addressが127.0.0.1(TCP/IP)になっていると、クライアントが自分自身と勘違いしてしまうのは容易に想像できます。
さらに、Signatureというのがあります。仕様書にはServer signatureと書かれています。これはサーバに固有の16byteのデータであり、これを使えば、クライアントが二重に接続することがなくなるというものです。
afp3の仕様書より
Server signature
A 16-byte value that uniquely identifies a server used to prevent an AFP client from logging on to the same server twice.
逆に言えば、同じServer signatureを報告してくるafp serverが2台以上あると、一台しか繋がらないことになります。
このユニークなServer signatureをどうやって生成するかが問題です。
netatalk 2.0.xは色々工夫してますが、結局はhostidから生成するようになっています。このhostidというのは非常に古い仕様であり、今となっては陳腐です。
次に、色々なAFPサーバのServer signatureを観察してみます。
MacOS 9.2.2
00 00 17 76 00 00 17 76 00 00 17 76 00 00 17 76
どういうルールで生成したかわからないが、同じパターンを4回繰り返している。
MacOSX 10.1.5及び10.2
31 39 32 2e 31 36 38 2e 31 2e 31 35 00 69 67 2d
ASCIIコード表で文字に変換すると、192.168.1.15(NUL)ig-である。
これはIPアドレスです。最後の(NUL)ig-は不明。
MacOSX 10.4
00 03 93 63 ea 36 00 00 00 06 00 00 06 0e 00 00
システムプロファイラで確認すると最初の6バイトがMACアドレスと一致しています。
その後は不明。無線LAN経由で接続したのだが、このMACアドレスは有線の方でした。
netatalk 2.0.x (Linux 32bit)
01 01 c0 a8 01 01 c0 a8 01 01 c0 a8 01 01 c0 a8
hostidを4回繰り返している。Linuxの場合、hostidはIPアドレスから生成している。
ちなみに、このマシンのIPアドレスは192.168.1.1です。
netatalk 2.0.x (Linux 64bit)
01 05 c0 a8 00 00 00 00 01 05 c0 a8 00 00 00 00
hostidを2回繰り返している。関数gethostid()はlong型で定義されており、このマシンの場合は64bitになる。hostidは32bitなので00 00 00 00というのが入るわけです。
netatalk 2.0.x (Solaris9 Intel 32bit)
a4 4c a0 06 a4 4c a0 06 a4 4c a0 06 a4 4c a0 06
hostidを4回繰り返している。Solarisの場合、hostidはIPアドレスではない。Sparcではハードウェアでhostidを持っているらしい。Intel版の場合、OSをインストールするときに何らかのルールで決まるらしい。再インストールすると別のhostidになるそうだ。
netatalk 2.1.3
a6 29 d7 5b e0 82 51 3e b0 6f 2d 19 dc 10 9e f8
全く規則性がありません。なぜなら最新版ではhostidを捨てて、乱数からsignatureを生成するからです。これが他のAFPサーバと偶然一致する確率は極めて低いです。
ここまでの説明で、/etc/hostsを正しくすれば問題ないと書きました。しかしそれでも問題が発生するケースがあるので説明します。
afpd.confでは複数の仮想サーバを定義することが出来ます。
次の例では、ポート番号を指定し、AppleVoumesの設定ファイルを別にして2台のサーバに見せかけています。
server1 -defaultvol /etc/netatalk/AppleVolumes1.default server2 -port 10548 -defaultvol /etc/netatalk/AppleVolumes2.default
他にも、-ipaddrオプションを使って別々のIPアドレスにする方法もあります。(ネットワークカード2枚の場合とか)
こういった手法で別サーバに見せかける場合、Server signatureを別にする必要があります。netatalkの場合は、hostidをインクリメントして生成します。
今回のマシンが32ビットCPUで、IPアドレスが192.168.0.1であり、これを基にhostidが生成されたとすると、次のようなsignatureになるでしょう。
server1のsignature
00 01 c0 a8 00 01 c0 a8 00 01 c0 a8 00 01 c0 a8
(192.168.0.1から生成されたものを4回くりかえしている)
server2のsignature
01 01 c0 a8 01 01 c0 a8 01 01 c0 a8 01 01 c0 a8
(上記をインクリメントしたものを4回くりかえしている)
hostidがインクリメントされた結果、2つめのsignatureはIPアドレス192.168.1.1を持つサーバから生成されるものと同じになるでしょう。
192.168.1.1のサーバでnetatalkが動いていると、繋がりません。
ウチの部署の2台目のnetatalkにつなぐと隣の部署のnetatalkに繋がらない。なんて事態が発生しそうです。
この問題を回避する方法が2つあります。
/etc/hostidを用意する-signatureオプションを使う
他のサーバ管理者が思い付かないようなユニークなhostidやsignatureを自分で考えれば良いのです。
hostidはデータ幅が短いので、16Byte使えるsignatureの方がユニークになりやすいと思います。
server1 -signature user:DaisukeMiyagawa -defaultvol /etc/netatalk/AppleVolumes1.default server2 -signature user:HanakoMiyagawa -port 10548 -defaultvol /etc/netatalk/AppleVolumes2.default
server1のsignature
44 61 69 73 75 6b 65 4d 69 79 61 67 61 77 61 00
(DaisukeMiyagawaのASCIIコード)
server2のsignature
48 61 6e 61 6b 6f 4d 69 79 61 67 61 77 61 00 00
(HanakoMiyagawaのASCIIコード)
他のnetatalk管理者に大助花子マニアがいない限り、問題は発生しません。
まとめ
- 少なくとも/etc/hostsはちゃんと書く。これ常識。
- /etc/hostidを用意する方法があるが、特におすすめするものではない。
- 2.0.xの場合、-signature user:を使うと安心。
- 2.1.xだと、問題は発生しない。







いつもNetatalk関連の記事でお世話になっております。
どこにPostしていいのか分からずこちらにコメントをしてみました。
openSUSE 11.2(x64)にてNetatalk 2.1をインストールすると、Server Signatureがオール0という現象に当たりました。
/etc/hostsの記述からlocalhostの行を削除してみたり、自力でafp_signature.confを書いてみたりしたのですが、直りません。
afpd -Vで見ると確かに/usr/local/etc/netatalk/afp_signature.confを見に行くようになってるっぽいのですが、何故か無視されてる感じがします。
今のところ同一ネットワーク上にAFPをサーブする何かを置く予定はないので困ってはいないのですが、気持ちは良くないので原因を探ってみたいところです。
どの辺を疑ってみたらよいか、ご教示いただけると幸いです。
by 煌りん☆彡 (2010-05-23 21:58)
これはたぶん、以下のバグです。
http://sourceforge.net/tracker/index.php?func=detail&aid=3001982&group_id=8642&atid=108642
http://marc.info/?l=netatalk-devel&m=127419848211628&w=2
このメールに添付されているnetatalk-2.1-np2.diffを当てて様子をみてもらえませんか。
これでも直らなかったら未知のバグってことになり、ヤバいです。
by HAT (2010-05-23 22:07)
残念ながら直りませんでした。
最新のソースをgitで落としてみたんですが、それもちゃんと動きませんでした。
by 煌りん☆彡 (2010-05-23 23:08)
だいたい原因がわかりました。
1) afpd.confが存在しない
または、
2) afpd.confに有効な設定行がない(コメント行だけとか)
という場合、
afpdは各種設定を行なうルーチンをスキップし、デフォルト設定値を使います。
このとき、signatureを設定する関数set_signature()もスキップしてしまうため、今回のような現象が発生します。
回避策としては、
"hogehoge" -maccodepage MAC_JAPANESE
のように、サーバ名を明示した設定を行なってください。
こうしておけば、全くパッチを当てないnetatalk 2.1でも正常動作します。
パッチはまだ書いてません。
このあたりのソースはややこしいので、時間がかかるかもしれません。
メーリングリストで報告済です。
http://marc.info/?l=netatalk-devel&m=127471317808902&w=2
by HAT (2010-05-25 00:13)
2.1.1で修正済。
by HAT (2010-05-26 21:05)