/etc/sudoers を LDAP で管理する

Posted by Gosuke Miyashita Sat, 30 Dec 2006 16:12:47 GMT

/etc/sudoers を LDAP で一元管理とかできないのかなぁ、と思っていたら、ちゃんと対応してた

利用方法はわりと簡単で、上記リンクの README.LDAP (ソースに同じものが同梱されてる)を見ればすぐわかるけど、一応ここにやったことをメモ。ほとんど README からの抜粋です。

手元の Slackware に元から入っている sudo は LDAP 対応していないので、ここからダウンロード して以下の手順でインストール。

$ ./configure --with-ldap
$ make
$ sudo make install

でもって /etc/ldap.conf に以下の記述を追加。(元々 LDAP は利用していて、基本的な設定はできているので、追加は一行だけ。)

sudoers_base   ou=SUDOers,o=southpark

LDAP 側の設定はまずスキーマの追加。

  #
  #  schema file for sudo
  #

  attributetype ( 1.3.6.1.4.1.15953.9.1.1
        NAME 'sudoUser'
        DESC 'User(s) who may  run sudo'
        EQUALITY caseExactIA5Match
        SUBSTR caseExactIA5SubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

  attributetype ( 1.3.6.1.4.1.15953.9.1.2
        NAME 'sudoHost'
        DESC 'Host(s) who may run sudo'
        EQUALITY caseExactIA5Match
        SUBSTR caseExactIA5SubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

  attributetype ( 1.3.6.1.4.1.15953.9.1.3
        NAME 'sudoCommand'
        DESC 'Command(s) to be executed by sudo'
        EQUALITY caseExactIA5Match
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

  attributetype ( 1.3.6.1.4.1.15953.9.1.4
        NAME 'sudoRunAs'
        DESC 'User(s) impersonated by sudo'
        EQUALITY caseExactIA5Match
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

  attributetype ( 1.3.6.1.4.1.15953.9.1.5
        NAME 'sudoOption'
        DESC 'Options(s) followed by sudo'
        EQUALITY caseExactIA5Match
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

  objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL
        DESC 'Sudoer Entries'
        MUST ( cn )
        MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoOption $
              description )
        )

次に sudoers 用のコンテナ ou=SUDOers, o=southpark と、デフォルト設定用の cn=defaults, ou=SUDOers, o=southpark を LDAP エントリに追加。

dn: ou=SUDOers,o=southpark
objectclass: organizationalunit
ou: SUDOers

dn: cn=defaults,ou=SUDOers,o=southpark
objectclass: top
objectclass: sudorole
cn: defaults
sudoOption: ignore_local_sudoers

sudoOption: ignore_local_sudoers があると、/etc/sudoers ファイルを見なくなる。

最後に sudo 用 role エントリを追加して準備 OK。

dn: cn=role1,ou=SUDOers,o=southpark
changetype: add
objectclass: top
objectclass: sudorole
cn: role1
sudouser: miya
sudohost: ALL
sudocommand: ALL

sudouser, sudohost, sudocommand は複数設定可。! で否定になる。なので、特定のユーザだけ許可しない、という場合には、

sudouser: ALL
sudouser: !miya

なんて書き方もできる。同様に特定のホストだけ許可しない、という場合には、

sudohost: ALL
sudohost: !kenny

とかできるし、特定のコマンドだけ許可しない、という場合には、

sudocommand: ALL
sudocommand: !/sbin/reboot

とかできる。もちろんこれらの組み合わせも OK。

あと、ユーザではなくグループで指定したい場合には

sudouser: %group

とする。(これは README.LDAP には明記されてない。/etc/sudoers の書き方から類推すればわかるけど。)

OpenSSH の公開鍵を LDAP で管理

Posted by Gosuke Miyashita Thu, 28 Dec 2006 15:49:08 GMT

OpenSSH LDAP Public key patch を試してみたのでメモ。(略して lpk patch とか言うらしい。)

SSH で公開鍵認証を行う場合、通常はホームディレクトリの .ssh/authorized_keys を参照しますが、このパッチを適用すると、authrized_keys の代わりに LDAP データベース内のユーザエントリが持つ sshPublicKey 属性を参照して、アクセスを許可するかどうかを判断する、という動作になります。

以下、試した手順です。

インストール

OpenSSH ダウンロードサイト から OpenSSH 本体を入手し、lpk サイト から lpk patch を入手しておきます。

4.3p1-0.3.7 patch が最新のようなので、本体は 4.3p1 をダウンロードしておきます。

入手したら、以下のような感じでインストールします。

$ cd openssh-4.3p1
$ patch < ../openssh-lpk-4.3p1-0.3.7.patch
$ ./configure --with-ldap
$ make
$ sudo make install

sshd の設定

/usr/loca/etc/sshd_config に以下のような設定をして、sshd を再起動します。

UseLPK yes
LpkServers ldap://myhost.mydomain.com
LpkUserDN  ou=People,dc=mydomain,dc=com

LDAP スキーマの設定

lpk patch をあてると、 ソースディレクトリに以下のような内容の openssh-lpk.schema がつくられます。

#
# $Id: openssh-lpk-4.3p1-0.3.7.patch,v 1.3 2006/04/18 15:29:09 eau Exp $
#
# LDAP Public Key Patch schema for use with openssh-ldappubkey
# Author: Eric AUGE 
# 
# Based on the proposal of : Mark Ruijter
#


# octetString SYNTAX
attributetype ( 1.3.6.1.4.1.22054.500.1.1.1.13 NAME 'sshPublicKey' 
	DESC 'MANDATORY: OpenSSH Public key' 
	EQUALITY octetStringMatch
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )

# printableString SYNTAX yes|no
objectclass ( 1.3.6.1.4.1.22054.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
	DESC 'MANDATORY: OpenSSH LPK objectclass'
	MUST ( sshPublicKey $ uid ) 
	)

OpenLDAP であればこいつを /etc/openldap/schema の下にでも置いて、slapd.conf で include してやれば OK でしょう。

Sun のやつであれば config/schema/99user.ldif あたりに以下の記述を追加すれば OK。

objectclasses: ( 1.3.6.1.4.1.22054.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY DESC 'MANDATORY: OpenSSH LPK objectclass' MUST ( sshPublicKey $ uid ) )
attributetypes: ( 1.3.6.1.4.1.22054.500.1.1.1.13 NAME 'sshPublicKey' DESC 'MANDATORY: OpenSSH Public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )

LDAP ユーザエントリへの公開鍵追加

最後に LDAP のユーザエントリへ公開鍵を登録します。以下のような LDIF をつくって ldapmodify で反映させてやれば OK。

dn: uid=xxx, ou=people, o=southpark
changetype: modify
add: objectclass
objectclass: ldapPublicKey
-
add: sshPublicKey
sshPublicKey: ssh-rsa
 AAAAB3NzaC1yc2EAAAABJQAAAIB3dsrwqXqD7E4zYYrxwdDKBUQxKMioXy9pxFVai64kAPxjU9KS
 qIo7QfkjslfsjflksjfldfkjsldfjLX/5zkzRmT28I5piGzunPv17S89z8XwSsuAoR1t86t+5dlI
 7eZE/gVbn2UQkQq7+kdDTS2yXV6VnC52N/kKLG3ciBkBAw== General Purpose RSA Key

これで公開鍵認証ができるようになります。

lpk patch をあてるとソースディレクトリに以下のドキュメントがつくられますので、詳細はこれらを読むと良いんではないでしょうか。

  • README.lpk
  • lpk-user-example.txt

cfengine メモ #0 - cfengine の構成パターン

Posted by Gosuke Miyashita Tue, 26 Dec 2006 13:55:53 GMT

I, newbie » cfengineによるシステム管理の自動化: その1 を読んで、cfengine よさげだなぁ、ってことで導入を検討することに。

このブログでは、上記エントリで「ややこしいけど魅力的」と書かれている cfengine について、自分なりに試したことや整理したことについてメモしていこうと思います。日本語のドキュメントが少ないですし、実際に手を動かしてみないと理解しにくいものなので、これを使ってみようかな、という方に少しでもお役に立てれば幸いです。

まず、cfengine ってそもそも何?というところですが、上記の I, newbie さんのエントリがわかりやすいので省略。今回は cfengine の構成パターンについて整理してみます。

単一マシンで利用するパターン

http://mizzy.org/img/linux/cfengine00.jpg

単一のマシンで cfengine を実行します。実際にこのパターンで運用することはない(cfengine 使う意味がない)と思いますが、cfengine の動作を理解するためのはじめの一歩として、まずはこのパターンで実行してみると良いです。

cfagent は cfengine に含まれるコマンドラインツールなのですが、以下の様に実行することで、設定情報がなどが書かれた cfagent.conf の内容にしたがって、自身の設定を行います。

# cfagent -f cfagent.conf

クライアント主導パターン

http://mizzy.org/img/linux/cfengine01.jpg

cfengine サーバ(設定情報を一元管理するサーバ)と cfengine クライアント(cfengine による管理対象サーバ)の2種類によって構成されます。今度は新しく cfserved というものが出てきましたが、これも cfengine に含まれているプログラムでデーモンとして常駐し、cfengine クライアントに cfagent.conf や他のファイルなどを提供したり、他のホストから cfagent を起動するリクエストを受け付けたり(これについては後述)します。

動作の流れは次のようになります。

  1. cfengine クライアントは cfengine サーバから最新の cfagent.conf を取得する。(どのサーバから取得するか、どのファイルを取得するか、といった情報が update.conf に記述されている。)
  2. cfengine クライアントは取得した cfagent.conf の内容にしたがって、自身の設定を行う。

この様に、最新の cfagent.conf の取得と実行は、クライアントサイド主導で行われますので、このパターンを「クライアント主導パターン」としています。実際の運用では、cron で定期的に実行することになるかと思います。

サーバ主導パターン

http://mizzy.org/img/linux/cfengine02.jpg

このパターンもサーバ/クライアント構成になっていますが、クライアント主導パターンと違うのは、クライアント側でも cfservd が動いていることと、サーバ側で cfrun というコマンドを実行していることです。cfrun も cfengine に含まれるコマンドラインツールで、リモートの cfserved に対して、cfagent を実行するようリクエストを出します。

このパターンでの動作の流れは次のようになります。

  1. サーバ側で cfagent.conf の更新をトリガーに cfrun を実行して、クライアントの cfagent をキックする。
  2. キックされた cfagent が cfagent.conf を取得し、その内容にしたがって自身の設定を行う。

何百とサーバがある環境だと、クライアントがサーバにアクセスする負荷もバカにならないので、クライアント主導型の様に、何も変更がないのに cron で定期的に実行するのも無駄ですし、一気にアクセスがこないように cron のスケジューリングを調整するのも面倒ですよね。そういった場合にはこのパターンが適しているかと思います。

cfrun は1ホストに対して1回実行というわけではなく、cfrun.hosts というファイルに書かれたホスト全部に対してコマンド一発実行もできますし、一度に起動できるプロセス数もオプションで指定できるので、サーバに一気にアクセスが集中する、ということがないようにコントロールすることも容易です。

以上が cfengine の構成パターンとして代表的なものになります。

次回以降、実際の使い方、注意点、運用上のノウハウなど少しづつ書いていきたいと思います。(まぁ、まだ運用してないので、ノウハウなんかないですが。)