OpenVPN を LinOTP で認証する設定方法
目次
- はじめに
- 前提条件
- LinOTP の設定
- PAM の設定(pam_py_linotp)
- OpenVPN の設定(クライアント・サーバー)
- PAM と OpenVPN の統合
- 運用チェックリスト(管理者/利用者別)
- トラブルシューティング
- セキュリティ強化のヒント
- 決定フロー(Mermaid)
- FAQ
- まとめ
はじめに
このガイドは、OpenVPN サーバーを LinOTP バックエンドで認証する方法を段階的に解説します。LinOTP はさまざまな OTP トークン(スマートフォン OTP、ハードウェアトークン、カードなど)を管理できる認証サーバーです。PAM モジュールを使えば、OpenVPN だけでなく SSH やデスクトップログインにも同じ二要素認証を適用できます。
重要: この手順はテスト/小規模運用向けの簡潔な構成を示しています。本番環境ではネットワーク分離、証明書ライフサイクル管理、ログ監査、監視を追加してください。
前提条件
- LinOTP のインストール先(同一マシンでも別マシンでも可)
- OpenVPN(サーバー/クライアント)
- root または sudo 権限
- Python と pip(pam_py_linotp のインストールに使用)
- libpam-python(PAM から Python モジュールを呼べるようにする)
短い用語定義:
- LinOTP: 複数種類の OTP トークンを管理するオープンソースの認証サーバー
- PAM: Pluggable Authentication Modules、Linux の認証フレームワーク
- OTP: One-Time Password、一度限り有効なワンタイムパスワード
LinOTP の設定
まず LinOTP をセットアップします。Debian/Ubuntu 用パッケージか、Python Package Index 経由でのインストールが可能です。ここでは詳細な LinOTP インストール手順は省きますが、公式ドキュメントに従って設定を行ってください。
注意: デモや小規模環境では LinOTP を OpenVPN と同一ホストにインストールすると構成が簡単になります。
PAM の設定 — pam_py_linotp を使う
LinOTP には C で書かれた pam_linotp モジュールもありますが、ビルドと依存関係の管理を避けたい場合は Python 製の pam_py_linotp を利用できます。以下はインストール手順の例です。
tar -ztf pam_py_linotp-0.1.tar.gz
cd pam_py_linotp-0.1/
sudo python setup.py install
代替: pip を使うと簡単です。
sudo pip install pam_py_linotp
または単一モジュールを直接コピーする方法:
cd pam_py_linotp-0.1/
cp src/ pam_linotp.py /lib/security
このモジュールを PAM で使うために libpam-python が必要です。ディストリビューションに応じてインストールしてください。
例:
sudo apt-get install libpam-python
または
yum install libpam-python
common-linotp というスタック可能な auth ファイルを作る
他サービス(ssh, gdm, kdm など)にも容易に二要素認証を追加できるよう、共通の PAM スタックファイルを作成します。ファイル名は /etc/pam.d/common-linotp などにします。
auth [success=1 default=ignore] pam_python.so /lib/security/pam_linotp.py \
debug url=https://localhost/validate/check
auth requisite pam_deny.so
auth required pam_permit.so
重要: pam_python.so の直後の引数はインストールした Python モジュール(/lib/security/pam_linotp.py)であり、その後に LinOTP サーバーの URL(例: https://localhost/validate/check)を指定します。LinOTP を別ホストで動かしている場合はホスト名または IP、プロトコル(http/https)、ポートを適切に変更してください。
OpenVPN の設定
クライアント構成例
クライアント側の client.ovpn は次のように最小構成します(サーバ名や証明書ファイル名は環境に合わせて変更してください)。
client
dev tun
proto udp
remote your.server.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
comp-lzo
verb 3
auth-user-pass
auth-user-pass があると接続時にユーザー名とパスワード(ここでは OTP を利用)が要求されます。
サーバー構成例
サーバー側の server.conf 例:
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
server 192.168.42.0 255.255.255.0
ifconfig-pool-persist ipp.txt
keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 3
plugin /usr/lib/openvpn/openvpn-auth-pam.so openvpn
plugin の最後の引数は PAM のサービス名(後述の /etc/pam.d/openvpn を参照)です。証明書名や IP プールは環境に合わせて調整してください。
PAM と OpenVPN の統合
/etc/pam.d/openvpn ファイルには次を含めます。これは common-linotp を組み込む例です。
@include common-linotp
session sufficient pam_permit.so
account sufficient pam_permit.so
session と account に pam_permit.so を置くことで、OpenVPN 接続のためにサーバー上でローカルユーザーアカウントを作成する必要を避けています。認証は LinOTP 側で行われ、成功すれば VPN が確立されます。
結果: クライアント証明書と正しい OTP(必要なら PIN を含む)が揃ったときのみ VPN 接続が許可されます。
運用チェックリスト
管理者向けチェックリスト:
- LinOTP サーバーが TLS(https)で保護されているか確認
- PAM モジュールの配置とパーミッションを確認(/lib/security/pam_linotp.py)
- OpenVPN の plugin 設定が PAM サービス名と一致しているか確認
- 証明書の失効リスト(CRL)を設定しているか確認
- 監査ログ(auth.log, openvpn-status.log)を定期的にチェック
利用者向け短縮ガイド:
- client.ovpn を受け取り、証明書とキーを正しく配置
- 接続時に求められるユーザー名と OTP を入力
- 接続できない場合は管理者にログを確認してもらう
トラブルシューティング
よくある問題:
- 接続できない: OpenVPN サーバーのログ(/var/log/syslog や openvpn-status.log)を確認
- PAM モジュールがロードされない: libpam-python の有無、モジュールのパスと権限を確認
- LinOTP へ到達できない: URL、ポート、TLS 設定をチェック、ファイアウォールの設定も確認
- OTP が拒否される: LinOTP 側のトークン状態(有効化、シードの同期)を確認
簡単なデバッグ手順:
- OpenVPN をデバッグモード(verb 4 以上)で起動
- /var/log/auth.log(またはディストリビューションの認証ログ)を監視
- PAM 呼び出しや pam_python のデバッグ出力を有効にして詳細を確認
セキュリティ強化のヒント
- LinOTP の管理コンソールは別管理ネットワークに置き、アクセスを制限する
- TLS 証明書を短期間でローテーションし、CRL/OCSP を運用する
- PAM スタックのログは十分に保護し、機密情報が平文で出力されないよう設定する
- OpenVPN の管理チャネル(管理インターフェース)を有効にして監視と自動復旧を組み込む
- 二要素のバックアップ(ハードウェアトークンの予備)を用意する
重要: LinOTP と OpenVPN 間の通信(API 呼び出し)は必ず TLS(https)で行ってください。http を使うと OTP 情報や認証結果が平文で漏洩する恐れがあります。
決定フロー(認証フロー例)
以下は簡易的な判定フローです。
flowchart TD
A[クライアント接続要求] --> B{クライアント証明書の検証}
B -- OK --> C[PAM を呼び出し]
B -- NG --> Z[接続拒否]
C --> D{ユーザー名/OTP の入力}
D -- OK --> E[LinOTP に検証リクエスト]
E -- 承認 --> F[セッション確立]
E -- 拒否 --> Z
FAQ
LinOTP と OpenVPN を同一サーバーに置いても安全ですか
同一サーバーで運用することは可能ですが、本番環境ではネットワーク分離や冗長化、監査要件を考慮し、別サーバー運用や高可用構成を検討してください。
PAM モジュールを使わずに LinOTP を使う方法はありますか
はい。LinOTP の Web API や RADIUS 経由で OpenVPN を認証する方法もあります。RADIUS を噛ませると既存の AAA(認証・認可・会計)基盤との統合が容易です。
スマートフォン OTP とハードウェアトークンは混在できますか
LinOTP は複数種のトークンを管理できるため混在運用が可能です。ユーザーごとにトークン種別を割り当てられます。
まとめ
このガイドでは、pam_py_linotp を用いた PAM 経由の LinOTP 認証と OpenVPN の統合手順を示しました。クライアント証明書によるマシン認証と OTP によるユーザー認証を組み合わせることで、より厳格な二要素認証が実現できます。運用では TLS 保護、ログ監査、証明書ライフサイクル管理を忘れずに行ってください。
重要: 本記事の設定例はテンプレートです。各組織のポリシーやコンプライアンスに合わせて調整してください。
事実ボックス:
- 主な構成要素: OpenVPN, LinOTP, libpam-python, pam_py_linotp
- 接続条件: クライアント証明書 + LinOTP による OTP 検証
運用プレイブック(短縮):
- LinOTP を設定しトークンを発行
- pam_py_linotp をインストールして /lib/security に配置
- common-linotp を作成して LinOTP の URL を設定
- /etc/pam.d/openvpn に include を追加
- OpenVPN の plugin 指定と証明書を配置
- テスト接続してログを確認
ロール別チェックリスト(管理者):
- LinOTP のバックエンド DB バックアップ
- 管理者アカウントの多要素化
- OpenVPN 設定のバージョン管理
ロール別チェックリスト(利用者):
- 証明書とキーの安全な保管
- OTP が同期しない場合の問い合わせ窓口を確認
短い告知文(100–200 文字): OpenVPN サーバーを LinOTP と連携して二要素認証を導入しました。ユーザーはクライアント証明書と OTP による認証で安全に VPN を利用できます。詳細な接続手順は社内ドキュメントを参照してください。