「Arch パッケージガイドライン/セキュリティ」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(→‎PIE: 飜訳)
(→‎RELRO: 情報を更新)
 
(他の1人の利用者による、間の7版が非表示)
1行目: 1行目:
 
[[Category:Arch パッケージガイドライン]]
 
[[Category:Arch パッケージガイドライン]]
 
[[Category:セキュリティ]]
 
[[Category:セキュリティ]]
  +
[[en:Arch package guidelines/Security]]
 
[[pt:Arch package guidelines (Português)/Security]]
 
[[pt:Arch package guidelines (Português)/Security]]
 
このページでは Arch Linux パッケージのセキュリティパッケージングガイドラインを説明します。C/C++ プロジェクトでは、コンパイラとリンカがセキュリティ強化オプションを適用することができます。Arch Linux はデフォルトで PIE, Fortify source, stack protector, nx, relro を適用します。
 
このページでは Arch Linux パッケージのセキュリティパッケージングガイドラインを説明します。C/C++ プロジェクトでは、コンパイラとリンカがセキュリティ強化オプションを適用することができます。Arch Linux はデフォルトで PIE, Fortify source, stack protector, nx, relro を適用します。
14行目: 15行目:
 
RELRO は、ELF バイナリ/プロセスのデータセクションを強化するための一般的な緩和技術です。プログラムがロードされる際、リンカによって書き込まれる必要があるいくつかのELFメモリセクションがありますが、プログラムへの制御を渡す前に読み取り専用にすることができます。これにより、攻撃者がELFセクションをオーバーライドするのを防ぐことができます。RELRO には2つの異なるモードがあります。
 
RELRO は、ELF バイナリ/プロセスのデータセクションを強化するための一般的な緩和技術です。プログラムがロードされる際、リンカによって書き込まれる必要があるいくつかのELFメモリセクションがありますが、プログラムへの制御を渡す前に読み取り専用にすることができます。これにより、攻撃者がELFセクションをオーバーライドするのを防ぐことができます。RELRO には2つの異なるモードがあります。
   
* 部分的な RELRO({{ic|-Wl,-z,relro}}プログラムのロード後、いくつかのセクションが読み取り専用にマークされますが、GOT({{ic|.got.plt}}はまだ書き込み可能です。
+
* 部分的な RELRO({{ic|-Wl,-z,relro}})プログラムのロード後、いくつかのセクションが読み取り専用にマークされますが、GOT({{ic|.got.plt}})はまだ書き込み可能です。
* 完全な RELRO({{ic|-Wl,-z,now}}プログラムのロード中にすべての動的シンボルが解決され、完全なGOTを読み取り専用にマークすることができます。
+
* 完全な RELRO({{ic|-Wl,-z,now}})プログラムのロード中にすべての動的シンボルが解決され、完全なGOTを読み取り専用にマークすることができます。
   
 
アプリケーションが部分的な relro を報告する場合、ビルドツールチェーンが LDFLAGS を渡すか、LDFLAGS をオーバーライドできるかどうかを調べてください。Go パッケージでは、ビルド方法が LDFLAGS を渡すことができない純粋な golang Makefile 置換として{{ic|build.go}} を使用しているかどうかを調べてください。
 
アプリケーションが部分的な relro を報告する場合、ビルドツールチェーンが LDFLAGS を渡すか、LDFLAGS をオーバーライドできるかどうかを調べてください。Go パッケージでは、ビルド方法が LDFLAGS を渡すことができない純粋な golang Makefile 置換として{{ic|build.go}} を使用しているかどうかを調べてください。
22行目: 23行目:
   
 
現時点では、Haskell で完全な RELRO をどのように達成するかは明確ではありません。
 
現時点では、Haskell で完全な RELRO をどのように達成するかは明確ではありません。
  +
  +
=== Go ===
  +
  +
こちらを参照 [[Go パッケージガイドライン#フラグとビルドオプション]]
   
 
== スタックカナリー ==
 
== スタックカナリー ==
27行目: 32行目:
 
[[Wikipedia:Stack canary|スタックカナリー]]は、コンパイラによってスタック上のバッファと制御データの間に追加されます。このよく知られた値が破損している場合、バッファオーバーフローが発生し、プログラムがセグフォールトし、任意のコード実行を防ぐために停止します。
 
[[Wikipedia:Stack canary|スタックカナリー]]は、コンパイラによってスタック上のバッファと制御データの間に追加されます。このよく知られた値が破損している場合、バッファオーバーフローが発生し、プログラムがセグフォールトし、任意のコード実行を防ぐために停止します。
   
{{Pkg|gcc}}パッケージは、デフォルトでスタック保護を有効化しており、[https://github.com/archlinux/svntogit-packages/blob/packages/gcc/trunk/PKGBUILD#L100 --enable-default-ssp]コンパイルオプションによってスタック保護が有効化されています。
+
{{Pkg|gcc}} パッケージは、デフォルトでスタック保護を有効化しており、[https://github.com/archlinux/svntogit-packages/blob/packages/gcc/trunk/PKGBUILD#L100 --enable-default-ssp]コンパイルオプションによってスタック保護が有効化されています。
   
 
== NX ==
 
== NX ==
57行目: 62行目:
 
== RPATH/RUNPATH ==
 
== RPATH/RUNPATH ==
   
  +
RUNPATH/RPATH は、リスト内のオブジェクト(実行可能ファイルおよび共有オブジェクトの両方に使用できる)のさらなる検索パスを提供します。
RUNPATH/RPATH provides further search paths for the object it is listed in (it can be used both for executable and for shared objects).
 
   
 
$ objdump -x /usr/bin/perl | grep -E 'RPATH|RUNPATH'
 
$ objdump -x /usr/bin/perl | grep -E 'RPATH|RUNPATH'
   
If the RPATH value contains a path within an attackers control it can possibly execute code by installing a malicious library in that directory for example [https://nvd.nist.gov/vuln/detail/CVE-2006-1566 CVE-2006-1566] [https://www.cvedetails.com/cve/CVE-2005-4280/ CVE-2005-4280]. See [[Debian:RpathIssue]].
+
RPATH 値に攻撃者が制御できるパスが含まれている場合、例えば [https://nvd.nist.gov/vuln/detail/CVE-2006-1566 CVE-2006-1566] [https://www.cvedetails.com/cve/CVE-2005-4280/ CVE-2005-4280] のように、そのディレクトリに悪意のあるライブラリをインストールすることで、コードが実行される可能性があります。[[Debian:RpathIssue]] を参照してください。
   
The RPATH entry is set by the linker by passing for example the following string to LDFLAGS {{ic|-Wl,-rpath -Wl,/usr/local/lib}}. To make an RUNPATH entry append {{ic|--enable-new-dtags}} to the linker flags.
+
RPATH エントリは、リンカに LDFLAGS に例えば {{ic|-Wl,-rpath -Wl,/usr/local/lib}} といった文字列を渡すことで設定されます。RUNPATH エントリを追加するには、リンカフラグに {{ic|--enable-new-dtags}} を追加してください。
   
 
== FORTIFY ==
 
== FORTIFY ==
   
  +
Fortify Source は、メモリや文字列の操作を行うさまざまな関数にバッファオーバーフロー保護を追加するマクロです。攻撃者がバッファをオーバーフローさせるためにより多くのバイトをコピーしようとしているかどうかをチェックし、プログラムの実行を停止します。この保護はデフォルトの {{ic|CPPFLAGS}} で有効になります。
Fortify source is a macro that adds buffer overflow protection in various functions that perform operations on memory and strings. It checks whether an attacker tries to copy more bytes to overflow a buffer and then stops the execution of the program. This protection is enabled with the default {{ic|CPPFLAGS}}:
 
   
 
{{hc|makepkg.conf|2=
 
{{hc|makepkg.conf|2=
73行目: 78行目:
 
}}
 
}}
   
  +
[[makepkg#設定]] を参照してください。
See [[makepkg#Configuration]].
 
   
== systemd services ==
+
== systemd サービス ==
   
  +
パッケージに上流が提供していない [[systemd]] サービスファイルを同梱する場合、以下の systemd サービスのハードニング機能を適用することを検討してください。Systemd は、サービスで有効になっているセキュリティ機能を分析する方法を提供しています。
If a [[systemd]] service file is shipped with the package due to upstream not providing any, look into applying the following systemd service hardening features. Systemd provides a way to analyse security features which are enabled for a service.
 
   
 
$ systemd-analyze security reflector.service
 
$ systemd-analyze security reflector.service
   
=== File access ===
+
=== ファイルアクセス ===
   
  +
サービスは、ファイルシステムアクセスを制限することでハードニングできます。
A service can be hardened by restricting file system access.
 
   
  +
実行されるプロセスに対して新しいファイルシステムの名前空間を設定し、その中にプライベートな {{ic|/tmp}} および {{ic|var/tmp}} ディレクトリをマウントします。この名前空間外のプロセスとは共有されません。{{ic|/tmp}} にデータを書き込むプログラムに役立ちます。
Set up a new file system namespace for the executed process and mounts private {{ic|/tmp}} and {{ic|var/tmp}} directories inside it that is not shared by processes outside the namespace. Useful for programs which write data to {{ic|/tmp}}.
 
   
 
PrivateTmp=true
 
PrivateTmp=true
   
ProtectSystem has three different varieties of mounting directories as read-only for the executed process. The "full" option mounts {{ic|/usr}}, {{ic|/boot}} and {{ic|/etc}} read only. ProtectHome makes {{ic|/home}}, {{ic|/root}} and {{ic|/run/user}} inaccessible to the executed process.
+
ProtectSystem は、実行されるプロセスに対して読み取り専用でディレクトリをマウントする 3 つの異なる方法を提供しています。"full" オプションは、{{ic|/usr}}{{ic|/boot}}{{ic|/etc}} を読み取り専用でマウントします。ProtectHome は、実行されるプロセスに対して {{ic|/home}}{{ic|/root}}{{ic|/run/user}} をアクセス不可にします。
   
 
ProtectSystem=strict
 
ProtectSystem=strict
 
ProtectHome=true
 
ProtectHome=true
   
  +
実行されるプロセスに対して新しい {{ic|/dev}} 名前空間を設定し、{{ic|/dev/null}} や {{ic|/dev/zero}} 、{{ic|/dev/random}} などの API 疑似デバイスのみを追加し、物理デバイスやシステムメモリ、システムポートなどは追加しないようにします。これは、実行されるプロセスが物理デバイスに直接書き込むことを防ぐために役立ちます。また、systemd は {{ic|@raw-io}} セット内のシステムコールに対してシステムコールフィルタを追加します。
Sets up a new {{ic|/dev}} namespace for the executed process and only adds API pseudo devices such as {{ic|/dev/null}}, {{ic|/dev/zero}} or {{ic|/dev/random}}, but not for physical devices or system memory, system ports and others. This is useful to secure the execute process from writing directly to physical devices, systemd also adds a system call filter for calls within the {{ic|@raw-io}} set.
 
   
 
PrivateDevices=true
 
PrivateDevices=true
   
These options make the executed process unable to change kernel variables accessible through {{ic|/proc/sys}}, {{ic|/sys}}, etc. ProtectControlGroups makes the {{ic|/sys/fs/cgroup}} hierarchy read-only.
+
これらのオプションは、実行されるプロセスが {{ic|/proc/sys}}{{ic|/sys}} などを介してカーネル変数を変更できないようにします。ProtectControlGroups {{ic|/sys/fs/cgroup}} 階層を読み取り専用にします。
   
 
ProtectKernelTunables=true
 
ProtectKernelTunables=true
 
ProtectControlGroups=true
 
ProtectControlGroups=true
   
  +
ファイルパスをアクセス不可にするには、以下のようにします:
Making file paths inaccessible can be done as following:
 
   
 
InaccessiblePaths=/etc
 
InaccessiblePaths=/etc
   
More detailed information can be found in {{man|5|systemd.exec}}.
+
詳細情報は {{man|5|systemd.exec}} で見ることができます。
   
=== User ===
+
=== ユーザー ===
   
  +
実行されるプロセスとその子プロセスが、{{man|2|execve}} を通じて新しい権限を得ることがないようにします。
Ensure that the executed process and its children can never gain new privileges through {{man|2|execve}}.
 
   
 
NoNewPrivileges=true
 
NoNewPrivileges=true
   
=== Memory ===
+
=== メモリー ===
   
  +
書き込み可能で実行可能なメモリマッピングの作成、マッピングを実行可能に変更、または実行可能な共有メモリの作成を禁止します。これにより、プロセスが攻撃者によってメモリに書き込まれることを防ぐためにサンドボックス化されます。ただし、[[Wikipedia:JIT (computing)|JIT]] に依存するすべてのアプリケーションと互換性があるわけではないことに注意してください。
Prohibit attempts to create memory mappings that are both writable and executable, to change mappings to be executable or to create executable shared memory. This sandboxes a process against allowing an attacker to write in to memory which is also executed. Note that enabling this is not compatible with all applications which rely on a [[Wikipedia:JIT (computing)|JIT]].
 
   
 
MemoryDenyWriteExecute=true
 
MemoryDenyWriteExecute=true
   
=== System calls ===
+
=== システムコール ===
   
  +
{{man|2|personality}} システムコールをロックダウンして、カーネルの実行ドメインを変更できないようにします。
Locks down the {{man|2|personality}} system call so that the kernel execution domain can not be changed.
 
   
 
LockPersonality=true
 
LockPersonality=true
   
  +
サービスのシステムコールも制限できます。systemd は、フィルタリング対象のシステムコールを表示できます。
System calls can be restricted in a service as well, systemd can display syscalls to filter on:
 
   
 
$ systemd-analyze syscall-filter
 
$ systemd-analyze syscall-filter
   
  +
事前に定義されたグループが利用可能であり、例えば、システムサービスに対してシステムコールのホワイトリストを作成する際の推奨される開始点を使用するには:
Predefined groups are available, e.g. to use the recommended starting point for whitelisting system calls for system services use:
 
   
 
SystemCallFilter=@system-service
 
SystemCallFilter=@system-service
   
  +
システムコールは、アーキテクチャによっても制限できます。たとえば、64ビットマシンで32ビットバイナリを実行できないようにする(ネイティブでないバイナリを使用しない):
System calls can be restricted by their architecture such as to prevent 32-bit binaries from executing on 64-bit machines (no non-native binaries):
 
   
 
SystemCallArchitectures=native
 
SystemCallArchitectures=native
   
=== Network ===
+
=== ネットワーク ===
   
  +
実行中のプロセスがネットワークアクセスを必要としない場合、プロセス用に新しいネットワーク名前空間を設定し、ループバックインターフェイスのみを設定することで完全に無効化できます。
If the running process does not require any network access it can be fully disabled by setting up a new network namespace for the process and only configuration a loopback interface.
 
   
PrivateNetwork=true
+
PrivateNetwork=true
   
  +
ネットワークが必要な場合、{{man|2|socket}} システムコールで使用されるアドレスファミリーのタイプを制限できます。例えば、UNIX ソケットのみを許可する場合:
If network is required, the type of address families used can be restricted for the {{man|2|socket}} system call by for example only allowing UNIX sockets.
 
   
 
RestrictAddressFamilies=AF_UNIX
 
RestrictAddressFamilies=AF_UNIX
   
  +
ローカルホストへのネットワークのみが必要である場合、または特定の IP 範囲へのネットワークが必要である場合、プロセスはローカルホストへのネットワークアクセスのみを許可することで制限できます。
For when only network to localhost or specific IP ranges is required a process can be restricted by only allowing network access to localhost.
 
   
 
IPAddressAllow=localhost
 
IPAddressAllow=localhost
 
IPAddressDeny=any
 
IPAddressDeny=any
   
More information about network filtering can be found in {{man|5|systemd.resource-control}}.
+
ネットワークフィルタリングに関する詳細情報は、{{man|5|systemd.resource-control}} で見ることができます。
   
=== Various ===
+
=== その他 ===
   
  +
実行されるプロセスに対して新しい UTS 名前空間を設定し、ホスト名やドメイン名の変更を禁止します。
Sets up a new UTS namespace for the execute process and disallows changing the hostname or domainname.
 
   
 
ProtectHostname=true
 
ProtectHostname=true

2023年10月30日 (月) 03:51時点における最新版

このページでは Arch Linux パッケージのセキュリティパッケージングガイドラインを説明します。C/C++ プロジェクトでは、コンパイラとリンカがセキュリティ強化オプションを適用することができます。Arch Linux はデフォルトで PIE, Fortify source, stack protector, nx, relro を適用します。

使用方法

checksecを実行することで、ハードニングプロテクションを確認することができます。

$ checksec --file=/usr/bin/cat

RELRO

RELRO は、ELF バイナリ/プロセスのデータセクションを強化するための一般的な緩和技術です。プログラムがロードされる際、リンカによって書き込まれる必要があるいくつかのELFメモリセクションがありますが、プログラムへの制御を渡す前に読み取り専用にすることができます。これにより、攻撃者がELFセクションをオーバーライドするのを防ぐことができます。RELRO には2つの異なるモードがあります。

  • 部分的な RELRO(-Wl,-z,relro)プログラムのロード後、いくつかのセクションが読み取り専用にマークされますが、GOT(.got.plt)はまだ書き込み可能です。
  • 完全な RELRO(-Wl,-z,now)プログラムのロード中にすべての動的シンボルが解決され、完全なGOTを読み取り専用にマークすることができます。

アプリケーションが部分的な relro を報告する場合、ビルドツールチェーンが LDFLAGS を渡すか、LDFLAGS をオーバーライドできるかどうかを調べてください。Go パッケージでは、ビルド方法が LDFLAGS を渡すことができない純粋な golang Makefile 置換としてbuild.go を使用しているかどうかを調べてください。

Haskell

現時点では、Haskell で完全な RELRO をどのように達成するかは明確ではありません。

Go

こちらを参照 Go パッケージガイドライン#フラグとビルドオプション

スタックカナリー

スタックカナリーは、コンパイラによってスタック上のバッファと制御データの間に追加されます。このよく知られた値が破損している場合、バッファオーバーフローが発生し、プログラムがセグフォールトし、任意のコード実行を防ぐために停止します。

gcc パッケージは、デフォルトでスタック保護を有効化しており、--enable-default-sspコンパイルオプションによってスタック保護が有効化されています。

NX

C/C++

実行スペース保護は、メモリ領域を実行不可能にマークし、これらの領域でのマシンコードの実行試行が例外を引き起こすようにします。NX ビット(no-execute ビット)などのハードウェア機能を利用するか、場合によってはそれらの機能のソフトウェアエミュレーションを利用します。

PIE

C/C++

gcc パッケージは、C/C++ でデフォルトで有効化されており、--enable-default-pie が指定されています。

Golang

go build に以下のフラグを渡します:

export GOFLAGS='-buildmode=pie'
export CGO_CPPFLAGS="-D_FORTIFY_SOURCE=2"
export CGO_LDFLAGS="-Wl,-z,relro,-z,now"

Haskell

runhaskell Setup.hs configure に以下のフラグを渡します:

--ghc-option='-pie'

RPATH/RUNPATH

RUNPATH/RPATH は、リスト内のオブジェクト(実行可能ファイルおよび共有オブジェクトの両方に使用できる)のさらなる検索パスを提供します。

$ objdump -x /usr/bin/perl | grep -E 'RPATH|RUNPATH'

RPATH 値に攻撃者が制御できるパスが含まれている場合、例えば CVE-2006-1566CVE-2005-4280 のように、そのディレクトリに悪意のあるライブラリをインストールすることで、コードが実行される可能性があります。Debian:RpathIssue を参照してください。

RPATH エントリは、リンカに LDFLAGS に例えば -Wl,-rpath -Wl,/usr/local/lib といった文字列を渡すことで設定されます。RUNPATH エントリを追加するには、リンカフラグに --enable-new-dtags を追加してください。

FORTIFY

Fortify Source は、メモリや文字列の操作を行うさまざまな関数にバッファオーバーフロー保護を追加するマクロです。攻撃者がバッファをオーバーフローさせるためにより多くのバイトをコピーしようとしているかどうかをチェックし、プログラムの実行を停止します。この保護はデフォルトの CPPFLAGS で有効になります。

makepkg.conf
CPPFLAGS="-D_FORTIFY_SOURCE=2"

makepkg#設定 を参照してください。

systemd サービス

パッケージに上流が提供していない systemd サービスファイルを同梱する場合、以下の systemd サービスのハードニング機能を適用することを検討してください。Systemd は、サービスで有効になっているセキュリティ機能を分析する方法を提供しています。

$ systemd-analyze security reflector.service

ファイルアクセス

サービスは、ファイルシステムアクセスを制限することでハードニングできます。

実行されるプロセスに対して新しいファイルシステムの名前空間を設定し、その中にプライベートな /tmp および var/tmp ディレクトリをマウントします。この名前空間外のプロセスとは共有されません。/tmp にデータを書き込むプログラムに役立ちます。

PrivateTmp=true

ProtectSystem は、実行されるプロセスに対して読み取り専用でディレクトリをマウントする 3 つの異なる方法を提供しています。"full" オプションは、/usr/boot/etc を読み取り専用でマウントします。ProtectHome は、実行されるプロセスに対して /home/root/run/user をアクセス不可にします。

ProtectSystem=strict
ProtectHome=true

実行されるプロセスに対して新しい /dev 名前空間を設定し、/dev/null/dev/zero/dev/random などの API 疑似デバイスのみを追加し、物理デバイスやシステムメモリ、システムポートなどは追加しないようにします。これは、実行されるプロセスが物理デバイスに直接書き込むことを防ぐために役立ちます。また、systemd は @raw-io セット内のシステムコールに対してシステムコールフィルタを追加します。

PrivateDevices=true

これらのオプションは、実行されるプロセスが /proc/sys/sys などを介してカーネル変数を変更できないようにします。ProtectControlGroups は /sys/fs/cgroup 階層を読み取り専用にします。

ProtectKernelTunables=true
ProtectControlGroups=true

ファイルパスをアクセス不可にするには、以下のようにします:

InaccessiblePaths=/etc

詳細情報は systemd.exec(5) で見ることができます。

ユーザー

実行されるプロセスとその子プロセスが、execve(2) を通じて新しい権限を得ることがないようにします。

NoNewPrivileges=true

メモリー

書き込み可能で実行可能なメモリマッピングの作成、マッピングを実行可能に変更、または実行可能な共有メモリの作成を禁止します。これにより、プロセスが攻撃者によってメモリに書き込まれることを防ぐためにサンドボックス化されます。ただし、JIT に依存するすべてのアプリケーションと互換性があるわけではないことに注意してください。

MemoryDenyWriteExecute=true

システムコール

personality(2) システムコールをロックダウンして、カーネルの実行ドメインを変更できないようにします。

LockPersonality=true

サービスのシステムコールも制限できます。systemd は、フィルタリング対象のシステムコールを表示できます。

$ systemd-analyze syscall-filter

事前に定義されたグループが利用可能であり、例えば、システムサービスに対してシステムコールのホワイトリストを作成する際の推奨される開始点を使用するには:

SystemCallFilter=@system-service

システムコールは、アーキテクチャによっても制限できます。たとえば、64ビットマシンで32ビットバイナリを実行できないようにする(ネイティブでないバイナリを使用しない):

SystemCallArchitectures=native

ネットワーク

実行中のプロセスがネットワークアクセスを必要としない場合、プロセス用に新しいネットワーク名前空間を設定し、ループバックインターフェイスのみを設定することで完全に無効化できます。

PrivateNetwork=true

ネットワークが必要な場合、socket(2) システムコールで使用されるアドレスファミリーのタイプを制限できます。例えば、UNIX ソケットのみを許可する場合:

RestrictAddressFamilies=AF_UNIX

ローカルホストへのネットワークのみが必要である場合、または特定の IP 範囲へのネットワークが必要である場合、プロセスはローカルホストへのネットワークアクセスのみを許可することで制限できます。

IPAddressAllow=localhost
IPAddressDeny=any

ネットワークフィルタリングに関する詳細情報は、systemd.resource-control(5) で見ることができます。

その他

実行されるプロセスに対して新しい UTS 名前空間を設定し、ホスト名やドメイン名の変更を禁止します。

ProtectHostname=true