yamada-hakase’s blog

LinuxなどのOSSやクラウドについて

意外に複雑なLinuxのパスワード生成事情とパスワード生成方法

1. 意外に複雑なパスワード生成事情

システムの構築や管理で強固なパスワードを生成したいことがある。しかしTL;DRに書いたように、Linuxでは意外に複雑な事情がある。そこで今回は主要なコマンドの特性と使い方を説明する。

1-1. TL;DR

  • Linuxにはパスワードを生成するコマンドが複数ある
  • コマンドによって特性が違い、標準リポジトリに「含まれている/含まれていない」などインストール方法も違う
  • 一見ランダムでありながら、発音しやすい(=覚えやすい)パスワード生成方法もある
  • パブリック・クラウドではOSにパスワード・ログインする機会は少ないが、VNCやxrdp、シリアルコンソール接続では必要になることがある

1-2. 対象環境

2. パスワード生成方法を考える

Linuxでパスワードを生成するには、大きく分けて以下の方法がある。

  1. pwmakeやpwgen、mkpasswdなどのパスワード生成コマンドを使う
  2. opensslや /dev/urandomなどを組み合わせて使う
  3. Bitwardenや1Password、LastpassGoogleパスワードマネージャーなどのWebサイトパスワード管理ツールを使う

Webサイトのパスワードを管理するなら3を使うべきだろう。しかし今回は汎用的なパスワード生成を目指している。そのため1の方法を説明する。2の方法は以下のリンクを参照のこと。

2-1. 各コマンドの概要

それぞれのコマンドを簡単に紹介する。

pwgen
 汎用的なパスワード生成コマンド。オプションに指定した条件でパスワードを生成できる。  http://sf.net/projects/pwgen

pwmake
 libpwqualityライブラリに含まれるパスワード生成コマンド。RHEL7系から採用されたpam_pwquality(libpwquality)に統合されているため、オプションを指定しなくてもOSのパスワードポリシーに従ったパスワードを生成できる。  https://github.com/libpwquality/libpwquality/

mkpasswd
 expectに含まれるパスワード生成コマンド。機能はpwgenに似ているが、pwgenのほうが高機能。ただしRHEL系とUbuntuでは、コマンド名は同じだが別物。

ヒント pwgenとpwmakeのmanを見ると「pronounceable passwords」と説明されている。つまり発音しやすいパスワードを生成できる。程度の問題なので、辞書に登録されている単語が含まれるわけではない。

2-2. 各コマンドの入手方法

以下の表は、Linuxディストリビューションごとの入手方法だ。OSのインストールタイプに依存するが、デフォルトでイントールされるのは青字のパッケージだけで、それ以外は任意にインストールする必要がある。カッコ内は入手先リポジトリだ。

ディストリビューション pwmake pwgen mkpasswd
RHEL6系 libpwquality(EPEL) pwgen(EPEL) expect
RHEL7系 libpwquality pwgen(EPEL) expect
RHEL8系 libpwquality pwgen(EPEL) expect
Ubuntu18.04LTS libpwquality-tools pwgen whois

2-3. 各コマンドの使い分け

これまで説明してきたことをまとめると次のようにいえる。次章ではpwmakeとpwgenの使い方を説明する。

  • RHEL7系以降もしくはUbuntuで、OSのログイン・パスワードを生成するにはpwmakeが適している
  • 利用方法を限定しないパスワードを生成するにはpwgenが適している

3. pwgenを使う

汎用的なパスワード生成コマンドpwgenの使用方法を説明する。

3-1. pwgenをインストールする

pwgenはEPELリポジトリから提供されている。ただしパブリック・クラウドのOSイメージでは標準リポジトリに含まれていることもある。RHEL系とUbuntuのそれぞれについて説明する。

RHEL

  1. pwgenがインストールされているか確認する。
$ rpm -qa | grep pwgen
★インストールされていないときは何も表示されない。

2.インストールされていないときは、既存のリポジトリに含まれているか確認する。

$ sudo yum provides pwgen
★No matchesと表示されたときはリポジトリに含まれていない。
No matches found

★リポジトリに含まれているときはパッケージ名が表示される。
pwgen-2.08-1.el7.x86_64 : Automatic password generation
Repo        : epel

3.既存のリポジトリに含まれていないときには、先にEPELリポジトリをインストールする。EPELの詳細は「あらためてEPELリポジトリの使い方をまとめてみた」を参照のこと。

# RHEL6系
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm -y

# RHEL7系
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm -y

# RHEL8系
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -y

# Amazon Linux 2
sudo amazon-linux-extras install epel

4.pwgenをインストールする。

$ sudo yum install pwgen -y

Ubuntu

$ sudo apt install pwgen

3-2. pwgenの実行方法

pwgenの文法は以下のとおり。オプションの後ろに、パスワード長と個数を指定する。下記以外のオプションはmanを参考のこと。

pwgen [ OPTIONS ] [ pw_length ] [ num_pw ]
オプション 内容
-c 最低一文字の大文字を含める
-A 大文字を含めない
-n 最低一文字の数値を含める
-0 数値を含めない
-y 最低一文字の記号を含める
-s 完全にランダムなパスワードを生成する
-B 1(イチ)やl(エル)、O(オー)、0(ゼロ)など紛らわしい文字は含めない
-1 1行あたり1パスワード表示する

例1)パスワード長は12文字で、最低1文字の大文字(-c)と数値(-n)を含める。個数指定しないときは、次のようにフルスクリーン分が表示される。この中から使いたいものを選べばよい。

$ pwgen -c -n 12
Eiv5roo5pha1 ahnie0Zeogh2 piedu8Vaijoo Foa2eghiiPho teiHosoh8ooF ohgh0Ohwaesh
pahph6Aiyu0M leiB2xahlah1 maePee7fonoe aeGo6xielaeM Veif1Iaj4Na7 beiB8IKungie
Ohlah2aithak Aelaelo2ieri bieRef8ceire cahxu7AF4Ung chah7Aht6vah edeva9Ooquie
gaeWo1Aijae7 ii1AeThuewei oohaeW0nahm5 ohmoot7Ia6Du pho0vooW4eet cu3eeThioKu9
★以下省略

例2)パスワード長は12文字で、最低1文字の大文字(-c)と数値(-n)、記号(-y)を含め、紛らわしい文字(-B)は含めない。1行1パスワード(-1)で5個生成する。

$ pwgen -c -n -y -B -1 12 5
ashoo3ga(M3W
goo7ke\o4aeL
beiHae4voeH.
AJ3ok3ahj{in
shoo7ExiJ"ir

4. pwmakeを使う

pwmakeは、OSのパスワード認証と関係が深いコマンドで、オプションを指定しなくてもOSのパスワードポリシーに従ったパスワードを生成できる。

pwgenが単独のコマンドなのに対し、pwmakeはRHEL7で採用されたpam_pwquality(libpwquality)モジュールに含まれている。そのためpwmakeの理解にはpam_pwqualityの理解も欠かせないので先に説明する。

4-1. pam_pwqualityとは

pam_pwqualityは「大文字小文字混在、○文字以上のパスワードが必須」といったパスワードポリシーを強制するPAMモジュールだ。passwdコマンドを実行すると、以下の順序でパスワードが評価され、満たしているときだけ設定できる。

  • 辞書チェック
  • 設定ファイル/etc/security/pwquality.confのルールチェック

pam_pwqualityの重要な2つのファイル/etc/pam.d/system-auth/etc/security/pwquality.confを説明する。

パスワードをチェックするPAMモジュールは、Linuxのバージョンや種類によって異なる。詳細は以下のリンクを参照のこと。

RHEL7以降:pam_pwquality
RHEL6:pam_cracklib
Ubuntupam_unix。pam_pwqualityもオプションで使用可能    →Enforce Password Complexity Policy On Ubuntu 18.04

4-1-1. /etc/pam.d/system-auth

このファイルはPAMモジュールの定義ファイルで、pam_pwqualityを呼び出し元になっている。今回の説明と関係ない行もあるのでgrepしたものを紹介する。

メディアからインストールしたときのデフォルトは以下のとおり。クラウドではカスタマイズされていることもある。

# grep ^password /etc/pam.d/system-auth
password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so

次の例では、過去N回のパスワード再利用を防止するためpam_pwhistoryモジュールを併用している。

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type= enforce_for_root
password    requisite     pam_pwhistory.so use_authtok enforce_for_root remember=4
password    sufficient    pam_unix.so sha512 shadow try_first_pass use_authtok enforce_for_root remember=4
password    required      pam_deny.so

参考:RHEL6系の例
RHEL6系ではpam_pwqualityの代わりにpam_cracklibを使用している。パスワードポリシーは後述する設定ファイルではなく、以下のように/etc/pam.d/system-authにインラインで指定する。

password    requisite     pam_cracklib.so retry=3 minlen=8 difok=3 gecoscheck ocredit=-1 dcredit=-1 ucredit=-1 lcredit=-1 enforce_for_root

4-1-2. /etc/security/pwquality.conf

/etc/security/pwquality.confはパスワードのルールを定義する設定ファイルだ。RHEL8系では/etc/security/pwquality.conf.d/pwquality.confのときもある。こちらもファイルが長いのでgrepしたものを紹介する。

# grep -v -e '^\s*#' /etc/security/pwquality.conf

メディアからインストールしたときは、すべてコメントアウトされているので、grepすると何も表示されない。

# Number of characters in the new password that must not be present in the
# old password.
# difok = 5
#
# Minimum acceptable size for the new password (plus one if
# credits are not disabled which is the default). (See pam_cracklib manual.)
# Cannot be set to lower value than 6.
# minlen = 9
★以下省略

多くのクラウドではデフォルト値が設定されていて、Oracle Cloud Infrastructure Computeでは次のように設定されている。簡単に意味を書いたが、詳しくは設定ファイル内のコメントやmanを参考にしてほしい。

difok = 3       # 過去3回のパスワードは利用不可
minlen = 8      # パスワードが8文字以上
dcredit = -1    # 数字が1文字以上
ucredit = -1    # 大文字アルファベットが1文字以上
lcredit = -1    # 小文字アルファベットが1文字以上
ocredit = -1    # 記号が1文字以上
gecoscheck = 1  # /etc/passwdエントリのGECOSフィールドの単語が含まれていない

4-2. pwmakeの実行方法

前置きが長くなったがpwmakeでパスワードを生成しよう。次のようにエントロピービット数を指定する。エントロピービット数を簡単に表すと解読の難易度だ。56以上の数値を指定でき、多くの場合64で十分だ。

pwmake <エントロピービット数>

pwmakeは「pam_pwqualityの設定値」と「エントロピービット数」の両方を考慮してパスワードを生成する。設定ファイルに値がないときは「エントロピービット数」だけを考慮する。次の例を見るとエントロピービット数が大きくなるほどパスワードも長くなっている。

$ pwmake 56
YKHUdiLIj$AH
$ pwmake 64
dEHimAf3PIwUgG
$ pwmake 80
iczaf0D4x@M-EhEGt
$ pwmake 128
Yc4kexIJiw5@sIDM3R6an(ijEDYM

次の例はOracle Cloud Infrastructure Computeで実行した例だ。定義ファイルの内容を反映し、大文字や数値、記号などが含まれている。気に入らないときは複数回実行すればよい。

$ pwmake 64
ErODFOROJ0w+YN

つまりパブリッククラウドのように設定ファイルに定義があるときには非常に便利なコマンドといえる。また定義がないときは大文字・小文字や数値などは運次第だが、強固なパスワードは生成できる。

  • man pwmake
  • man pam_pwquality
  • man pwquality.conf

5. まとめ

  • pwgenは、広い用途で使用できるパスワード生成コマンド
  • pwmakeは、RHEL7系以降でデフォルト・インストールされているパスワード生成コマンド。OSのパスワードポリシーに準じたパスワードを生成するときに便利

今さらOSのログイン・パスワードと思うかも知れないが、一番のきっかけはVNCやxrdpである。これらを使用するときにはクラウドでもパスワードログインが必要だ。

またOracle Cloud InfrastructureやAzure VMのシリアルコンソール接続では、OSユーザーにパスワードを設定する必要がある。

自分で決めた強度の高いパスワードを使ってもよいが、あまり考えずに強度の高いパスワードを生成する方法として、これらのコマンドを活用してはどうだろう。