Linux-PAM
PAMについて調べたことのまとめ。内容については十分確認してないのでもしかしたら見当違いな事を書いてるかもしれない。
PAMとは
- Pluggable Authentication Module
- 認証処理を行うモジュール群とそれを利用するためのAPIからなるユーザー認証システム
- http://www.linux-pam.org/ のドキュメントでは認証処理を行うモジュールをLinux-PAM Module、APIを利用するアプリケーションをLinux-PAM Applicationと呼んでいる
モジュールの例
Chapter 6. A reference guide for available modules
pam_time
/etc/security/time.confの記述に従って、時間帯によるログインの制限ができる
pam_nologin
root以外のログインを禁止する
pam_permit
常に許可する
pam_mount
ログイン時に自動でマウントする
暗号化したホームディレクトリのマウントなどに使える
アプリケーションの例
- sudo
- login
PAMの動作
/etc/pam.d/*に各Applicationがどのようにモジュールを利用するかを記述したファイルが存在する
Linuxの各アプリケーションが共通して利用する「PAM認証」についてやhttps://www.freebsd.org/doc/en/articles/pam/pam-essentials.htmlが分かりやすい
% ls /etc/pam.d/ accountsservice cron newusers chfn cups-daemon other chpasswd gnome-screensaver passwd chsh lightdm polkit-1 common-account lightdm-autologin ppp common-auth lightdm-greeter samba common-password lightdm-remote-freerdp su common-session lightdm-remote-uccsconfigure sudo common-session-noninteractive login % cat /etc/pam.d/login # # The PAM configuration file for the Shadow `login' service # # Enforce a minimal delay in case of failure (in microseconds). # (Replaces the `FAIL_DELAY' setting from login.defs) # Note that other modules may require another minimal delay. (for example, # to disable any delay, you should add the nodelay option to pam_unix) auth optional pam_faildelay.so delay=3000000 # Outputs an issue file prior to each login prompt (Replaces the # ISSUE_FILE option from login.defs). Uncomment for use # auth required pam_issue.so issue=/etc/issue # Disallows root logins except on tty's listed in /etc/securetty # (Replaces the `CONSOLE' setting from login.defs) # # With the default control of this module: # [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die] # root will not be prompted for a password on insecure lines. # if an invalid username is entered, a password is prompted (but login # will eventually be rejected) # # You can change it to a "requisite" module if you think root may mis-type # her login and should not be prompted for a password in that case. But # this will leave the system as vulnerable to user enumeration attacks. # # You can change it to a "required" module if you think it permits to # guess valid user names of your system (invalid user names are considered # as possibly being root on insecure lines), but root passwords may be # communicated over insecure lines. auth [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die] pam_securetty.so # Disallows other than root logins when /etc/nologin exists # (Replaces the `NOLOGINS_FILE' option from login.defs) auth requisite pam_nologin.so # SELinux needs to be the first session rule. This ensures that any # lingering context has been cleared. Without out this it is possible # that a module could execute code in the wrong domain. # When the module is present, "required" would be sufficient (When SELinux # is disabled, this returns success.) session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close # This module parses environment configuration file(s) # and also allows you to use an extended config # file /etc/security/pam_env.conf. # # parsing /etc/environment needs "readenv=1" session required pam_env.so readenv=1 # locale variables are also kept into /etc/default/locale in etch # reading this file *in addition to /etc/environment* does not hurt session required pam_env.so readenv=1 envfile=/etc/default/locale # Standard Un*x authentication. @include common-auth # This allows certain extra groups to be granted to a user # based on things like time of day, tty, service, and user. # Please edit /etc/security/group.conf to fit your needs # (Replaces the `CONSOLE_GROUPS' option in login.defs) auth optional pam_group.so # Uncomment and edit /etc/security/time.conf if you need to set # time restrainst on logins. # (Replaces the `PORTTIME_CHECKS_ENAB' option from login.defs # as well as /etc/porttime) # account requisite pam_time.so # Uncomment and edit /etc/security/access.conf if you need to # set access limits. # (Replaces /etc/login.access file) # account required pam_access.so # Sets up user limits according to /etc/security/limits.conf # (Replaces the use of /etc/limits in old login) session required pam_limits.so # Prints the last login info upon succesful login # (Replaces the `LASTLOG_ENAB' option from login.defs) session optional pam_lastlog.so # Prints the message of the day upon succesful login. # (Replaces the `MOTD_FILE' option in login.defs) # This includes a dynamically generated part from /run/motd.dynamic # and a static (admin-editable) part from /etc/motd. session optional pam_motd.so motd=/run/motd.dynamic noupdate session optional pam_motd.so # Prints the status of the user's mailbox upon succesful login # (Replaces the `MAIL_CHECK_ENAB' option from login.defs). # # This also defines the MAIL environment variable # However, userdel also needs MAIL_DIR and MAIL_FILE variables # in /etc/login.defs to make sure that removing a user # also removes the user's mail spool file. # See comments in /etc/login.defs session optional pam_mail.so standard # Standard Un*x account and session @include common-account @include common-session @include common-password # SELinux needs to intervene at login time to ensure that the process # starts in the proper default security context. Only sessions which are # intended to run in the user's context should be run after this. session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open # When the module is present, "required" would be sufficient (When SELinux # is disabled, this returns success.)
Programming
- 認証の情報はpam_handle_t型(へのポインタ)のpamhが持っている
- Application側もModule側もpam_set_itemやpam_get_itemで必要な情報をsetしたりgetしたりする
- struct pam_convにApplicationとModuleが直接やりとりするためのcallback関数を設定する
モジュールを書く
The Linux-PAM Module Writers' Guide
コードはlinux-pam.gitのmodules(特にpam_permitは単純)やSample PAM Moduleを参考にすればいいと思う
- pam_get_user
- PAM_USERか、PAM_USERがNULLならプロンプトを出してユーザー名を取得する
アプリケーションを書く
The Linux-PAM Application Developers' Guide
Sample PAM Applicationやsudoのソースコードのplugins/sudoers/auth/pam.c、loginのソースコードのlogin.cが参考になると思う
sudoやloginのソースコードの取得はUbuntuなら`apt-get source sudo(またはlogin)`とすればいいはず
- pam_chauthtok
authentication token(パスワードとか)の変更 - pam_open_session
認証に成功したユーザーのセッションの開始時に呼び出す。pam_close_sessionをあとで呼び出すべきである。 - pam_close_session
セッション終了時に呼び出す。 - pam_acct_mgmt
パスワードの期限切れ、アカウントの期限切れなどを調べてユーザーアカウントが有効かどうかを判定する
It is typically called after the user has been authenticated. - pam_setcred
It should be called to set the credentials after a user has been authenticated and before a session is opened for the user (with pam_open_session(3)). - pam_authenticate
ユーザーの認証 - pam_fail_delay
pam_authenticateが認証に失敗した時にアプリケーションに制御を返すまでの時間を設定する - pam_start
初期化
第一引数service_nameが/etc/pam.d/に対応する - pam_end
- pam_strerror
エラーコードを説明する文字列
モジュールで実装する関数とAPIの対応
Application側API | Module側 |
pam_authenticate | pam_sm_authenticate |
pam_setcred | pam_sm_setcred |
pam_acct_mgmt | pam_sm_acct_mgmt |
pam_open_session | pam_sm_open_session |
pam_close_session | pam_sm_close_session |
pam_chauthtok | pam_sm_chauthtok |
呼び出す順序は3.4. Transactionsが詳しい