序章

サンドボックスは、通常の操作中に対話する必要のないシステムの部分からプログラムまたはプロセスを分離することに焦点を当てたコンピューターセキュリティ技術です。 新しいプログラムが開始されると、それはそれが実行されるユーザーのすべての能力を備えています。 これらの能力は、プログラムがその機能を実行するために必要な能力をはるかに超えていることがよくあります。 これは、悪意のある攻撃者がプログラムを操作して、プログラムが通常は実行しないことを実行するために未使用の機能の一部にアクセスする場合に、セキュリティの問題を引き起こす可能性があります。

サンドボックス化の目的は、プログラムに必要な機能とリソースを正確に特定し、それ以外のすべてをブロックすることです。

ツールのシステム管理スイートsystemdは、プログラムとプロセスを開始、停止、および管理するために、ほとんどすべての主要なLinuxディストリビューションで使用されています。 開始するプロセスがホストシステムにアクセスする方法を制限する多くのサンドボックスオプションがあり、より安全になります。

このチュートリアルの目的は、可能な限り厳密なサンドボックス環境を作成することではなく、推奨され、簡単に有効にできる設定を使用して、システムをより安全にすることです。

このチュートリアルでは、Ubuntu 20.04でsystemdのサンドボックス技術を使用して、これらの技術を実装およびテストするための効率的なワークフローを実現する方法の実践的なデモンストレーションを実行します。 systemdを使用するLinuxシステムで実行されるプロセスはすべて、これらの手法を使用してより安全にすることができます。

前提条件

このガイドを開始するには、次のものが必要です。

ステップ1—lighttpdをインストールする

このチュートリアルでは、 lighttpdWebサーバーをサンドボックス化します。 lighttpdは、他のソフトウェアよりも安全性が低いために選択されませんでしたが、サンドボックス化が容易な単一の機能を備えた小さなプログラムであるためです。 これにより、学習アプリケーションに最適です。

システムを更新して開始しましょう。

  1. sudo apt update

入力する前に、システムでアップグレードされるパッケージを確認してください y:

  1. sudo apt upgrade

次にlighttpdをインストールします。

  1. sudo apt install lighttpd

このインストールプロセスにより、lighttpdのsystemdサービスファイルが自動的にインストールされて有効になります。 これにより、システムの再起動時にlighttpdが起動します。

システムにlighttpdをインストールして実行したので、サンドボックス化を開始するときに使用するsystemdツールについて理解します。

ステップ2—システムの準備

このステップでは、使用するsystemdコマンドに精通し、プロセスを効率的にサンドボックス化できるようにシステムを準備します。

systemdは、それぞれ異なる名前を持つ一連のツールの包括的な名前です。 使用する2つは systemctljournalctl. systemctl プロセスとそのサービスファイルを管理し、 journalctl システムログと対話します。

systemdはサービスファイルを使用して、プロセスの管理方法を定義します。 systemdは、ファイルシステム内のいくつかの場所からこれらのファイルをロードします。 次のコマンドは、アクティブなサービスファイルの場所を表示し、使用中のオーバーライドを表示します。

  1. sudo systemctl cat process.service

交換する必要があります process あなたが取り組んでいるプロセスで。 ここではlighttpdが使用されています:

  1. sudo systemctl cat lighttpd.service

これは前のコマンドからの出力です:

Output
# /lib/systemd/system/lighttpd.service [Unit] Description=Lighttpd Daemon After=network-online.target [Service] Type=simple PIDFile=/run/lighttpd.pid ExecStartPre=/usr/sbin/lighttpd -tt -f /etc/lighttpd/lighttpd.conf ExecStart=/usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf ExecReload=/bin/kill -USR1 $MAINPID Restart=on-failure [Install] WantedBy=multi-user.target

この出力は、サービスファイルが次の場所にあることを示しています。 /lib/systemd/system/lighttpd.service また、使用中のオーバーライドオプションはありません。 オーバーライドオプションは、ベースサービスファイルに追加または変更します。 専用のオーバーライドファイルを使用してlighttpdをサンドボックス化するためにオーバーライドを使用します。

オーバーライドファイルは次の場所にあります /etc/systemd/system/process.service.d/override.conf. systemdには専用があります edit 正しい場所にオーバーライドファイルを作成して実行するコマンド systemctl daemon-reload 保存してエディターを終了した後。 The systemctl daemon-reload 作成した新しい構成を使用するようにsystemdに指示します。

systemdeditコマンドの形式は次のとおりです。

  1. sudo systemctl edit process.service

このコマンドを実行すると、systemdは通常デフォルトのCLIエディターを選択しますが、常にそうであるとは限らず、viまたはedにいることもあります。 systemdが使用するエディターを構成するには、 SYSTEMD_EDITOR シェル変数。

に行を追加して、このシェル変数を設定します ~/.bashrc ファイル。 このファイルをテキストエディタで開きます。

  1. nano ~/.bashrc

そして、次の行を追加します。

〜/ .bashrc
export SYSTEMD_EDITOR=editor

変化する editor お好みのCLIエディターに。 nanoエディターを使用するために設定された行は次のとおりです。

〜/ .bashrc
export SYSTEMD_EDITOR=nano

ログアウトしてから再度ログインした後、これが設定されていることを確認してください。 echo 指図:

  1. echo $SYSTEMD_EDITOR

このコマンドは、設定したエディターの名前を出力します。

The SYSTEMD_EDITOR シェル変数はユーザーのシェルでのみ設定され、rootのシェルでは設定されません。 sudo. この変数をrootのシェルに渡すには、 systemctl edit を使用して sudo -E:

  1. sudo -E systemctl edit process.service

最後の推奨事項は、変更によって発生したエラーを表示することにより、サンドボックスのデバッグを容易にします。 これらのエラーは、journalctlコマンドでアクセスされるシステムログに記録されます。

サンドボックス化中に、サンドボックス化しようとしているプロセスを中断する多くの変更を加えます。 そのため、2つ目の端末を開いて、システムログの追跡専用にすることをお勧めします。 これにより、システムログを再度開く時間を節約できます。

次のコマンドを実行して、2番目の端末のシステムログを追跡します。

  1. sudo journalctl -f -u process.service
  • -f:システムログをフォローまたはテールして、新しい行がすぐに表示されるようにします。
  • -u process.service:のログ行のみを表示します process あなたはサンドボックス化しています。

以下は、lighttpdのエラーのみを出力するために実行する必要があるものです。

  1. sudo journalctl -f -u lighttpd.service

次に、編集を開始します override.conf ファイルを作成し、lighttpdのサンドボックス化を開始します。

ステップ3—ユーザーとグループを強制する

このステップでは、lighttpdを実行するroot以外のユーザーを設定します。

デフォルト設定では、lighttpdは root ユーザーとして実行を開始し、www-dataユーザーとグループに変更します。 これは問題です。lighttpdがrootとして実行されている間は、rootが実行できることは何でも実行できるからです。

systemdは、root以外のユーザーとしてプロセスを開始および実行する機能を提供するため、この問題を回避できます。

最初のターミナルセッションに戻り、次のコマンドを実行してオーバーライドファイルの編集を開始します。

  1. sudo -E systemctl edit lighttpd.service

ここで、次の行を追加します。

lighttpdオーバーライドファイル
[Service]
User=www-data
Group=www-data
  • [Service]:次のオプションをに適用する必要があることをsystemdに通知します [Service] セクション。
  • User=www-data:プロセスを開始するユーザーをとして定義します。
  • Group=www-data:プロセスを開始するグループを定義します。

次に、エディタを保存して終了し、次のコマンドでlighttpdを再起動します。

  1. sudo systemctl restart lighttpd.service

lighttpdは、を使用していたため、起動できません。 root rootが所有する場所にPIDファイルを書き込む権限。 www-data ユーザーは、rootが所有するディレクトリに書き込むことができません。 この問題は、2番目のターミナルセッションに表示されるシステムログに示されます。

journalctl error message
Aug 29 11:37:35 systemd lighttpd[7097]: 2020-08-29 11:37:35: (server.c.1233) opening pid-file failed: /run/lighttpd.pid Permission denied

この問題の解決は、サンドボックス化のプロセスに従います。

  1. サンドボックス制限を実装します。
  2. プロセスを再開し、エラーを確認します。
  3. エラーを修正します。

次に、このセクションで設定したユーザーとグループの制限を適用しながら、PIDファイルの問題を解決します。

ステップ4—PIDファイルの管理

PIDファイルは、実行中のプロセスのPIDまたはプロセス識別番号を含むファイルです。 lighttpdのような長時間実行されるプログラムは、それらを使用して独自のプロセスを管理します。 前のセクションで発生した問題は、lighttpdがPIDファイルをに書き込むことができなかったことです。 /run/lighttpd.pid、 なぜなら /run/ rootが所有しています。

systemdには RuntimeDirectory この問題のオプション。lighttpdにPIDファイルを書き込める場所を指定するために使用します。

The RuntimeDirectory オプションを使用すると、下のディレクトリを指定できます /run/ これは、systemdがlighttpdを起動したときに、ステップ3で設定したユーザーとグループで作成されます。 lighttpdは、 rootの権限を必要とせずに、そのPIDをこのディレクトリに書き込むことができます。

まず、ステップ3 で使用したのと同じコマンドを使用して、オーバーライドファイルを開いて編集します。

  1. sudo -E systemctl edit lighttpd.service

次に、オーバーライドファイルにすでに追加した2行の下に次の行を追加します。

lighttpdオーバーライドファイル
RuntimeDirectory=lighttpd

エディターを保存して終了します。

ディレクトリへのフルパスを追加しないでください RuntimeDirectory、下のディレクトリの名前のみ /run/. この場合、systemdが作成するディレクトリは /run/lighttpd/.

PIDファイルを新しいディレクトリに書き込むようにlighttpdを設定する必要があります /run/lighttpd/ それ以外の /run/.

テキストエディタでlighttpdの設定ファイルを開きます。

  1. sudo nano /etc/lighttpd/lighttpd.conf

次の行を変更します。

/etc/lighttpd/lighttpd.conf
server.pid-file             = "/run/lighttpd.pid"

に:

/etc/lighttpd/lighttpd.conf
server.pid-file             = "/run/lighttpd/lighttpd.pid"

エディターを保存して終了します。

ここで、lighttpdを再起動します。

  1. sudo systemctl restart lighttpd.service

rootの機能の1つを必要とする何かを実行できないため、起動しません。 次に、この新しい問題を解決します。

ステップ5—ルートの機能を借用する

システムログの次の行は、lighttpdの起動を停止した問題を説明しています。

journalctl error message
Aug 29 12:07:22 systemd lighttpd[7220]: 2020-08-29 12:07:22: (network.c.311) can't bind to socket: 0.0.0.0:80 Permission denied

rootのみが番号以下のネットワークポートを開くことができます 1024. lighttpdはHTTPポートを開こうとしています 80、しかし、 www-data ユーザーがそれを行うことができないため、拒否されています。

この問題は、lighttpdプロセスに rootのパワーのごく一部を与えることで解決されます。つまり、以下のポートを開くことができます。 1024.

rootの「力」は、「能力」と呼ばれる能力に分けられます。 root ユーザーはすべての機能を備えているため、何でもできます。 rootのパワーアップを機能に分割することは、それらを非rootプロセスに個別に与えることができることを意味します。 これにより、そのプロセスは完全な root ユーザーを必要とする何かを実行できますが、通常のユーザーはrootの機能の1つを使用できるようになります。

プロセスにrootの機能の1つ以上を提供するsystemdオプションは、 AmbientCapabilities オプション。

オーバーライドファイルを開きます。

  1. sudo -E systemctl edit lighttpd.service

次に、すでに追加した行の下に次の行を追加します。

lighttpdオーバーライドファイル
AmbientCapabilities=CAP_NET_BIND_SERVICE

The CAP_NET_BIND_SERVICE 機能により、プロセスは下のポートを開くことができます 1024.

ファイルを保存して終了します。

これでlighttpdを起動できるようになります。

これで、デフォルト設定よりも安全にしたlighttpdWebサーバーが機能するようになりました。 systemdが提供するサンドボックスオプションには、ターゲットプロセスをさらに安全にするために使用できるものがあります。 次のセクションでは、これらのいくつかについて説明します。

次のステップでは、lighttpdがファイルシステムでアクセスできるものを制限します。

ステップ6—ファイルシステムをロックダウンする

lighttpdプロセスはwww-dataユーザーとして実行されるため、www-dataが読み取りおよび書き込みを許可されているシステム上の任意のファイルにアクセスできます。 www-data の場合、それほど多くはありませんが、lighttpdが必要とする以上のものです。

最初で最も簡単なサンドボックス設定は ProtectHome オプション。 このオプションは、プロセスが下にあるものの読み取りまたは書き込みを停止します /home/. lighttpdは以下のものにアクセスする必要はありません /home/ したがって、これを実装すると、lighttpdに影響を与えることなくすべてのプライベートファイルが保護されます。

オーバーライドファイルを開きます。

  1. sudo -E systemctl edit lighttpd.service

次に、ファイルの最後に次の行を追加します。

lighttpdオーバーライドファイル
ProtectHome=true

エディターを保存して終了し、lighttpdを再起動して、次のコマンドで期待どおりに機能していることを確認します。

  1. sudo systemctl restart lighttpd.service

あなたは保護しました /home/、しかしそれでもファイルシステムの残りの部分は残ります。 これは、 ProtectSystem オプション。プロセスがファイルシステムの一部に書き込むのを停止します。

The ProtectSystem オプションには、保護レベルを上げる3つの設定があります。 それらは次のとおりです。

  • true:次のディレクトリを読み取り専用に設定します。
    • /usr/
    • /boot/
    • /efi/
  • full:次のディレクトリを読み取り専用に設定します。
    • /usr/
    • /boot/
    • /efi/
    • /etc/
  • strict:次のディレクトリを読み取り専用に設定します。
    • ファイルシステム全体

より高いレベルの保護はより安全なので、 ProtectSystem オプション strict オーバーライドファイルに次の行を追加します。

lighttpdオーバーライドファイル
ProtectSystem=strict

エディターを保存して終了し、次のコマンドでlighttpdを再起動します。

  1. sudo systemctl restart lighttpd.service

lighttpdは、ログファイルをに書き込む必要があるため、起動できません。 /var/log/lighttpd/ そしてその strict 設定はそれを禁止します。 システムログの次の行は、問題を示しています。

journalctl error message
Aug 29 12:44:41 systemd lighttpd[7417]: 2020-08-29 12:44:41: (server.c.752) opening errorlog '/var/log/lighttpd/error.log' failed: Read-only file system

この問題は、systemdによって予期されていました。 LogsDirectory オプション。 下のディレクトリの名前を取ります /var/log/ プロセスがログを書き込むことが許可されていること。

最初のターミナルセッションでオーバーライドファイルを再度開きます。

  1. sudo -E systemctl edit lighttpd.service

lighttpdログディレクトリは /var/log/lighttpd/ したがって、オーバーライドファイルの最後に次の行を追加します。

lighttpdオーバーライドファイル
LogsDirectory=lighttpd

エディターを保存して終了し、lighttpdを再起動します。

  1. sudo systemctl restart lighttpd.service

これでlighttpdを起動して実行できるようになります。

注: lighttpd以外のプロセスをサンドボックス化していて、プロセスが外部の特定のディレクトリへの書き込みアクセスを許可したい場合 /var/log/ ReadWritePathsオプションを使用します。

次のステップでは、lighttpdプロセスがシステムの他の部分と対話する方法を制限するために、許可されているシステムコールを制限します。

ステップ7—システムコールを制限する

システムコールは、プログラムがカーネルに何かを要求する方法です。 システムコールの数は非常に多く、ファイルの読み取り、書き込み、削除などのアクション、ファイルシステムのマウント、スポーンプロセス、再起動などのハードウェア関連のタスクが含まれます。

systemdは、lighttpdのようなプロセスが通常使用し、使用しないコールを除外するシステムコールのグループを作成しました。 ブロックされたシステムコールは、ファイルシステムのマウントやシステムの再起動などですが、lighttpdでは実行する必要はありません。

まず、オーバーライドファイルを開きます。

  1. sudo -E systemctl edit lighttpd.service

次の行をファイルの最後に追加して、 SystemCallFilter を設定するオプション @system-service グループ:

lighttpdオーバーライドファイル
SystemCallFilter=@system-service

エディターを保存して終了し、lighttpdを再起動します。

  1. sudo systemctl restart lighttpd.service

次のセクションでは、残りの推奨サンドボックスオプションを適用します。

ステップ8—追加オプションの実装

systemdのドキュメントでは、lighttpdのような長時間実行されるネットワークプロセスに対して次のオプションを有効にすることを推奨しています。 これらの設定はすべてオプションですが、それぞれがサンドボックス化するプロセスをより安全にするため、可能であれば使用する必要があります。

これらのオプションを一度に1つずつ有効にし、各オプションの後でプロセスを再開する必要があります。 それらをすべて一度に追加すると、問題のデバッグははるかに困難になります。

以下の推奨オプションには、それらの機能の簡単な説明が付いています。 これらの行を、すでに追加した行の下のオーバーライドファイルに追加します。

lighttpdオーバーライドファイル
NoNewPrivileges=true

このオプションは、サンドボックス化されたプロセスとその子が新しい特権を取得するのを停止します。

lighttpdオーバーライドファイル
ProtectKernelTunables=true

このオプションは、プロセスがカーネル変数を変更するのを停止します。

lighttpdオーバーライドファイル
ProtectKernelModules=true

このオプションは、プロセスがカーネルモジュールをロードまたはアンロードするのを停止します。

lighttpdオーバーライドファイル
ProtectKernelLogs=true

このオプションは、プロセスがカーネルログに直接読み書きするのを停止します。 ログメッセージを記録するには、システムログアプリケーションを使用する必要があります。

lighttpdオーバーライドファイル
ProtectControlGroups=true

このオプションは、プロセスによるシステム制御グループの変更を停止します。

lighttpdオーバーライドファイル
MemoryDenyWriteExecute=true

このオプションは、システムのメモリで実行されているコードをプロセスが変更するのを停止します。

lighttpdオーバーライドファイル
RestrictSUIDSGID=true

このオプションは、プロセスがファイルまたはディレクトリにset-user-ID(SUID)またはset-group-ID(SGID)を設定するのを停止します。 この能力は、特権を高めるために悪用される可能性があります。

lighttpdオーバーライドファイル
KeyringMode=private

このオプションは、プロセスが同じユーザーとして実行されている他のプロセスのカーネルキーリングにアクセスするのを停止します。

lighttpdオーバーライドファイル
ProtectClock=true

このオプションは、プロセスがハードウェアおよびソフトウェアのシステムクロックを変更するのを停止します。

lighttpdオーバーライドファイル
RestrictRealtime=true

このオプションは、CPUを過負荷にするために悪用される可能性のあるリアルタイムスケジューリングをプロセスが有効にするのを停止します。

lighttpdオーバーライドファイル
PrivateDevices=true

このオプションは、プロセスがストレージデバイスやUSBデバイスなどのシステムに接続されている物理デバイスにアクセスするのを停止します。

lighttpdオーバーライドファイル
PrivateTmp=true

このオプションは、プロセスにプライベートを使用するように強制します /tmp//var/tmp/ ディレクトリ。 これにより、プロセスは、これらの共有システムディレクトリに保存されている他のプログラムの一時ファイルを読み取ることができなくなります。

lighttpdオーバーライドファイル
ProtectHostname=true

このオプションは、プロセスがシステムのホスト名を変更するのを停止します。

サンドボックス化したプロセスは、デフォルト構成よりもはるかに安全になりました。 これで、これらの手法を使用して、Linuxシステムで保護する必要のある他のプロセスに使用できます。

結論

この記事では、systemdサンドボックスオプションを使用してlighttpdプログラムをより安全にしました。 これらの手法は、systemdが管理する任意のプロセスで使用できるため、システムのセキュリティを継続的に向上させることができます。

サンドボックスおよびその他のセキュリティオプションの全リストは、systemdのオンラインドキュメントにあります。 また、DigitalOceanコミュニティでセキュリティトピックをさらにチェックしてください。