28
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

LDAPでsudoを一元管理する

Last updated at Posted at 2014-11-04

=====================

環境

  • CentOS 6.5
  • OpenLDAP

Overview

まともに管理すると煩雑になりがちなsudoをLDAPで一元的に管理したい。

Installation

with Ansible

インストール手順は全てplaybook化してあります。

$ git clone git@github.com:shufo/ansible-sudo-ldap.git
$ cd ansible-sudo-ldap
$ vagrant up

でVagrant仮想マシン上に以下の手動でのインストール手順を再現したOpenLDAP+sudoなテスト環境が出来ます。(要Ansible, Vagrant)

立ち上がったら

$ vagrant ssh
[vagrant@vagrant ~]$ sudo su
[root@vagrant ~]$ su - test
[test@vagrant ~]$ sudo cat /var/log/secure 
"Enter [test]'s Password:" password

で動作確認出来ます。

リモートに構築する場合はansible_hostsファイルを編集し

default ansible_ssh_host=127.0.0.1 ansible_ssh_port=22

playbookを直接実行してください。

ansible-playbook site.yml -i ansible_hosts

クライアント側のみ構築する場合はtasks/main.ymlのLDAPサーバ側用のタスクをコメントアウトしてください。

---
# - include: server.yml
- include: client.yml

手動

LDAPサーバ設定

  • OpenLDAP、依存パッケージのインストール

    yum install openldap openldap-servers openldap-clients pam_ldap 
    
  • LDAPディレクトリ初期化

mkdir /var/lib/ldap
chown ldap:ldap /var/lib/ldap
rm -fR /etc/openldap/slapd.d/*


- 設定ファイルコピー

  ```bash
cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
cp /usr/share/openldap-servers/slapd.conf.obsolete /etc/openldap/slapd.conf
  • LDAPサーバのrootパスワード生成

/usr/sbin/slappasswd -s password


```/etc/openldap/slapd.conf
# スキーマファイル設定
include /etc/openldap/schema/corba.schema
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/duaconf.schema
include /etc/openldap/schema/dyngroup.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/java.schema
include /etc/openldap/schema/misc.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/openldap.schema
include /etc/openldap/schema/ppolicy.schema
include /etc/openldap/schema/collective.schema

# 接続プロトコル
allow bind_v2

# 管理ファイル
pidfile     /var/run/openldap/slapd.pid
argsfile    /var/run/openldap/slapd.args

# TLS設定
#TLSCACertificatePath  /etc/openldap/ssl/cacert.pem
#TLSCertificateFile    /etc/openldap/ssl/server.crt
#TLSCertificateKeyFile /etc/openldap/ssl/server.key

# userPasswordに関するアクセス権
access to attrs=userPassword
    by self write
    by dn="cn=Directory Manager,dc=example,dc=com" write
    by anonymous auth
    by * none

# その他の属性に対するアクセス権
access to *
    by self write
    by dn="cn=Directory Manager,dc=example,dc=com" write
    by * read

# monitorデータベースに対するアクセス権
database monitor
access to *
    by dn.exact="cn=Directory Manager,dc=example,dc=com" read
    by * none

# データベース設定
database    bdb
suffix      "dc=example,dc=com"
checkpoint  1024 15
rootdn      "dc=example,dc=com"
rootpw      {SSHA}jadajsdna〜中略〜hogehoge
directory   /var/lib/ldap

# indexの設定
index objectClass                       eq,pres
index ou,cn,mail,surname,givenname      eq,pres,sub
index uidNumber,gidNumber,loginShell    eq,pres
index uid,memberUid                     eq,pres,sub
index nisMapName,nisMapEntry            eq,pres,sub

  • LDAPサーバにsudo用のschemaを読みこませる

    schema.OpenLDAPをスキーマに追加。

    cp /usr/share/doc/sudo-1.8.6p3/schema.OpenLDAP /etc/openldap/schema/sudo.schema
    

    /etc/openldap/slapd.confに

    /etc/openldap/slapd.conf
    include /etc/openldap/schema/sudo.schema
    

    を追加。

  • openldapを起動

    service slapd start
    
  • エントリを作成する

    ベースになるエントリを作成します。

    add_ou.ldif
    dn: dc=example,dc=com
    objectClass: dcObject
    objectClass: organization
    dc: example
    o: example
    
    dn: ou=people,dc=example,dc=com
    objectClass: organizationalUnit
    ou: people
    
    dn: ou=groups,dc=example,dc=com
    objectClass: organizationalUnit
    ou: groups
    
    ldapadd -D "cn=Directory Manager,dc=example,dc=com" -w password -f add_ou.ldif
    
  • ユーザを作成する

    サンプルとしてtestユーザを作成する。

    add_user.ldif
    dn: uid=test,ou=people,dc=example,dc=com
    

objectClass: account
objectClass: posixAccount
uid: test
cn: test
userPassword: {SSHA}hogehoge〜中略〜
loginShell: /bin/bash
uidNumber: 1000
gidNumber: 1000
homeDirectory: /home/test


`posixAccount`クラスの必須属性は`loginShell`、`uidNumber`、`gidNumber`、`homeDirectory`なのでこの4つは最低限含める必要があります。

```bash
ldapadd -D "cn=Directory Manager,dc=example,dc=com" -w password -f add_user.ldif
  • グループを作成する

    サンプルとしてmembersグループを作成する。

    add_group.ldif
    dn: cn=members,ou=groups,dc=example,dc=com
    objectClass: top
    cn: members
    objectClass: posixGroup
    gidNumber: 1000
    
    ldapadd -D "cn=Directory Manager,dc=example,dc=com" -w password -f add_group.ldif
    
  • sudoers用ouを作成する

    vim sudoersOU.ldif
    
    sudoersOU.ldif
    dn: ou=SUDOers,dc=example,dc=com
    description: SUDOers
    objectClass: organizationalUnit
    objectClass: top
    ou: SUDOers
    
    ldapadd -x -D "cn=Directory Manager,dc=example,dc=com" -w password -f sudoersOU.ldif
    
  • /etc/sudoersを編集する

    [root@agenttest user.0]# cat /etc/sudoers | grep -v "^#" | grep -v "^\s*$"
    

Cmnd_Alias FILE_READ = /bin/cat, /bin/more, /usr/bin/tail
Cmnd_Alias SERVICE = /sbin/service
Cmnd_Alias NETWORK_LOOKUP = /bin/ping, /bin/netstat, /usr/bin/nslookup
Cmnd_Alias DELEGATING = /bin/chown, /bin/chmod, /bin/chgrp
Defaults !visiblepw
Defaults always_set_home
Defaults env_reset
Defaults env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
Defaults env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
Defaults !root_sudo
Defaults !lecture
Defaults log_host
Defaults log_year
Defaults logfile=/var/log/sudo.log
Defaults ignore_dot
Defaults ignore_local_sudoers
Defaults timestamp_timeout=0
Defaults passprompt="Enter [%u]'s Password:"
Defaults badpass_message="The password is not corresponding. Try again."
Defaults insults
Defaults secure_path=/sbin:/bin:/usr/sbin:/usr/bin
root ALL=(ALL) ALL
%members ALL=(ALL) FILE_READ
%wheel ALL=NOPASSWD: ALL


解説: `Cmnd_Alias`で定義したコマンドの集まりを各グループに対して割り当てている。
`%members       ALL=(ALL) FILE_READ`で`members`グループに`FILE_READ`で定義した`/bin/cat, /bin/more, /usr/bin/tail`コマンドの実行を許可している。`members`グループのユーザに対して`ALL`(全て)のホストから`ALL`(任意)のユーザ権限で`FILE_READ`で定義したコマンドが実行可能という意味。`less`ではなく`more`を許可しているのは`less`は`:!/bin/bash`とless内でコマンドを実行することでrootのシェルを取得出来るから。
`!root_sudo`でrootでのsudoを禁止、`!lecture`で最初にでる説明を非表示、`ignore_local_sudoers`でLDAP参照のみにしてローカルの/etc/sudoersを無視するようにしている。


- `sudoers2ldif`でldifファイルに変換する

```bash
export SUDOERS_BASE=ou=SUDOers,dc=example,dc=com
cat /etc/sudoers | perl /usr/share/doc/sudo-1.8.6p3/sudoers2ldif > sudoers.ldif
sudoers.ldif
dn: cn=defaults,ou=SUDOers,dc=example,dc=com
objectClass: top
objectClass: sudoRole
cn: defaults
description: Default sudoOption's go here
sudoOption: !visiblepw
  sudoOption: always_set_home
sudoOption: env_reset
sudoOption: env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
sudoOption: env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
sudoOption: env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
sudoOption: env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
sudoOption: env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
sudoOption: !root_sudo
sudoOption: !lecture
sudoOption: log_host
sudoOption: log_year
sudoOption: logfile=/var/log/sudo.log
sudoOption: ignore_dot
sudoOption: ignore_local_sudoers
sudoOption: timestamp_timeout=0
sudoOption: passprompt="Enter [%u]'s Password:"
sudoOption: badpass_message="The password is not corresponding. Try again."
sudoOption: secure_path=/sbin:/bin:/usr/sbin:/usr/bin
  
〜中略〜
  • LDIFをインポートする

    sudoers2ldifで変換したLDIFをインポートする

    ldapadd -x -D "cn=Directory Manager,dc=example,dc=com" -w password -f sudoers.ldif
    

LDAPクライアント側設定

  • 依存パッケージのインストール
yum install openldap-clients nss-pam-ldapd pam_ldap openssh-ldap authconfig
  • 認証周りをauthconfigで設定
# LDAPによるユーザ情報参照を有効にする
authconfig --enableldap --update
# LDAPによる認証を有効にする
authconfig --enableldapauth --update
# ユーザのホームディレクトリの自動作成を有効にする
authconfig --enablemkhomedir --update
# shadowパスワードの使用を有効にする
authconfig --enableshadow --update  
# local認証を有効にする
authconfig --enablelocauthorize --update
# LDAPサーバのURIを指定
authconfig --ldapserver=ldap://127.0.0.1:389 --update
# LDAPサーバのベースDNを指定
authconfig --ldapbasedn=dc=example,dc=com --update 

以上のコマンドを実行した結果のPAMの設定は以下です。

/etc/pam.d/system-auth
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 500 quiet
auth        sufficient    pam_ldap.so use_first_pass
auth        required      pam_deny.so

account     required      pam_unix.so broken_shadow
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 500 quiet
account     [default=bad success=ok user_unknown=ignore] pam_ldap.so
account     required      pam_permit.so

password    requisite     pam_cracklib.so try_first_pass retry=3 type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    sufficient    pam_ldap.so use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
session     optional      pam_mkhomedir.so skel=/etc/skel umask=077
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
session     optional      pam_ldap.so

pam_mkhomedirモジュールを有効にしているのでユーザのホームディレクトリが存在しない場合自動的に作られます。自動削除はされないので必要なくなったら削除しましょう。

/etc/pam.d/password-auth
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 500 quiet
auth        sufficient    pam_ldap.so use_first_pass
auth        required      pam_deny.so

account     required      pam_unix.so broken_shadow
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 500 quiet
account     [default=bad success=ok user_unknown=ignore] pam_ldap.so
account     required      pam_permit.so

password    requisite     pam_cracklib.so try_first_pass retry=3 type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    sufficient    pam_ldap.so use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
session     optional      pam_mkhomedir.so skel=/etc/skel umask=077
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
session     optional      pam_ldap.so
  • sudo-ldapの設定

sudo-ldap.confauthconfigでは設定出来ないので手動で設定します。

[root@localhost]# sudo -V
ldap.conf path: /etc/sudo-ldap.conf

[root@localhost ]# cat /etc/sudo-ldap.conf  | grep -v "^#" | grep -v "^\s*$"
binddn cn=Directory Manager
bindpw password
uri ldap://127.0.0.1:389
sudoers_base ou=SUDOers,dc=example,dc=com
sudoers_debug 1
  • sudoersの参照先をldapに切り替え
[root@localhost]# cat /etc/nsswitch.conf | grep sudoers
sudoers:	ldap files
  • 確認

他ユーザにsuして確認してみる。

[root@localhost]# su - test
[shufo@localhost ~]$ sudo cat /var/log/secure 
sudo: ldap_set_option: debug -> 0
sudo: ldap_set_option: ldap_version -> 3
sudo: ldap_sasl_bind_s() ok
sudo: Looking for cn=defaults: cn=defaults
sudo: found:cn=defaults,ou=SUDOers,dc=example,dc=com
sudo: ldap search '(|(sudoUser=test)(sudoUser=%test)(sudoUser=%#501)(sudoUser=ALL))'
sudo: searching from base 'ou=SUDOers,dc=example,dc=com'
sudo: adding search result
sudo: result now has 0 entries
sudo: ldap search '(sudoUser=+*)'
sudo: searching from base 'ou=SUDOers,dc=example,dc=com'
sudo: adding search result
sudo: result now has 0 entries
sudo: sorting remaining 0 entries
sudo: searching LDAP for sudoers entries
sudo: done with LDAP searches
sudo: user_matches=1
sudo: host_matches=0
sudo: sudo_ldap_lookup(0)=0x40
Enter [test]'s Password: [パスワード入力]
test is not allowed to run sudo on localhost.  This incident will be reported.

LDAPサーバに問い合わせされているのがログから分かる。
実際に問い合わせているクエリはbaseDNのou=SUDOers,dc=example,dc=com(|(sudoUser=shufo)(sudoUser=%shufo)(sudoUser=%#501)(sudoUser=ALL))で検索している。

28
26
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?