ホスト名で許される文字って何なんだっけという話

以前の同期の友人と、そういえば数字だけのドメイン名って許されてるんだっけ?という話題で一通り盛り上がった。なかなか面白いことがわかったのと、イマイチよーわからんなーということが出てきたので、せっかくなので記事にしておこうと思う。

TL;DR

  • 数字のみのホスト名は RFC 的に OK
  • アンダースコアはホスト名的には NG だがドメイン名的には OK

数字だけのドメイン

https://0.30000000000000004.com/ というサイトが Twitter で回ってきた。 こういうドメインって RFC 的にどうなんだっけ。数字だけのドメインって大丈夫なんだっけ?

ホスト名の定義(大元)

host name については、元々は RFC952 に記載がある。以下、関係のある部分だけ抜き出し。

GRAMMATICAL HOST TABLE SPECIFICATION

      <official hostname> ::= <hname>
      <hname> ::= <name>*["."<name>]
      <name>  ::= <let>[*[<let-or-digit-or-hyphen>]<let-or-digit>]

見ての通り、 name は文字から開始して、あいだにハイフンとか入ってもいいけど、最後は letter or digit で終わること、とある。ホスト名はこれがドット区切りで1つか複数。これが最初のホスト名の定義だ。*1

でも、ホスト名ってドメイン名と同じなんだっけ?定義はよくわからない。

わからないなら、調べるしかないよね。

ドメイン名の定義(大元)

DNS 初期の RFC は結構gdgdなのは業界的に常識だけど、とりあえず RFC1035 を見てみよう。 ホスト名に対して 推奨される 形式がさっそく見つかった。とりあえず定義部分だけを見てみよう:

The following syntax will result in fewer problems with many
applications that use domain names (e.g., mail, TELNET).
<domain> ::= <subdomain> | " "
<subdomain> ::= <label> | <subdomain> "." <label>
<label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
<let-dig-hyp> ::= <let-dig> | "-"
<let-dig> ::= <letter> | <digit>
The labels must follow the rules for ARPANET host names.  They must
start with a letter, end with a letter or digit, and have as interior
characters only letters, digits, and hyphen.

この定義はホスト名とほぼ同じだ。違いとしては、先ほどは name だったものが label と呼ばれているくらいだろうか。 RFC 952 は ARPANET を念頭に書かれているので、 RFC 1035 の推奨するドメイン名は RFC 952 のホスト名と同等ということになる。

ただし、この部分はあくまで推奨。時代背景を見てみると、この頃はまだプロトコルの統一も完全でなければ商用インターネットもできる前なので、いろんな環境で共通して使えるような命名規則を作ろうとしていた…という面が強そうだ。

The DNS specifications attempt to be as general as possible in the rules
for constructing domain names.  The idea is that the name of any
existing object can be expressed as a domain name with minimal changes.

However, when assigning a domain name for an object, the prudent user
will select a name which satisfies both the rules of the domain system
and any existing rules for the object, whether these rules are published
or implied by existing programs.

For example, when naming a mail domain, the user should satisfy both the
rules of this memo and those in RFC-822.  When creating a new host name,
the old rules for HOSTS.TXT should be followed.  This avoids problems
when old software is converted to use domain names.

The following syntax will result in fewer problems with many
applications that use domain names (e.g., mail, TELNET).

具体的に「何を使っていいか」ということになると、あまり具体的には指定されていないように見える。

ちょっと脱線してしまったので、話に戻ろう。

そう、数字だ。数字だけのドメイン。 結局、数字だけのドメイン名は RFC 違反なわけ??

いやいやそんなわけ……。調べるしかないので、調べてみる。

ホスト名の定義(更新)

実はホスト名の定義は RFC1123 2.1 で更新されてる。

   2.1  Host Names and Numbers

      The syntax of a legal Internet host name was specified in RFC-952
      [DNS:4].  One aspect of host name syntax is hereby changed: the
      restriction on the first character is relaxed to allow either a
      letter or a digit.  Host software MUST support this more liberal
      syntax.

「RFCC952 で定義されたホスト名の先頭の文字、べつに数字でもよくね?」って言ってる。 RFC952 の BNF っぽい記法でこれを書き直してみると:

GRAMMATICAL HOST TABLE SPECIFICATION

      <official hostname> ::= <hname>
      <hname> ::= <name>*["."<name>]
      <name>  ::= <let-or-digit>[*[<let-or-digit-or-hyphen>]<let-or-digit>]

こういうことになる!! *2 *3

ということで、めでたしめでたし。最初の疑問、「数字オンリーのホスト名はRFC違反か」という疑問への答えが出た。 答えは「the Internet 開始前、 1989年からRFC 1123 で許容されている」ということになる。

ドメインにアンダースコア

……が、ここでふと次の疑問が湧いてきた。アンダースコアってどうなんだっけ?

そういやホスト名ってハイフンしか使っちゃダメって書いてあるよね。でも Let's Encrypt とか各種サービスの認証で ACME 使うとき、アンダースコアから始まるドメイン名使うよね。あれは RFC 的にはオッケーなんだっけ?

Informational な RFC で許容されている

実は、 DNS Operation の方法を記した RFC1033 ではアンダースコアが明示的に許容されている。

   The domain system allows a label to contain any 8-bit character.
   Although the domain system has no restrictions, other protocols such
   as SMTP do have name restrictions.  Because of other protocol
   restrictions, only the following characters are recommended for use
   in a host name (besides the dot separator):

           "A-Z", "a-z", "0-9", dash and underscore

各種サービス側で問題が出るから色々な制限を入れているけれど、 DNS はただのデータベースなのだから、何をラベルに使ったっていいんだ、アンダースコアはオッケーだよ、と、こう言っているわけ。

一方で、 RFC1912 というドキュメントがある。これは Common DNS Operational and Configuration Errors というタイトルの RFC 。重要な部分だけ抜き出してみると:

2.1 Inconsistent, Missing, or Bad Data

   Every Internet-reachable host should have a name.  The consequences
   of this are becoming more and more obvious.  Many services available
   on the Internet will not talk to you if you aren't correctly
   registered in the DNS.

   DNS domain names consist of "labels" separated by single dots.  The
   DNS is very liberal in its rules for the allowable characters in a
   domain name.  However, if a domain name is used to name a host, it
   should follow rules restricting host names.

   Allowable characters in a label for a host name are only ASCII
   letters, digits, and the `-' character.  Labels may not be all
   numbers, but may have a leading digit  (e.g., 3com.com).  Labels must
   end and begin only with a letter or digit.

   Note there are some Internet
   hostnames which violate this rule (411.org, 1776.com).  The presence
   of underscores in a label is allowed in [RFC 1033], except [RFC 1033]
   is informational only and was not defining a standard.  There is at
   least one popular TCP/IP implementation which currently refuses to
   talk to hosts named with underscores in them.

つまりアンダースコアを使うのはよくあるミスであって、使うべきではないぞと。 また、 RFC1035 の表現は問題を避けたいがゆえの曖昧さでいっぱいなので問題だとも言ってる。著者のクセが強い。

ちなみに RFC2181 の方ではアンダースコアが許容されていると語る人もいて、うーんなるほど曖昧という気持ちになる。

   The DNS itself places only one restriction on the particular labels
   that can be used to identify resource records.  That one restriction
   relates to the length of the label and the full name. 

結局、ドメイン名的にはアンダースコアは許容されているのかいないのか、微妙なところだ。

Apache 2.4 ではアンダースコアは使えない

じゃあ現実世界はどうだっけと、ふと Apache に目を向けてみると、なんと。

Apache 2.4 では host name を RFC 準拠にしたことで、 virtualhost などにアンダースコアを使えなくなっていた。まじかよ……

nderscores are not permitted in hostnames and are now rejected.  RFC 3986 sec 3.2.2 - https://tools.ietf.org/html/rfc3986#section-3.2.2 --

   A registered name intended for lookup in the DNS uses the syntax
   defined in Section 3.5 of [RFC1034] and Section 2.1 of [RFC1123].
   Such a name consists of a sequence of domain labels separated by ".",
   each domain label starting and ending with an alphanumeric character
   and possibly also containing "-" characters.

Using "HttpProtocolOptions unsafe" should allow the old behaviour.

https://bugzilla.redhat.com/show_bug.cgi?id=1410130

何がまじかよって、この RFC 3986 って URI を定義している RFC なんだよね。ということは、 URI 的には hyphen - は OK で underscore _ は NG とされているわけで。 Web サービスを提供する際は、ハイフンを使うのは必須だった ってことになる。知らなかった……。

Microsoft 的にはハイフンが推奨

とはいっても、やはりアンダースコアは世の中に存在している。存在するものをなかったことにはできない。ウォーハクタク。

ここで、 RFC に準拠しすぎて相互接続に難が出ることで有名な Microsoft のドキュメントを見てみよう。

ドメイン名にアンダースコア (_) を使用することは避けてください。
厳重に RFC に従ったアプリケーションがドメイン名を拒否して、
インストールされなかったり、ドメイン内で機能しなかったりして、
古い DNS サーバーで問題が発生する可能性があります。

https://support.microsoft.com/ja-jp/help/909264/naming-conventions-in-active-directory-for-computers-domains-sites-and

意外と柔軟

そして、こんな文言も見つかる:

アンダースコアには特殊な役割があり、RFC 定義では SRV レコードの
先頭文字として許可されていますが、比較的新しい DNS サーバーでは、
名前の任意の場所での使用が許容される場合もあります。 

ん…? SRV レコードの先頭には使っていいの?

SRV レコードの先頭には underscore を使っていいんです

SRV レコードでのアンダースコアについては、 RFC2782 に明確に記載がある。

The format of the SRV RR

   Here is the format of the SRV RR, whose DNS type code is 33:

        _Service._Proto.Name TTL Class SRV Priority Weight Port Target

   Service
        The symbolic name of the desired service, as defined in Assigned
        Numbers [STD 2] or locally.  An underscore (_) is prepended to
        the service identifier to avoid collisions with DNS labels that
        occur in nature.

ホスト名やその他の世間的に使われているドメイン名では、先頭アンダースコアなんて変なことしない。だからカブらない。 SRV レコードはこの書式を使っても大丈夫なんだ!と、こう RFC に書かれているわけ。

なるほどー。*4

オチ

だいたい疑問が解決したところで、また違う MS のドキュメントを見て、アレッとなってしまった。

    Strict RFC (ANSI) . Allows "A" to "Z", "a" to "z", the hyphen (-), the asterisk (*) as a first label; and the underscore (_) as the first character in a label.

    Non RFC (ANSI) . Allows all characters allowed when you select Strict RFC (ANSI) , and allows the underscore (_) anywhere in a name.

    Multibyte (UTF-8) . Allows all characters allowed when you select Non RFC (ANSI) , and allows UTF - 8 characters.

    Any character . Allows any character, including UTF - 8 characters.

https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-2000-server/cc959336(v=technet.10)

マルチバイト文字が許容されている…?

そう、実は RFC 2181 を読むと、ドメイン名のラベル部分には any binary string が使用可能、と書かれているんです。えー……今更そんな……

11. Name syntax

   Occasionally it is assumed that the Domain Name System serves only
   the purpose of mapping Internet host names to data, and mapping
   Internet addresses to host names.  This is not correct, the DNS is a
   general (if somewhat limited) hierarchical database, and can store
   almost any kind of data, for almost any purpose.

   The DNS itself places only one restriction on the particular labels
   that can be used to identify resource records.  That one restriction
   relates to the length of the label and the full name.
(略)
   Those restrictions
   aside, any binary string whatever can be used as the label of any
   resource record.  Similarly, any binary string can serve as the value
   of any record that includes a domain name as some or all of its value
   (SOA, NS, MX, PTR, CNAME, and any others that may be added).

   Implementations of the DNS protocols must not place any restrictions
   on the labels that can be used.  In particular, DNS servers must not
   refuse to serve a zone because it contains labels that might not be
   acceptable to some DNS client programs.

ということで、ドメイン名にはどんな文字でも使えちゃう、したがって当然ドメイン名にアンダースコアがあっても問題は一切ない、ということでした。*5

ちなみにドメイン名の基本的な挙動*6については case insensitive であることが RFC 的に MUST なんだけど、そうすると(記号類もフルで使えると仮定しても) 1byte が 256 - 26 - 1 = 230 の情報量しか示さないことになって、なんだか中途半端で気持ち悪い。

でも逆に、こういうところが DNS 最高って思うんです()

終わりに

ということで、以上まとめると、結論としては以下のようになる。

  • 数字だけのドメインRFC 的に許容されている
  • アンダースコアについては、 RFC 上、ホスト名はもちろん URI でも許容されていない
  • ドメイン名にはどのような文字でも使えるのでアンダースコアを含むドメイン名を作ることには一切問題がない

こうやって調べてみるのも久しぶりでなかなか面白かった。どさにっきさんっぽくなりたい。

でも記事の内容的には、 RFC を 3000番台までしか参照していなくて deprecated かもしれないし、また読み違いもあるかもしれない。 非常に不安なので、詳しいところの読み方については識者からのご指摘を待ちたいところです。

そんなとこ。

*1:ちなみに letter 一文字でも valid な official hostname になる

*2:数字オンリーの name が4桁続くと IP Address Form と同じになってしまう可能性があるじゃないか、とおっしゃる方、実際その通りなのだけど、この RFC では TLD は必ず letter が入るので問題ない、と言っており、この点は問題ないことになっている

*3:このあたりからは、 host name は DNS での lookup が前提とされていることも読み取れる。 host name と domain name との区別はかなり微妙だったようだ

*4:ただこれでも疑問は残って、 TXT レコードに転用されるようになった経緯とかそれに関する RFC とかはよーわからん

*5:バイナリラベルの書き方についてはRFC2673に定義されている。現実世界で有効活用している様子を見たことはないけれど、 C&C との通信や VPN over DNS なんかで使えそうではある。 Punycode あればいらない気がして仕方ない…

*6:case を利用した security extension もあるので、あくまで「基本的に」という表現にはなってしまう

2016年に買ってよかったもの

なんか「2016年に買ってよかったもの」みたいなエントリが大量に生産されているようなので、いまさらながら流行に乗って書いてみる。

コーヒーのハンドドリップセット

2016年で最も買ってよかったものと言うと、まちがいなくハンドドリップセットだった。コーヒーという趣味がひとつ増えた。
コーヒーは、楽しい。コンビニで買ったクッキーを食べるだけでも、ハンドドリップしたコーヒーがあると一気に「コーヒータイム」になる。知らない街で豆を買ったりコーヒーの美味しい店を探して入ったりする楽しみも増えた。

ハンドドリップってどうやって初めていいかよくわからないものだと思うのだけど、そういう人には東急ハンズの福袋をおすすめしたい。必要なものを必要な組み合わせできちんと入れてくれて、しかもリーズナブル。
正月を待てない人には、上リンクのドリッパーセットとケトルを買うのがおすすめ。豆を粉にするミルは、持っていなくても全然問題なし。

ちなみに個人的には Hario めっちゃ使いやすいと思うけど、プロへの憧れとしては Kalita 一式を欲しいなと思うとき結構ある。特に↓このケトル…最高にかっこいい…。


Chromecast

https://www.google.com/intl/ja_jp/chromecast/tv/chromecast/

一人で色々なことをするぶんにはパソコンがあればなんでもできるけれど、コンピュータに疎い人とのコミュニケーションにパソコンはまったく役に立たない。
写真を一緒に見るためにと思って Chromecast を買ったところ、実際これが大正解で、写真はもちろんのこと youtube を見るのにも使えて、結果、お互いにスマホの画面を見ているだけみたいな時間が圧倒的に減った。
本当に期待していたのは Web ページを見ることだったんだけど、こちらは iPhone ではできないのと、 Nexus5 でもちょっと解像度が低くて使えないなとなった。
まあでも、買ってよかったと思う。

AriaProII エレキギター用ギグバッグ AGC-EG

昨年からギターの持ち運びが増えて、これまで使ってきた付属ケースがボロボロに壊れてしまった。仕方ないから持ち運び用にケースを検討したら、これが「ダサい」か「高い」かの二択になっているもんで、とても困ってしまった。NAZCAとか二万くらいするし、そうでなければ5000円くらいだけど使いにくい。

そんな中でずっと探していてこれいいなとなったのがこの Aria 社のケース。実店舗で8000円程度で売っているのに、内容的にはすごくいい。外見も気に入ったので個人的には2016年でいちばんいい買い物のひとつになった。

いいところはこんな感じ:

  • 運びやすい
    • 背中と腰にぴったり合う形でクッションがついている
    • 肩紐が適度に太くて背負いやすい。こちらもクッション付き
  • ポケットが多彩
    • シールドとエフェクターとチューナーとカポと…と全部入る。このバッグだけ持っていけばスタジオ練習できる
    • 楽譜すら入れられる大きなポケット
    • 大きさの違うポケットがそれぞれあるので物を入れやすい
  • ギターへの負荷も小さい
    • 周り全体に7mmくらいのクッションがある
    • ネックをマジックテープで留められる
    • 12フレットくらいのところに肩の根元が来る(ので背負っていてネックに過剰な負荷がかからない)
  • 防水
    • 雨でもまったく問題なし

割とマジな話、ソフト(セミハード)ケースの1万円未満部門とかあったら優勝間違いないし、2万円未満部門でもかなり戦えるレベルだと思う。

8インチタブレット

スマホで漫画を読むようになってから常々、5インチのスマホではなくもっと大きな画面で見たいと思っていた。で色々電気屋で試したところ、どうも私は7インチだと中身に入り込めず、9インチは最高だと感じるものの重いのだということがわかった。必要なのは、その中間の8インチだった。
で、何種類もの機種を検討した結果、さほど解像度はよいわけではないが軽くて安い ASUS の 8 インチ Android タブレットを買った。
結果、漫画を紙媒体で買わなくなった。技術書もこの端末で読むようになった。
今となってはもう自分にとっては電子書籍はあって当たり前な存在だけど、一年前はそうでもなかった。それを変えたのは圧倒的に、この8インチタブレットだった。

自転車

自転車、十年くらい乗ってなかったんだけど、久しぶりに手に入れてみたらびっくり。うちから徒歩15〜30分くらいのところにある街々にシュッと行けるようになったし、10分くらいかかっていたスーパーに夜中でも行こうという気になれる。まさに生活が変わった。

…とまあ私にとってはライフチェンジングだったわけだけど、読んでる人からすれば、買ってよかったものに自転車って言われてもねえ、ということになるんじゃないかな。そういう人はあきらめてください。所詮その程度の日記です。

なんでもいいから書こう

iPhoneをやめた。

iPhoneを使っていた、月額6000円くらいのつもりだったけど月によって9000円くらいになることもざらにあってちょっともう耐えられないぞという気持ちになったので電話用端末と通信用端末の二台持ち+Walkman A10に移行した。月額は2000円以内になった。

で、何か月か利用してみて、色々と生活が変わった。

まず、音楽を聴かなくなった。

iPhoneの頃、通勤途中にイヤホンをして音楽を聴くことが多かったのだけど、それだとiPhoneでゲームをすることができなかったのが不満だった。しかしいざ Android + Walkman にしてみると、端末を二台取り出すのが圧倒的に億劫。Walkman はポケットに入れておくにしても、ずっと入れておくわけにもいかない。
またiPhoneの頃は夜中に仕事中しているときにもよく音楽を聴いていて、しかし聴きすぎると充電が切れてしまうのも悩みだった。Walkmanなら充電も気にならないぞ、となるかというとそうでもなく、Walkmanはケーブルが専用のやつなので一本しか持っていなく、充電とデータ転送の片方しか一度にできない。まあ正確にはデータ転送時にも充電されるけど、夜中にパソコンつけっぱにするのは無駄だし。
それと、ケーブルのこともあって、新曲を入れるのが本当に面倒。まあケーブルさえあればiPhoneとそう変わらない(あるいは少ないくらいの)労力でもって曲を入れられるのだけど、ケーブルが専用というそれだけで圧倒的に使い勝手が悪い。
そしてネットで買えない。買えないわけではないけど、買ってすぐに聴けない。これがいちばん大きい。その時その時に頭に浮かんだあの曲を買うぞと思っても買えない。そうするともう聞く気が失せてしまう。とても残念。

電話にあまり気づかなくなった。

生活に支障はない。LINE時代の今、電話はLINEで済む。メールを受け取ることもまれだし、古典的なメールしか使えない人に対してはGmailアドレスを取得している。これでもう困っていない。

充電をしょっちゅうするようになった。

いやこれは Nexus5 の電池の持ちが悪すぎるだけなのだけど、一日二回充電しないと絶対切れてしまうようになった。
iPhone時代はその3倍くらいは持ったし、かなり酷使していたという認識もある。やはりこのあたりは iPhone が圧倒的に良かった。

まあそれくらいか。ほとんどかわってないな。音楽を聴かなくなったことと、料金が安くなったことくらい。
まあまあ、悪くはない。悪くはないんだ。

Truly Ergonomic Keyboard (JIS配列) 使い始めた

職場で Mac OS X を使うようになり、また腱鞘炎にもなっていたところだったので Truly Ergonomic Keyboard を買うことにした。…のが4月になりたての頃。
購入して早速 Mac にぶっ刺してみたところ、どうも動かないキーが多くて困った。裏側にあるDIPスイッチを Mac 向けとか日本語系とかにしてみても、真ん中の Del が Backspace だったり Del と Backspace との区別が(動作上)なかったり、Tabが遠かったりパイプがどこだかわからなかったり、何より「半角全角」キーがないせいで日本語入力ができなかったりして、実質的には使えたもんじゃない状態だった。
幸いにしてこれはファームウェア書き換えをすることによってキー配置を自在に変更できるようになっており、その辺の問題は無事解決できそうに思えた、が、肝心のファームウェア入れ替えはWindowsでしかできないのだった。(発売当初。今はmacでもできるので心配ない)
ということで持ち帰って、ついでに書き換えるのならしばらく Mac でのキー入力を試してみてそれに合った入力方法を選択するのhttp://d.hatena.ne.jp/suu-g/edit#がよいのではないかということになり、そのまま放置されることとなった。ありがちだ。

で、しばらく使ってみるとまあ Mac のキーボードってそんなに押しやすいわけでもないし本体熱くなるしでだんだん別キーボードを使いたい気持ちがふつふつと盛り上がってきて、今回ようやく重い腰を上げて入れ替えをしたってわけ。
suu-g: Mac向けカスタマイズ

今回は上記の構成にしてみた。しばらく使ってみて、また考えたいところ。
未だに悩んでいるのは半角全角をどうするかで、スペースキーはわりとッターンしたいから親指に置きたいけれど、カタカナ・ひらがなと無変換キーも親指で押したいので、これはどうしたものか。スペースキー基本的に左手で打っているようなので、変換(全角半角)キーを右スペースにするのでいいかも知れない。
そのへん直したら適当に追記か書き換えしていくつもり。

=> さっそく右スペースを全角半角にしたバージョン。ど真ん中の※マークにはパイプをおいた。もったいない気もするけどいちばん使うのシェルだし…。

=> さらに更新。パイプ周りとかを修正。アンダースコアが若干遠いことが今の難点だけどさすがにキーが足りないのでしゃーなし。あとは意外とスペースキー右側も使いたいときあるらしい。なんか気分次第で右も使ってた。それと Mac キーは頻繁に使うので左下に配置。Altはあまり使わないから諦めて左上にした。

AironetのMBSSID設定方法

久々に Aironet をきちんとMBSSIDにて設定した。公式の設定例を見ながらだいたいできたのだけど、最後の最後でひとつうまく行かないことがあって、40分くらいはそれで浪費してしまった。

学生のころはこんなもんだろと思っていた設定が、今となってみるとずいぶん不合理に見えてきて、「どこに何が必要か」について把握するのが難しいと感じるのは自分の能力不足とか以上にその設定が分かりにくいからだ、そしてその設定を筋を通して説明するページがないからだ、という考えに至ったので、今回行った設定の考え方をなんとなく記録として残しておく。

無線を落とす

AP をつけたとき、最初にすべきことは、コマンドを打っている最中も容赦なく出力されてくるエラーメッセージを黙らせること。無線を止めることで実現できる。

en
conf t
int dot11 0
shut
int dot11 1
shut
do wr mem

do wr mem は非常にお行儀が悪いけど、消えるよりゃマシだろまぁ。do で書き込むなという話もあるし、いまの推奨は copy running-config startup-config だっけ。

VLANとサブインターフェイス

通常、Aironet の AP にはイーサの口は一つだけ。なので、そこには Tagged VLAN を食わせて MBSSID 対応していくことになる。

その口が interface fa 0 だとしたら、中で利用したいVLAN番号に応じたサブインターフェイスを作っていく。 今回の例では、42は(すべての答えだから)管理用セグメント、398は(サンキュッパで安そうだから)ユーザセグメント。

interface FastEthernet0.42
 encapsulation dot1Q 42
!
interface FastEthernet0.398
 encapsulation dot1Q 398
!

無線の方も、イーサと同様にサブインターフェイスを作る。

interface Dot11Radio0.398
 encapsulation dot1Q 398
!

ブリッジする

実はAironetは、VLANを決めただけでは通信が通るようにはなっていない*1。通信を通したいインターフェイス同士を、同じ「ブリッジグループ」に含める必要がある。

先ほどの二つのインターフェイスを、 bridge-group でまとめる。

interface FastEthernet0.42
 encapsulation dot1Q 42
 bridge-group 2
!
interface FastEthernet0.398
 encapsulation dot1Q 398
 bridge-group 3
!
interface Dot11Radio0.398
 encapsulation dot1Q 398
 bridge-group 3
!

VLANと違い、bridge-groupは1-255くらいまでしか設定できないので、VLANと同じ番号は使えない。VLAN番号の末尾や先頭などにちなんだ、分かりやすいものを選んでおくとよい。 Aironet 本体へ telnet/ssh するために使用する BVI (Bridge Virtual Interface) はデフォルトではVLAN番号 1 上のネットワークに勝手につながるのだけど、それ以外を利用する場合は bridge-group を設定した、ような気がする。

interface BVI 1
 ip address 192.168.0.2 255.255.255.0
 bridge-group 2
!

VLAN と bridge-group と BVI との関係は、 http://packetlife.net/blog/2012/feb/20/aironet-aps-bridge-groups-and-bvi/ の図がわかりやすい。

SSID の設定をする

Aironet の SSID の設定の仕方には歴史があり、昔は SSID を一つしか設定できなかった。その名残りがあるので、SSIDの設定をするときは、以下のような困ったことが起きることがある。

  • 設定の順序を間違えると入らなくなる設定がある
  • ググって出てきた情報が間違っている
  • タブ補完でそれっぽい設定を探しても、それがまったく意味のない設定
  • タブ補完が効かない(あるいは、タブ補完は効くが、コマンド途中の入力は受け付けられない)
  • あとでコンフィグ見るとそこだけインデントが違う

わりとまじでよくある。だるい。

さて、SSIDを設定するにあたって設定する順番は、だいたい以下の通り:

  1. MBSSID(マルチBSSID)宣言をする
  2. SSIDの設定をする
  3. SSIDをVLANに紐付ける
  4. 無線インターフェイスに、VLANごとの暗号化方式を設定する
  5. 無線インターフェイスに、出力するSSIDを宣言する

それぞれについて、以下で説明していく。

MBSSID 宣言

(conf) dot11 mbssid

元来はインターフェイスごとに mbssid を宣言する必要があった。グローバルな設定として宣言しておくと、インターフェイスに書く必要がなくなる。

SSID の設定をする

dot11 ssid GuestUser398
   vlan 1
   authentication open
   authentication key-management wpa version 2
   mbssid guest-mode
   wpa-psk ascii 7 XXXXXXXXXXX
!

特に言うことはないけれど、

  • RADIUS 使わない限りは authentication open はほぼ固定設定
  • WPA2 を利用するとここで宣言しておく
  • WPA2-PSK で認証する場合、ここで wpa-psk とパスワードを入力する。ユーザが接続するときに利用するやつはここで入力する
  • mbssid guest-mode は、まあ、mbssid でかつ guest-mode(SSIDを広報する)ということ。色気を出して guest-mode を消すとかはしないほうがいい。セキュリティが悪化する

そして VLAN を設定。Aironet的には、SSIDはVLANに所属するものになっている。これ大事なポイント。テストに出る。

無線インターフェイスにVLANごとの暗号化方式を設定する

このあたりがどうにも気持ち悪くて、全然覚えられない。なんか筋が通った話はあるんだろうか…。Cisco公式ドキュメントを熟読しないと…。

先ほどは SSID ごとにパスフレーズを設定し、その SSID は VLAN に紐付いていた。 ここでは、無線インターフェイスの VLAN ごとに、通信路の暗号化に利用する方式(AES or TKIP)を設定する。

interface Dot11Radio0
 encryption vlan 398 mode ciphers aes-ccm
 !
 shutdown
!
interface Dot11Radio1
 encryption vlan 398 mode ciphers aes-ccm
 !
 shutdown
!

TKIPの場合は encryption vlan 398 mode ciphers aes-ccm tkip とする。まあいまどきTKIP必須とかないだろうけど。

ここでの注意点は、設定を入れるDot11Radioのインターフェイスがサブじゃないということ。せっかくサブインターフェイスを作ったのに悪いけどさ、あれは bridge-group しか設定しないんだわ。おかしいだろ常識的に考えて…だがこれが現実…。

さて。これで準備は万端だ。あとは数コマンドだけ。

無線インターフェイスSSID を設定する

ところで、無線インターフェイスDot11Radio0Dot11Radio1 とに分かれているのは、 0 が 2.4GHz帯で 1 が 5GHz帯のインターフェイスになっている、というところにある。

インターフェイスごとつまり周波数帯ごとに、吹きたいSSIDが変わってくることがある。 最近だと、SSIDの末尾に -a をつけたものを 5GHz帯に、 -g をつけたものを 2.4GHz帯に、なんてことがよくある。 これは無線インターフェイスごとに別々の SSID を設定していくことで実現可能なわけ。

今回、 GuestUser398 という SSID を 2.4GHz 5GHz 両方に設定するのであれば、以下のような設定をする。

interface Dot11Radio0
 encryption vlan 398 mode ciphers aes-ccm
 !
 ssid GuestUser398
 shutdown
!
interface Dot11Radio1
 encryption vlan 398 mode ciphers aes-ccm
 !
 ssid GuestUser398
 shutdown
!

設定が完了したら、interface の shutdown を外そう。

int dot 0
no shut
int dot 1
no shut

no shutdown すると、Aironetが無線を発し始める。周りの無線のスキャンを行うので、起動までは少し時間がかかることになる。

数十秒ほどして、ランプが緑色になったら、APが準備完了したしるしだ。接続テストをしよう。繋がったら Assoc したとシリアル画面へとログ出力されるし、ランプも青色へと変化する。

以上

まっとうな運用をするのであればもっと色々と設定することはあるけれど、まずは以上の設定を行い SSID を確認できてからでないと話は始まらない。とりあえず Cisco の考え方に身を染めていこう。人間、あきらめが肝心だ。

*1:このへんはルータと考え方が一緒

rbish gem 作成中

erb を組み入れたシェルスクリプトを実行する gem を作成している。とりあえず公開だけはした。
https://rubygems.org/gems/rbish
読みは rubbish と同じ【rʌ'biʃ】。

erb で書かれたシェルスクリプトを動かすだけなら下にある一行くらいでもどうにかなるので、ほとんどの労力はコマンドとして整えるところに行ってることになるかな。

`#{ERB.new(File.read(ARGV[0])).result}` 

今回は thor ではなく mixlib シリーズを使用してコマンドラインを立ててみてる。Thor はサブコマンドを作るときは最高の選択肢のひとつだけど、UNIX style のコマンドを作成するには最適ではない感じがしたので、ほかの諸々を調査してた。で、いくつかの候補の中から mixlib-cli を選択してみた、というわけ。
mixlib には config や log などもあるので、それらと一緒に一通り使ってみて、それから判断しようと思ってる。

現在のバージョンは 0.1.0 ってことにしてる。Semantic Versioning 2.0 によると、公開時は 1.0.0 にしろってことなんだけど、今のものにその数字を背負わせる自信はない。
まずはこちらで認識してる、エラー表示とかテストとかデバッグ出力とか、そのあたり直したらもうちょっとバージョンを上げようかなと思う。

libv8 のバージョンを探す

2013年の Ruby on Rails Advent Calendar に参加しようと思ったら、その日のぶんが空いていたので、当日の 23:45 からプログラムを書いてそのまま記事にするというエクストリームアドベントをすることとなりました。プログラマ的には 33 時までは当日だから問題ないよね。

さて今回は Ruby on Rails というか therubyracer というか libv8 の話です。

Ruby on Rails では therubyracer gem をちょくちょく使いますね。therubyracer gem は Ruby から使用できる v8 エンジンで、環境ごとに適切なバイナリパッケージがインストールされるのですが、時折やたらと時間がかかることがあります。*1
この適切なバージョンを見つけ出すためのスクリプトを作成しました。

これを走らせると、

 $ ruby libv8_check.rb
gem 'libv8', '3.16.14.3'

と、Gemfile に書くべき行を表示してくれます。

何が表示されているか?

libv8 gem には、特定の環境用にビルドされたバイナリ gem と汎用の gem とがあります。この汎用gemをインストールすると非常に時間がかかることになります。
したがって、汎用 gem をインストールするのは避けたいのですが、バイナリパッケージが存在するかどうかの確認は案外手間がかかり、「誰でもできる」とは言い難い状況でした。
ということで、その確認を簡単にするためににこのスクリプトを作成した、ということになります。

このスクリプトは、「存在している libv8 gem の中でもっとも新しい、ユーザ環境で使用できるバイナリ gem のバージョンを表示する」ということをしています。つまり Linux x86_64 環境であればその環境用のバイナリ gem を、また MacOS X 用であればそれ用のバイナリ gem を確認して出力します。
ただ、バイナリパッケージのない環境も存在します。そういう環境で実行した場合は、下のように ~> を使用したバージョンを表示します。

gem 'libv8', '~> 3.16.14.3'

やっていること

環境の選択

bundle install の際、インストールするべきバージョンを選択しているのは bundler ですが、環境やバイナリパッケージを選択しているのは rubygems です。
rubygems の中では Gem::Platform クラスがこのあたりをコントロールしていますので、少しだけこれを借りています。

rubygems API v1 の利用

はじめは Gem クラスを利用して完全なバージョンを取得しようと思ったのですが、「特定の gem の全バージョンを取得する」ということをできるメソッドが見つからず。
Rubygems API を直接利用することにしたところ、これが非常に簡単!

$ curl http://rubygems.org/api/v1/versions/libv8.yaml
---
- authors: Charles Lowell
  built_at: '2013-12-05T00:00:00Z'
  description: Distributes the V8 JavaScript engine in binary and source forms in
    order to support fast builds of The Ruby Racer
  downloads_count: 79
  number: 3.16.14.3
  summary: Distribution of the V8 JavaScript engine
  platform: x86_64-solaris-2.11
  prerelease: false
  licenses:
  - MIT
  requirements: []
- authors: Charles Lowell
  built_at: '2013-12-04T00:00:00Z'
  description: Distributes the V8 JavaScript engine in binary and source forms in
    order to support fast builds of The Ruby Racer
  downloads_count: 96
...

API については http://github.com/rubygems/rubygems.org を git clone して rake routes とか適当にして確認していましたが、ちゃんと公式ドキュメントが整備されていたようです…。

GET - /api/v1/versions/[GEM NAME].(json|xml|yaml)

Returns an array of gem version details like the below:

$ curl https://rubygems.org/api/v1/versions/coulda.json

[
{
"number" : "0.6.3",
"built_at" : "2010-12-23T05:00:00Z",
"summary" : "Test::Unit-based acceptance testing DSL",
"downloads_count" : 175,
"platform" : "ruby",
"authors" : "Evan David Light",
"description" : "Behaviour Driven Development derived from Cucumber but
as an internal DSL with methods for reuse",
"prerelease" : false,
}
]

http://guides.rubygems.org/rubygems-org-api/#gem_version_methods

Rubygems API は色々と面白く使えそうですね。

おわりに

ということで、 Ruby on Rails を使用するうえで比較的欠かせない libv8 の gem をより短い時間でインストールできるようにするべく、適切なバージョンを探し出してくれるスクリプトをこねこねと作成しました。

今回ざっくり実装したこの機能ですが、あと若干汎用化すると「バイナリパッケージが準備された gem かどうかを判定する」機能となるので、そこまで作ってから gem として公開しようかなあなどともくろんでいます。さすがに今日中は無理でした。

以上、2013年 の Ruby on Rails Calendar 9 日目の記事でした。
…あれ?この記事 Rails 関係あったと言えるのかな? …まあいいか!

*1:このへんの詳細については以前書いた http://d.hatena.ne.jp/suu-g/20121222/1356189597 参照のこと