LoginSignup
41
41

More than 5 years have passed since last update.

SSHをLDAP公開鍵認証 + TOTP(Google Authenticator)の多要素認証にする

Posted at

環境

  • CentOS 6.5

Overview

SSHを多要素認証にしたい。
公開鍵認証が端末の紛失などによって突破された場合の保険としてTOTP(Time-Based One Time password)のGoogle Authenticator認証を追加する。

Requirements

  • pam_google_authenticator
  • pam_ldap

Install

  • 依存パッケージのインストール
yum install openldap-clients nss-pam-ldapd pam_ldap openssh-ldap
tar jxf libpam-google-authenticator-1.0-source.tar.bz2
cd libpam-google-authenticator-1.0
make && make install
  • LDAPクライアントの設定
/etc/pam_ldap.conf
authconfig-tui

・ユーザ情報
「LDAPを使用」にチェック
・認証
「シャドウパスワードを使用」
「LDAP認証を使用」
「ローカル認証は十分です」
にチェック
・LDAP設定
「サーバー」「baseDN」を入力しOKを押す。
/etc/ssh/ldap.conf
uri ldap://210.129.173.120/
base dc=tako,dc=asia
# host 210.129.173.120
binddn cn=Directory Manager
bindpw password

ssl no
  • PAMの設定

/etc/pam.d/sshd

/etc/pam.d/sshd
#%PAM-1.0
auth       required     pam_sepermit.so
auth       required     pam_google_authenticator.so
# auth       include      password-auth

account    required     pam_nologin.so
account    include      password-auth
password   include      password-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open env_params
session    optional     pam_keyinit.so force revoke
session    include      password-auth
session     required      pam_mkhomedir.so skel=/etc/skel umask=0022

auth required pam_google_authenticator.soを追記します。
ここでauth include password-authをコメントアウトし無効にするのがポイントです。これをしないとパスワードログインが有効であると認識されます。

/etc/pam.d/system-auth

/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

/etc/pam.d/password-auth

/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
  • sshd_configの設定

以下の項目を設定する。

RSAAuthentication yes
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication yes

RequiredAuthentications2 publickey,keyboard-interactive

AuthorizedKeysCommand  /usr/libexec/openssh/ssh-ldap-wrapper
AuthorizedKeysCommandRunAs nobody

UsePAM yes

解説: RequiredAuthentications2はRHEL系のOpenSSHのみ有効。
Debian系はOpenSSH6.2以上で同じ意味のAuthenticationMethodsが使える。
RequiredAuthentications2 publickey,keyboard-interactiveで認証方法を2つ指定している。

  • LDAP用のスキーマをインポートする
/usr/share/doc/openssh-ldap-5.3p1/openssh-lpk-openldap.schema
attributetype ( 1.3.6.1.4.1.24552.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.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
        DESC 'MANDATORY: OpenSSH LPK objectclass'
        MUST ( sshPublicKey $ uid )
        )
  • LDAPに公開鍵を登録。
dn: uid=test,ou=people,dc=tako,dc=asia
givenName: test
objectClass: person
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: posixAccount
objectClass: top
objectClass: ldapPublicKey
uid: test
cn: test
sn: user
userPassword:: e1NTSEF9VjlzaDEvd1pmQ0Z0Vjc1NGdGZGdKN2tlNitFNk9PRDJUTnRWcHc9PQ=
 =
homeDirectory: /home/test
sshPublicKey: ssh-rsa ...... hoge@localhost
uidNumber: 100
gidNumber: 500

上記の/etc/ssh/sshd_configで設定した

AuthorizedKeysCommand  /usr/libexec/openssh/ssh-ldap-wrapper


実際にLDAPサーバを検索するときにかけるフィルタは

(&(objectClass=posixAccount)(objectClass=ldapPublicKey))

なのでこの2つのオブジェクトクラスが必要。openssh-ldapを使わない場合はAuthorizedKetsCommandにLDAPサーバを検索して公開鍵を返すスクリプト、例えば以下のようなスクリプトで検索し、posixAccountクラスは不要。

#!/bin/bash

uri=ldap://127.0.0.1/
binddn="cn=Directory Manager"
bindpw=password
base="dc=example,dc=com"
uid=$1

/usr/bin/ldapsearch -LLL -H ${uri} -w "${bindpw}" -D "${binddn}" -b "${base}" "(& (objectClass=ldapPublicKey) (uid=${uid}))" "sshPublicKey" | tail -n +2 | sed -e "s/sshPublicKey\: //g" | sed -e 's/^[ ]*//g' | awk '{printf $0}'
  • アカウント情報を引けるか確認
[root@hoge]# id test
uid=100(test) gid=500(vagrant) groups=500(vagrant)

引けない場合は/etc/pam_ldap.confにある設定が正しいか確認。

  • ユーザを作成
adduser test
  • google-authenticator用のシークレットファイルを作る
$ su - test
$ google-authenticator -t -D -f -u -W
バーコードのURLが表示されるのでブラウザで開き、iPhoneまたはAndroidの「Google Authenticator」で検索して出てくるアプリで読み取ってtokenを登録する
  • 確認
$ ssh example.com -l test
Authenticated with partial success.
Verification code: <<Google AuthenticatorのOTPを入力>>

ここにモバイル端末のGoogle Authenticatorアプリで表示されているワンタイムパスワードを入力し、無事ログイン出来れば完了です。

参照: OpenSSH 6.2を使って公開鍵認証もLDAPで行いたい。 - Qiita

41
41
0

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
41
41