could not read Auth username from stdin 認証の問題のように見えますが、そうではありません。OpenVPN は標準入力からユーザー名を求めようとしましたが、読み取れるものがなく、サーバーに接続する前に停止しました。アカウント自体は有効な場合が多く、尋ねる相手がいないだけです。

だから最初に確認すべきは、クライアントが何を読んでいるかであり、接続の再試行やサーバー側の設定変更ではありません。以下の確認を順に行い、最初に失敗したところで止めてください。

エラーをローカルな入力の失敗として読む

auth-user-pass をファイル引数なしで指定すると、クライアントは問い合わせを期待します。対話的なシェルではプロセスが端末を持つため、その問い合わせは機能します。systemd、cron ジョブ、コンテナの下では標準入力が通常空であり、読み取りは目にしているエラーで直ちに戻ります。

メッセージは失敗したフィールド、つまりユーザー名かパスワードも示すので、読み取りがどこまで進んだか分かります。ユーザー名が欠けていれば、プロセスは何も読めていません。ユーザー名の成功後にパスワードが欠けていれば、二度の読み取りの間に入力ストリームが終わったということで、書きかけのファイルや閉じたパイプでよく起きます。

ほかを変える前に、クライアント自身の見え方を確認してください。同じ設定と同じユーザーで前面実行し、問い合わせが出るか観察します。シェルでは出るのにサービス管理下では出ないなら、違いは入力元であり、認証情報ではありません。unit ファイルとシェル環境を素早く比べれば、どちらが端末を提供しているか通常は分かります。

サービスにサポートされた認証情報の供給元を与える

無人実行でサポートされる供給元は、引数として渡す認証情報ファイルです: auth-user-pass。ファイルは平文として読まれ、先頭行がユーザー名、次の行がパスワードです。サービスアカウントの作業ディレクトリがディレクティブの意味を変えられないよう、次のような絶対パスで指定してください: /etc/openvpn/client/creds。

権限はパスと同じくらい重要です。ファイルはクライアントを実行するアカウントから読め、他の全員からは読めないようにし、サービスアカウントまたはサービスを含むグループを持つ root が所有するべきです。内容を表示せずに、そのアカウントとして読めるか確認します。

相対パスは静かな失敗の型です。プロファイルが一方のディレクトリにあり、systemd が別の場所でプロセスを起動すると、シェルで解決するファイルがサービスでは解決しません。認証情報を固定の場所へ移し、絶対パスで参照してください。そのうえでサービスを一度起動し、プロファイルエディターの表示を信じるのではなく同じパスが使われることを確認します。

配備がワンタイムコードや別の対話的チャレンジを必要とするなら、クライアントのワークフローがそれを無人で本当に支えられるか決めてください。静的パスワードのファイルは回転するコードに答えられず、答えられない問い合わせを繰り返しても情報は増えません。

script-security が助けにならない理由

script-security は、クライアントがスクリプトを実行できるか、どれだけ渡せるか、環境変数でスクリプトにパスワードを渡せるかまで制御します。ユーザー名とパスワードがそもそもどこから来るかについては何も言いません。

メッセージに Auth とあるため水準を上げるのはよくある反射ですが、変わるのは入力元ではなくスクリプトの権限で、クライアントが実行できる範囲が広がります。補助スクリプトが設計の一部なら、まず入力元を直し、セキュリティ水準は配備に必要な最小値に保ってください。

管理インターフェースは正当な代替手段です。フロントエンドが接続し、認証情報の要求を受け取り、ユーザー名とパスワードで応答でき、一部の GUI はこうして動いています。クライアントの制御チャネルなので、使う場合はローカルアドレスに束縛し、管理パスワードファイルで保護し、接続できる相手を制限してください。

クライアントがファイルを読んだ後の段階を確認する

クライアントが認証情報を読めるようになると、次の失敗はサーバーとの実際のやり取りであり、そのメッセージの意味は異なります。その段階の認証失敗はサーバーがアカウントを拒否したという意味で、チャレンジ応答は別の要素を求めているという意味です。同じ問題の繰り返しではなく、新しい問題として扱ってください。

サービスが実行するのと同じ条件(同じアカウント、同じ作業ディレクトリ、同じ unit 環境)で経路全体を試します。シェルから起動したときだけ機能する接続は、環境変数や端末がまだ流れの一部だという印です。

秘密はあるべき場所に置きます。コマンドライン引数のパスワードはプロセステーブルに現れ、デバッグ出力のパスワードはチケットに残ります。保護されたファイルか管理インターフェースを使い、認証情報を繰り返さない水準でログを保ち、アクセスを持つ人が去ったらファイルを交換してください。

チェックリスト: 認証情報の絶対パス、サービスアカウントとして読めること、端末不要、script-security は最小のまま、管理インターフェースは束縛と認証がある場合のみ、そして結果のサーバー応答は別の事象として扱うこと。

関連記事