「セキュリティ」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(→‎カーネルの防御: カーネルロックダウンモードを翻訳して追加)
(→‎カーネルの防御: Linux Kernel Runtime Guard (LKRG)を翻訳して追加)
529行目: 529行目:
   
 
{{man|7|kernel_lockdown}} も参照してください。
 
{{man|7|kernel_lockdown}} も参照してください。
  +
  +
=== Linux Kernel Runtime Guard (LKRG) ===
  +
  +
[https://www.openwall.com/lkrg/ LKRG] ({{AUR|lkrg-dkms}}) は、カーネルの整合性チェックと悪用行為の検出を行うカーネルモジュールです。
   
 
== アプリケーションのサンドボックス化 ==
 
== アプリケーションのサンドボックス化 ==

2022年2月5日 (土) 20:23時点における版

関連記事

この記事では Arch Linux システムを防御するための推奨事項とベストプラクティスを並べています。

目次

概念

  • セキュリティを厳しくするあまりシステムが使い物にならなくなってしまう可能性があります。うまいやり方は度を越さない程度にセキュリティを強化します。
  • セキュリティを高めるために出来ることは数多く存在しますが、一番の脅威はいつだってユーザー自身です。セキュリティを考える時は、多層防御を考える必要があります。ある層が突破されたとしても、他の層が攻撃を防御しなくてはなりません。ただし全てのネットワークからマシンを切断して、金庫にしまって決して使わないかぎり、システムを100%セキュアにすることは不可能です。
  • 少しだけ病的なまでの心配性 (パラノイド) になりましょう。それは役に立ちます。そして疑り深くなってください。話がうますぎるように聞こえたら、おそらくその通りです。
  • 最小権限の原則: システムの各部位は使用に必要なことにだけしかアクセスできないようにするべきで、それ以上は必要ありません。

パスワード

パスワードは安全な linux システムのかぎです。パスワードはユーザーアカウント, 暗号化されたファイルシステム, SSH/GPG 鍵などを守ります。コンピュータを使用する人を信頼するのに使う主要な手段なので、安全なパスワードを選んでそれを保護するというのがセキュリティの大部分と言っても過言ではありません。

強力なパスワードの選び方

パスワードは簡単に割り出されたりまたは個人情報から類推されないようにすることが重要です。そういうわけで、辞書に載っている単語やあなたの飼っている犬の名前などは使わないようにしましょう。パスワードは出来るだけ8文字以上で、小文字と大文字を混ぜてください。さらに数字や特殊文字も1文字以上含めると良いでしょう。当たり前ですが、長くて複雑なパスワードが基本的に良いパスワードとされます。

pwgenapgAUR などのツールは安全なパスワードを生成するのに役立ちます。

また、ある文章の各単語の一番最初を取ってパスワードを作ることもできます。 例えば “the girl is walking down the rainy street” なら “t6!WdtR5” とパスワードにすることができます。この方法はパスワードを覚えるのをずっと簡単にしてくれます。さらに、入力するのが面倒くさくなりますがパスワードを “The girl is walking down the rainy street" にすることも可能です。

パスワードの管理

強固なパスワードを選び出したら、それを安全に保管してください。心理操作ショルダーサーフィンに注意したり、セキュアでないサーバーから必要以上に情報が流出するのをふせぐためにパスワードを再利用しないようにしてください。pass, keepassxAUR, gnome-keyring などのツールは大量の複雑なパスワードを管理するのに役立ちます。Lastpass はデバイス間で同期するためにオンラインで暗号化されたパスワードを保存するサービスですが、クローズドソースのコードと外部の企業の両方を信頼する必要があります。

概して、安全なパスワードは覚えにくいからといって安全でないパスワードを使ってはいけません。パスワードはバランスを取る必要があります。弱いパスワードをたくさん作るよりは、安全なパスワードの暗号化されたデータベースを作り、一つの強いマスターパスワードで守るほうが良いでしょう。パスワードを紙に書くのも、物理的なセキュリティを必要としますがソフトウェアの脆弱性を防ぐ点では同じくらい有効です [1]

パスワードのハッシュ

警告: SHA512 は高速なハッシュ関数として設計されており、パスワードのハッシュ用には作られていません。bcrypt や scrypt などに比べて SHA512 によってハッシュ化されたパスワードには攻撃者ははるかに高速にブルートフォース攻撃をすることができます。

デフォルトの Arch のハッシュ sha512 はとても強固で変更する必要はありません。デフォルトでは、/etc/shadow にパスワードがハッシュ化されて保存され、root にだけ読み取り許可を与え、/etc/passwd にはユーザー識別子だけが保存されます。従って、root ユーザーが安全である限り、ファイルが外部システムにコピーされたり解読されることはありえません。

How are passwords stored in Linux (Understanding hashing with shadow utils) も参照してください。

pam_cracklib を用いた強力なパスワードの強制

pam_cracklib辞書攻撃からの防御を提供し、システム全体で強制するパスワードポリシーの設定を補助します。

警告: root アカウントはこのポリシーの影響を受けません。
ノート: root アカウントを利用することで望ましい/設定されたポリシーを迂回したユーザーのパスワードを設定することができます。これは一時的なパスワードを設定するときに便利です。

例えば以下のようなポリシーを強制させたい場合:

  • エラー時に2回パスワードプロンプト
  • 最小で10文字の長さ (minlen オプション)
  • 新しくパスワードを設定する場合、少なくとも6文字は古いパスワードと異なる (difok オプション)
  • 少なくとも1文字数字を含む (dcredit オプション)
  • 少なくとも1文字は大文字を含む (ucredit オプション)
  • 少なくとも1文字は異なる文字を含む (ocredit オプション)
  • 少なくとも1文字は小文字を含む (lcredit オプション)

/etc/pam.d/passwd ファイルを以下のように書き換えます:

#%PAM-1.0
password required pam_cracklib.so retry=2 minlen=10 difok=6 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1
password required pam_unix.so use_authtok sha512 shadow

password required pam_unix.so use_authtok でパスワードのプロンプトを表示するときに pam_unix モジュールではなく pam_cracklib によるプロンプトを使うようになります。

詳細な情報については pam_cracklib(8) と pam_unix(8) の man ページを参照してください。

CPU

マイクロコード

CPU のマイクロコードに対する重要なセキュリティ更新プログラムをインストールする方法については、マイクロコード を参照してください。

ハードウェアの脆弱性

CPU の中には、ハードウェアの脆弱性を含んでいるものがあります。これらの脆弱性の一覧と、特定の使用シナリオに合わせてこれらの脆弱性を緩和するためにカーネルをカスタマイズするのに役立つ緩和策の選択ガイドについては、kernel documentation on hardware vulnerabilities を参照してください。

既知の脆弱性の影響を受けているかどうかを確認するには、以下を実行してください。

$ grep -r . /sys/devices/system/cpu/vulnerabilities/

ほとんどの場合、カーネルとマイクロコードを更新することで、脆弱性を軽減することができます。

同時マルチスレッディング (ハイパースレッディング)

同時マルチスレッディング] (SMT) は、インテル CPU のハイパースレッディングとも呼ばれ、L1 Terminal Fault および Microarchitectural Data Sampling 脆弱性の原因となる可能性のあるハードウェア機能です。Linux カーネルとマイクロコードのアップデートには、既知の脆弱性に対する緩和策が含まれていますが、信頼できない仮想化ゲストが存在する場合、特定の CPU で SMT を無効にしたほうが良い場合があります。

SMT は、システムのファームウェアで無効にできることがよくあります。詳細については、マザーボードまたはシステムのドキュメントを参照してください。また、以下の カーネルパラメータ を追加することで、カーネルで SMT を無効にすることができます。

l1tf=full,force mds=full,nosmt mitigations=auto,nosmt nosmt=force

メモリ

ハード化された malloc

hardened_malloc (hardened_mallocAUR, hardened-malloc-gitAUR) は glibc の malloc() をハード化した代替品です。元々は Android の Bionicmusl に組み込むために開発されましたが、 x86_64 アーキテクチャの標準 Linux ディストリビューションのサポートにも組み込みました。

hardened_malloc はまだ glibc に統合されていませんが(支援とプルリクエストは歓迎します)、LD_PRELOAD と一緒に簡単に使用することができます。これまでのテストでは、 /etc/ld.so.preload でグローバルに有効にすると、 一握りのアプリケーションにしか問題を起こしません。例えば、getrandom が標準のホワイトリストにないため、seccomp 環境フラグが無効でないと man は正常に動作しませんが、これはシステムコールを追加して再構築すれば簡単に修正可能です。hardened_malloc は性能上のコストがあるので、どの実装を使うかは攻撃対象領域と性能上の必要性に基づいてケースバイケースで決めるとよいでしょう。

スタンドアロンで試すには、hardened-malloc-preload ラッパー スクリプトを使用するか、適切なプリロード値でアプリケーションを手動で開始します。

LD_PRELOAD="/usr/lib/libhardened_malloc.so" /usr/bin/firefox

Firejail の正しい使い方は、その wiki ページにあります。また、hardened_malloc の設定可能なビルドオプションは、githubレポで見つけることができます。

ストレージ

ディスク暗号化

ディスク暗号化、特に強固なパスフレーズによる完全ディスク暗号化は、物理的なリカバリからデータを守る唯一の方法です。コンピュータの電源がオフになっていて問題のディスクがアンマウントされている時は完璧なセキュリティを提供します。

しかしながら、コンピュータの電源が入れられてドライブがマウントされると、そのデータは暗号化されていないドライブと同じように無防備になります。そのためデータが必要なくなったときはすぐにデータのパーティションをアンマウントするのが最善です。

Dm-crypt など特定のプログラムでは、ループファイルを物理ボリュームとして暗号化することができます。これはシステムの特定部分だけを守りたいときに完全なディスク暗号化の代わりの選択肢となりえます。

ファイルシステム

現在カーネルは fs.protected_hardlinksfs.protected_symlinks sysctl スイッチが有効になっていればハードリンクやシンボリックリンクに関するセキュリティの問題を解決するので、world-writable なディレクトリを分離させるセキュリティ的な利点はもはや存在しません。

それでもディスク容量が消耗したときのダメージを低減させる荒っぽい方法として world-writable なディレクトリを含むパーティションが分割されることがあります。しかしながら、サービスを落とすには /var/tmp などのパーティションを一杯にするだけで十分です。この問題の対処についてはもっと柔軟性のある方法が存在します (クォータなど)、またファイルシステムによっては関連する機能を持っていることがあります (btrfs はサブボリュームにクォータを設定できます)。

マウントオプション

最小権限の原則に従って、パーティションは (機能性を失わない限りで) 最も制限的なマウントオプションを使ってマウントすると良いでしょう。

  • nodev: ファイルシステム上のキャラクタ・ブロック特殊デバイスを解釈しない。
  • nosuid: set-user-identifier や set-group-identifier ビットの効果を許可しない。
  • noexec: マウントされたファイルシステム上の全てのバイナリの直接実行を許可しない。
ノート: データパーティションはいつでも nodev, nosuid, noexec でマウントするべきです。
パーティション nodev nosuid noexec
/var yes yes yes [1] [2]
/home yes yes yes (wine や steam を使用しない場合 [2])
/dev/shm yes yes yes
/tmp yes yes no (パッケージをコンパイルできなくなる可能性があります)
/boot yes yes yes

[1] パッケージによっては (例えば nvidia-dkms) /varexec を必要とすることがあるので注意してください。

[2] noexec がパーティションに設定されている場合、Qt 5.8 以上では QML を使用するアプリケーションがクラッシュしたり機能しなくなることがあります。解決方法は Qt#Qt 5.8 で QML を使用するアプリケーションがクラッシュあるいは動作しないを参照。

ファイルシステムのパーミッション

デフォルトのファイルシステムのパーミッションはほぼ全ての読み取りアクセスが許可されているため、パーミッションを変更することで httpnobody ユーザーなど root 以外のアカウントへのアクセスを手に入れた攻撃者から重要な情報を隠すことができます。

例えば:

# chmod 700 /boot /etc/{iptables,arptables}

デフォルトの Umask を変更することで新しく作成したファイルのセキュリティを向上させることができます。NSA RHEL5 Security Guide はセキュリティを最大化させるために 077 の umask を提案しています、これは新しいファイルの所有者以外のユーザーによる読み取りを出来なくします。umask を変更するには、Umask#マスクの値を設定を参照してください。

ユーザー設定

root アカウントを日常的に使用しない

最小特権の原則に従い、root ユーザーを日常的に使用しないようにしてください。システムを使用する各人に非特権ユーザーアカウントを作成するか。一時的な特権アクセスには、必要に応じて sudo を使用する。

ログイン失敗後の遅延時間の設定

以下の行を /etc/pam.d/system-login に追加し、ログインに失敗した際に最低4秒の遅延を追加します。

/etc/pam.d/system-login
auth optional pam_faildelay.so delay=4000000

4000000 は遅延させる時間をマイクロ秒単位で指定します。

3回ログインを失敗したユーザーをロックアウトする

pambase 20200721.1-2 の時点では 、デフォルトで pam_faillock.so が有効になっており、15分間に3回ログインに失敗すると10分間ユーザをロックアウトします (FS#67644 を参照してください) このロックアウトはパスワード認証 (例:ログインと sudo) にのみ適用され、SSH 経由の公開鍵認証はそのまま利用可能です。 完全なサービス拒否を防ぐために、このロックアウトは root では無効になっています。

ユーザーをロック解除するには、次のようにします。

$ faillock --reset --user username

デフォルトでは、ロック機構は /run/faillock/ にあるユーザーごとのファイルです。ディレクトリの所有者は root ですが、ファイルの所有者はユーザーなので、 faillock コマンドはファイルを空にするだけで、root は必要ありません。

モジュール pam_faillock.so は、ファイル /etc/security/faillock.conf で設定することが可能です。ロックアウトのパラメータです。

  • unlock_time - ロックアウト時間 (秒単位、デフォルトは10分)
  • fail_interval - ロックアウトに失敗するとロックアウトされる時間 (秒単位、デフォルトは15分)
  • deny - ロックアウトするまでに何回ログインに失敗するか (デフォルトは 3)
ノート: deny = 0 はロックアウトを無効化します

デフォルトでは、すべてのユーザーロックは再起動後に失われます。攻撃者がマシンをリブートできるのであれば、ロックは持続させた方が安全です。ロックを持続させるには、/etc/security/faillock.confdir パラメータを /var/lib/faillock に変更する必要があります。

変更を反映させるために再起動する必要はありません。root アカウントのロックアウトを有効にする、集中ログイン (LDAP など) を無効にするなど、さらなる設定オプションについては faillock.conf(5) を参照してください。

プロセスの数を制限する

信頼できないユーザーが大量に存在するシステムでは、一度に実行できるプロセスの数を制限して、フォーク爆弾などのサービス拒否攻撃を予防することが重要です。ユーザーやグループごとに実行できるプロセスの数は /etc/security/limits.conf で定義することができ、デフォルトでは空になっています。以下の値をファイルに追加すると、実行できるプロセスが100個までに制限されます。prlimit コマンドを使って一時的に上げられる最大数も200個までに制限します。ユーザーが普段実行するプロセスの数や、管理するハードウェアにあわせて適切な値に変更してください。

* soft nproc 100
* hard nproc 200

Wayland を使用する

Xorg よりも Wayland を使用することをお勧めします。Xorg の設計は現代のセキュリティ慣行より古く、多くの人が は安全でないと考えています 例えば、Xorg のアプリケーションは非アクティブな状態でもキーストロークを記録することがあります。

もし Xorg を実行しなければならないなら、root での実行を避けることが推奨されます。Wayland 内では、XWayland 互換レイヤーは自動的に root レス Xorg を使用します。

root の制限

root ユーザーは、定義上、システムで最も強力なユーザーです。このため、root ユーザーの権限を維持しながら害を及ぼす力を制限する、もしくは root ユーザーの行動をもっと追跡できるようにする方法が多数存在します。

su の代わりに sudo を使う

色々な理由から特権アクセスには su よりも sudo を使うほうが好ましいとされます。

  • 通常の権限しか持たないユーザーが実行した特権コマンドのログを保持します。
  • root アクセスを必要とする各ユーザーに root ユーザーのパスワードを与える必要がありません。
  • 完全な root ターミナルは作成されないため、sudo は root アクセスが必要ないコマンドを偶発的に root で実行してしまうことを防止します。これは最小権限の原則と合っています。
  • 一つのコマンドを実行するためだけに完全な root アクセスを与える代わりに、ユーザーごとに個々のプログラムを有効にすることができます。例えば、ユーザー alice に特定のプログラムへのアクセス権限を与えるには:
# visudo
/etc/sudoers
alice ALL = NOPASSWD: /path/to/program

また、全てのユーザーに個別のコマンドを許可することも可能です。通常ユーザーでサーバーから Samba 共有をマウントするには:

%users ALL=/sbin/mount.cifs,/sbin/umount.cifs

これによって users グループのメンバーである全てのユーザーが全てのマシン (ALL) から /sbin/mount.cifs/sbin/umount.cifs コマンドを実行できるようになります。

ヒント: visudovi の代わりに nano を使うには:
/etc/sudoers
Defaults editor=/usr/bin/rnano

# EDITOR=nano visudo のエクスポートは何にでも EDITOR として使うことができるためにセキュリティリスクとされています。

sudo を使ってファイルを編集する

root で vim などのテキストエディタを使用するのはセキュリティ上の脆弱性になりえます。ユーザーは任意のシェルコマンドを実行でき、コマンドを実行したユーザーのログが残らないからです。これを解決するには、以下をシェルの設定ファイルに追加してください:

export SUDO_EDITOR=rvim

ファイルの編集には sudoedit filename または sudo -e filename を使って下さい。自動的に rvim によって filename が編集されるようになり、テキストエディタからのシェルコマンドが無効になります。

root ログインの制限

sudo を適切に設定することで、ユーザビリティをあまり下げることなく完全な root アクセスを大分制限することが可能です。sudo を使える状態のまま root を無効化したい場合、passwd -l root を使用します。

特定のユーザーだけに許可を与える

PAMpam_wheel.sowheel グループに入っているユーザーだけに su を使用したログインを許可します。/etc/pam.d/su/etc/pam.d/su-l の両方を編集して次の行をアンコメントしてください:

# Uncomment the following line to require a user to be in the "wheel" group.
auth		required	pam_wheel.so use_uid

特権コマンドを実行できる既存のユーザーだけが root でログインできるようになります。

ssh ログインを拒否する

ローカルユーザーの root ログインを拒否したくない場合でも、SSH による root ログインを拒否するのがグッドプラクティスです。この目的は、ユーザーがリモートでシステムを完全に手にかける前にセキュリティ層を追加することにあります。

access.conf で許容されるログインの組み合わせを指定する

誰かが PAM でログインしようとすると、 /etc/security/access.conf がそのログインプロパティに一致する最初の組み合わせをチェックします。そして、その組み合わせのルールに基づいて、試行が失敗するか成功するかが決まります。

+:root:LOCAL
-:root:ALL

特定のグループやユーザーに対してルールを設定することができます。この例では、ユーザー archie は、wheel および adm グループに属するすべてのユーザーと同様に、ローカルでのログインを許可されています。それ以外のログインは拒否されます。

+:archie:LOCAL
+:(wheel):LOCAL
+:(adm):LOCAL
-:ALL:ALL

詳しくは access.conf(5) で確認してください。

強制アクセス制御

強制アクセス制御 (Mandatory Access Control, MAC) は Arch やほとんどの Linux ディストリビューションで使われている任意アクセス制御 (Discretionary Access Control, DAC) とは大きく異なるタイプのセキュリティポリシーです。原則的に MAC ではシステムに影響を与えるプログラムの行動は全てセキュリティルールセットによってチェックを受けます。このルールセットは、DAC とは対照的に、ユーザーが変更することは不可能です。実装方法は色々と異なるタイプが存在しますが、強制アクセス制御を使うことで実質的にコンピュータのセキュリティを著しく向上させることになります。

パス名 MAC

パス名ベースのアクセス制御は指定されたファイルのパスに基づいてパーミッションを与えるというシンプルな形式のアクセス制御です。この形式のアクセス制御の欠点としてはファイルが移動されてもパーミッションはファイルと一緒に付いていかないということが挙げられます。プラス面となるのは、パス名ベースの MAC はラベルベースの MAC と異なり、幅広いファイルシステムに実装できることです。

  • AppArmorCanonical によって開発されている MAC 実装で SELinux に比べて"簡単"になっています。
  • Tomoyo はもうひとつのシンプルで、使いやすい強制アクセス制御を提供するシステムです。利用と実装の両面でシンプルになるように設計されており、依存するライブラリがとても少なくなっています。

ラベル MAC

ラベルベースのアクセス制御ではファイルの拡張属性を使ってセキュリティパーミッションを管理します。このシステムはセキュリティの機能においてパス名ベースの MAC よりも間違いなく柔軟性が高い一方、拡張属性をサポートしているファイルシステムでしか動作しません。

  • SELinux は、Linux セキュリティを向上させる NSA プロジェクトに基づいており、システムユーザーやロールとは完全に独立して MAC を実装しています。成長してオリジナルの設定が変わっていくシステムのコントロールを簡単に維持できる、極めて強固なマルチレベル MAC ポリシー実装を提供します。

アクセス制御リスト

アクセス制御リスト (Access Control List, ACL) は何らかの方法で直接ファイルシステムにルールを付加する代わりとなる手段です。ACL はプログラムの行動を許可された挙動のリストでチェックすることによりアクセス制御を実装しています。

カーネルの防御

カーネルの自己防衛機能/脆弱性攻撃対策

linux-hardened パッケージは basic kernel hardening patch setlinux パッケージよりもセキュリティに重点を置いたコンパイル時設定オプションを使用します。カスタムビルドでは、セキュリティ寄りのデフォルトとは異なる、セキュリティと性能の妥協点を選択することができます。

しかし、このカーネルを使うといくつかのパッケージが動かなくなることに注意する必要があります。例えば

NVIDIA などのアウトオブツリードライバを使用している場合、その DKMS パッケージに切り替える必要があるかもしれません。

ユーザー空間 ASLR の比較

linux-hardened パッケージは、ユーザ空間プロセス用のアドレス空間レイアウトランダム化の改良された実装を提供します。paxtest コマンドは提供されるエントロピーの推定値を得るために使用されます。

64 ビット プロセス
linux-hardened 5.4.21.a-1-hardened
Anonymous mapping randomization test     : 32 quality bits (guessed)
Heap randomization test (ET_EXEC)        : 40 quality bits (guessed)
Heap randomization test (PIE)            : 40 quality bits (guessed)
Main executable randomization (ET_EXEC)  : 32 quality bits (guessed)
Main executable randomization (PIE)      : 32 quality bits (guessed)
Shared library randomization test        : 32 quality bits (guessed)
VDSO randomization test                  : 32 quality bits (guessed)
Stack randomization test (SEGMEXEC)      : 40 quality bits (guessed)
Stack randomization test (PAGEEXEC)      : 40 quality bits (guessed)
Arg/env randomization test (SEGMEXEC)    : 44 quality bits (guessed)
Arg/env randomization test (PAGEEXEC)    : 44 quality bits (guessed)
Offset to library randomisation (ET_EXEC): 34 quality bits (guessed)
Offset to library randomisation (ET_DYN) : 34 quality bits (guessed)
Randomization under memory exhaustion @~0: 32 bits (guessed)
Randomization under memory exhaustion @0 : 32 bits (guessed)
linux 5.5.5-arch1-1
Anonymous mapping randomization test     : 28 quality bits (guessed)
Heap randomization test (ET_EXEC)        : 28 quality bits (guessed)
Heap randomization test (PIE)            : 28 quality bits (guessed)
Main executable randomization (ET_EXEC)  : 28 quality bits (guessed)
Main executable randomization (PIE)      : 28 quality bits (guessed)
Shared library randomization test        : 28 quality bits (guessed)
VDSO randomization test                  : 20 quality bits (guessed)
Stack randomization test (SEGMEXEC)      : 30 quality bits (guessed)
Stack randomization test (PAGEEXEC)      : 30 quality bits (guessed)
Arg/env randomization test (SEGMEXEC)    : 22 quality bits (guessed)
Arg/env randomization test (PAGEEXEC)    : 22 quality bits (guessed)
Offset to library randomisation (ET_EXEC): 28 quality bits (guessed)
Offset to library randomisation (ET_DYN) : 28 quality bits (guessed)
Randomization under memory exhaustion @~0: 29 bits (guessed)
Randomization under memory exhaustion @0 : 29 bits (guessed)
linux-lts 4.19.101-1-lts
Anonymous mapping randomization test     : 28 quality bits (guessed)
Heap randomization test (ET_EXEC)        : 28 quality bits (guessed)
Heap randomization test (PIE)            : 28 quality bits (guessed)
Main executable randomization (ET_EXEC)  : 28 quality bits (guessed)
Main executable randomization (PIE)      : 28 quality bits (guessed)
Shared library randomization test        : 28 quality bits (guessed)
VDSO randomization test                  : 19 quality bits (guessed)
Stack randomization test (SEGMEXEC)      : 30 quality bits (guessed)
Stack randomization test (PAGEEXEC)      : 30 quality bits (guessed)
Arg/env randomization test (SEGMEXEC)    : 22 quality bits (guessed)
Arg/env randomization test (PAGEEXEC)    : 22 quality bits (guessed)
Offset to library randomisation (ET_EXEC): 28 quality bits (guessed)
Offset to library randomisation (ET_DYN) : 28 quality bits (guessed)
Randomization under memory exhaustion @~0: 28 bits (guessed)
Randomization under memory exhaustion @0 : 28 bits (guessed)
32ビットプロセス(x86_64カーネル上)
linux-hardened
Anonymous mapping randomization test     : 16 quality bits (guessed)
Heap randomization test (ET_EXEC)        : 22 quality bits (guessed)
Heap randomization test (PIE)            : 27 quality bits (guessed)
Main executable randomization (ET_EXEC)  : No randomization
Main executable randomization (PIE)      : 18 quality bits (guessed)
Shared library randomization test        : 16 quality bits (guessed)
VDSO randomization test                  : 16 quality bits (guessed)
Stack randomization test (SEGMEXEC)      : 24 quality bits (guessed)
Stack randomization test (PAGEEXEC)      : 24 quality bits (guessed)
Arg/env randomization test (SEGMEXEC)    : 28 quality bits (guessed)
Arg/env randomization test (PAGEEXEC)    : 28 quality bits (guessed)
Offset to library randomisation (ET_EXEC): 18 quality bits (guessed)
Offset to library randomisation (ET_DYN) : 16 quality bits (guessed)
Randomization under memory exhaustion @~0: 18 bits (guessed)
Randomization under memory exhaustion @0 : 18 bits (guessed)
linux
Anonymous mapping randomization test     : 8 quality bits (guessed)
Heap randomization test (ET_EXEC)        : 13 quality bits (guessed)
Heap randomization test (PIE)            : 13 quality bits (guessed)
Main executable randomization (ET_EXEC)  : No randomization
Main executable randomization (PIE)      : 8 quality bits (guessed)
Shared library randomization test        : 8 quality bits (guessed)
VDSO randomization test                  : 8 quality bits (guessed)
Stack randomization test (SEGMEXEC)      : 19 quality bits (guessed)
Stack randomization test (PAGEEXEC)      : 19 quality bits (guessed)
Arg/env randomization test (SEGMEXEC)    : 11 quality bits (guessed)
Arg/env randomization test (PAGEEXEC)    : 11 quality bits (guessed)
Offset to library randomisation (ET_EXEC): 8 quality bits (guessed)
Offset to library randomisation (ET_DYN) : 13 quality bits (guessed)
Randomization under memory exhaustion @~0: No randomization
Randomization under memory exhaustion @0 : No randomization

カーネルログへのアクセスを制限する

ノート: linux-hardened ではデフォルトで有効になっています。

カーネルログにはカーネルの脆弱性を突こうとしている攻撃者にとって有益な情報、保護が必要なメモリーアドレスなどが含まれています。kernel.dmesg_restrict フラグは (デフォルトで root として実行しているプロセスしか持たない) CAP_SYS_ADMIN ケイパビリティのないログへのアクセスを禁止します。

/etc/sysctl.d/50-dmesg-restrict.conf
kernel.dmesg_restrict = 1

proc ファイルシステムのカーネルポインタへのアクセスを制限する

ノート: linux-hardened ではデフォルトで kptr_restrict=2 と設定されています。

kernel.kptr_restrict を有効にすると CAP_SYSLOG のない通常ユーザーから /proc/kallsyms のカーネルシンボルのアドレスが秘匿され、動的にアドレス・シンボルを解決するカーネル exploit が難しくなります。これは事前にコンパイルされた Arch Linux カーネルではあまり意味がありません、周到な攻撃者はカーネルパッケージをダウンロードしてそこから手動でシンボルを取得することができるからです。しかしながら自分でカーネルをコンパイルする場合は、ローカルの root 攻撃を減らす効果があります。ただし root 以外のユーザーで使用する場合いくつかの perf コマンドが破壊されます (メインの perf 機能には結局 root アクセスが必要になりますが)。詳しくは FS#34323 を見て下さい。

/etc/sysctl.d/50-kptr-restrict.conf
kernel.kptr_restrict = 1

BPF のハードニング

BPF は、実行時にカーネル内のバイトコードを動的にロードして実行するために使用されるシステムです。ネットワーク (XDP, tc など)、トレース (kprobes, uprobes, tracepoints など)、セキュリティ (seccomp など) など、多くの Linux カーネルサブシステムで使用されています。また、高度なネットワークセキュリティ、パフォーマンスプロファイリング、ダイナミックトレースにも有効です。

BPF はもともと Berkeley Packet Filter の頭文字をとったもので、オリジナルの古典的な BPF は BSD 用のパケットキャプチャツールに使われていたためである。これは最終的に拡張 BPF (eBPF) に発展し、その後まもなくただの BPF (頭字語ではありません) に改名されました。BPFはパケットフィルタリングツールの実装に使われることがありますが、 iptables や netfilter のようなパケットフィルタリングツールと混同しないでください。

BPF のコードは解釈されるか、Just-In-Time (JIT) compiler を使ってコンパイルされるかのどちらかである。Arch のカーネルは CONFIG_BPF_JIT_ALWAYS_ON でビルドされており、BPF インタープリタを無効にして全ての BPF を JIT コンパイラでコンパイルするよう強制しています。これにより、攻撃者が BPF を使って SPECTRE 型の脆弱性を悪用したエスカレーション攻撃をすることが難しくなります。詳しくは the kernel patch which introduced CONFIG_BPF_JIT_ALWAYS_ON を参照してください。

カーネルは JIT コンパイルされた BPF に対して、パフォーマンスと多くの BPF プログラムをトレース・デバッグする能力を犠牲にして、ある種の JIT スプレー攻撃を軽減するためのハードニング機能を備えています。この機能は net.core.bpf_jit_harden1 に設定することによって有効になります。(非特権コードのハードニングを有効にする) または 2 です。(すべてのコードのハードニングを有効にする)。

詳しくは、カーネルドキュメントnet.core.bpf_* 設定を参照してください。

ヒント:
  • linux-hardened では、デフォルトで net.core.bpf_jit_harden=2 が設定されており、 0 ではありません。
  • デフォルトでは、BPFプログラムは非特権ユーザでも実行可能です。この挙動を変更するには kernel.unprivileged_bpf_disabled=1 [2] を設定してください。

ptrace スコープ

kernel.yama.ptrace_scope フラグによって、Arch は Yama LSM をデフォルトで有効にしています。このフラグはプロセスが CAP_SYS_PTRACE のないスコープの外で他のプロセスに ptrace コールを実行するのを止めます。多くのデバッグツールがいくつかの機能を使うためにこれを必要としますが、セキュリティの面では飛躍的な改善になります。この機能がないと、名前空間のような外部レイヤーを適用しないかぎり同一ユーザーで動作するプロセスの分割は基本的に行われません。デバッガを既存プロセスにアタッチできることはこの欠点のデモンストレーションです。

破壊される機能の例

ノート: sudo を使って特定のユーザーに、パスワード有り無しで許可を与えたりすることで、root で以下のコマンドを実行することは可能です。
  • gdb -p $PID
  • strace -p $PID
  • perf trace -p $PID
  • reptyr $PID

リンクの TOCTOU 攻撃を防止する

この機能が追加された日時や根拠についてはこの commit メッセージを見て下さい。

fs.protected_hardlinks = 1
fs.protected_symlinks = 1
ノート: 現在は /usr/lib/sysctl.d/50-default.conf によってデフォルトで有効にされています。

hidepid

通常は /proc から他のユーザーのプロセスを確認することができますが、カーネルにはプロセスを秘匿する機能が存在し proc ファイルシステムを hidepid=gid= オプションを使ってマウントすることで有効になります。詳しいドキュメントは こちら に存在します。

プロセスを隠すことで侵入者は動作中のプロセスに関する情報を得るのが難しくなります (どのデーモンが特権権限で動作しているか、プログラムの実行に使われているユーザーはどれか、など)。さらに、引数で機密情報を渡すような問題のあるプログラムから情報が漏れてしまうことを防ぎます。

filesystem パッケージに含まれている proc グループはホワイトリストとして機能し、グループに含まれているユーザーは他のユーザーのプロセス情報を閲覧することが可能です。/proc/<pid> ディレクトリから他のユーザーの情報を得る必要があるユーザーやサービスがある場合、グループにユーザーを追加してください。

proc グループに含まれていないユーザーに他のユーザーのプロセス情報を表示しない設定は以下の通りです:

/etc/fstab
proc	/proc	proc	nosuid,nodev,noexec,hidepid=2,gid=proc	0	0

Xorg を動作させるために systemd-logind の例外を追加する必要があります:

/etc/systemd/system/systemd-logind.service.d/hidepid.conf
[Service]
SupplementaryGroups=proc

モジュールのロードを制限する

デフォルトの Arch カーネルは CONFIG_MODULE_SIG_ALL が有効で、linux パッケージの一部としてビルドされた全てのカーネルモジュールに署名します。これにより、カーネルは有効なキーで署名されたモジュールだけをロードするように制限できます。実際、これはローカルでコンパイルされた、もしくは virtualbox-host-modules-arch などのパッケージによって提供された、ツリー外のモジュールは全てロードできないことを意味します。カーネルモジュールの読み込みは カーネルパラメータ を設定することで制限することができます。module.sig_enforce=1. 詳細は、kernel documentation を参照してください。

kexec を無効にする

Kexec は、現在実行中のカーネルを置き換えることを可能にします。

/etc/sysctl.d/51-kexec-restrict.conf
kernel.kexec_load_disabled = 1
ヒント: kexec は linux-hardened ではデフォルトで無効になっています。

カーネルロックダウンモード

Linux 5.4 以降、カーネルは [3] オプションで ロックダウン機能を獲得しました これは UID 0 (root) とカーネルの間の境界を強化することを目的としています。この機能を有効にすると、ハードウェアやカーネルへの低レベルのアクセスに依存している一部のアプリケーションは動作しなくなる可能性があります。

ロックダウンを使用するには、その LSM が初期化され、ロックダウンモードが設定されている必要があります。

すべての オフィシャルサポートカーネル は LSM を初期化しますが、ロックダウンモードを強制するものはありません。

ヒント: 有効な LSM は cat /sys/kernel/security/lsm

を実行することで確認することができます。

ロックダウンは2つの動作モードがあります。

  • ユーザーランドが実行中のカーネルを変更できるカーネル機能 (kexec, bpf) は無効化されます。
  • confidentiality: ユーザーランドがカーネルから機密情報を抽出するためのカーネル機能も無効化されます。

実行時にカーネルのロックダウンを有効にするには、以下を実行します。

# echo mode > /sys/kernel/security/lockdown

起動時にカーネルのロックダウンを有効にするには、カーネルパラメータ lockdown=mode を使用します。

ノート:
  • カーネルロックダウンを実行時に無効化することはできません。
  • カーネルロックダウンは、ハイバネーション を無効にします。

kernel_lockdown(7) も参照してください。

Linux Kernel Runtime Guard (LKRG)

LKRG (lkrg-dkmsAUR) は、カーネルの整合性チェックと悪用行為の検出を行うカーネルモジュールです。

アプリケーションのサンドボックス化

ノート: 標準の Arch カーネルではユーザー名前空間の CONFIG_USER_NS が設定されていないため、特定のサンドボックス機能がアプリケーションから使えない場合があります。linux-hardened パッケージでは有効になっていますが、非特権での使用はデフォルトで無効になっています。kernel.unprivileged_userns_clonesysctl1 に設定することで使用できるようになりますが、ローカルの権限昇格を引き起こす可能性が高くなるので注意してください。

Firejail

Firejail はアプリケーションやサーバーをサンドボックス化するためのシンプルで使いやすいツールです。Firejail はサーバーだけでなくブラウザなどのインターネットに接続するアプリケーションでも使うことができます。

bubblewrap

bubblewrapFlatpak から開発された setuid サンドボックスアプリケーションです。Firejail よりもリソースの消費力が少なく抑えられています。ファイルパスのホワイトリストなどの機能を欠いていますが、バインドマウントやユーザー/IPC/PID/ネットワーク/cgroup 名前空間の作成ができ、簡単なサンドボックスから 複雑なサンドボックス まで自在に使うことが可能です。

chroot

手動で chroot 監獄を構築する方法もあります。

Linux Containers

他の手段 (KVM や Virtualbox) よりも強力な分離が必要なときは Linux Containers を選択するのもよいでしょう。LXC は仮想ハードウェアを使って擬似的な chroot で既存のカーネル上で動作します。

他の仮想化手段

VirtualBox, KVM, Xen などの完全な仮想化マシンを使うことでもセキュリティを向上させることができます。危険なアプリケーションを実行したり危険なウェブサイトを開いたりするときに役に立つでしょう。

ネットワークとファイアウォール

ファイアウォール

標準の Arch カーネルは Netfilteriptables を使用する能力がありますが、デフォルトでは有効になっていません。公式リポジトリから iptables をインストールして、有効にし、ファイアウォールを設定することが強く推奨されます。

カーネルパラメータ

ネットワークに影響を与えるカーネルパラメータは sysctl を使って設定できます。設定方法は sysctl#TCP/IP スタックの防御 を見て下さい。

SSH

SSH 鍵を必要としない Secure Shell を使うのは避けましょう。これは総当たり攻撃を防ぎます。また、Fail2banSshguard はログを監視して iptables ルールを書き込む方式の保護を提供しますが、攻撃者がアドレスを識別して管理者からのパケットのように偽装することができるため、サービスの妨害が行われる危険性があります。

2段階認証によって認証を強化することができます。Google Authenticator はワンタイムパスコード (OTP) を使用する2段階認証方式を提供します。

root ログインを拒否するのは、侵入追跡と root アクセス前のセキュリティレイヤを追加するという両方の面でグッドプラクティスです。

DNS

DNSSECDNSCrypt を見て下さい。

プロキシ

プロキシはアプリケーションとネットワークの間に挟まる追加レイヤーとして使われ、信頼できないソースからのデータをサニタイズします。少ない権限でプロキシを動作させることで、エンドユーザー権限で複雑なアプリケーションを実行するよりも攻撃対象を小さくすることができます。

例えば glibc の中に実装されている DNS リゾルバを考えてみてください。(root で実行することもある) アプリケーションにリンクされている DNS リゾルバにバグが存在した場合、リモートコード実行につながる危険があります。dnsmasq などの DNS キャッシュサーバーをインストールしてプロキシとして使うことで問題を防ぐことが可能です [4]

SSL 証明書の管理

サーバーサイドの SSL 証明書の管理については OpenSSLNetwork Security Services (NSS) を参照してください。また、関連する Let’s Encrypt プロジェクトも見てください。

デフォルトのインターネット SSL 証明書のトラストチェーンは ca-certificates パッケージによって提供されています。Arch はデフォルトで信頼しても問題ないとされる証明書を提供しているソース (例: ca-certificates-cacertAUR, ca-certificates-mozilla) に依存しています。

デフォルトの証明書を変えたいと思うことがあるかもしれません。例えば、ニュース を読んで証明書を信頼しないようにしたい場合 (ソースのプロバイダーによって無効になるのを待てない場合)、Arch のインフラを使うことで簡単に設定できます:

  1. .crt 形式の証明書を入手してください (例: view, download; 既存のルート認証局の場合、システム内にあるはずです)。
  2. /etc/ca-certificates/trust-source/blacklist/ にコピーしてください。
  3. root で update-ca-trust を実行してください。

お好きなブラウザを開いて信頼できないサイトとして表示されれば、ブラックリストが上手く機能しています。

パッケージの認証

パッケージの署名が適正に使われていないと パッケージマネージャへの攻撃 が考えられ、さらに 適切な署名システム を使っているパッケージマネージャにも影響を与える可能性があります。Arch はデフォルトでパッケージの署名を使用しており5つの信頼されたマスターキーによる web of trust を使っています。詳しくは Pacman-key を見て下さい。

NVD/CVE アラートを購読する

National Vulnerability Database による Common Vulnerabilities and Exposure (CVE) を講読する (NVD のダウンロードページ)。また、Arch Linux セキュリティトラッカー は Arch Linux Security Advisory (ASA), Arch Linux Vulnerability Group (AVG), CVE データセットをまとめた情報を提供しています。Arch CVE モニタリングチームも見てください。

警告: 無理に部分アップデートをしないでください。Arch Linux によってサポートされている手段ではなく、問題が発生する可能性があります。ひとつのコンポーネントをアップグレードする時はシステム全体をアップグレードしてください。システムアップデートをほとんどやらないとアップデートプロセスが複雑になる可能性があります。

物理セキュリティ

ノート: リモート攻撃からコンピュータを守りたいだけの場合はこのセクションは無視してかまいません。

十分な時間とリソースさえあればコンピュータへの物理的なアクセスは root アクセスになります。しかしながら、十分な防御策を張ることで実用的で高いレベルのセキュリティを得ることができます。

攻撃者は悪意のある IEEE 1394 (FireWire), Thunderbolt, PCI Express デバイスを取り付けることでメモリーへの完全なアクセスを手に入れることができ、次に起動した時には簡単にコンピュータの完全なコントロールを手中に収めることができます [5]。これを防ぐために出来ることは限られており、悪意のあるファームウェアをドライブに書き込むなどハードウェア自体の改変に対処することは不可能です。ただし、攻撃者の大部分にはこうした知識がなく実行されることはほとんどありません。

ディスク暗号化はコンピュータが盗まれた場合にデータへのアクセスを防止しますが、あなたが次にログインしたときにデータを取得するために悪意のあるファームウェアが能力のある攻撃者によってインストールされる可能性があります。

BIOS をロックダウンする

BIOS にパスワードを追加することによってリムーバブルメディアから誰かが起動する (これはコンピュータへの root アクセスと基本的に同義です) のを予防します。使用しているドライブがブートの順番で一番最初に来ることを確認して、可能であれば他のドライブのブートを無効にしてください。

ブートローダー

ブートローダーの保護はとても重要です。init=/bin/sh というたった一つのカーネルパラメータで、全てのユーザー・ログイン制限が全くの無に帰します。

Syslinux

Syslinux はブートローダーのパスワード保護をサポートしています。メニューのアイテムごとにパスワードを設定したり、ブートローダー全体にパスワードの保護を設定することが可能です。

GRUB

GRUB も同じくブートローダーのパスワードをサポートしています。詳しくは GRUB/ヒントとテクニック#GRUB メニューのパスワード保護 を見て下さい。

root でのコンソールログインを拒む

コンソールからの root ログインを拒否するよう設定を変更すれば侵入者がシステムへのアクセスを取得するのを難しくすることができます。侵入者はシステムに存在するユーザーの名前とそのユーザーのパスワードを考えなくてはならなくなります。コンソールによって root がログインできるようになっている場合、侵入者が解き当てるのはパスワードだけで十分になります。 コンソールの root ログインのブロックは /etc/securetty の tty 行をコメントアウトすることで行います。

/etc/securetty
#tty1

ブロックしたい tty 全てで同じようにコメントアウトしてください。 変更の効果を確認するには、一つの行だけをコメントアウトしてから特定のコンソールに移って root でのログインを試行してみてください。Login incorrect というメッセージが表示されるはずです。ブロックされたことを確認したら、戻ってから残りの tty 行をコメントアウトしてください。

ノート: ttyS0 が表示された場合は、シリアルコンソール用です。同様に Xen 仮想化システムでは hvc0 は管理者用です。

自動ログアウト

Bash または Zsh を使っている場合、TMOUT によってタイムアウトによるシェルからの自動ログアウトを設定できます。

例えば、以下は仮想コンソールから自動でログアウトします (X11 のターミナルエミュレータからはログアウトしません):

/etc/profile.d/shell-timeout.sh
TMOUT="$(( 60*10 ))";
[ -z "$DISPLAY" ] && export TMOUT;
case $( /usr/bin/tty ) in
	/dev/tty[0-9]*) export TMOUT;;
esac

(X のコンソールも含めて) 全ての Bash/Zsh プロンプトでタイムアウトさせたい場合は、次を使って下さい:

$ export TMOUT="$(( 60*10 ))";

シェルで何かコマンドが動作している間はこのタイムアウトは動作しないので注意してください (例: SSH セッションや TMOUT をサポートしていない他のシェル)。しかしながら固まった GDM/Xorg を root で再起動するのに VC を使っているような場合は、とても有用です。

X からの TTY アクセスをブロック

Xorg#TTY のアクセスをブロックを見てください。

パッケージの再ビルド

パッケージを再ビルドして無駄な機能を省くことで攻撃対象を減らすことができます。例えば bzip2 から bzip2recover を外してビルドすることで CVE-2016-3189 に対処できます。ハードニングフラグは手動で設定したり hardening-wrapper[リンク切れ: パッケージが存在しません] で適用できます。

カスタムハードニングフラグ

以下のビルドフラグを /etc/makepkg.conf で有効にできます。将来的に Arch のデフォルトフラグ となることが予定されています:

  • LDFLAGS: z,now
  • CFLAGS: -fno-plt -fstack-check

hardening-checkAUR を使って標準の bzip2 バイナリの状態を確認:

$ hardening check -v /usr/bin/bzip2
/usr/bin/bzip2:
Position Independent Executable: no, normal executable!
Stack protected: yes
Fortify Source functions: no, only unprotected functions found!
       unprotected: fread
       unprotected: fprintf
       unprotected: strcat
       unprotected: strncpy
       unprotected: strcpy
Read-only relocations: no, not found!
Immediate binding: no, not found!

hardening-checkAUR を使って堅牢化した bzip2 バイナリの状態を確認:

$ hardening check -v /usr/bin/bzip2
/usr/bin/bzip2:
Position Independent Executable: yes
Stack protected: yes
Fortify Source functions: yes (some protected functions found)
       unprotected: memcpy
       unprotected: fread
       unprotected: strncpy
       protected: fprintf
       protected: strcat
Read-only relocations: yes
Immediate binding: yes

checksec を使って標準の bzip2 バイナリの状態を確認:

$ checksec -f /usr/bin/bzip2
RELRO           STACK CANARY      NX                   PIE                RPATH        RUNPATH         FORTIFY Fortified Fortifiable  FILE
No RELRO     Canary found         NX enabled     No PIE          No RPATH  No RUNPATH    Yes         0                    5        /usr/bin/bzip2

checksec を使って堅牢化した bzip2 バイナリの状態を確認:

$ checksec -f /usr/bin/bzip2
RELRO           STACK CANARY      NX                   PIE                RPATH        RUNPATH         FORTIFY Fortified Fortifiable  FILE
Full RELRO    Canary found         NX enabled     PIE enabled  No RPATH  No RUNPATH   Yes         0                    5        /usr/bin/bzip2
ノート: PIE を有効にするとパッケージによっては問題が発生します。その場合は export HARDENING_PIE=0 で無効にできます。

参照