はじめに
数年前に触ったものを思い出しがてら触ってみよう。
目的
Web サイトにアクセスした際、Basic 認証のパスワードをワンタイムパスワード(OTP)にする。
導入方法
mod_authn_otp の導入
その辺に転がっていた CentOS で試す。
# 必要なモジュールをインストール
yum install -y httpd httpd-devel openssl-devel automake gcc git
# GitHub から mod-authn-otp を落とす
git clone https://github.com/archiecobbs/mod-authn-otp.git
# make & make install
cd mod-authn-otp/
./autogen.sh -c
make && make install
Apache httpd の設定変更
無事、モジュールの作成が完了したら、httpd に反映させる
# モジュールを追加
echo 'LoadModule authn_otp_module modules/mod_authn_otp.so' > /etc/httpd/conf.modules.d/99-authn.conf
# Syntax Check
httpd -t
# httpd の起動
systemctl start httpd
検証環境の準備
テキトーな VirtualHost を用意
cat /etc/httpd/conf.d/vhost.conf
<VirtualHost *:80>
ServerName hoge.com
DocumentRoot /var/www/html
<Location />
Satisfy any
Order allow,deny
Allow from 127.0.0.1
AuthType Basic
AuthName "OTP Authentication (Enter OTP as password)"
AuthBasicProvider OTP
Require valid-user
OTPAuthUsersFile /var/www/otp/users
OTPAuthMaxLinger 3600
OTPAuthLogoutOnIPChange On
</Location>
</VirtualHost>
OTP用のUserファイルの作成
Userファイルを生成するスクリプト。
「your_company_name」は任意のものに変えて利用する。このスクリプトを実行する時は、引数にBasic認証用のユーザ名をつけて実行する。
#!/bin/bash -e
user=${1:?Usage: $0 username}
issuer=${2:-your_company_name}
secret=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 15 | head -n 1)
secret_base16=$(python -c "import base64; print base64.b16encode('${secret}')")
secret_base32=$(python -c "import base64; print base64.b32encode('${secret}')")
otpauth_uri="otpauth://totp/${issuer}:${user}?secret=${secret_base32}&issuer=${issuer}"
otpauth_uri=$(python -c "import urllib; print urllib.quote('${otpauth_uri}')")
qrcode_url="https://chart.googleapis.com/chart?chs=300x300&cht=qr&chl=${otpauth_uri}"
file="/var/www/otp/users"
if [ ! -f "${file}" ]; then
[ -d $(dirname "$file") ] || mkdir -p $(dirname "$file")
touch ${file}
chown -R apache:apache $(dirname "$file")
fi
[ -w "${file}" ] || (echo "${file}: Permission denied" && exit 1)
count=$(awk "\$2 ~ /^$user}\$/" ${file} | wc -l)
if [ $count -le 0 ]; then
echo "HOTP/T30 $(printf '%-12s' $user) - ${secret_base16}" >> ${file}
echo "$qrcode_url"
else
echo "User '$user' already exists"
fi
実行後、標準出力にGoogle Authenticator 等で利用出来る登録用の QR コードが表示される URL が出力される。設定した Username と QR コードの URL は忘れないように。
# ↓の URL はダミーだよ
./authn.sh hoge
https://chart.googleapis.com/chart?chs=300x300&cht=qr&chl=otpauth%3A/~
利用するユーザ側の準備
スマホを用意し、Google Authenticator とか OTP 対応アプリをダウンロードしよう。アプリから↑で発行された QR コードを読み込む。
サイトにアクセスする
該当サイトにアクセスすると簡易認証が表示されるので、スクリプト実行の際に指定したユーザ名と、OTP 対応アプリに表示されているパスワードを入力し、認証が通ればOK。
注意点
- QR コード発行の URL の取扱に注意(外部に漏れたら意味なし)
- URL の再発行は出来ない(作り直し)
仲間募集中
弊社ではエンジニアを募集中です。インフラからアプリ、ユーザサポートまで幅広く業務を行ってます。
https://www.nittsu-infosys.com/recruit/2019/index.html