「Arch パッケージガイドライン/セキュリティ」の版間の差分
Kusanaginoturugi (トーク | 投稿記録) (→NX: 飜訳) |
Kusanaginoturugi (トーク | 投稿記録) (→PIE: 飜訳) |
||
39行目: | 39行目: | ||
=== C/C++ === |
=== C/C++ === |
||
− | + | {{Pkg|gcc}} パッケージは、C/C++ でデフォルトで有効化されており、[https://github.com/archlinux/svntogit-packages/blob/packages/gcc/trunk/PKGBUILD#L99 --enable-default-pie] が指定されています。 |
|
=== Golang === |
=== Golang === |
||
+ | {{ic|go build}} に以下のフラグを渡します: |
||
− | Pass the following flags to {{ic|go build}}: |
||
export GOFLAGS='-buildmode=pie' |
export GOFLAGS='-buildmode=pie' |
||
51行目: | 51行目: | ||
=== Haskell === |
=== Haskell === |
||
− | + | {{ic|runhaskell Setup.hs configure}} に以下のフラグを渡します: |
|
--ghc-option='-pie' |
--ghc-option='-pie' |
2023年4月10日 (月) 13:30時点における版
このページでは 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 をどのように達成するかは明確ではありません。
スタックカナリー
スタックカナリーは、コンパイラによってスタック上のバッファと制御データの間に追加されます。このよく知られた値が破損している場合、バッファオーバーフローが発生し、プログラムがセグフォールトし、任意のコード実行を防ぐために停止します。
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 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'
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 CVE-2006-1566 CVE-2005-4280. See Debian:RpathIssue.
The RPATH entry is set by the linker by passing for example the following string to LDFLAGS -Wl,-rpath -Wl,/usr/local/lib
. To make an RUNPATH entry append --enable-new-dtags
to the linker flags.
FORTIFY
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 CPPFLAGS
:
makepkg.conf
CPPFLAGS="-D_FORTIFY_SOURCE=2"
systemd services
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
File access
A service can be hardened by restricting file system access.
Set up a new file system namespace for the executed process and mounts private /tmp
and var/tmp
directories inside it that is not shared by processes outside the namespace. Useful for programs which write data to /tmp
.
PrivateTmp=true
ProtectSystem has three different varieties of mounting directories as read-only for the executed process. The "full" option mounts /usr
, /boot
and /etc
read only. ProtectHome makes /home
, /root
and /run/user
inaccessible to the executed process.
ProtectSystem=strict ProtectHome=true
Sets up a new /dev
namespace for the executed process and only adds API pseudo devices such as /dev/null
, /dev/zero
or /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 @raw-io
set.
PrivateDevices=true
These options make the executed process unable to change kernel variables accessible through /proc/sys
, /sys
, etc. ProtectControlGroups makes the /sys/fs/cgroup
hierarchy read-only.
ProtectKernelTunables=true ProtectControlGroups=true
Making file paths inaccessible can be done as following:
InaccessiblePaths=/etc
More detailed information can be found in systemd.exec(5).
User
Ensure that the executed process and its children can never gain new privileges through execve(2).
NoNewPrivileges=true
Memory
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 JIT.
MemoryDenyWriteExecute=true
System calls
Locks down the personality(2) system call so that the kernel execution domain can not be changed.
LockPersonality=true
System calls can be restricted in a service as well, systemd can display syscalls to filter on:
$ 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
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
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
If network is required, the type of address families used can be restricted for the socket(2) system call by for example only allowing UNIX sockets.
RestrictAddressFamilies=AF_UNIX
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 IPAddressDeny=any
More information about network filtering can be found in systemd.resource-control(5).
Various
Sets up a new UTS namespace for the execute process and disallows changing the hostname or domainname.
ProtectHostname=true