「Arch パッケージガイドライン/セキュリティ」の版間の差分
Kusanaginoturugi (トーク | 投稿記録) (→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,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' |
||
− | + | 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]] を参照してください。 |
|
− | + | 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 |
+ | == 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 |
||
− | === |
+ | === ファイルアクセス === |
+ | サービスは、ファイルシステムアクセスを制限することでハードニングできます。 |
||
− | 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 |
+ | 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 |
||
− | + | これらのオプションは、実行されるプロセスが {{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 |
||
− | + | 詳細情報は {{man|5|systemd.exec}} で見ることができます。 |
|
− | === |
+ | === ユーザー === |
+ | 実行されるプロセスとその子プロセスが、{{man|2|execve}} を通じて新しい権限を得ることがないようにします。 |
||
− | Ensure that the executed process and its children can never gain new privileges through {{man|2|execve}}. |
||
NoNewPrivileges=true |
NoNewPrivileges=true |
||
− | === |
+ | === メモリー === |
+ | 書き込み可能で実行可能なメモリマッピングの作成、マッピングを実行可能に変更、または実行可能な共有メモリの作成を禁止します。これにより、プロセスが攻撃者によってメモリに書き込まれることを防ぐためにサンドボックス化されます。ただし、[[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 |
||
− | === |
+ | === システムコール === |
+ | {{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 |
||
− | === |
+ | === ネットワーク === |
+ | 実行中のプロセスがネットワークアクセスを必要としない場合、プロセス用に新しいネットワーク名前空間を設定し、ループバックインターフェイスのみを設定することで完全に無効化できます。 |
||
− | 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 |
|
+ | ネットワークが必要な場合、{{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 |
||
− | + | ネットワークフィルタリングに関する詳細情報は、{{man|5|systemd.resource-control}} で見ることができます。 |
|
− | === |
+ | === その他 === |
+ | 実行されるプロセスに対して新しい 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-1566 や CVE-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