著者は、 Electronic Frontier Foundation を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。

序章

二要素認証(2FA)は、アカウントまたはデバイスに正常にログインするために複数の情報を入力する必要がある認証方法です。 2FAでは、ユーザー名とパスワードの組み合わせを入力するだけでなく、6桁の確認コードなどのワンタイムパスワード(OTP)などの追加情報を入力する必要があります。

一般に、2FAでは、ユーザーがさまざまなタイプの情報を入力する必要があります。

  • パスワードなど、ユーザーが知っていること
  • オーセンティケーターアプリケーションから生成された検証コードなど、ユーザーが持っているもの

2FAは、多要素認証(MFA)のサブセットであり、ユーザーが知っているものと持っているものに加えて、ユーザーであるものを必要とします。 これは、指紋や音声認識などのテクノロジーを使用するバイオメトリクスの場合です。

2FAは、特定のサービスまたはデバイスへの認証プロセスを強化するのに役立ちます。パスワードが侵害された場合でも、攻撃者は、セキュリティコードの生成に使用される認証アプリを保持するユーザーのデバイスにアクセスする必要があります。 このため、多くのオンラインサービス( DigitalOcean を含む)は、認証フェーズに関して、ユーザーアカウントの2FAを有効にしてアカウントのセキュリティを強化する可能性を提供します。

このガイドでは、GooglePAMモジュールを使用したUbuntu18.04インストールでroot以外のsudoerユーザー用に2FAを構成します。 root以外のユーザーで2FAを構成しているため、ロックアウトが発生した場合でも、rootアカウントからマシンにアクセスできます。 チュートリアルは、ローカルとリモートの両方のサーバーとデスクトップの両方のインストールに適用できるほど一般的です。

前提条件

このガイドを開始する前に、次のものが必要です。

  • 1つのUbuntu18.04サーバーまたはデスクトップ環境。 Ubuntuサーバーを使用している場合は、 Ubuntu 18.04初期サーバーセットアップガイドに従ってセットアップします。これには、sudo権限を持つroot以外のユーザーとファイアウォールが含まれます。

  • GoogleAuthenticatorAuthyなどの2FAQRコードをスキャンできるモバイルデバイスにインストールされた認証システム。

ステップ1—GooglePAMモジュールをインストールする

Ubuntu 18.04で2FAを構成するには、Linux用のGoogleのPAMモジュールをインストールする必要があります。 Pluggable Authentication Module (PAM)は、Linuxが使用する認証メカニズムです。 GoogleのPAMモジュールを使用して、Googleが生成したOTPコードを使用して2FAでユーザーを認証します。

まず、前提条件で構成した非rootユーザーとしてログインします。

  1. ssh sammy@your_server_ip

Ubuntuリポジトリを更新して、オーセンティケーターの最新バージョンをダウンロードします。

  1. sudo apt-get update

リポジトリが最新になったら、最新バージョンのPAMモジュールをインストールします。

  1. sudo apt-get install libpam-google-authenticator

これは依存関係のない非常に小さなパッケージであるため、インストールには数秒かかります。 次のセクションでは、システムの非rootユーザー用に2FAを構成します。

ステップ2—ユーザー用に2FAを構成する

PAMモジュールをインストールしたので、それを実行して、ログインしているユーザーのQRコードを生成します。 これでコードが作成されますが、このチュートリアルの後半で有効にするまで、Ubuntu環境で2FAは必要ありません。

google-authenticatorコマンドを実行して、PAMモジュールを起動および構成します。

  1. google-authenticator

このコマンドは、いくつかの構成に関する質問をするプロンプトを表示します。 最初の質問は、トークンを時間ベースにするかどうかを尋ねます。 時間ベースの認証トークンは、設定された時間が経過すると期限切れになります。ほとんどのシステムでは、デフォルトで30秒になります。 時間ベースのトークンは、時間ベースではないトークンよりも安全であり、ほとんどの2FA実装はそれらを使用します。 ここではどちらのオプションも選択できますが、このチュートリアルでは、時間ベースの認証トークンを使用するためにYesを選択します。

Output
Do you want authentication tokens to be time-based (y/n) y

この質問にyと答えると、コンソールに数行出力されます。

  • QRコード:これは、認証システムアプリを使用してスキャンする必要のあるコードです。 スキャンすると、すぐにコード生成デバイスに変わり、30秒ごとに新しいOTPが作成されます。
  • 秘密鍵:これは、オーセンティケーターアプリを構成するための代替方法です。 QRスキャンをサポートしていないアプリを使用している場合は、秘密鍵を入力して認証アプリを構成できます。
  • 確認コード:これは、この特定のQRコードが生成する最初の6桁の確認コードです。
  • 緊急スクラッチコード:バックアップコードとも呼ばれるこれらの使い捨てトークンを使用すると、オーセンティケーターデバイスを紛失した場合に2FA認証に合格できます。 アカウントからロックアウトされないように、これらのコードは安全な場所に保管してください。

オーセンティケーターアプリを構成し、バックアップコードを安全な場所に保存すると、構成ファイルを更新するかどうかを尋ねるプロンプトが表示されます。 nを選択した場合は、構成プログラムを再実行する必要があります。 yと入力して、変更を保存し、次に進みます。

Output
Do you want me to update your "~/.google_authenticator" file (y/n) y

次の質問では、認証コードの複数回の使用を禁止するかどうかを尋ねられます。 デフォルトでは、30秒間有効なままであっても、各コードを使用できるのは1回だけです。 これは、使用後に確認コードを取得した攻撃者からのリプレイ攻撃を防ぐため、最も安全な選択です。 このため、コードを複数回使用することを禁止する方が安全です。 yと答えて、同じトークンの複数の使用を禁止します。

Output
Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) y

次の質問では、認証トークンを通常の有効期間の少し前または直後に受け入れるかどうかを尋ねます。 確認コードは非常に時間に敏感です。つまり、デバイスが同期されていない場合、トークンが拒否される可能性があります。 このオプションを使用すると、検証コードのデフォルトの有効期間を延長してこの問題を回避できるため、デバイスが一時的に同期していない場合でも、認証コードは受け入れられます。 yesを選択するとシステムのセキュリティが低下するため、すべてのデバイスで時間が同じであることを確認するのが最善のオプションです。 猶予期間を許可しないようにするには、この質問にnと答えてください。

Output
By default, tokens are good for 30 seconds and in order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time. If you experience problems with poor time synchronization, you can increase the window from its default size of 1:30min to about 4min. Do you want to do so (y/n) n

最後の質問は、ログイン試行のレート制限を有効にするかどうかを尋ねます。 これにより、30秒ごとに3回を超えるログイン試行が失敗することはありません。これは、優れたセキュリティ強化手法です。 yと答えて有効にします。

Output
If the computer that you are logging into isn't hardened against brute-force login attempts, you can enable rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login attempts every 30s. Do you want to enable rate-limiting (y/n) y

これで、PAMモジュールを使用してroot以外のユーザー用に2FAコードを構成および生成しました。 コードが生成されたので、環境で2FAを有効にする必要があります。

ステップ3—Ubuntuで2FAをアクティブ化する

Google PAMモジュールは現在ユーザーに2FAコードを生成していますが、Ubuntuはユーザーの認証プロセスの一部としてコードを使用する必要があることをまだ認識していません。 このステップでは、Ubuntuの構成を更新して、通常の認証方法に加えて2FAトークンを要求します。

この時点で、2つの異なるオプションがあります。

  • ユーザーがシステムにログインするたびに2FAを要求し、ユーザーがsudo特権を要求するたびにを要求することができます。
  • ログイン中にのみ2FAを要求できます。その後のsudo認証の試行では、ユーザーパスワードのみが要求されます。

最初のオプションは、sudo権限を必要とするアクションを保護したい共有環境に最適です。 2番目のアプローチは、システム上の唯一のユーザーであるローカルデスクトップ環境でより実用的です。

注: DigitalOcean DropletなどのSSH経由でアクセスするリモートマシンで2FAを有効にする場合は、多要素認証の設定方法の手順2と3に従う必要があります。このチュートリアルに進む前に、Ubuntu16.04ガイドでSSHを使用してください。 このチュートリアルの残りの手順はすべてのUbuntuインストールに適用されますが、リモート環境ではSSHサービスが2FAを認識できるようにするために追加の更新が必要です。

SSHを使用してUbuntuインストールにアクセスしていない場合は、チュートリアルの残りの手順にすぐに進むことができます。

ログインおよびsudoリクエストに2FAが必要

ログインおよびその後の特権昇格要求中に2FAの入力を求められるようにするには、既存のファイルの末尾に行を追加して/etc/pam.d/common-authファイルを編集する必要があります。

common-authファイルは、使用されているデスクトップ環境に関係なく、システム上のすべての認証メカニズムに適用されます。 また、端末から新しいパッケージをインストールするときのsudoエスカレーション要求中など、ユーザーがシステムにログインした後に発生する認証要求にも適用されます。

次のコマンドでこのファイルを開きます。

  1. sudo nano /etc/pam.d/common-auth

ファイルの最後に強調表示された行を追加します。

/etc/pam.d/common-auth
...
# and here are more per-package modules (the "Additional" block)
session	required	pam_unix.so
session	optional	pam_systemd.so
# end of pam-auth-update config
auth required pam_google_authenticator.so nullok

この行は、GooglePAMモジュールを介してログインするときに2FAを要求するようにUbuntu認証システムに指示します。 nullokオプションを使用すると、既存のユーザーは、アカウントに2FA認証を構成していない場合でもシステムにログインできます。 つまり、2FAを構成したユーザーは、次回のログイン時に認証コードを入力する必要がありますが、google-authenticatorコマンドを実行していないユーザーは、ユーザー名とパスワードのみでログインできます。 2FAを設定するまで。

行を追加したら、ファイルを保存して閉じます。

ログイン専用に2FAが必要

デスクトップ環境でシステムに最初にログインしたときにのみ2FAのプロンプトが表示されるようにする場合は、使用しているデスクトップマネージャーの構成ファイルを編集する必要があります。 構成ファイルの名前は通常、デスクトップ環境の名前と一致します。 たとえば、Ubuntu16.04以降のデフォルトのUbuntuデスクトップ環境であるgdmの構成ファイルは、/etc/pam.d/gdmです。

DigitalOcean Dropletなどのヘッドレスサーバーの場合は、代わりに/etc/pam.d/common-sessionファイルを編集します。 環境に基づいて関連ファイルを開きます。

  1. sudo nano /etc/pam.d/common-session

強調表示された行をファイルの最後に追加します。

/etc/pam.d/common-session
#
# /etc/pam.d/common-session - session-related modules common to all services
#
...
# # and here are more per-package modules (the "Additional" block)
session	required	pam_unix.so
session	optional	pam_systemd.so
# end of pam-auth-update config
auth required pam_google_authenticator.so nullok

これにより、ユーザーがコマンドラインを介して(ローカルまたはリモートでSSHを介して)システムに接続するときに2FAを要求するようにUbuntuに指示しますが、sudo要求などの後続の認証試行中は要求しません。

これで、ログイン中、またはシステムで実行されたすべての認証済みアクションに対して2FAのプロンプトを表示するようにUbuntuを正常に構成できました。 これで、構成をテストする準備が整い、Ubuntuインストールにログインするときに2FAの入力を求められることを確認します。

ステップ4—2FAのテスト

前の手順では、30秒ごとにコードを生成するように2FAを構成しました。 このステップでは、Ubuntu環境にログインして2FAをテストします。

まず、Ubuntu環境にログアウトして再度ログインします。

ssh sammy@your_server_ip

パスワードベースの認証を使用している場合は、ユーザーパスワードの入力を求められます。

Output
Password:

注: DigitalOcean Dropletまたは証明書認証で保護されている別のリモートサーバーでこれをテストしている場合、パスワードの入力を求められることはなく、キーは自動的に渡されて受け入れられます。 したがって、確認コードの入力のみが求められます。

パスワードを入力すると、2FA確認コードの入力を求められます。

Output
Verification code:

確認コードを入力すると、次の場所にログインします。

Output
sammy@your_server_ip: ~#

2FAがログインに対してのみ有効になっている場合、セッションが期限切れになるか、手動でログアウトするまで、2FAコードの入力を再度求められることはありません。

common-authファイルを介して2FAを有効にした場合、ログインおよびsudo特権の要求のたびに2FAの入力を求められます。

Output
sammy@your_server_ip: ~# sudo -s
 sudo password for sammy:
 Verification code: 
root@your_server_ip:

このステップでは、2FA構成が期待どおりに機能していることを確認しました。 このフェーズで確認コードの入力を求められなかった場合は、チュートリアルのステップ3に戻り、正しいUbuntu認証ファイルを編集したことを確認してください。

ステップ5—2FAロックアウトの防止

電話を紛失したりワイプしたりした場合は、2FA対応アカウントへのアクセスを回復するための適切なバックアップ方法を用意することが重要です。 2FAを初めて構成するときは、ロックアウトから確実に回復できるようにするためのいくつかのオプションがあります。

  • シークレット構成コードのバックアップコピーを安全な場所に保存します。 これは手動で行うことができますが、Authyなどの一部の認証アプリはバックアップコード機能を提供します。
  • 2FA対応環境の外部からアクセスできる安全な場所にリカバリコードを保存します。

何らかの理由でバックアップオプションにアクセスできない場合は、追加の手順を実行して、2FA対応のローカル環境またはリモートサーバーへのアクセスを回復できます。

ステップ6—ローカル環境での2FAロックアウトからの回復(オプション)

マシンに物理的にアクセスできる場合は、レスキューモードで起動して、2FAを無効にすることができます。 レスキューモードは、管理タスクの実行に使用されるLinuxの target タイプ( runlevel と同様)です。 レスキューモードに入るには、UbuntuのデフォルトのブートローダーであるGRUBのいくつかの設定を編集する必要があります。

GRUBにアクセスするには、最初にマシンを再起動します。

  1. reboot

GRUBメニューが表示されたら、Ubuntuエントリが強調表示されていることを確認します。 これは18.04インストールのデフォルト名ですが、インストール後に手動で変更した場合は異なる場合があります。

The default GRUB menu in Ubuntu 18.04

次に、システムを起動する前に、キーボードのeキーを押してGRUB構成を編集します。

The GRUB configuration file in edit mode

表示されるファイルで、linuxで始まり$vt_handoffで終わる行が表示されるまで下にスクロールします。 この行の最後に移動してsystemd.unit=rescue.targetを追加し、$vt_handoffsystemd.unit=rescue.targetの間にスペースを空けてください。 これにより、Ubuntuマシンにレスキューモードで起動するように指示されます。

Editing the GRUB Configuration File to Enable Maintenance Mode

変更を加えたら、Ctrl+Xキーボードの組み合わせでファイルを保存します。 マシンが再起動し、コマンドラインが表示されます。 Enterを押して、レスキューモードに入ります。

Command line maintenance mode prompt in Ubuntu 18.04

レスキューモードになったら、Google認証システムの構成ファイルを開きます。 これは、ロックアウトされたユーザーのホームディレクトリ内にあります。

  1. nano /home/sammy/.google-authenticator

このファイルの最初の行は、オーセンティケーターアプリを構成するために使用されるユーザーの秘密鍵です。

現在、2つの選択肢があります。

  • 秘密鍵をコピーして、認証システムアプリを構成できます。
  • きれいな状態から始めたい場合は、~/.google-authenticatorファイルを完全に削除して、このユーザーの2FAを無効にすることができます。 root以外のユーザーとして再度ログインした後、2FAを再度構成して、新しい秘密鍵を取得できます。

どちらを選択しても、GRUBブートローダーを使用して、ローカル環境での2FAロックアウトから回復できます。 次のステップでは、リモート環境での2FAロックアウトから回復します。

ステップ7—リモート環境での2FAロックアウトからの回復(オプション)

ルート以外のsudoerアカウントがリモートマシンでロックアウトされている場合は、 root ユーザーを使用して、2FAを一時的に無効にするか、2FAを再構成できます。

rootユーザーでマシンにログインすることから始めます。

  1. ssh root@your_server_ip

ログインしたら、ロックアウトされたユーザーのホームディレクトリ内にあるGoogle認証システム設定ファイルを開きます。

  1. sudo nano /home/sammy/.google_authenticator

このファイルの最初の行はユーザーの秘密鍵です。これは、オーセンティケーターアプリを構成するために必要なものです。

現在、2つの選択肢があります。

  • 新しいデバイスまたはワイプされたデバイスをセットアップする場合は、秘密鍵を使用して認証システムアプリを再構成できます。
  • きれいな状態から始めたい場合は、/home/sammy/.google_authenticatorファイルを完全に削除して、このユーザーの2FAを無効にすることができます。 root以外のユーザーとしてログインした後、2FAをもう一度構成して、新しい秘密鍵を取得できます。

どちらを選択しても、 root ユーザーを使用して、ローカル環境での2FAロックアウトから回復することができました。

結論

このチュートリアルでは、Ubuntu18.04マシンで2FAを構成しました。 ご使用の環境で2FAを構成すると、アカウントに保護のレイヤーが追加され、システムがより安全になります。 従来の認証方法に加えて、ログインするには追加の確認コードを入力する必要があります。 これにより、ログイン資格情報を取得した攻撃者が、この追加の確認コードなしでアカウントにログインすることは不可能になります。