Arch パッケージガイドライン/セキュリティ

提供: ArchWiki
ナビゲーションに移動 検索に移動

このページでは 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