とあるエンジニアの備忘log
2012年12月19日水曜日
NFSv4 + Kerberos で セキュリティとユーザーマッピングを解決
NFSv4 と Kerberos を組み合わせることで、NFSのセキュリティとユーザーマッピングの課題を解決してみました。 これまで、自分が NFS を使う際の懸念事項がセキュリティの問題とユーザーマッピングの問題でした。 #### セキュリティについて #### `/etc/exports` でマウントを許可するクライアントを指定することはできるものの、IPアドレスは基本的に自己申告ですから、LAN内にある全てのマシンが信用できるという場合を除いては、かなり危険だと思います。 ある程度規模の大きい LAN につないでいる場合、中には悪い人がいるかもしれません。 例えば、サーバー側が `/etc/exports` に /home 192.168.11.30(rw,sync) と書いて、公開したとします。 他のマシンから $ showmount -e NFS_SERVER_NAME で問い合わせると /home 192.168.11.30 と表示されます。 つまりどのホストに対して、どのディレクトリを公開しているかは一目瞭然です。 その IPアドレスになりすまされると、悪意のある人に簡単にマウントされてしまいます。 #### ユーザーマッピングの問題について #### NFSv3 までは、パーミッションについては クライアント側の UID と GID がサーバー側でも利用されるので、サーバー/クライアント間で UID と GID の同期が取れていない場合、別ユーザーになってしまうという問題があります。 例えば、サーバー側では taro が UID 500 だったとします。 もし、クライアント側で taro が UID 600 になっていたとすると、 taro は サーバー上のファイルへアクセスできなくなってしまいます。 しかも、クライアント側で、もし hanako が UID 500 に割り当たっていたとすると、 hanako は サーバー上の taro のファイルにアクセスできてしまうことになる。 ディストリビューションによって、一般ユーザーの UID に使われる範囲が違います。 RedHat系は 500~、Ubuntuなどでは 1000~ が使われるようです。 ですから、 NIS や LDAP などでユーザー情報を一元管理しているか、気をつけてユーザーID を設定している場合を除いては、サーバー/クライアント間で UID や GID は一致しないことが多いです。 そもそも「サーバー/クライアント間でユーザーに同じ UID/GID が使われている」という前提は期待されるべきものでもないと思うのです。 exports の古い man ページを見るとかつて `map_static` というオプションがあって、 サーバー/クライアント間で UID と GID を再マッピングできたみたいなのですが、すでに廃止されていているみたいです。 そこで、NFSv4 + Kerberos version5 をセットアップし、上記の「セキュリティの問題」と「ユーザーマッピングの問題」を解決してみました。 ユーザーマッピングについては NFSv4 で idmapd デーモンがやってくれるので、Kerberos までは必要ないようにも思えます。 ところが、NFSv4 単独だと、ユーザーマッピングがうまく動きませんでした。 検索してみたところ、 「idmapd が期待通り動かない」という書き込みが多かったですし、私も実際試してみたのですが、結局やり方がわかりませんでした。 一方、認証を Kerberos に任せた場合は、ユーザーマッピングもうまく動作しました。 最初、 RHEL/CentOS での設定をまとめます。その後、 Ubuntu での設定も簡単に説明します。 前提として、すでに Kerberos の基本的な設定は済んでいるものとします。 この部分は、前回 [Kerberos を使ってみる(RHEL/CentOS/Ubuntu編)](/2012/12/kerberos-v5.html)の記事で説明しました。 ### RHEL/CentOS編 ### RHEL6.3/CentOS6.3で確認しています。 ここでは説明上、 - NFSサーバーのホスト名: `nfsserver.mydomain.com` - NFSクライアントのホスト名: `nfsclient.mydomain.com` とする。 NFSサーバー/NFSクライアント両方とも `/etc/sysconfig/nfs` で SECURE_NFS="yes" の行を有効にしておきます。 さらに、どのホストからでもいいですけど、 kadmin: addprinc -randkey nfs/nfsserver.mydomain.com kadmin: addprinc -randkey nfs/nfsclient.mydomain.com として、サーバー側、クライアント側の両方のサービスプリンシパルを作成する。 通常のサービスではサーバー側だけサービスプリンシパルを作成するのですが、NFS については サーバー/クライアント両方とも必要です。 `ktadd` はおのおののホスト上で行わないといけません。 NFSサーバー (`nfsserver.mydomain.com`)上で kadmin: ktadd nfs/nfsserver.mydomain.com NFSクライアント(`nfsclient.mydomain.com`)上で kadmin: ktadd nfs/nfsclient.mydomain.com とする。 それぞれのホストの `/etc/krb5.keytab` にキーが保存されるはず。 ちゃんと保存されているか念のために確認してみます。 NFSサーバー側の結果: [root@nfsserver] # klist -e -k /etc/krb5.keytab Keytab name: WRFILE:/etc/krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 2 nfs/nfsserver.mydomain.com@MYDOMAIN.COM (aes256-cts-hmac-sha1-96) 2 nfs/nfsserver.mydomain.com@MYDOMAIN.COM (aes128-cts-hmac-sha1-96) 2 nfs/nfsserver.mydomain.com@MYDOMAIN.COM (des3-cbc-sha1) 2 nfs/nfsserver.mydomain.com@MYDOMAIN.COM (arcfour-hmac) 2 nfs/nfsserver.mydomain.com@MYDOMAIN.COM (des-hmac-sha1) 2 nfs/nfsserver.mydomain.com@MYDOMAIN.COM (des-cbc-md5) NFSクライアント側の結果: [root@nfsclient]# klist -e -k /etc/krb5.keytab Keytab name: WRFILE:/etc/krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 3 nfs/nfsclient.mydomain.com@MYDOMAIN.COM (aes256-cts-hmac-sha1-96) 3 nfs/nfsclient.mydomain.com@MYDOMAIN.COM (aes128-cts-hmac-sha1-96) 3 nfs/nfsclient.mydomain.com@MYDOMAIN.COM (des3-cbc-sha1) 3 nfs/nfsclient.mydomain.com@MYDOMAIN.COM (arcfour-hmac) 3 nfs/nfsclient.mydomain.com@MYDOMAIN.COM (des-hmac-sha1) 3 nfs/nfsclient.mydomain.com@MYDOMAIN.COM (des-cbc-md5) また、NFSサーバー側の `/etc/exports` の書き方は /home gss/krb5(fsid=0,crossmnt,rw,sync) などとなります。公開先のホスト名の部分を `gss/krb5` とする部分がポイントです。 あとはクライアント側から # mount -t nfs4 -o sec=krb5 nfsserver:/ hogehoge といった感じでマウントができます。 (実は `-t nfs4` の部分はなくてもよい。) マウントはこれでできますが、実際にアクセスするには、ユーザーは Kerberos 認証を済ませないといけません。 $ kinit でTGT を入手しておけば、アクセス可能になります。 なお、NFSv4 + Kerberos を解説したページで `ktadd` するときに `-e des-cbc-crc:normal` オプションを付けると説明しているページもありますが、現在はこのオプションは不要ですので、このオプションは付けないでください。 `dec-cbc-crc` 自体が廃止で、エラーになります。 ### Ubuntu編 ### Ubuntu 12.04 LTS で確認しました。 やり方は、RHEL/CentOS とほとんど同じなので、差分だけ説明します。 NFSサーバーは `nfs-kernel-server` パッケージ、NFSクライアントは `nfs-common` パッケージのインストールが必要です。 RHEL/CentOS で `/etc/sysconfig/nfs` で SECURE_NFS="yes" を設定するとなっている部分は Ubuntu では不要です。 その代わり、Ubuntu では、NFSサーバーの `/etc/default/nfs-kernel-server` に NEED_SVCGSSD=yes NFSクライアントの `/etc/default/nfs-common` に NEED_GSSD=yes を追加します。 あとは、同じやり方でできます。 ### RHEL/CentOS と Ubuntu の組み合わせ ### RHEL/CentOS 同士、 Ubuntu 同士の組み合わせで説明しましたが、もちろん、 CentOSのNFSサーバー と Ubuntu クライアントといった組み合わせでも動きました。 CentOS では UID は 500~ から使われていて、Ubuntuでは UID は 1000~ なので、当然ながら UID/GID はまったくバラバラなのですが、うまくユーザーマッピングして動いてくれています。
Kerberos を使ってみる (RHEL/CentOS/Ubuntu編)
NFSv4 と Kerberos を組み合わせて、 NFS のセキュリティの弱さをカバーしてみたいと思います。 長いので 2回に分けました。 今回は Kerberos の初期設定の部分までやってみます。 まずは RHEL/CentOS の場合のやり方を説明し、最後に Ubuntu でやる場合の差分情報をまとめておきます。 ### RHEL/CentOS編 ### RHEL 6.3/CentOS 6.3で確認しました。 Kerberos サーバー側は `krb5-server` パッケージをインストールします。 クライアント側については `krb5-workstation` がデフォルトでインストールされているので、特にインストールする必要はないです。 Kerberos サーバーのことを KDC (Key Distribution Center) と言います。 主に設定変更するファイルは3点です。 - `/etc/krb5.conf` : Kerberos 認証を利用する全ホストで設定必要 - `/var/kerberos/krb5kdc/kdc.conf`: KDCのみ設定する - `/var/kerberos/krb5kdc/kadm5.acl`: KDCのみ設定する 以下、説明の都合上、 - KDCのホスト名 : `mykdc.mydomain.com` - サービスサーバーのホスト名: `myserver.mydomain.com` - サービスクライアントのホスト名: `myclient.mydomain.com` として説明します。 `mykdc` と `myserver` は同一ホストであってもいいですが、一応、別々として説明しています。 Kerberos のシングルサインオンで、 `myclient` から `myserver` へ ssh ログインするところまでやってみます。 #### krb5.conf の修正 #### 各ホストの `/etc/krb5.conf` を以下のように修正します。 [logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] # default_realm = EXAMPLE.COM ←コメントアウト default_realm = MYDOMAIN.COM ←追加 dns_lookup_realm = false dns_lookup_kdc = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true [realms] EXAMPLE.COM = { kdc = kerberos.example.com admin_server = kerberos.example.com } MYDOMAIN.COM = { ←追加 kdc = mykdc.mydomain.com ←追加 admin_server = mykdc.mydomain.com ←追加 } ←追加 [domain_realm] .example.com = EXAMPLE.COM example.com = EXAMPLE.COM レルム名 (Kerberos が管理する範囲のこと) が `EXAMPLE.COM` になっているので、 `MYDOMAIN.COM` に変更しました。 ドメイン名を大文字にしたものをレルム名にするのが慣例です。 #### kdc.conf の修正 #### KDCホストの `/var/kerberos/krb5kdc/kdc.conf` を以下のように修正。 [kdcdefaults] kdc_ports = 88 kdc_tcp_ports = 88 [realms] # EXAMPLE.COM = { ← コメントアウト MYDOMAIN.COM = { ← 追加 #master_key_type = aes256-cts acl_file = /var/kerberos/krb5kdc/kadm5.acl dict_file = /usr/share/dict/words admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal } #### kadm5.acl の修正 #### KDCホストの `/var/kerberos/krb5kdc/kadm5.acl` を以下のように修正。 # */admin@EXAMPLE.COM * ← コメントアウト */admin@MYDOMAIN.COM * ← 追加 これは `kadmin` 中で実行可能なコマンドを設定しています。 `*/admin` のユーザーに全コマンドを許可するのが慣習です。 #### データベース設定 #### 3種類のファイルの修正ができたら KDC上で root@mykdc # kdb5_util create -s でデータベースを作成する。 途中で KDC database master key を入力するように言われるので、パスワードを設定します。 さらにサーバー側で `kadmin.local` で `root/admin` プリンシパルを作成する。 `kadmin.local` はどんなコマンドでもパーミッションを無視して、成功します。 root@mykdc # kadmin.local ... kadmin.local: addprinc root/admin ... kadmin.local: exit kadmin サービスと krb5kdc サービスを開始する。 root@mykdc # chkconfig kadmin on root@mykdc # service kadmin start root@mykdc # chkconfig krb5kdc on root@mykdc # service krb5kdc start ファイアウォールを設定している場合、 - `88/tcp, 88/udp` (krb5kdc サービス) - `749/tcp` (kadminサービス) を開けておきます。 これ以降は、どのホストからでも $ kadmin -p root/admin とすれば、KDC database のメンテができるようになります。 どのホストからでもいいのですが、以下のようにユーザープリンシパルやホストプリンシパルを作ります。 $ kadmin -p root/admin kadmin: addprinc user01 kadmin: addprinc -randkey host/myserver.mydomain.com kadmin: exit とします。 `user01` は使うユーザー名で適宜置き換えてください。 最後、ホストプリンシパルのパスワードを `ktadd` する。これは必ずサービスサーバー上で行わないといけない。 root@myserver # kadmin -p root/admin kadmin: ktadd host/myserver.mydomain.com kadmin: exit キーはサービスサーバーの `/etc/krb5keytab` へ保存されます。 試しに、以下のようにするとキーが保存されているのがわかります。 myserver # klist -e -k /etc/krb5.keytab Keytab name: WRFILE:/etc/krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 2 host/myserver.mydomain.com@MYDOMAIN.COM (aes256-cts-hmac-sha1-96) 2 host/myserver.mydomain.com@MYDOMAIN.COM (aes128-cts-hmac-sha1-96) 2 host/myserver.mydomain.com@MYDOMAIN.COM (des3-cbc-sha1) 2 host/myserver.mydomain.com@MYDOMAIN.COM (arcfour-hmac) 2 host/myserver.mydomain.com@MYDOMAIN.COM (des-hmac-sha1) 2 host/myserver.mydomain.com@MYDOMAIN.COM (des-cbc-md5) 以上でセットアップ完了です。 クライアント側で user01@myclient $ kinit で認証します。 user01@myclient $ ssh myserver で `myserver` のログインパスワードを入力せずに、ssh 接続できます。 Kerberos で認証できているためです。シングルサインオンが実現しました! user01@myclient $ klist でキャッシュされているチケットが表示されます。 Valid starting Expires Service principal 12/17/12 16:26:33 12/18/12 16:26:33 krbtgt/MYDOMAIN.COM@MYDOMAIN.COM renew until 12/17/12 16:26:33 12/17/12 16:27:17 12/18/12 16:26:33 host/myserver.mydomain.com@MYDOMAIN.COM renew until 12/17/12 16:26:33 なお、 ホストプリンシパルのサービスチケットの取得がうまく行かない場合、 `/etc/hosts` を確認してみてください。 192.168.10.xx myserver.mydomain.com myserver のように Fully Qualified Domain Name が先にくるように書いておかないと、ホストの逆引きで失敗します。 192.168.10.xx myserver myserver.mydomain.com のように書くとうまくいきません。 ### Ubuntu編 ### Ubuntu 12.04 LTS で確認しました。 KDC側は $ sudo apt-get install krb5-kdc krb5-admin-server KDC以外のホストは $ sudo apt-get install krb5-user をインストールします。 インストールの途中で - レルム - あなたのレルムのケルベロスサーバー (`/etc/krb5.conf` の `kdc` に設定される) - あなたのレルムのケルベロス管理サーバー (`/etc/krb5.conf` の `admin_server` に設定される) を質問されるので、答えます。 これに基づき、`/etc/krb5.conf` と `/etc/krb5kdc/kdc.conf` (KDCのみ)を作ってくれるので、とりあえずそのまま使えます。 ちなみに、RHEL/Ubuntu で `/var/kerberos/krb5kdc/` にあったディレクトリは Ubuntu では `/etc/krb5kdc/` にあります。 mykdc $ sudo krb5_newrealm でデータベースを作成する。この時に `/etc/krb5kdc/kadmin.acl` も作成されます。 `/etc/krb5kdc/kadmin.acl` の # */admin * のコメントを外す。 あとは mykdc $ sudo kadmin.local kadmin.local: addprinc user01/admin などとし、RHEL/CentOS と同様にプリンシパルを追加していきます。 なお、Kerberos による ssh シングルサインオンをするには ssh サーバー側の `/etc/ssh/sshd_config` の GSSAPIAuthentication no を GSSAPIAuthentication yes に変更する必要があります。
autofs 設定 (RHEL/CentOS/Ubuntu編)
autofs はアクセスするときに自動的にマウントしてくれる機能です。 [前回](/2012/12/nfs-v3-v4-rhelcentosubuntu.html) 説明した NFS と合わせて使用すると大変便利です。 (もちろん autofs は NFS専用ではなくて、ローカルなファイルシステムに対しても使えますが。) 以下では、最初に RHEL/CentOS でのやり方を説明し、最後に Ubuntu でやる場合の差分を簡単にまとめます。 ### RHEL/CentOS編 ### 動作確認は RHEL 6.3 / CentOS 6.3 でやっております。 NFSクライアント側で autofs サービスを起動しておきます。 パッケージ名は autofs ですが、RHEL/CentOSでは多分デフォルトでインストールされていると思います。 $ service autofs status で autofs が動いていることを確認しておきます。 設定は `/etc/auto.master` ですが、とりあえずデフォルトのままで使えるようにしてくれています。 実際にやってみましょう。 `MY_NFS_SERVER` というホスト名の NFS server がすでに稼働しているとします。 $ cd /net $ ls 何も表示されません。。しかし、 $ cd /net/MY_NFS_SERVER $ ls ディレクトリが表示されるはず。 このように `/net/<サーバー名>` にアクセスするとそのサーバーが公開しているディレクトリを自動的に全部マウントしてくれます。 これだけでも、十分使えると思いますが、自分で細かく設定したい場合は `/etc/auto.master` をいじります。 先ほどの /net については /net -hosts という設定が書かれています。 `-hosts` というのは特別なオプション設定で、 `/etc/hosts` に基づいて、NFS で公開しているものを全部マウントしてくれる(と自分では理解している)。 細かく設定する場合、 `/etc/auto.misc` のような別ファイルに詳細設定を記載し、それを `/etc/auto.master` から読み込むという書き方が一般的のようです。 例えば、 `/etc/auto.master` には /misc /etc/auto.misc --timeout=60 のように <マウントポイント> <サブ設定ファイル> [<オプション>] の書式で書いておく。 (`--timeout=60` は、60秒アクセスがないと、自動的にアンマウントされるというオプションです。) 細かい設定は `/etc/auto.misc` の方で hoge -rw MY_NFS_SERVER:/piyo のように key option location という書式で書いておく。(詳しくは autofs(5) 参照してください。) すると `/misc/hoge` にアクセスすると `MY_NFS_SERVER:/piyo` 以下を勝手にマウントしてくれるというわけです。 ### Ubuntu 編 ### 動作確認は Ubuntu 12.04 LTS でやっています。 Ubuntu はデフォルトではインストールされていないので、 $ sudo apt-get install autofs でインストールする。 設定の仕方は RHEL/CentOS のやり方と同じです。 /net の設定はデフォルトではコメントアウトされているので、使いたければ、 `/etc/auto.master` の #/net -hosts のコメントを外します。
NFS v3 と v4 設定まとめ (RHEL/CentOS/Ubuntu編)
NFSのセットアップ手順を簡単にまとめておきます。 NFS v3以前と v4とでポリシーがかなり違うので、それぞれの方法をまとめておきます。 まずは、 RHEL/CentOS でのやり方をメインに説明します。最後に Ubuntu でやる場合の差分情報もまとめておきました。 ### REEL/CentOS 編 #### NFSv3以前の場合 CentOS の場合、nfs-file-server パッケージはデフォルトでインストールされています。 サーバー側の設定は `/etc/exports` に directory client(option,...) client(option,...) ... の形で記述します。 /path/to/dir1 nfs.client.addr(rw,sync) /path/to/dir2 nfs.client.addr(rw,sync) みたいな感じ。 同じクライアントへ、複数のディレクトリを公開することもできる。 設定したら # chkconfig nfs on # service nfs restart RHEL や CentOS はデフォルトでファイアウォールでブロックされているので、システム->管理->ファイアウォールで無効にしておきます。 (ポート番号が固定されないらしいので。) クライアント側から # mount nfs.server.addr:/path/to/dir1 /mount/point1 # mount nfs.server.addr:/path/to/dir2 /mount/point2 みたいな感じでマウントできます。 マウント対象のディレクトリパスは、実際にサーバーが公開されているディレクトリパスよりも上の階層、下の階層も指定できます。 # mount nfs.server.addr:/ /mount/point のようにサーバー側のルートディレクトリも指定できる。 もちろん、公開されているディレクトリしか見えないわけですけど。 #### NFSv4 の場合 v3以前は、サーバーはディレクトリごとに個別に export し、クライアント側もディレクトリごとに個別にマウントしていた。 それに対して、v4 ではサーバーは一つの仮想的なファイルシステムを export し、クライアント側からはそれがサーバーのルートディレクトリとして見えます。 サーバー側の `/etc/exports` の設定は /path/to/dir nfs.client.addr(rw,sync,fsid=0) などのようにします。 `fsid=0` を指定するのがポイントです。 クライアント側はv3以前と同じように # mount nfs.server.addr:/ /mount/point のようにする。`-t nfs4` はつけてもつけなくても変わらなかった。 v4では、クライアントから見た時のディレクトリの見え方が異なります。 v3以前は サーバー側の `/path/to/dir` はクライアントからも `server:/path/to/dir` として見えました。 v4の場合、サーバー側の `/path/to/dir` はクライアント側からは `server:/` に見えます。 前述の通り、v4 では 仮想的なファイルシステムを一つだけ作ってそれを export し、ルートディレクトリとしてクライアントに見せるというポリシーのため、別々のディレクトリを export したいときはちょっと手間がかかります。 とりあえず export するディレクトリツリーを `/export` の下に構築することにする。 例えば、 `/home/user1` と `/home/user2` を export したい場合 # mkdir -p /export/user1 /export/user2 # mount --bind /home/user1 /export/user1 # mount --bind /home/user2 /export/user2 このように export したいディレクトリを bind で `/export` の下に集めるわけだ。 `/etc/exports` の書き方は2通りあります。 1つ目は親ディレクトリに `fsid=0` を指定、子ディレクトリには `nohide` を指定する方法。 /export nfs.client.addr(rw,sync,fsid=0) /export/user1 nfs.client.addr(rw,sync,nohide) /export/user2 nfs.client.addr(rw,sync,nohide) 2つ目は親ディレクトリに `fsid=0` と `crossmnt` を指定する方法。 /export nfs.client.addr(rw,sync,fsid=0,crossmnt) 親に `crossmnt` 指定すると、子に `nohide` 指定するのと同じ効果が得られます。 後者のやり方の方が、重複する記載がないので、楽だと思います。 なお、v4ではポートが固定されるので、ファイアウォールといっしょに使いやすいです。 2049/tcp を開いておきます。 #### v3以前とv4が混在したら、、、 上記のように `/etc/exports` の書き方、つまり `fsid=0` がついているかどうかで、v3 か v4 かが判断されるわけです。 一つの `/etc/exports` の中に、v3以前の書き方とv4の書き方を混在して書くこともできるわけだが、その場合どうなるんでしょうね。実験してみました。 `/etc/exports` の記載は以下のようにします。 # v3 style /path/to/dir1 nfs.client.addr(rw,sync) /path/to/dir2 nfs.client.addr(rw,sync) # v4 style /export nfs.client.addr(rw,sync,fsid=0) /export/user1 nfs.client.addr(rw,sync,nohide) /export/user2 nfs.client.addr(rw,sync,nohide) クライアントから # mount nfs.server.addr:/ /mount/point とするとサーバーの `/export` がマウントされた。ルートディレクトリをマウントしようとすると v4 の意味に解釈されるらしい。 # mount nfs.server.addr:/path/to/dir1 /mount/point とするとサーバーの `/path/to/dir1` がマウントされた。 一応、同一サーバー、同一クライアント間で v3以前と v4 は同時使用できるみたいだ。 ただし、 #mount nfs.server.addr:/path/to /mount/point のように v3 スタイルの上位ディレクトリを指定するとアクセス拒否されるようになりました。 v3以前のやり方のほうが設定は簡単でわかりやすいとは思いますが、v4 だと - ポート番号が2049 固定でファイアウォールと一緒に使いやすい - Kerberos と組み合わせてセキュリティ面を強化 - idmapd で サーバー/クライアント間で異なるUID/GID でも対応できる などのメリットもあるので、自分は NFSv4 を使うようになりました。 Kerberosとの組み合わせ方は、後日まとめます。 ### Ubuntu編 さて、上記は RHEL/CentOS の場合ですが、Ubuntuの場合にも簡単にまとめておきます。 Ubuntu ではデフォルトでは NFS は入っていないので サーバー側は `nfs-kernel-server` パッケージをインストール。 クライアント側は `nfs-common` パッケージをインストールします。 サービス名は `nfs-kernel-server` です。 あとのやり方は RHEL/CentOS編 で説明したのと同じですので、割愛します。
2012年12月18日火曜日
NIS 設定まとめ (RHEL/CentOS/Ubuntu編)
NISの設定方法をメモっておきます。 最初に RHEL/CentOS での方法を記載し、最後に Ubuntu の場合の差分を記載します。 ### RHEL/CentOS編 CentOS 6.3でやってみました。 NISに関連するパッケージは以下です。 - ypserv : NISサーバ - ypbind : NISクライアントとNISドメインをバインドするデーモン - yp-tools: NISクライアントプログラム集 ypbind と yp-tools はデフォルトで入っているはず。 ypserv はサーバー側にだけ必要になります。 #### NISサーバー側の設定 # yum install ypserv でインストールします。 `/etc/sysconfig/network` に以下のようにNISドメイン名を追加する。NISドメイン名はとりあえずサーバーとクライアントで共通であればよいです。普通、ホスト名のドットより後ろの部分を使います。 NISDOMAIN=
ypserv サービスを起動しておく。 `/var/yp/Makefile` の `all:` ターゲットの部分を見ればどのマップ(=NISで管理されるファイル)が作成されるかがわかります。 とりあえずデフォルトのままでOKです。 NISデータベースを初期化します。 32bit OSなら # /usr/lib/yp/ypinit -m 64bit OSなら # /usr/lib64/yp/ypinit -m を実行する。 #### NISクライアント側の設定 RHEL/CentOS なら ypbind と yp-tools はデフォルトで入っているので、特にインストールするものはなし。 `/etc/yp.conf` に以下のような設定を記載する domain
server
`/etc/nsswitch.conf` を開き passwd: files shadow: files group: files のようになっているところを passwd: nis files shadow: nis files group: nis files のように書きかえます。 これで、`passwd`, `shadow`, `group` は NIS ⇒ ローカルファイルの順番に見にいってくれるようになります。 `/etc/nsswitch.conf` の設定を間違えると最悪起動しなくなるので、ご注意ください。(`files` を `file` と書き間違えて、起動しなくなった経験あり)。 もし起動しなくなった場合、KNOPPIX とかで起動して、ハードディスクをマウントし、 `/etc/nsswitch.conf` を正しく修正するのが手っ取り早いと思います。 そして ypbind のサービスを起動する。 # ypwhich を実行し、でNISサーバーとバインドできているのを確認できればOKです。 ちゃんと動いていれば # ypcat passwd とすることでマップの中身が読めるはず。 ユーザー認証を NISで管理できても、ホームディレクトリが作られていなかったら、まともにログインできません。したがって、NIS単独で使うことはあまりなくて、NIS と NFS (さらには autofsも)と組み合わせるのが通常の運用形態だと思います。 NFSのセットアップ方法は次回まとめます。 最後に `yppasswd` コマンドでNIS経由でパスワード変更できるようにします。 NISサーバー側で `yppasswdd` サービスを起動させておきます。すると、NISクライアント側は `yppasswd` コマンドでパスワード変更できるようになります。 ちゃんと設定したつもりなのに、最初は $ yppasswd とすると yppasswd: yppasswdd not running on NIS master host ("localhost.localdomain") というエラーメッセージが出てうまくいきませんでした。 しばらく考えて、エラーの意味がわかった。 NISサーバーもNISクライアントもホスト名が `localhost.localdomain` になっていて、混同されていたようです。 CentOS6.3 はインストーラーがバグっているみたいで、インストール時にホスト名に何を入力しても、結局 `localhost.localdomain` になってしまう。 (RHELのインストーラーは大丈夫です。) で、そのままほったらかしにして、サーバー側もクライアント側も `localhost.localdomain` でかぶっていると `yppasswd` が動きません。 ホスト名は `/etc/sysconfig/network` で HOSTNAME=<ホスト名> で設定できるので、ここで NISサーバーとNISクライアントに別々の名前をつけてあげましょう。 例えば、 `HOSTNAME=my.nisserver` というホスト名にしたとする。 そして、もう一回 # /usr/lib/yp/ypinit -m としてあげると next host to add: my.nisserver next host to add: のように 今つけた、NIS サーバー名が入っている。 そして、クライアント側の `/etc/hosts` に 192.168.11.5 my.nisserver のように NIS サーバーのIPアドレスとの対応を書いておけば `yppasswd` がうまくいきます。 以上が、RHEL/CentOSの場合のやり方です。 ### Ubuntu編 Ubuntu 12.04LTS でのやり方も簡単にまとめておきます。 Ubuntu の場合、サーバーもクライアントも $ sudo apt-get install nis でインストールします。 インストール途中で NISドメインを聞かれると思いますので適当なドメイン名を入れます。 このNISドメイン名は `/etc/defaultdomain` に書き込まれます。 NISサーバー側は `/etc/default/nis` という設定ファイルを開いて NISSERVER=false という行を NISSERVER=master に変更します。 ypserv サービスを起動し $ sudo /usr/lib/yp/ypinit -m でデータベース作成します。 NISクライアント側は `/etc/yp.conf` を編集して domain
server
という設定を記載します。 `/etc/nsswitch.conf` を開き passwd: compat shadow: compat group: compat のようになっている部分を passwd: nis compat shadow: nis compat group: nis compat のように変更。 ypbind サービスを起動します。 なお、Ubuntu 12.04 ではデスクトップマネジャーが lightdm になっていて、ローカルに存在するアカウント名しか選択できないようになっております。 そのままでは任意のアカウント名が入力できないので NISで管理しているアカウント名を入力ができないことになります。 そこで、以下のように入力します。 $ /usr/lib/lightdm/lightdm-set-defaults -m true ログイン画面に「ログイン」という項目が出てきて、任意のアカウント名が入力ができるようになります。
2012年12月15日土曜日
標準エラー出力をファイルに落としたい (teeの標準エラー出力版)
`tee` というコマンドがあります。 「標準入力から読んだ内容を標準出力とファイルに書きだす」というものです。 例えば、 $ foo | tee logfile とすると、 `foo` コマンドの標準出力は、 `logfile` に書き出されます。 なおかつ、標準出力は標準出力として、標準エラー出力は標準エラー出力として出力されます。 ログを記録するときには便利なコマンドですね。 そこで思ったのは、 `tee` コマンドの標準エラー版に相当するものを実現できないかと思いました。 コンパイルのときの warning とかは通常、標準エラー出力へ出てきます。 標準エラー出力をファイルに記録しておいて、 warning を潰していくのに使いたいのです。 で、考えたシェルスクリプトが以下です。 #!/bin/sh exec 3>&1 foo 2>&1 >&3 3>&- | tee logfile >&2 `foo` コマンドの標準エラー出力を `logfile` に書き出します。 なおかつ、標準出力は標準出力として、標準エラー出力は標準エラー出力として出力されます。 `m>&n` は 「`n` 番の出力先と同じものを `m` 番へコピーする (`dup2` する)」という意味です。 `m>&-` は 「`m` 番を閉じる」という意味です。 また、 `exec` は引数にコマンドが与えられていない場合、リダイレクト処理はカレントシェルで効果を表します。 つまり、上記のスクリプトは、 `foo` コマンドの標準出力と標準エラー出力を入れ替えて、 パイプに流し、さらに `tee` コマンドの標準出力(= `foo` コマンドの標準エラー出力) を標準エラー出力に戻す、ということをしています。 (後日、bash なら `foo |& tee logfile >&2` のように簡単に書けることを知った。。) さらに、 `foo` が異常終了した場合に、即座にシェルスクリプトを止めたいときは、以下のようにします。 パイプに渡してしまうと、そのままでは終了ステータスを取れませんので、ちょっと複雑になっております。。 #!/bin/sh exec 3>&1 status=$({ { foo 2>&1 >&3 3>&- 4>&-; echo $? 1>&4 3>&- 4>&-;} | tee log >&2 3>&- 4>&- ;} 4>&1) if [ "$status" != "0" ]; then set -e /bin/false fi bash の `$PIPESTATUS` の実現方法は[こちらのページ](http://x68000.q-e-d.net/~68user/unix/pickup?%A5%EA%A5%C0%A5%A4%A5%EC%A5%AF%A5%C8)で勉強させていただきました。
2012年12月4日火曜日
シェルで四則演算
### 方法1 ### 16進数は使えません。 $ expr 1 + 1 2 $ expr 0x10 + 0x0F expr: 整数でない引数 ### 方法2 ### 16進数も使える。 $ echo $(( 1 + 1 )) 2 $ echo $(( 0x10 + 0x0F )) 31 ### 方法3 ### bashの場合は以下も可。 $ echo $[ 1 + 1 ] 2 $ echo $[ 0x10 + 0x0F ] 31 ### 方法4 ### bash の場合、以下のようなこともできるらしい。 $ i=0 $ echo $i 0 $ ((i++)) $ echo $i 1
新しい投稿
前の投稿
ホーム
登録:
投稿 (Atom)