読者です 読者をやめる 読者になる 読者になる

nvme(4) ベンチマーク

NetBSD NVMe

人から Intel SSD 750 400GB や Intel SSD 750 800GB を二枚借りたり、自分でも既に SAMSUNG SM951 NVMe 128GB を持っているのに SAMSUNG SM950 PRO 256GB と SAMSUNG SM951 NVMe 256GB を買ったりしたので、ベンチマークを取ってみたり。

注意

この記事はディスクのベンチマークですが、残念ながら水晶雫さんは登場いたしません。

環境

パーツ 品名
CPU Intel Core i7-6700
M/B Shuttle SH170R6
OS NetBSD/amd64 HEAD (20160507)

Shuttle SH170R6 は PCIe 3.0 x16、PCIe 3.0 x4 スロット各一本と M.2 (PCIe 3.0 x4) スロットが一つあります。

チップセットは H170 なので PCIe 3.0 x16 は CPU 直結、それ以外の PCIe 3.0 x4 と M.2 はチップセット側のものだと思われます。

dmesg は http://dmesgd.nycbug.org/index.cgi?do=view&id=2966 を参照。

ベンチマーク結果

面倒なので同じベンチマークを何回も実行していません。一発勝負です。

dd

if, of 以外のパラメータは dd bs=1g count=100

SSD Slot Read Write 備考
Intel SSD 750 400GB PCIe 3.0 x16 2213718093 (2111MB/s) 933794101 (890MB/s)
Intel SSD 750 400GB PCIe 3.0 x4 2209572639 (2107MB/s) 937765785 (894MB/s)
SAMSUNG SM951 256GB M.2 2479715997 (2364MB/s) 1056073710 (1007MB/s)
SAMSUNG SM951 128GB M.2 (PCIe 2.0 x 2) 835018410 (796MB/s) 601738300 (573MB/s) Mouse LB-J300X

その他

このベンチマークもやってくれとかありましたらコメントなり Twitter の @nonakap にお願いします。

Xnp2 更新

Xnp2

Xnp2 ver.0.86 をリリースしました。

ver.0.86 更新内容

X11 依存部

GTK+ 3 対応とか夢のまた夢ですね…

Xnp2 更新

Xnp2

Xnp2 ver.0.85 をリリースしました。

ver.0.85 更新内容

X11 依存部
  • 環境によってサウンドの設定を変更した後にリセットするとプログラムがクラッシュする不具合を修正
  • SDL 2.0 サポート追加
    SDL 2.0 → SDL 1.2 の順番でライブラリを検索するので SDL 1.2 を明示的に使用したい場合には configure のオプションに --disable-sdl2 を指定する必要があります。
  • SDL audio のバックエンドとして PulseAudio を使用している場合に音が正常に鳴らない不具合を修正
  • SPFM Light、C86BOX サポート追加。SPFM Light+Re:birth(RE1-YM2608) と C86BOX+PC-9801-86 の組み合わせで動作確認済みです。
    なお、C86BOX を使用するには libusb 1.0 が必要です。

とりあえず ver.0.84 リリース時に書いたリストの半分は実現できたのでよしとしましょう(棒

次のリリースでは GTK+ 2.x と SDL 1.2 のサポートを切りたいと思います、思っています、出来たら良いなぁ…。

NetBSD で USB デバイスを強制的に ugen(4) として attach したい

NetBSD

通常は uftdi(4) とか uhid(4) として認識される USB デバイスを ugen(4) として認識させたい事ってありませんか?

そうですか、ありませんか…。

はじめに

これは「NetBSD でも YubiKey を使って二要素認証したい」の以下の文章を説明するための記事です。

ここで ukbd(4) が attach されていないと動作モードの変更が必要になるのですが、素の NetBSD カーネルだと動作モードの変更が難しいので後述することにします、しないかもしれません。

なんで ugen(4) にしたいの?

まずは libusb のソースを見てもらおうか。話はそれからだ。

int
netbsd_get_device_list(struct libusb_context * ctx,
    struct discovered_devs **discdevs)
{
    struct libusb_device *dev;
    struct device_priv *dpriv;
    struct usb_device_info di;
    unsigned long session_id;
    char devnode[16];
    int fd, err, i;

    usbi_dbg("");

    /* Only ugen(4) is supported */
    for (i = 0; i < USB_MAX_DEVICES; i++) {
        /* Control endpoint is always .00 */
        snprintf(devnode, sizeof(devnode), "/dev/ugen%d.00", i);

libusb を使えばデバイスドライバを書かなくてもユーザーランドプログラムから USB デバイスを制御できるのですが、残念ながら NetBSD 上では libusb は上記ソースに記載されている通り ugen(4) として認識されている USB デバイスしか扱えないのです。

そんな訳で uhid(4) や ukbd(4) として認識されている YubiKey 4 を libusb 経由で YubiKey を制御する ykpersonalize や ykinfo といったプログラムは制御する以前にそもそも YubiKey デバイスを見つけられません。

nonaka@koharu$ dmesg
(snip...)
uhidev2 at uhub2 port 1 configuration 1 interface 0
uhidev2: Yubico Yubikey NEO OTP+U2F, rev 2.00/3.43, addr 6, iclass 3/1
ukbd1 at uhidev2: 8 modifier keys, 6 key codes
wskbd2 at ukbd1 mux 1
wskbd2: connecting to wsdisplay0
uhidev3 at uhub2 port 1 configuration 1 interface 1
uhidev3: Yubico Yubikey NEO OTP+U2F, rev 2.00/3.43, addr 6, iclass 3/0
uhid0 at uhidev3: input=64, output=64, feature=0
nonaka@koharu$ sudo ykinfo -v
Yubikey core error: no yubikey present

本来ならば ukbd(4) などの USB デバイスドライバはすべからく ugen(4) として振る舞えるべき、もしくはインタフェースを持つべきだとは思うのですが、それを実現するにはちょっと長い道のりとなります。

なのでここではデバイスドライバの match/attach 処理に小細工をして、USB デバイスを接続した際に正しいデバイスドライバではなく ugen(4) として認識させようとします。

デバイスドライバ match/attach 処理

もの凄くざっくりとした説明

NetBSD ではあるバス(PCI とか USB とか)に接続されているデバイスドライバを attach する際には、該当バスに接続できるすべてのデバイスドライバの match 関数を呼び出します。

match 関数は PCI や USB であれば Vendor ID, Product ID といったバス固有の情報を受け取り、その情報から該当デバイスドライバで取り扱うデバイスであると判断したら match 関数の戻り値として 1 以上の整数値を返します。

全てのデバイスドライバの match 関数を呼び終わった後で 0 では無い一番大きな値を返したデバイスドライバの attach 関数を呼び出してデバイスドライバを attach します。

まあ、要するに ugen(4) として attach してほしいデバイスには ugen(4) の match 関数で他のデバイスドライバよりも大きな値を戻り値として返せば良いだけです。

USB スタック固有事情

実は USB スタックでは この match 関数で返すべき値が用意されています。

/* Match codes. */
#define UMATCH_HIGHEST                 15
/* First five codes is for a whole device. */
#define UMATCH_VENDOR_PRODUCT_REV          14
#define UMATCH_VENDOR_PRODUCT              13
#define UMATCH_VENDOR_DEVCLASS_DEVPROTO            12
#define UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO       11
#define UMATCH_DEVCLASS_DEVSUBCLASS            10
/* Next six codes are for interfaces. */
#define UMATCH_VENDOR_PRODUCT_REV_CONF_IFACE        9
#define UMATCH_VENDOR_PRODUCT_CONF_IFACE        8
#define UMATCH_VENDOR_IFACESUBCLASS_IFACEPROTO      7
#define UMATCH_VENDOR_IFACESUBCLASS             6
#define UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO  5
#define UMATCH_IFACECLASS_IFACESUBCLASS             4
#define UMATCH_IFACECLASS               3
#define UMATCH_IFACECLASS_GENERIC           2
/* Generic driver */
#define UMATCH_GENERIC                  1
/* No match */
#define UMATCH_NONE                     0

という訳で他のデバイスとして attach して貰いたくない場合には ugen(4) で該当デバイスの場合に UMATCH_HIGHEST を返すようにすれば良いという事になります。

ugen(4) match 関数

それでは ugen(4) の match 関数である ugen_match() 関数を見てみましょう。

/* toggle to control attach priority. -1 means "let autoconf decide" */
int ugen_override = -1;

int
ugen_match(device_t parent, cfdata_t match, void *aux)
{
    struct usb_attach_arg *uaa = aux;
    int override;

    if (ugen_override != -1)
        override = ugen_override;
    else
        override = match->cf_flags & 1;

    if (override)
        return (UMATCH_HIGHEST);
    else if (uaa->usegeneric)
        return (UMATCH_GENERIC);
    else
        return (UMATCH_NONE);
}

既に UMATCH_HIGHEST を返すコードがありますね。

struct usb_attach_arg が先ほど説明したバス固有のデバイス情報になります。

struct usb_attach_arg {
    int            port;
    int            vendor;
    int            product;
    int            release;
    usbd_device_handle  device; /* current device */
    int            class, subclass, proto;
    int            usegeneric;
};

struct usb_attach_arg に接続されたデバイスの Vendor ID と Product ID があるので、この二つが ugen(4) として attach したいデバイスの値と一致したら UMATCH_HIGHEST を返すコードを追加すれば良いですかね。

後は ugen(4) として attach したいデバイスの Vendor ID と Product ID をどうやって指定するかという事になります。

Linux であれば /proc 経由で良いのでしょうが、NetBSD では何年前かはまで知りませんが今時は sysctl(8) 経由でユーザランドから設定できるようにするらしいです。

完成

良くあるように実際の処理よりもユーザインタフェース部分の方が処理が多い差分になりました。仕方ないね

USB デバイスの Vendor ID と Product ID はデバイスを接続した状態で usbdevs -v で表示されます。

nonaka@koharu$ sudo usbdevs -v
Controller /dev/usb0:
addr 0: high speed, self powered, config 1, xHCI Root Hub(0x0000), NetBSD(0x0000), rev 1.00
 port 1 powered
 port 2 powered
 port 3 powered
 port 4 powered
 port 5 powered
 port 6 powered
 port 7 powered
 port 8 powered
 port 9 powered
Controller /dev/usb1:
addr 1: high speed, self powered, config 1, EHCI root hub(0x0000), Intel(0x8086), rev 1.00
 port 1 addr 2: high speed, self powered, config 1, product 8000(0x8000), Intel(0x8087), rev 0.04
  port 1 addr 6: full speed, power 30 mA, config 1, Yubikey NEO OTP+U2F(0x0114), Yubico(0x1050), rev 3.43
  port 2 powered
  port 3 powered
  port 4 powered
  port 5 addr 3: full speed, self powered, config 1, product 0a2a(0x0a2a), Intel(0x8087), rev 0.01
  port 6 addr 4: high speed, power 200 mA, config 1, BisonCam, NB Pro(0x024b), vendor 5986(0x5986), rev 6.08
  port 7 addr 5: full speed, power 100 mA, config 1, ThinkPad Compact USB Keyboard with TrackPoint(0x6047), Lenovo(0x17ef), rev 3.00
  port 8 powered
 port 2 powered

実際に使ってみた

$ dmesg
(snip...)
uhidev2 at uhub2 port 1 configuration 1 interface 0
uhidev2: Yubico Yubikey NEO OTP+U2F, rev 2.00/3.43, addr 6, iclass 3/1
ukbd1 at uhidev2: 8 modifier keys, 6 key codes
wskbd2 at ukbd1 mux 1
wskbd2: connecting to wsdisplay0
uhidev3 at uhub2 port 1 configuration 1 interface 1
uhidev3: Yubico Yubikey NEO OTP+U2F, rev 2.00/3.43, addr 6, iclass 3/0
uhid0 at uhidev3: input=64, output=64, feature=0
$ sysctl hw.ugen
hw.ugen.override = -1
hw.ugen.forced_attach.vendor = 65535
hw.ugen.forced_attach.product = 65535
hw.ugen.forced_attach.addr = -1
hw.ugen.forced_attach.add = 0
hw.ugen.forced_attach.delete = 0
hw.ugen.forced_attach.clear = 0
hw.ugen.forced_attach.list = 
$ sudo sysctl -w hw.ugen.forced_attach.vendor=0x1050
hw.ugen.forced_attach.vendor: 65535 -> 4176
$ sudo sysctl -w hw.ugen.forced_attach.product=0x114
hw.ugen.forced_attach.product: 65535 -> 276
$ sudo sysctl -w hw.ugen.forced_attach.add=1
hw.ugen.forced_attach.add: 0 -> 1
$ sysctl hw.ugen
hw.ugen.override = -1
hw.ugen.forced_attach.vendor = 65535
hw.ugen.forced_attach.product = 65535
hw.ugen.forced_attach.addr = -1
hw.ugen.forced_attach.add = 0
hw.ugen.forced_attach.delete = 0
hw.ugen.forced_attach.clear = 0
hw.ugen.forced_attach.list = [0x1050 0x0114 -1]
(ここでデバイスを一旦抜いてから接続しなおす)
$ dmesg
(snip...)
wskbd2: disconnecting from wsdisplay0
wskbd2: detached
ukbd1: detached
uhidev2: detached
uhidev2: at uhub2 port 1 (addr 6) disconnected
uhid0: detached
uhidev3: detached
uhidev3: at uhub2 port 1 (addr 6) disconnected
ugen0 at uhub2 port 1
ugen0: Yubico Yubikey NEO OTP+U2F, rev 2.00/3.43, addr 6
$ sudo ykinfo -v
version: 3.4.3

使い方

デバイス追加
$ sudo sysctl -w hw.ugen.forced_attach.vendor=0x1050
hw.ugen.forced_attach.vendor: 65535 -> 4176
$ sudo sysctl -w hw.ugen.forced_attach.product=0x114
hw.ugen.forced_attach.product: 65535 -> 276
$ sudo sysctl -w hw.ugen.forced_attach.add=1
hw.ugen.forced_attach.add: 0 -> 1
$ sysctl hw.ugen
hw.ugen.override = -1
hw.ugen.forced_attach.vendor = 65535
hw.ugen.forced_attach.product = 65535
hw.ugen.forced_attach.addr = -1
hw.ugen.forced_attach.add = 0
hw.ugen.forced_attach.delete = 0
hw.ugen.forced_attach.clear = 0
hw.ugen.forced_attach.list = [0x1050 0x0114 -1]
デバイス削除
$ sudo sysctl -w hw.ugen.forced_attach.vendor=0x1050
hw.ugen.forced_attach.vendor: 65535 -> 4176
$ sudo sysctl -w hw.ugen.forced_attach.product=0x114
hw.ugen.forced_attach.product: 65535 -> 276
$ sudo sysctl -w hw.ugen.forced_attach.delete=1
hw.ugen.forced_attach.delete: 0 -> 1
デバイス全削除
$ sudo sysctl -w hw.ugen.forced_attach.clear=1
hw.ugen.forced_attach.clear: 0 -> 1

課題など

USB スタックにも設定がおかしな USB デバイスが接続された場合の振る舞いを変更するための quirk を決定する処理が実は既に存在しています。

Cross Reference: /src/sys/dev/usb/usb_quirks.c

何故これを使わなかったのかと言えば、動的にデバイスの追加・削除をするのが面倒だったのと Vendor ID と Product ID 以外でも指定したかったからです。現在のパッチでは Vendor ID と Product ID の他に addr が指定できます。これは同じ Vendor ID と Product ID を持っているけれど特定のデバイスだけ ugen(4) として使いたいという要求があったからです。

後で usbdevs -v の出力を見て気付いたのですが、addr だけでは controller だか bus が違う場合にも適用されてしまうのでもう細かく少し指定できる必要がありそうです。それを修正するのは後の課題としたいと思います。

パッチ

GitHubnetbsd-src リポジトリの nonakap-catfood ブランチでパッチは保守しているのでそちらを参照して貰った方が良いかもしれません。

nonakap/netbsd-src at nonakap-catfood · GitHub

続きを読む

NetBSD でも YubiKey を使って二要素認証したい

NetBSD

これは NetBSD Advent Calendar 2015 の 24 日目の記事です。

はじめに

Github ユーザなら 20% off というキャンペーンを見かけて IYH した YubiKey 4 が届いたので NetBSD で使えるか試してみました。

今回はコンソールログイン時の認証を既存のパスワードに加え YubiKey の OTP を使った認証を使えるようにしてみようと思います。

前提条件

  • 使用しているシステムは 2015/12/20 あたりのソースがベースの独自パッチがあたっている NetBSD/amd64 7.99.24 です。
  • pam_yubico で使用される認証サーバーには Yubico の提供しているサーバー YubiCloud を使用します。
  • 上記条件より pam_yubico を使用するシステムはインターネットに接続されている必要があります。

YubiKey 設定確認

YubiKey 4 の初期設定では OTP が使えるようになっているはずなので、とりあえず NetBSD マシンに YubiKey 4 を接続してみます。

uhidev2 at uhub2 port 1 configuration 1 interface 0
uhidev2: Yubico Yubikey 4 OTP+U2F+CCID, rev 2.00/4.27, addr 6, iclass 3/1
ukbd1 at uhidev2: 8 modifier keys, 6 key codes
wskbd2 at ukbd1 mux 1
wskbd2: connecting to wsdisplay0
uhidev3 at uhub2 port 1 configuration 1 interface 1
uhidev3: Yubico Yubikey 4 OTP+U2F+CCID, rev 2.00/4.27, addr 6, iclass 3/0
uhid0 at uhidev3: input=64, output=64, feature=0

接続後の dmesg に上記の様に「Yubico Yubikey 4 OTP+U2F+CCID」と「OTP」が含まれている、かつ ukbd(4) が attach されていて YubiKey 4 の「y」マークをタッチして 44 文字入力されれば問題ないようです。

ここで ukbd(4) が attach されていないと動作モードの変更が必要になるのですが、素の NetBSD カーネルだと動作モードの変更が難しいので後述することにします、しないかもしれません。*1

NetBSD 設定

pam_yubico インストール

NetBSD では PAM を使ってログイン時の認証などを行っています。 調べてみたところ YubiKey 開発元の Yubicopam_yubico という PAM のモジュールを提供しているのでこれを使えば YubiKey を使った認証ができるようになりそうです。

幸いにして pkgsrc に security/pam-yubico が存在しているのでこれを使えば苦労することなく目的を達することができそうです。

というわけで pam_yubico を pkgsrc を使ってインストールします。

$ cd /usr/pkgsrc/security/pam-yubico
$ sudo make install
$ pkg_info | grep pam-yubico
pam-yubico-2.17     Pluggable Authentication Module for Yubikey validation

Client ID 取得

PAM 設定ファイルを編集する前に pam_yubico の Configuration を見ると Client ID というものが出てきますが、これは Yubico Get API Key で取得可能なようです。

「Your e-mail address」には適当に自分のメールアドレスを、「YubiKey one-time password」には右側の入力欄にフォーカスさせてから YubiKey を指でタッチして文字列を入力します。「Get API Key」ボタンをクリック後に Client ID と Secret Key が表示されるので忘れないようにメモしておきます。

PAM 設定

コンソールログイン時の login プロンプトは /usr/bin/login が表示しています。これに対応する PAM の設定ファイルはどうマッピングされているのかまでは調べていませんが /etc/pam.d/login になるようです。

2015/12/23 時点の HEAD の /etc/pam.d/login の内容はこんな感じです。

# $NetBSD: login,v 1.4 2005/02/27 03:40:14 thorpej Exp $
#
# PAM configuration for the "login" service
#

# auth
auth        sufficient  pam_self.so     no_warn
auth        required    pam_nologin.so      no_warn
auth        include     system

# account
account     requisite   pam_securetty.so
account     required    pam_login_access.so
account     include     system

# session
session     include     system

# password
password    include     system

今回注目するのは auth です。

auth の最後の行で system を include しているので、こっちも見てみます。

# $NetBSD: system,v 1.8 2008/03/26 11:31:17 lukem Exp $
#
# System-wide defaults
#

# auth
auth        sufficient  pam_skey.so     no_warn try_first_pass
auth        sufficient  pam_krb5.so     no_warn try_first_pass
auth        optional    pam_afslog.so       no_warn try_first_pass
auth        required    pam_unix.so     no_warn try_first_pass nullok

# account
account     required    pam_krb5.so
account     required    pam_unix.so

# session
session     required    pam_lastlog.so      no_fail no_nested

# password
password    sufficient  pam_krb5.so     no_warn try_first_pass
password    required    pam_unix.so     no_warn try_first_pass

/etc/pam.d/system にはシステムデフォルトが記述されているようです。このファイルを編集すると別のプログラムでも影響があるので、/etc/pam.d/login の方を編集することにします。

※PAM 設定ファイル中の auth 以外の箇所は変更しないので、これ以降は auth 部分のみを例示します。

pam_yubico の Configuration を参考に /etc/pam.d/login に pam_yubico の設定を追加します。

auth     sufficient  pam_self.so     no_warn
auth        required    pam_nologin.so      no_warn
auth        sufficient  /usr/pkg/lib/security/pam_yubico.so id=XXX debug
auth        include     system

NetBSD では特定のディレクトリに PAM モジュールを配置する必要は無く、モジュールのフルパスを指定すれば良いようです。

id には取得した Client ID を設定します。

また、この時点では設定ミスなどがあった場合にわかりやすくなるので debug を指定しておきます。

認可用マッピングファイル作成

pam_yubico の Authorization Mapping Files に記載されているように、ユーザと YubiKey の対応付けを行うファイルを作成します。 今回はユーザのホームディレクトリに認可用マッピングファイルを作成します。

$ cd
$ pwd
/home/nonaka
$ mkdir .yubico
$ chmod 700 .yubico
$ ls -ld .yubico
drwx------  2 nonaka  nonaka  512 Dec 23 09:22 .yubico
$ cd .yubico
$ pwd
/home/nonaka/.yubico
$ echo "nonaka:OTPfirst12char" > authorized_yubikeys
$ chmod 600 authorized_yubikeys
$ ls -l authorized_yubikeys
-rw-------  1 nonaka  nonaka  20 Dec 23 09:22 authorized_yubikeys

$HOME/.yubico/authorized_yubikeysOTPfirst12char には YubiKey をタッチして入力される文字列の先頭 12 文字を設定します。

最初は Modhex を指定する必要があるのかと思ったのですがそういう訳では無いようです。

さあ試してみよう

ここまで設定すると YubiKey を使ったログインができるようになっている筈なので実際にログインしてみます。

system の前に pam_yubico を追加したのでパスワードの前に YubiKey の入力が求められる筈です。

NetBSD/amd64 (koharu.myhome.nonakap.org) (ttyE1)

login: nonaka
Password:
Last login: Wed Dec 23 14:24:22 2015 on ttyE1
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 7.99.24 (KOHARU) #3367: Sun Dec 20 14:07:44 JST 2015
nonaka@koaru$ 

おいィ?

YubiKey のゆの字すら出てきません。

慌てず騒がず /var/log 配下のログファイルを見てみます。認証認可関連なので /var/log/authlog でしょう。

Dec 23 14:34:19 koharu login: in openpam_dispatch(): /usr/pkg/lib/security/pam_yubico.so: no pam_sm_authenticate()
Dec 23 14:34:21 koharu login: nonaka on tty ttyE1
Dec 23 14:34:21 koharu login: in openpam_dispatch(): /usr/pkg/lib/security/pam_yubico.so: no pam_sm_setcred()

おいィ?(二回目

慌てず騒がず /usr/pkg/lib/security/pam_yubico.so のシンボル一覧を見ます。

$ nm /usr/pkg/lib/security/pam_yubico.so
0000000000203028 d _DYNAMIC
0000000000203388 d _GLOBAL_OFFSET_TABLE_
                 w _Jv_RegisterClasses
0000000000203008 d __CTOR_LIST_END__
0000000000002870 r __FUNCTION__.4014
0000000000002850 r __FUNCTION__.4029
0000000000002990 r __FUNCTION__.4254
0000000000002970 r __FUNCTION__.4260
000000000020355c D __bss_start
                 w __cxa_finalize
                 w __deregister_frame_info@@GCC_3.0
0000000000203510 d __dso_handle
                 U __errno
                 U __getpwnam50
                 w __register_frame_info@@GCC_3.0
                 U __sF
000000000020355c D _edata
0000000000203560 D _end
0000000000002580 T _fini
00000000000013b0 T _init
00000000000019f3 T challenge_response
00000000000018b9 T check_firmware_version
                 U fclose
                 U fflush
                 U fileno
                 U fopen
                 U fprintf
                 U fread
                 U free
                 U fscanf
                 U fsync
                 U ftruncate
                 U fwrite
0000000000001863 T generate_random
0000000000001770 T get_user_cfgfile_path
0000000000001b19 T get_user_challenge_file
                 U getegid
                 U geteuid
                 U getgroups
00000000000019ce T init_yubikey
                 U initgroups
0000000000001c6d T load_chalresp_state
                 U malloc
                 U memset
00000000000021f0 T pam_modutil_drop_priv
0000000000002422 T pam_modutil_regain_priv
                 U printf
                 U putchar
                 U rewind
                 U setegid
                 U seteuid
                 U setgroups
                 U snprintf
                 U strerror
0000000000001ffe T write_chalresp_state
                 U yk_challenge_response@@LIBYKPERS_1.8
                 U yk_get_serial@@LIBYKPERS_1.5
                 U yk_get_status@@LIBYKPERS_1.0
                 U yk_hmac_sha1@@LIBYKPERS_1.9
                 U yk_init@@LIBYKPERS_1.0
                 U yk_open_first_key@@LIBYKPERS_1.0
                 U yk_pbkdf2@@LIBYKPERS_1.0
                 U ykds_alloc@@LIBYKPERS_1.0
                 U ykds_version_build@@LIBYKPERS_1.0
                 U ykds_version_major@@LIBYKPERS_1.0
                 U ykds_version_minor@@LIBYKPERS_1.0
                 U yubikey_hex_decode@@YUBIKEY_1.0
                 U yubikey_hex_encode@@YUBIKEY_1.0
                 U yubikey_hex_p@@YUBIKEY_1.5

確かに pam_sm_* なんてシンボルは存在していません。

pam_yubico 訪問

pam_yubico のソースを確認してみましょう。

$ cd /usr/pkgsrc/security/pam-yubico
$ make patch
$ cd /usr/obj.pkgsrc/security/pam-yubico/work.koharu/pam_yubico-2.17
$ grep -n pam_sm_authenticate *.[ch]
pam_yubico.c:792:pam_sm_authenticate (pam_handle_t * pamh,
pam_yubico.c:1107:  pam_sm_authenticate,
test.c:50:  rc = pam_sm_authenticate (pamh, 0, 1, (const char **) argv);

ありました。pam_yubico.c の 792 行目付近を見てます。

PAM_EXTERN int
pam_sm_authenticate (pam_handle_t * pamh,
                     int flags, int argc, const char **argv)

PAM_EXTERN というのが怪しそうです。

$ grep -n PAM_EXTERN *.[ch] | grep define
pam_yubico.c:81:#ifndef PAM_EXTERN
pam_yubico.c:83:#define PAM_EXTERN static
pam_yubico.c:85:#define PAM_EXTERN extern
pam_yubico.c:791:PAM_EXTERN int
pam_yubico.c:1097:PAM_EXTERN int

pam_yubico.c の 81 行目付近を見てます。

#ifndef PAM_EXTERN
#ifdef PAM_STATIC
#define PAM_EXTERN static
#else
#define PAM_EXTERN extern
#endif
#endif

PAM_STATIC というのはどこで define されるのでしょうか。

$ grep -n PAM_STATIC *.[ch]
pam_yubico.c:56:#define PAM_STATIC
pam_yubico.c:82:#ifdef PAM_STATIC
pam_yubico.c:1103:#ifdef PAM_STATIC

pam_yubico.c の 56 行目ですね。

/* Libtool defines PIC for shared objects */
#ifndef PIC
#define PAM_STATIC
#endif

この PIC は共有ライブラリを作成する際に指定されるやつですかね?

では実際に pkgsrc/security/pam-yubico をビルドしてみましょう。

$ cd /usr/pkgsrc/security/pam-yubico
$ make V=1 2>&1 | tee make.log
$ grep pam_yubico.c make.log
/bin/sh ./libtool  --tag=CC   --mode=compile gcc -DDEBUG_PAM -DPAM_DEBUG -DPACKAGE_NAME=\"pam_yubico\" -DPACKAGE_TARNAME=\"pam_yubico\" -DPACKAGE_VERSION=\"2.17\" -DPACKAGE_STRING=\"pam_yubico\ 2.17\" -DPACKAGE_BUGREPORT=\"yubico-devel@googlegroups.com\" -DPACKAGE_URL=\"\" -DPACKAGE=\"pam_yubico\" -DVERSION=\"2.17\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_SECURITY_PAM_APPL_H=1 -DHAVE_SECURITY_PAM_MODULES_H=1 -DHAVE_LIBPAM=1 -DHAVE_LIBLDAP=1 -DHAVE_LIBYKCLIENT=1 -DHAVE_LIBYUBIKEY=1 -DHAVE_CR=1 -I.  -pthread -I/usr/pkg/include/ykpers-1 -I/usr/pkg/include -I/usr/include/krb5 -I/usr/include  -O2 -I/usr/pkg/include -I/usr/include/krb5 -I/usr/include -MT pam_yubico_la-pam_yubico.lo -MD -MP -MF .deps/pam_yubico_la-pam_yubico.Tpo -c -o pam_yubico_la-pam_yubico.lo `test -f 'pam_yubico.c' || echo './'`pam_yubico.c
libtool: compile:  gcc -DDEBUG_PAM -DPAM_DEBUG -DPACKAGE_NAME=\"pam_yubico\" -DPACKAGE_TARNAME=\"pam_yubico\" -DPACKAGE_VERSION=\"2.17\" "-DPACKAGE_STRING=\"pam_yubico 2.17\"" -DPACKAGE_BUGREPORT=\"yubico-devel@googlegroups.com\" -DPACKAGE_URL=\"\" -DPACKAGE=\"pam_yubico\" -DVERSION=\"2.17\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_SECURITY_PAM_APPL_H=1 -DHAVE_SECURITY_PAM_MODULES_H=1 -DHAVE_LIBPAM=1 -DHAVE_LIBLDAP=1 -DHAVE_LIBYKCLIENT=1 -DHAVE_LIBYUBIKEY=1 -DHAVE_CR=1 -I. -pthread -I/usr/obj.pkgsrc/security/pam-yubico/work.koharu/.buildlink/include/ykpers-1 -I/usr/obj.pkgsrc/security/pam-yubico/work.koharu/.buildlink/include -I/usr/include/krb5 -O2 -MT pam_yubico_la-pam_yubico.lo -MD -MP -MF .deps/pam_yubico_la-pam_yubico.Tpo -c pam_yubico.c  -fPIC -DPIC -o .libs/pam_yubico_la-pam_yubico.o
pam_yubico.c: In function 'display_error':
pam_yubico.c:452:14: warning: assignment discards 'const' qualifier from pointer target type [enabled by default]
libtool: compile:  gcc -DDEBUG_PAM -DPAM_DEBUG -DPACKAGE_NAME=\"pam_yubico\" -DPACKAGE_TARNAME=\"pam_yubico\" -DPACKAGE_VERSION=\"2.17\" "-DPACKAGE_STRING=\"pam_yubico 2.17\"" -DPACKAGE_BUGREPORT=\"yubico-devel@googlegroups.com\" -DPACKAGE_URL=\"\" -DPACKAGE=\"pam_yubico\" -DVERSION=\"2.17\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_SECURITY_PAM_APPL_H=1 -DHAVE_SECURITY_PAM_MODULES_H=1 -DHAVE_LIBPAM=1 -DHAVE_LIBLDAP=1 -DHAVE_LIBYKCLIENT=1 -DHAVE_LIBYUBIKEY=1 -DHAVE_CR=1 -I. -pthread -I/usr/obj.pkgsrc/security/pam-yubico/work.koharu/.buildlink/include/ykpers-1 -I/usr/obj.pkgsrc/security/pam-yubico/work.koharu/.buildlink/include -I/usr/include/krb5 -O2 -MT pam_yubico_la-pam_yubico.lo -MD -MP -MF .deps/pam_yubico_la-pam_yubico.Tpo -c pam_yubico.c -o pam_yubico_la-pam_yubico.o >/dev/null 2>&1

ちなみに make に V=1 を指定しないとコンパイル時に実行されるコマンドが表示されません。

少なくとも共有ライブラリ向けにコンパイルしている .libs/pam_yubico_la-pam_yubico.o では -fPIC -DPIC が指定されているので問題なさそうです。

一応 .libs/pam_yubico_la-pam_yubico.o のシンボルも見てみましょう。

$ nm /usr/obj.pkgsrc/security/pam-yubico/work.koharu/pam_yubico-2.17/.libs/pam_yubico_la-pam_yubico.o

おいィ?(三回目

何も表示されませんでした。

何かの間違いかもしれないので別のファイル .libs/pam_yubico_la-util.o のシンボルも見てみましょう。

$ nm /usr/obj.pkgsrc/security/pam-yubico/work.koharu/pam_yubico-2.17/.libs/pam_yubico_la-util.o
0000000000000000 r .LC0
0000000000000006 r .LC1
0000000000000054 r .LC10
000000000000005b r .LC11
0000000000000068 r .LC12
000000000000006f r .LC13
00000000000000a8 r .LC14
0000000000000075 r .LC15
00000000000000d8 r .LC16
0000000000000120 r .LC17
0000000000000140 r .LC18
0000000000000178 r .LC19
0000000000000014 r .LC2
00000000000001a8 r .LC20
00000000000001d0 r .LC21
0000000000000091 r .LC22
00000000000000a9 r .LC23
0000000000000016 r .LC3
0000000000000023 r .LC4
0000000000000000 r .LC5
000000000000003e r .LC6
0000000000000043 r .LC7
0000000000000038 r .LC8
000000000000004a r .LC9
                 U _GLOBAL_OFFSET_TABLE_
0000000000000020 r __FUNCTION__.4014
0000000000000000 r __FUNCTION__.4029
                 U __getpwnam50
                 U __sF
0000000000000283 T challenge_response
0000000000000149 T check_firmware_version
                 U fclose
                 U fflush
                 U fileno
                 U fopen
                 U fprintf
                 U fread
                 U free
                 U fscanf
                 U fsync
                 U ftruncate
                 U fwrite
00000000000000f3 T generate_random
0000000000000000 T get_user_cfgfile_path
00000000000003a9 T get_user_challenge_file
000000000000025e T init_yubikey
00000000000004fd T load_chalresp_state
                 U malloc
                 U memset
                 U printf
                 U putchar
                 U rewind
                 U snprintf
000000000000088e T write_chalresp_state
                 U yk_challenge_response
                 U yk_get_serial
                 U yk_get_status
                 U yk_hmac_sha1
                 U yk_init
                 U yk_open_first_key
                 U yk_pbkdf2
                 U ykds_alloc
                 U ykds_version_build
                 U ykds_version_major
                 U ykds_version_minor
                 U yubikey_hex_decode
                 U yubikey_hex_encode
                 U yubikey_hex_p

おいィ?(四回目

そんなバカな…

$ ls -l /usr/obj.pkgsrc/security/pam-yubico/work.koharu/pam_yubico-2.17/.libs/pam_yubico_la-*
-rw-r--r--  1 nonaka  wsrc   5704 Dec 23 15:09 /usr/obj.pkgsrc/security/pam-yubico/work.koharu/pam_yubico-2.17/.libs/pam_yubico_la-drop_privs.o
-rw-r--r--  1 nonaka  wsrc    814 Dec 23 15:09 /usr/obj.pkgsrc/security/pam-yubico/work.koharu/pam_yubico-2.17/.libs/pam_yubico_la-pam_yubico.o
-rw-r--r--  1 nonaka  wsrc  11048 Dec 23 15:09 /usr/obj.pkgsrc/security/pam-yubico/work.koharu/pam_yubico-2.17/.libs/pam_yubico_la-util.o

おいィ?(五回目

オブジェクトファイルのサイズが妙に小さい上にシンボルが一つも表示されないのってあれですかね、ファイル内に public なシンボルが無かったから全部消されたとかいう事なんでしょうか。

それって PAM_EXTERN として static が指定されているって事じゃないすか!やだー

という事で PIC 定義の有無に関係無く PAM_EXTERN に static が指定されているという事に。

$ cd /usr/obj.pkgsrc/security/pam-yubico/work.koharu/pam_yubico-2.17
$ find . -type f | xargs grep -n PAM_EXTERN /dev/null
./pam_yubico.c:81:#ifndef PAM_EXTERN
./pam_yubico.c:83:#define PAM_EXTERN static
./pam_yubico.c:85:#define PAM_EXTERN extern
./pam_yubico.c:791:PAM_EXTERN int
./pam_yubico.c:1097:PAM_EXTERN int

という事で pam_yubico は無罪

OpenPAM 訪問

NetBSD では PAM 関連のヘッダファイルは /usr/include/security にあるようです。

$ cd /usr/include/security/
$ grep -n PAM_EXTERN *
openpam.h:281:PAM_EXTERN int                                \
openpam.h:372:# define PAM_EXTERN static
openpam.h:389:# define PAM_EXTERN
pam_modules.h:56:PAM_EXTERN int
pam_modules.h:64:PAM_EXTERN int
pam_modules.h:72:PAM_EXTERN int
pam_modules.h:80:PAM_EXTERN int
pam_modules.h:88:PAM_EXTERN int
pam_modules.h:96:PAM_EXTERN int
pam_modules.h:107:PAM_EXTERN int
pam_modules.h:118:PAM_EXTERN int
pam_modules.h:128:PAM_EXTERN int
pam_modules.h:139:PAM_EXTERN int
pam_modules.h:149:PAM_EXTERN int

おいィ?(六回目

PAM_EXTERN は openpam.h で定義されているようです。

#if (defined(__GNUC__) || defined(__PCC__)) && !defined(NO_STATIC_MODULES)
# include <sys/cdefs.h>
# ifdef __FreeBSD__
#  include <linker_set.h>
# endif
# ifdef __NetBSD__
#  define DATA_SET(a, b) __link_set_add_data(a, b)
#  define SET_DECLARE(a, b) __link_set_decl(a, b)
#  define SET_FOREACH(a, b) __link_set_foreach(a, b)
# endif
# define OPENPAM_STATIC_MODULES
# define PAM_EXTERN static
# define PAM_MODULE_ENTRY(name)                        \
   static char _pam_name[] = name PAM_SOEXT;         \
   static struct pam_module _pam_module = {          \
       .path = _pam_name,                  \
       .func = {                       \
           [PAM_SM_AUTHENTICATE] = _PAM_SM_AUTHENTICATE,   \
           [PAM_SM_SETCRED] = _PAM_SM_SETCRED,     \
           [PAM_SM_ACCT_MGMT] = _PAM_SM_ACCT_MGMT,     \
           [PAM_SM_OPEN_SESSION] = _PAM_SM_OPEN_SESSION,   \
           [PAM_SM_CLOSE_SESSION] = _PAM_SM_CLOSE_SESSION, \
           [PAM_SM_CHAUTHTOK] = _PAM_SM_CHAUTHTOK      \
       },                          \
   };                              \
   DATA_SET(openpam_static_modules, _pam_module)
#else
/* normal case */
# define PAM_EXTERN
# define PAM_MODULE_ENTRY(name)
#endif

あー

どうやら NO_STATIC_MODULES が定義されていないと PAM_EXTERN に static が自動定義されるスバラシイ(褒めてない)コードになっていますね。

どうしてやろうか…

システム側のヘッダファイルがおかしいのであれば他の PAM 関連 pkgsrc でも問題が発生するような気がするんだけど、実は何か対処しているのだろうか

$ cd /usr/pkgsrc/security
$ grep -n NO_STATIC_MODULES */Makefile
gnome-keyring/Makefile:26:CFLAGS.NetBSD+=       -DNO_STATIC_MODULES
google-authenticator/Makefile:17:CFLAGS+=   -DNO_STATIC_MODULES
pam-dbm/Makefile:27:CFLAGS+=        -DNO_STATIC_MODULES
pam-fprint/Makefile:24:CFLAGS+=     -DNO_STATIC_MODULES
pam-krb5/Makefile:17:CPPFLAGS.NetBSD+=       -DNO_STATIC_MODULES
pam-ldap/Makefile:31:CFLAGS+=       -DNO_STATIC_MODULES
pam-mkhomedir/Makefile:38:CFLAGS+=      -DNO_STATIC_MODULES
pam-passwdqc/Makefile:16:CFLAGS+=   -DNO_STATIC_MODULES
pam-pwauth_suid/Makefile:13:PAMDEF+= -DNO_STATIC_MODULES
pam-yubico.new/Makefile:21:CFLAGS.NetBSD+=      -DNO_STATIC_MODULES
pam-yubico/Makefile:24:CFLAGS+=     -DNO_STATIC_MODULES

あー(二回目

とりあえず一番上の gnome-keyring/Makefile を見てましょう。

# $NetBSD: Makefile,v 1.83 2015/04/25 14:24:48 tnn Exp $

DISTNAME=   gnome-keyring-2.32.1
PKGREVISION=    19
CATEGORIES= security gnome
MASTER_SITES=   ${MASTER_SITE_GNOME:=sources/gnome-keyring/2.32/}
EXTRACT_SUFX=   .tar.bz2

MAINTAINER= pkgsrc-users@NetBSD.org
HOMEPAGE=   http://www.gnome.org/
COMMENT=    GNOME password and secret manager

USE_TOOLS+=     gmake intltool msgfmt pkg-config
GNU_CONFIGURE=      YES
USE_LIBTOOL=        YES
USE_PKGLOCALEDIR=   YES

PKGCONFIG_OVERRIDE+=    gcr/gcr.pc.in
PKGCONFIG_OVERRIDE+=    gp11/gp11.pc.in

CFLAGS.HPUX+=       -DMAP_ANON=MAP_ANONYMOUS

# Workaround a bug with NetBSD's openpam
# The bug is described in PR security/39313
#
CFLAGS.NetBSD+=     -DNO_STATIC_MODULES

.include "../../mk/bsd.prefs.mk"
.if ${OPSYS} == "SunOS"
CONFIGURE_ENV+= ac_cv_header_security_pam_modules_h=yes
.endif

.include "../../mk/dlopen.buildlink3.mk"

BUILDLINK_TRANSFORM+=   opt:-ldl:${BUILDLINK_LDADD.dl:M*}

BUILDLINK_API_DEPENDS.glib2+=   glib2>=2.26.0
.include "../../devel/glib2/schemas.mk"
.include "../../devel/gettext-lib/buildlink3.mk"
.include "../../devel/glib2/buildlink3.mk"
.include "../../security/libgcrypt/buildlink3.mk"
.include "../../security/libtasn1/buildlink3.mk"
.include "../../sysutils/dbus/buildlink3.mk"
.include "../../x11/gtk2/buildlink3.mk"
.include "../../mk/pam.buildlink3.mk"
.include "../../mk/bsd.pkg.mk"

あー(三回目

lib/39313、そういう事のようです

workaround をパチってきました。

Index: security/pam-yubico/Makefile
===================================================================
RCS file: /cvsroot/pkgsrc/security/pam-yubico/Makefile,v
retrieving revision 1.10
diff -u -p -r1.10 Makefile
--- security/pam-yubico/Makefile  10 Nov 2014 21:55:31 -0000  1.10
+++ security/pam-yubico/Makefile  23 Dec 2015 06:59:08 -0000
@@ -15,6 +15,11 @@ GNU_CONFIGURE=        yes
 USE_TOOLS+=        pkg-config
 USE_LIBTOOL=       yes
 
+# Workaround a bug with NetBSD's openpam
+# The bug is described in PR security/39313
+#
+CFLAGS.NetBSD+=        -DNO_STATIC_MODULES
+
 .include "../../security/libyubikey/buildlink3.mk"
 .include "../../security/ykclient/buildlink3.mk"
 .include "../../security/ykpers/buildlink3.mk"

Makefile にパッチをあてて pam_yubico パッケージを再作成します。

$ cd /usr/pkgsrc/security/pam-yubico
$ make clean
$ make update

新しい pam_yubico モジュールのシンボルを確認しておきます。

$ nm /usr/pkg/lib/security/pam_yubico.so
0000000000208620 d _DYNAMIC
0000000000208980 d _GLOBAL_OFFSET_TABLE_
                 w _Jv_RegisterClasses
0000000000208600 d __CTOR_LIST_END__
0000000000008050 r __FUNCTION__.4014
0000000000008030 r __FUNCTION__.4029
0000000000008170 r __FUNCTION__.4254
0000000000008150 r __FUNCTION__.4260
0000000000007ce0 r __FUNCTION__.6198
0000000000007d00 r __FUNCTION__.6211
0000000000007d20 r __FUNCTION__.6235
0000000000007d3a r __FUNCTION__.6252
0000000000007d50 r __FUNCTION__.6275
0000000000007d66 r __FUNCTION__.6289
0000000000007d70 r __FUNCTION__.6319
0000000000208d34 D __bss_start
                 w __cxa_finalize
                 w __deregister_frame_info@@GCC_3.0
0000000000208ce8 d __dso_handle
                 U __errno
                 U __fstat50
                 U __getpwnam50
                 w __register_frame_info@@GCC_3.0
                 U __sF
0000000000208d34 D _edata
0000000000208d38 D _end
0000000000006f60 T _fini
00000000000023b0 T _init
                 U _yk_errno_location@@LIBYKPERS_1.0
                 U ber_free
0000000000006033 T challenge_response
0000000000005ef9 T check_firmware_version
0000000000006bc0 t check_user_token.isra.1
                 U close
                 U fclose
                 U fdopen
                 U fflush
                 U fgets
                 U fileno
                 U fopen
                 U fprintf
                 U fread
                 U free
                 U fscanf
                 U fsync
                 U ftruncate
                 U fwrite
0000000000005ea3 T generate_random
0000000000005db0 T get_user_cfgfile_path
0000000000006159 T get_user_challenge_file
                 U getegid
                 U geteuid
                 U getgroups
000000000000600e T init_yubikey
                 U initgroups
                 U ldap_count_values_len
                 U ldap_err2string
                 U ldap_first_attribute
                 U ldap_first_entry
                 U ldap_get_values_len
                 U ldap_init
                 U ldap_initialize
                 U ldap_memfree
                 U ldap_msgfree
                 U ldap_next_attribute
                 U ldap_search_ext_s
                 U ldap_set_option
                 U ldap_simple_bind_s
                 U ldap_unbind
                 U ldap_value_free_len
00000000000062ad T load_chalresp_state
                 U malloc
                 U memcmp
                 U memcpy
                 U memset
                 U open
                 U pam_get_item
                 U pam_get_user
0000000000006830 T pam_modutil_drop_priv
0000000000006a62 T pam_modutil_regain_priv
                 U pam_set_data
                 U pam_set_item
0000000000002b30 T pam_sm_authenticate
0000000000005dac T pam_sm_setcred
                 U pam_strerror
                 U printf
                 U putchar
                 U rename
                 U rewind
                 U setegid
                 U seteuid
                 U setgroups
                 U snprintf
                 U sprintf
                 U sscanf
                 U strcmp
                 U strdup
                 U strerror
                 U strncmp
                 U strncpy
                 U strtok
                 U strtok_r
                 U syslog
000000000000663e T write_chalresp_state
                 U yk_challenge_response@@LIBYKPERS_1.8
                 U yk_close_key@@LIBYKPERS_1.0
                 U yk_get_serial@@LIBYKPERS_1.5
                 U yk_get_status@@LIBYKPERS_1.0
                 U yk_hmac_sha1@@LIBYKPERS_1.9
                 U yk_init@@LIBYKPERS_1.0
                 U yk_open_first_key@@LIBYKPERS_1.0
                 U yk_pbkdf2@@LIBYKPERS_1.0
                 U yk_release@@LIBYKPERS_1.0
                 U yk_strerror@@LIBYKPERS_1.0
                 U yk_usb_strerror@@LIBYKPERS_1.0
                 U ykclient_done@@Base
                 U ykclient_init@@Base
                 U ykclient_request@@Base
                 U ykclient_set_ca_path@@Base
                 U ykclient_set_client_b64@@Base
                 U ykclient_set_url_bases@@YKCLIENT_2.12
                 U ykclient_set_url_template@@Base
                 U ykclient_set_verify_signature@@Base
                 U ykclient_strerror@@Base
                 U ykds_alloc@@LIBYKPERS_1.0
                 U ykds_version_build@@LIBYKPERS_1.0
                 U ykds_version_major@@LIBYKPERS_1.0
                 U ykds_version_minor@@LIBYKPERS_1.0
                 U yubikey_hex_decode@@YUBIKEY_1.0
                 U yubikey_hex_encode@@YUBIKEY_1.0
                 U yubikey_hex_p@@YUBIKEY_1.5

ヤッター

再度試してみよう

気を取り直して再度ログインしてみましょう。

NetBSD/amd64 (koharu.myhome.nonakap.org) (ttyE1)

login: nonaka
debug: pam_yubico.c:764 (parse_cfg): called.
(snip...)
YubiKey for `nonaka': (ここで YubiKey にタッチする)
debug: pam_yubico.c:972 (pam_sm_authenticate): conv returned 44 bytes
(snip...)
Last login: Wed Dec 23 14:59:11 2015 on 192.168.0.103
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 7.99.24 (KOHARU) #3367: Sun Dec 20 14:07:44 JST 2015
nonaka@koaru$ 

ヤッター(二回目

pam_yubico モジュールのフラグに debug を指定しているのでデバッグログがちょっとうるさいですが、YubiKey 認証が実行されました。

ってあれ? そういえばパスワード入力無しでログインできてしまいました。

これはこれで大変便利なのですが今回は二要素認証したいという事なのでちょっと困ります。

再度 PAM 設定

これは YubiKey 関係無しに PAM の設定の話になります。

int128.hatenablog.com

/etc/pam.d/login に設定で二要素認証するようになっていなかったという事です。

auth     sufficient  pam_self.so     no_warn
auth        required    pam_nologin.so      no_warn
auth        sufficient  /usr/pkg/lib/security/pam_yubico.so id=XXX debug
auth        include     system

認証のバリエーションとしては以下の三つですかね

YubiKey→パスワード、YubiKey が成功したらログイン成功
auth     sufficient  pam_self.so     no_warn
auth        required    pam_nologin.so      no_warn
auth        sufficient  /usr/pkg/lib/security/pam_yubico.so id=XXX
auth        include     system
YubiKey→パスワード、両方成功したらログイン成功
auth     sufficient  pam_self.so     no_warn
auth        required    pam_nologin.so      no_warn
auth        required    /usr/pkg/lib/security/pam_yubico.so id=XXX
auth        include     system
パスワード→YubiKey、両方成功したらログイン成功
auth     sufficient  pam_self.so     no_warn
auth        required    pam_nologin.so      no_warn
auth        include     system
auth        required    /usr/pkg/lib/security/pam_yubico.so id=XXX

再々度試してみよう

「パスワード→YubiKey、両方成功したらログイン成功」の設定を使ってログインしてみます。

NetBSD/amd64 (koharu.myhome.nonakap.org) (ttyE1)

login: nonaka
Password:
YubiKey for `nonaka': (ここで YubiKey にタッチする)
Last login: Wed Dec 23 16:22:58 2015 on ttyE1
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 7.99.24 (KOHARU) #3367: Sun Dec 20 14:07:44 JST 2015
nonaka@koaru$ 

ヤッター(三回目

やっと当初の目的をとりあえず達成できました。

まとめ

コンソールログインだと二要素認証はそんなに便利でもないというか、その前にやる事が沢山あるだろうという気持ちでいっぱいです。

pam-u2f を使った U2F も試そうと思ったのですが、pkgsrc にパッケージが無かったので早々に諦めました。

pam_yubico を使った ssh 接続時の認証は多分 NetBSD 固有の設定は無いと思うのでググれ。

Authentication Using Challenge-ResponseNetBSD 固有の設定は無いと思うのでググれ。

しかし pkgsrc にもちゃんと使えないパッケージがあるんですね(棒

*1:書きました。nonakap.hatenablog.com