sshのパスワード認証(公開鍵認証ではない) + MFAtoken によるログインの設定方法です。
やりたいことは、クラメソさんのこの記事のパスワード認証版です。
- 検証には、AWSさんから、Amazon Linux AMI 2017.03.1 (HVM), SSD Volume Type (ami-3bd3c45c) を利用しました。
- MFAtoken は Google Authenticator です。
[Note] 本ドキュメントの command枠 のコピペ作業で、動作できるように作っています。(ミスを避けるため vi による編集を避けた)
- pre-conditions
======================================
1.1 Login to the server
AWSの操作は省略します。下記のAMIをつかってサーバを起動しました。
- Amazon Linux AMI 2017.03.1 (ami-3bd3c45c) をつかってEC2を起動します。
- 起動後、サーバーへログインします。
1.2 Chenge timezone (追記: たぶん変更しなくても大丈夫)
Timezoneの設定はこちらを参考にしました。
timezoneファイル差し替え
sudo cp /etc/localtime /etc/localtime.org
sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
&& cat /etc/localtime
reboot後変更したタイムゾーンがUTCにもどらないための設定
sudo cp /etc/sysconfig/clock /etc/sysconfig/clock.org
sudo sh -c "echo -e 'ZONE=\"Asia/Tokyo\"\nUTC=false' > /etc/sysconfig/clock" \
&& cat /etc/sysconfig/clock
1.3 Update packages
sudo yum update
1.4 Installing google/google-authenticator
sudo yum install google-authenticator qrencode-libs -y
- How to setup
===================================================
2.1 Editing sshd_config
/etc/ssh/sshd_config の編集
編集するsshd_configのバックアップをとります.
cp /etc/ssh/sshd_config ${HOME}/_bak_sshd_config
sshd_configが下記になるよう編集します。
PasswordAuthentication は yes
でも no
でもどちらでも大丈夫です。
/etc/pam.d/sshd
の password-auth
を有効にすることでこの設定は関係なく上手く動くようです。
- ChallengeResponseAuthentication
yes
- UsePAM
yes
現状を確認します。
cat /etc/ssh/sshd_config \
| grep -e ^PasswordAuthentication \
-e ^ChallengeResponseAuthentication \
-e ^UsePAM
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes
ここでは ChallengeResponseAuthentication
を yes
になるよう編集する必要があることがわかりましたので、修正します。
BEFORE="ChallengeResponseAuthentication no"
AFTER="ChallengeResponseAuthentication yes"
sudo sed -i s/"${BEFORE}"/"${AFTER}"/g /etc/ssh/sshd_config
再度内容を確認します。
cat /etc/ssh/sshd_config \
| grep -e ^ChallengeResponseAuthentication
ChallengeResponseAuthentication yes
ec2-userは今まで通り公開鍵認証のログインのままとします。
sudo sh -c "cat << EOF >> /etc/ssh/sshd_config
# -- EC2 USER Setting --
Match User ec2-user
AuthenticationMethods publickey
PubkeyAuthentication yes
PasswordAuthentication no
EOF" && tail /etc/ssh/sshd_config
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs serverMatch User ec2-user
# -- EC2 USER Setting --
Match User ec2-user
AuthenticationMethods publickey
PubkeyAuthentication yes
PasswordAuthentication no
sshdの再起動
sshdの再起動します。
sudo service sshd restart
Stopping sshd: [ OK ]
Starting sshd: [ OK ]
2.2 Editing PAM sshd
次にPAMの設定を修正し、sshログイン認証時にGoogle Authenticatorが使われるようにします。
/etc/pam.d/google-authの作成
同じファイル名のファイルがないことを確認します。
ls -l /etc/pam.d/google-auth
ls: cannot access /etc/pam.d/google-auth: No such file or directory
google-authという名前のファイルを作成します。これは /etc/pam.d/sshd
から読み込みます。
sudo sh -c "cat << EOF > /etc/pam.d/google-auth
#%PAM-1.0
auth required pam_env.so
auth sufficient pam_google_authenticator.so nullok
auth requisite pam_succeed_if.so uid >= 500 quiet
auth required pam_deny.so
EOF" && cat /etc/pam.d/google-auth
/etc/pam.d/sshdの編集
編集する /etc/pam.d/sshd
のバックアップをとります.
cp /etc/pam.d/sshd ${HOME}/_bak_pam_sshd
現在の変数の状況を確認します。
cat /etc/pam.d/sshd | grep ^auth
auth required pam_sepermit.so
auth substack password-auth
auth include postlogi
google authentication を有効にするためこのファイルを編集します。
BEFORE="auth substack password-auth"
AFTER="auth substack password-auth\nauth substack google-auth"
sudo sed -i s/"${BEFORE}"/"${AFTER}"/g /etc/pam.d/sshd
もう一度ファイルを確認します。
cat /etc/pam.d/sshd | grep "^auth"
auth required pam_sepermit.so
auth substack password-auth
auth substack google-auth
auth include postlogin
もう一度サービスを再起動します(いらないかも...)
sudo service sshd restart
Stopping sshd: [ OK ]
Starting sshd: [ OK ]
2.3 Creating ".google_authenticator" at first user's login
/etc/profile.d/google-authenticator.shを作成し、root と ec2-user以外のユーザがはじめてログインしたとき、google_authenticatorの初期設定がなされ、ユーザの ${HOME}/.google_authenticator
が強制的に作成されるよう設定します。
同名のファイルがないかを確認します。
ls -l /etc/profile.d/google-authenticator.sh
ls: cannot access /etc/profile.d/google-authenticator.sh: No such file or directory
/etc/profile.d/google-authenticator.sh
を作成します
cat << EOF > google-authenticator.sh
#!/bin/sh
trap 'exit' SIGINT
if [ "\$USER" != "root" -a "\$USER" != "ec2-user" ]; then
if [ ! -f "\$HOME/.google_authenticator" ]; then
echo "setup google-authenticator..."
/usr/bin/google-authenticator -t -d -w 17 -u -f
fi
fi
EOF
sudo cp google-authenticator.sh /etc/profile.d/google-authenticator.sh
sudo chmod +x /etc/profile.d/google-authenticator.sh
cat /etc/profile.d/google-authenticator.sh
-W 17
はもし、/usr/bin/google-authenticator
を直だたきしたあと、4つめの "window" に関する質問 y
で答えると、設定される値です。ここを調整しないとなぜかログインできなかったです。サーバとTokenデバイス間の Time-skew?
- Test
====================
3.1 Creating Test User
サーバー側へのログイン用のユーザを作ります。
/etc/pam.d/google-auth
の設定により、UIDは必ず500以上にする必要があります。
ユーザ名を決定します。
NEWUSER=<'任意のユーザ名'>
ユーザを作成します。
sudo useradd ${NEWUSER}
ユーザの状態を確認します。
id -a ${NEWUSER}
uid=501(<'任意のユーザ名'>) gid=501(<'任意のユーザ名'>) groups=501(<'任意のユーザ名'>)
初期パスワードを設定します。
sudo passwd ${NEWUSER}
3.2 Test
初回ログイン
テストを実施します。
ssh <'作成したユーザ'>@<'サーバー名'>
下記スクリーンショットの1行目の "Password" で Unixパスワードを入力しました。
1回目は、MFATokenの設定がされていないので、そのままログインできます。
2回目以降
サーバにログインします。
ssh <'作成したユーザ'>@<'サーバー名'>
PasswordでUnixパスワードを入力し、Verification code でMFATokenを入力します。
Password:
Verification code:
Last login: Mon Aug 7 22:18:47 2017 from aa20111001946f573a19.userreverse.dion.ne.jp
__| __|_ )
_| ( / Amazon Linux AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-ami/2017.03-release-notes/
- Refereces
==================
- http://dev.classmethod.jp/cloud/aws/amazon-linux-ssh-two-step-authentication/
- http://blog.kenichimaehashi.com/?article=13076317960
- http://qiita.com/azusanakano/items/b39bd22504313884a7c3
- http://dev.classmethod.jp/cloud/aws/amazon-linux-ssh-two-step-authentication/
- Appendix
==================
# $OpenBSD: sshd_config,v 1.93 2014/01/10 05:59:19 djm Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
# The default requires explicit activation of protocol 1
#Protocol 2
# HostKey for protocol version 1
#HostKey /etc/ssh/ssh_host_key
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
# Lifetime and size of ephemeral version 1 server key
#KeyRegenerationInterval 1h
#ServerKeyBits 1024
# Ciphers and keying
#RekeyLimit default none
# Logging
# obsoletes QuietMode and FascistLogging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
#PermitRootLogin yes
# Only allow root to run commands over ssh, no shell
PermitRootLogin forced-commands-only
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
#RSAAuthentication yes
#PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#RhostsRSAAuthentication no
# similar for protocol version 2
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# RhostsRSAAuthentication and HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
# EC2 uses keys for remote access
PasswordAuthentication no
# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication yes
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
#GSSAPIEnablek5users no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
# WARNING: 'UsePAM no' is not supported in Amazon Linux AMI and may cause several
# problems.
# Leaving enabled as described so that account and session checks are run
UsePAM yes
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
# Explicitly enable
PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
UsePrivilegeSeparation sandbox # Default for new installations.
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#ShowPatchLevel no
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
# override default of no subsystems
Subsystem sftp /usr/libexec/openssh/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs serverMatch User ec2-user
Match User ec2-user
AuthenticationMethods publickey
PubkeyAuthentication yes
PasswordAuthentication no
#%PAM-1.0
auth required pam_env.so
auth sufficient pam_google_authenticator.so nullok
auth requisite pam_succeed_if.so uid >= 500 quiet
auth required pam_deny.so
#%PAM-1.0
auth required pam_sepermit.so
auth substack password-auth
auth substack google-auth
auth include postlogin
# Used with polkit to reauthorize users in remote sessions
-auth optional pam_reauthorize.so prepare
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 required pam_namespace.so
session optional pam_keyinit.so force revoke
session include password-auth
session include postlogin
# Used with polkit to reauthorize users in remote sessions
-session optional pam_reauthorize.so prepare
#!/bin/sh
trap 'exit' SIGINT
if [ "$USER" != "root" -a "$USER" != "ec2-user" ]; then
if [ ! -f "$HOME/.google_authenticator" ]; then
echo "setup google-authenticator..."
/usr/bin/google-authenticator -t -d -w 17 -u -f
fi
fi
Memo: 1回目はパスワード、2回目はMFATokenのみの動作
1回目はパスワード、2回目はMFATokenのみのログインにしたい場合、/etc/pam.d/sshd
を下記のようにします。またgoogle-authは必要ありません。なぜかは分からないけど、いろいろ触っていたらできた。
ようわからん。。。
#%PAM-1.0
auth required pam_sepermit.so
#auth substack password-auth
auth sufficient pam_google_authenticator.so
auth requisite pam_succeed_if.so uid >= 500 quiet
auth substack password-auth
#auth substack google-auth
auth include postlogin
# Used with polkit to reauthorize users in remote sessions
-auth optional pam_reauthorize.so prepare
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 required pam_namespace.so
session optional pam_keyinit.so force revoke
session include password-auth
session include postlogin
# Used with polkit to reauthorize users in remote sessions
-session optional pam_reauthorize.so prepare