これまでのLinuxでは、ユーザーの追加はuseradd
で行われ、ホームディレクトリは/home
以下にディレクトリとして作られ、ユーザーのアカウントは/etc/passwd
、/etc/group
、/etc/shadow
で管理されていました。
これからは、systemd-homed
がその全ての仕事を置換することになります。
※タイトル詐欺感がありますが、従来の方式も並行して使えます。安心してください。
systemd-homedとは?
systemd バージョン245で追加された、ユーザー管理デーモン。実体はsystemdのサービスユニットファイルで、systemd-homed.service
として起動されます。
今後、ユーザーの管理や認証はsystemd-homed(以下、 homed )によって行われることになるようですね。 出典が無く間違いだったため、訂正しました。systemd-homedを使うかはユーザーの選択であるため、無理に移行する必要はありません。
homed自体は、最新のsystemdをインストールしてある環境であれば自動的に有効化されます。(ただ、使うためには要設定です。後述します。)
homedができること
- ユーザーの作成、削除、編集
-
/etc/passwd
、/etc/group
、/etc/shadow
に変わる、ユーザーごとのJSONファイルによるユーザー情報の管理 - ホームディレクトリの暗号化・復号
- ホームディレクトリへのnosuid,nodev,noexecの付与
- ユーザーの使用リソースの制限
上3つのみ一つずつ説明していきます。
ユーザーの作成、削除、編集
homedでユーザーを管理する場合、useradd
等のコマンドではなくhomectl
コマンドを使うことになります。
もちろん、homedが導入されたLinuxで今後もuseradd
と/etc/passwd
を使ったユーザー管理は継続できるので安心してください。ただ、片方で作成したアカウントはもう片方で管理できません。(互換性がない)
また、homedはNSSに対応しているため(nsswitch.confにsystemdが追記されています)getent
コマンドやglibcを使った従来のソフトウェアでも正しくLinuxユーザーが認識されます。
新しいhomectl
コマンドを簡単に説明します。
-
homectl create <user>
ユーザー追加 -
homectl remove <user>
ユーザー削除 -
homectl update <user>
ユーザー更新 -
homectl passwd <user>
ユーザーのパスワードを変更
createとupdateで指定・変更できるオプションは以下です。※より沢山あるのですが、長いため割愛しています。詳しくはhomectl -h
へ。
General User Record Properties:
-c --real-name=REALNAME Real name for user
--realm=REALM Realm to create user in
--email-address=EMAIL Email address for user
--location=LOCATION Set location of user on earth
--icon-name=NAME Icon name for user
-d --home-dir=PATH Home directory
--uid=UID Numeric UID for user
-G --member-of=GROUP Add user to group
--skel=PATH Skeleton directory to use
--shell=PATH Shell for account
--setenv=VARIABLE=VALUE Set an environment variable at log-in
--timezone=TIMEZONE Set a time-zone
--language=LOCALE Set preferred language
--ssh-authorized-keys=KEYS
Specify SSH public keys
--pkcs11-token-uri=URI URI to PKCS#11 security token containing
private key and matching X.509 certificate
Account Management User Record Properties:
--locked=BOOL Set locked account state
--not-before=TIMESTAMP Do not allow logins before
--not-after=TIMESTAMP Do not allow logins after
--rate-limit-interval=SECS
Login rate-limit interval in seconds
--rate-limit-burst=NUMBER
Login rate-limit attempts per interval
Password Policy User Record Properties:
--password-hint=HINT Set Password hint
--enforce-password-policy=BOOL
Control whether to enforce system's password
policy for this user
-P Equivalent to --enforce-password-password=no
--password-change-now=BOOL
Require the password to be changed on next login
--password-change-min=TIME
Require minimum time between password changes
--password-change-max=TIME
Require maximum time between password changes
--password-change-warn=TIME
How much time to warn before password expiry
--password-change-inactive=TIME
How much time to block password after expiry
Resource Management User Record Properties:
--disk-size=BYTES Size to assign the user on disk
--access-mode=MODE User home directory access mode
--umask=MODE Umask for user when logging in
--nice=NICE Nice level for user
--rlimit=LIMIT=VALUE[:VALUE]
Set resource limits
--tasks-max=MAX Set maximum number of per-user tasks
--memory-high=BYTES Set high memory threshold in bytes
--memory-max=BYTES Set maximum memory limit
--cpu-weight=WEIGHT Set CPU weight
--io-weight=WEIGHT Set IO weight
今までuseraddで指定できたオプションとは別に、追加で色々なリソース制限がかけられるようになっているのがわかります。
※余談ですが、リソース制限を試してみたところ、cgroupがプロセスに適用されていました。だろうね。
また、パスワードの有効期限がユーザーごとに設定可能になった点や、一定時間あたりのログイン試行回数がここで制限できるようになった点もポイントが高いです。
ユーザー情報の管理
homedは、ユーザー情報も管理します。homectlによって作成されたユーザーは、/etc/passwd
、/etc/group
、/etc/shadow
へ記載されません。
そのかわり、
- ユーザー情報はhomedのデーモンが管理し、APIによって情報を提供します。(おそらく
/run/systemd/userdb/io.systemd.Home
ソケット) - また、各ホームディレクトリへ
~/.identity
というファイルが作成され、JSON形式でユーザー情報を確認できます。
~/.identity
は、例えばこんな内容です。
{
"cpuWeight" : 10,
"disposition" : "regular",
"lastChangeUSec" : 1584387192577240,
"lastPasswordChangeUSec" : 1584382416144118,
"memberOf" : [
"testgroup"
],
"perMachine" : [
{
"diskSize" : 10737418240,
"matchMachineId" : [
"48801054a2af8b2c0104ff82c482fe2d"
]
}
],
"privileged" : {
"hashedPassword" : [
"$6$h9kNT.dmjmHXt/i1$ATJy/KnBCXMlmIjBziemYqRa8XUtiVDMCnC.m/iSNNh8zdXfX5V7jJwwsZCJo3PJIv3.C0p/6OXTxN8CXCIcS1"
]
},
"signature" : [
{
"data" : "hoge",
"key" : "-----BEGIN PUBLIC KEY-----\fuga=\n-----END PUBLIC KEY-----\n"
}
],
"userName" : "test"
}
このファイルはrootでなくても読み書きできるので、おそらく本体は別の場所にあるか、もしくはsignature
項目でhomedがこのファイルに署名している気がします。が、両方共私の憶測なのでどうかはわかりません。
userdbctl
ユーザーの作成・更新以外に、ユーザーの情報やグループの情報を確認したい場合はuserdbctl
コマンドを使用します。
user [USER…] Inspect user
group [GROUP…] Inspect group
users-in-group [GROUP…] Show users that are members of specified group(s)
groups-of-user [USER…] Show groups the specified user(s) is a member of
例えばuserdbctl user <ユーザー名>
でそのユーザーの所属グループやホームディレクトリの暗号化状況、リソース制限が確認できます。
ユーザーの認証について
Linuxのユーザーの管理をしているのは、PAM(Pluggable Authentication Modules)です。
pam小話をしましょう。
- PAMの実体はただの設定ファイルと共有ライブラリ(PAMモジュール)です。
- PAMの役割は、ログイン時にログインプロンプトやsshdがユーザーの情報を取得する場合にユーザーの認証情報を確認することです
- 具体的には、TTYからパスワードを取ってきて正しければ成功を返すような共有ライブラリ(PAMモジュール)を、各ログインソフトウェアが実行します。
- 各ソフトウェアは、成功が帰ってきたらデフォルトシェルをそのユーザーで動作させます。
homedのない従来の環境では、「/etc/passwd
と/etc/shadow
を読みに行きパスワードが正しければ成功をソフトウェアへ返すPAMモジュール」が存在し、またデフォルトでそれを使うような設定ファイルになっていました。(細かい話は省略)
homed時代では、このpamに「homedを呼び出しユーザーの認証情報の確認をさせるようなPAMモジュール」を追加します。追加なので、今までのユーザー管理も適用されるというわけです。
ちなみに余談ですが、LDAP認証やNIS認証など、Linuxユーザーのネットワーク管理を行う際にもこのPAMにモジュールを追加しています。
homedのpamを有効にする
※この設定をしない場合、homectl
でユーザーを追加してもログインができません。
homedを使うためには、一応準備が必要です。pamの設定ファイルを更新する必要があります。
おそらく、最新のsystemdが入ったOSをインストールすればデフォルトで更新された設定ファイルが入るのでしょうが、途中でアップデートする我々は設定ファイルを手動で書き換える必要があります。
これは推測ですが、pam設定ファイルは環境によってインストール後に結構編集されるため(LDAP認証のため等)でしょう。
特にpamの設定を弄っていない場合は、pam設定を上書きすれば更新は完了です。
$ sudo cp /usr/share/factory/etc/pam.d/system-auth /etc/pam.d/system-auth
設定を弄っている場合は、diffを見てよしなに設定してください。man pam_systemd_home
を実行すると詳しい設定の方法が確認できます。
ホームディレクトリの暗号化
おそらく、homedでの一番大きな特徴が、ホームディレクトリの暗号化に対応したことです。今まではecryptfs等で一々設定する必要がありました。
homedでは、ユーザー作成時にホームディレクトリの種類を選べます。(--storage=
)
何も指定しない場合、homedはデフォルトでluks
を使用します。
-
directory
… 従来どおり、/home
以下にユーザー名のディレクトリを作成する -
subvolume
…/home
以下に、ユーザー名のbtrfs subvolumeを作成する -
luks
…/home
以下に、LUKS暗号化を使ったホームディレクトリを作成する -
fscrypt
…/home
以下に、FSCryptを使った(略 -
cifs
…/home
以下に、cifs(いわゆるSamba/ネットワーク共有)を使った(略
この内、luks
かfscrypt
を使うと暗号化されます。まあLUKSとFSCrpytを使うので当たり前ですね。特に理由がなければ、fscrypt
よりluks
を使うことをsystemdは推奨しています。
また、このhomedによるluks暗号化は、ユーザーログイン時・ログアウト時の自動復号・自動最暗号化に対応しています。便利ですね。
homedでluks
を使った場合の動作について(おまけ)
homedでluksを使用した場合、/home/
以下にユーザー名.home
と呼ばれる数十GBのサイズのファイルが生成されます。これがどうやらホームディレクトリの本体です。
このファイルはext4
やbtrfs
のイメージファイルになっていて(luks内部をどのファイルシステムにするかは選べます)、これがluks(dm-verity)でブロックストレージごと暗号化されています。
homedはログイン時にこのイメージファイルを復号化しつつ/home/ユーザー名
にマウントするようです。
ユーザーがログインしていないときにホームディレクトリを復号(マウント)するのには、homectl
コマンドを使用します。もちろん復号には復号パスフレーズ(ユーザーのログインパスワードと同じっぽい)が必要です。
-
homectl activate <user>
復号 -
homectl deactivate <user>
暗号化
どうやら復号化された状態を「アクティブ」って呼んでいるみたいですね。ちなみに今どのユーザーがアクティブかどうかはhomectl list
で確認できます。
ここで気づくのが、ユーザーのホームディレクトリへアクセスする場合に復号パスフレーズが必要という点です。root権限を持っていても、ユーザーがログインしていなければ(ユーザーが復号化していなければ)他人のホームディレクトリへアクセスできないのは、セキュリティやプライバシーの観点から大変有利です。
ホームディレクトリのサイズ制限について
homectlで作成したユーザーは、デフォルトでホームディレクトリのサイズが制限されるようです。luksの場合はイメージファイルのサイズが制限されます。
サイズ制限を変更するにはhomectl resize
コマンドが使用できます。
例:
$ homectl resize user1 10G
luksモード時のイメージファイルは、固定イメージファイル(予め容量を確保する方式)のため、最初から空のイメージファイルが数十GB作成されます。非効率だしそこまで使わないので、resizeコマンドで10GB程度に抑えておくのがいいと思います。
まとめ
systemd-homedを紹介しました。これからも従来の方法でユーザー管理は行えます。そのため、現状で問題がない場合は徐々にhomedが浸透するまで長い時間がかかると思います。ただ、Linuxデスクトップユーザーにとっては大変便利なため、興味がある方はぜひ使用してみてください。
長文失礼いたしました&ここまで読んでくれてありがとうございます。