systemd編~サーバーで不要なものは動かさない~ - Linuxセキュリティ入門(1)

今回から5回に渡り、Linuxサーバーのセキュリティ設定を皆さんと一緒に確認しつつ、セキュリティに関連するコマンドの説明を書かせてもらう川井です。皆さんと同じく、さくらインターネットの一ユーザーでもありますので、以後、よろしくお願いいたします。

これから説明するセキュリティを確認する環境は、さくらインターネットが提供しているサービスの『さくらのVPS』や『さくらのクラウド』でCentOS 7以降の利用が対象です。さくらインターネットさんはセキュリティにとても留意しているため、初期状態でも危機はかなり低いとはいえ、利用している皆さんがよりセキュリティに関心を寄せることで、更なる安全を手に入れられるでしょう(この連載では以降、さくらのVPSとさくらのクラウドをさくらのサービスとまとめて記述します)。

対象サービス さくらのVPS、さくらのクラウド
対象OS CentOS 7

これから触れるセキュリティの元ネタは個人的にも利用しているさくらのVPSと、お仕事がらみだったり、趣味の実験でたま〜に使わせて頂いているさくらのクラウドの環境で筆者が試した内容です。もちろん、よりハイエンドなユーザーに向けたさくらの専用サーバ高火力でも、CentOS 7を使うのであれば基本的な考え方は同じとなるため、お使いいただける知識でもありますので、少しでも興味がわいた方はご参考にしてください。

究極のセキュリティから考える「あるべき姿」

それでは気を引き締め、セキュリティに関わる今回のテーマをはじめに決めさせていただきます。唐突ではありますが、第一回目はセキュリティを突き詰めた形から考えてみました。そう、究極のセキュリティとは何かを考え、煮詰めたところ、次の一文で語れるのではないでしょうか。

  サーバーを動かさない・・・①

確かに止まっているコンピュータのデータを盗むのは難しく、サーバーを分解し、取り出した部品を他の動いているコンピュータに接続でもしない限り不可能でしょう。ところが、お気付きのように、サーバーを止めてしまうと、とても大きな問題が発生してしまいます。というのもサーバー本来の働きを全くしなくなってしまいますから、ちょっとじゃなく、とっても苦しく意味がないですね……。

本末転倒とも思えるセキュリティ対策①とはいえ、実はあながち間違いでもなく、ここは日本人らしからぬいい加減さ(私だけだと思いたい)を生かし、極論から現実へ捻じ曲げてみましょう。

  サーバーで不要なものは動かさない ≒ サーバーで必要なものだけ動かす・・・❶

図1:サーバーでは必要なサービスだけ動かす

これはWindowsというOSと比較したときのLinuxの大きな特徴でもあります。というのも、LinuxというOSは開発に複数の会社や学校などの違う組織の人々が関わっているため、結果的に独立した複数のプログラムの寄せ集めとなりました。多くのプログラムは個別に動くことも多いため、お互いに関係のない機能をそぎ落とせば、動くプログラムが少なくなり、セキュリティ問題の数も合わせて少なくなります。プログラムのダイエットをすることで必要なメモリ使用量も減るためシステムが快活に動き、一石二鳥です。という話の流れから、第一回目はLinuxのシステム絡みのサービスのプログラムを管理するsystemdという仕組みを調整してみましょう。

Linuxサーバーで動いているプログラムといえば、ワードやエクセルではありません。ホームページを提供するWebサーバー機能のApache HTTP Serverだったり、メールを送受信するpostfixというサーバープログラムだったり、はたまた、リレーショナルデーターベースシステムのMariaDBなどです。これらのサーバーとして動くプログラムはサービスと呼ばれ、以前は起動・停止用のスクリプトが個別に用意されていました。スクリプトはテキストで書かれたプログラムファイルなので、ユーザーが自由に変更できて便利です。CentOSなどの元となっているRed Hat Enterprise Linuxを開発しているRedHat社はシステム周りの統一性・高速化をねらい、systemdに合わせたプログラムを用意して管理するようにしました。systemdはサービスプログラム管理の他にディスクマウントポイントやスワップやデバイスなども管理しているとはいえ、本連載で対象としているさくらのサービスを初めて使う場合は緊急の要件ではないため、今回はサービス管理にしぼって見ていきます。

実際にサービスを管理してみよう

まずは現状どれだけのサービスプログラムが動いてるか筆者の環境で確認してみます。systemdで管理されているサービスプログラムを操作するのはsystemctlコマンドです。次のコマンドを試しました(できれば皆さんもお試しください)。

ヒント:Linuxのコマンドラインは皆さんのPCからssh接続して利用するものですが、最初はWeb管理画面に用意されているコンソールボタンから表示されるコンソールを利用することをお勧めします。コンソールで利用する場合は、rootユーザでログインしてコマンドを入力するプロンプトの最後に # が表示された状態で以降のコマンドを試しましょう。一般のユーザでログインしてしまうと、プロンプトの最後が $ と表示されてしまい、管理系のコマンドが使えません。
# systemctl list-units --type service  ↩︎
UNIT                               LOAD   ACTIVE SUB     DESCRIPTION
abrt-ccpp.service                  loaded active exited  Install ABRT coredump hook
abrt-oops.service                  loaded active running ABRT kernel log watcher
abrtd.service                      loaded active running ABRT Automated Bug Reporting Tool
                                   :
                                   :
chronyd.service                    loaded active running NTP client/server                       ❶
                                   :
                                   :
dovecot.service                    loaded active running Dovecot IMAP/POP3 email server          ②
                                   :
                                   :
                                   :
mariadb.service                    loaded active running MariaDB database server                 ③
named.service                      loaded active running Berkeley Internet Name Domain (DNS)     ④
network.service                    loaded active exited  LSB: Bring up/down networking           ❺
NetworkManager-wait-online.service loaded active exited  Network Manager Wait Online
NetworkManager.service             loaded active running Network Manager                         ❻
nginx.service                      loaded active running The nginx HTTP and reverse proxy server ⑦
polkit.service                     loaded active running Authorization Manager
postfix.service                    loaded active running Postfix Mail Transport Agent            ❽
                                   :
                                   :
                                   :
sshd.service                       loaded active running OpenSSH server daemon                   ❾
                                   :
                                   :
                                   :
tomcat.service                     loaded active running Apache Tomcat Web Application Container ⑩
tuned.service                      loaded active running Dynamic System Tuning Daemon

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

51 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

リスト1:systemctlコマンドにlist-unitsコマンドを指定してサービスの一覧表示

ここで、systemdが管理するサービスなどの一つ一つの単位をUnitと呼び、systemctlコマンドlist-unitsコマンドで動いているUnit、それも「--type service」オプションでサービスだけのリスト一覧を表示しています。
 
さくらのサービスを使い始めたばかり、かつ、標準OSを利用さている方であれば、基本的には最小限のサービスだけがインストールされており、多くの人に必要なWebサービスなどは各自でインストールしていきます。とてもしぼられているので、ある意味、余計なことをしないのであればセキュリティについて考える必要は殆どないでしょう。ところが、現実世界で段々と身の回りの物が増えて部屋が汚くなっていく様に、追加サービスも増えていきがちです。

ここに表示した結果は筆者が個人的に利用しているサーバーで、黒丸の番号がつけられた❶❺❻❽❾は初めから動いていたサーバーのプログラム、一方で白丸の番号がつけられた②③④⑦⑩は後から追加して動いているサーバーのプログラムです。常時動かしているサービス以外に、テストしたかったtomcat(学校で教えているJavaサーブレット/JSPのサーバー)や試しにimapメールを読むためのdovecotサーバーなど、普段使わない余計なサービスが幾つも動いているため、セキュリティ的なスキを生み出しやすくなります(お恥ずかしい……)。

番号 サービス(プログラム名) 機能
chronyd 時間管理サーバーから受信するサーバー
dovecot メールサーバー(クライアントがメールを読むため)
mariadb リレーショナル・データーベース・システム
named 名前情報を公開するサーバー
network ネットワークインターフェース
NetworkManager ネットワークインターフェース
nginx Webサーバー
postfix メール送受信のサーバー
sshd ssh接続のためのサーバー
tomcat Java用サーバー

表1:リスト1で動いているサービス

もう少し詳しく見ていくと、❶はマシンの時間調節をするプログラムでサーバーからデータを受け取るだけです。❺❻はネットワークインターフェースそのものを立ち上げ・管理するので止めてしまえば誰もサーバーに近寄れません。❽はメールを扱うプログラムで、WordpressなどのWebアプリからメール送信するプログラム、❾は皆さんのPCからのssh接続を受け付けるサーバーでこれがないとクライアントから細かな設定がし辛いため必須です。なので黒丸の番号は止めなくてよいでしょう。

一方、②は受け取ったメールをクライアントで読むためのプログラム、③はデーターベースのプログラム、④は名前情報を公開するbindというプログラム、⑦はWebページやアプリを公開するためのプログラム、⑩は前述のJavaプログラムを動かすためのプログラムとなり、もちろん全てサーバーとして動くサービスです。

なので、まずやることは、自分でインストールしたけれど、現在使っていない白丸の番号が付いているサービスを止めることから始めましょう。筆者の例ではデーターベース絡みのWebサービスを提供するサーバーなので、止める必要があるのは①のクライアント用メールのサーバーや⑨のJavaサーバーとなります。サービスを止めるには次のようにsystemctlコマンドにstopコマンドとサービス名を記述してください。

# systemctl stop dovecot ↩︎    ・・・・メールサービスの停止
# systemctl stop tomcat ↩︎      ・・・・tomcatサービスを停止

何もエラーが表示されなければ、まず、OKです。Linuxの場合はエラーが起きた時だけメッセージが表示されます。また、サービスを止めただけではサーバーの再起動時にサービスが再起動してしまうかもしれません。サーバーの再起動時にはサービスが起動しない設定も必要で、起動時にサービスを起動しない指定はsystemctlコマンドにdisableコマンドとサービス名を記述します。

# systemctl disable dovecot ↩︎    ・・・・メールサービスの起動時の自動実行の停止
Removed symlink /etc/systemd/system/multi-user.target.wants/dovecot.service.
# systemctl disable tomcat ↩︎      ・・・・tomcatサービスの起動時の自動実行の停止
Removed symlink /etc/systemd/system/multi-user.target.wants/tomcat.service.

ここではエラーではなく、ファイルを切り替えたメッセージが表示されます。

ただ、一つ気になることとして、何をインストールしたか忘れてしまう……という恥ずかしい状況におちいることが往々にしてありえます。そんな時は、systemd向けの設定ファイルが置いてある/usr/lib/systemd/systemディレクトリを見てみましょう。次のコマンドはserviceのみを抜き出し、リンボリックリンクファイルを取り除き、名前を昇順にソートしています。

# ls -l  /usr/lib/systemd/system  | grep service | grep -v ^l | sort -k9  ↩︎
-rw-r--r--  1 root root  353  3月 14 19:19 NetworkManager-dispatcher.service
-rw-r--r--  1 root root  303  3月 14 19:19 NetworkManager-wait-online.service
-rw-r--r--  1 root root 1495  3月 14 19:19 NetworkManager.service
                                 :
                                 :
-rw-r--r--  1 root root  472  9月 15  2017 chrony-wait.service
                                 :
                                 :
-rw-r--r--  1 root root  970 10月 31  2018 dovecot.service 
                                 :
                                 :
-rw-r--r--  1 root root  752  4月 24 22:44 httpd.service
                                 :
                                 :
-rw-r--r--  1 root root 1697  8月 16  2018 mariadb.service
                                 :
                                 :
-rw-r--r--  1 root root  824  1月 30 02:23 named.service
-rw-r--r--  1 root root  618  5月 10 17:10 nginx.service
-rw-r--r--  1 root root  272  4月 11  2018 ntpdate.service
                                 :
                                 :
-rw-r--r--  1 root root  463 10月 31  2018 postfix.service
                                 :
                                 :
-rw-r--r--  1 root root  324  4月 11  2018 rpc-rquotad.service
-rw-r--r--  1 root root  385 10月 31  2018 rpcbind.service
-rw-r--r--  1 root root  237  4月 26 02:17 rsyncd.service
                                 :
                                 :
-rw-r--r--  1 root root  373  4月 11  2018 sshd.service
-rw-r--r--  1 root root  260  4月 11  2018 sshd@.service
-rw-r--r--  1 root root  267  4月 11  2018 svnserve.service
                                 :
                                 :
-rw-r--r--  1 root root  453  3月 12 19:12 tomcat.service
                                 :
                                 :

/usr/lib/systemd/systemディレクトリにあるUnitのオリジナル設定ファイルは、利用可能なメモリ容量などの起動条件などを指定できます。書き換えるのであれば、/etc/systemd/systemへコピーしてから書き換えてください。

ディレクトリ 内容
/usr/lib/systemd/system Unitのオリジナル設定ファイルがある場所
/etc/systemd/system Unitの変更後の設定ファイルがある場所

表2:systemdのUnit設定ファイルの場所

テスト的にインストールしたサービスを思い出すのが大変だとしても、趣味的に作っているサイトだからといって悪質なハッカーが見逃してくれることはあり得ません! ただ、次回に説明するファイアーウォール機能が有効であれば、大事には至り辛いため、できるならば、二重三重の備えをした方が心強いです。

ちなみに、インストールしたけれど、今たまたま止まっているサービスなんてこともあるので、次にLinuxが起動するときどうなっているかを確認しておくと、より心強いでしょう。次のコマンドを試してみてください。

# systemctl is-enabled httpd↩︎
disabled

Linuxの起動時にサービスが動くかどうか確認するには、systemctlコマンドにis-enabledコマンドとサービス名を指定します。これまでに例として出ている筆者の確認した環境ではnginxというWebサーバーのプログラムを動かしています。これを一般的なApache HTTP Serverに切り替えるのであれば、次のように停止と開始をして切り替える必要があります。

# systemctl stop nginx ↩︎               ・・・nginxサービスを停止
# systemctl disable nginx ↩︎          ・・・nginxサービスをLinux起動時に動かさない
Removed symlink /etc/systemd/system/multi-user.target.wants/nginx.service.
# systemctl start httpd ↩︎               ・・・Apache HTTP Serverサービスを開始
# systemctl enable httpd ↩︎           ・・・Apache HTTP ServerサービスをLinux起動時に起動に切替
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.

上記のstartは即時開始、stopは即時停止、enableはLinux起動時に開始、disableはLinux起動時に停止するコマンドとなります。

さて、サービスを起動したときに設定が悪ければエラーとなって動かないところがあるかもしれません。そんなときは各サービスの専用ログを見るのが必須とはいえ、Systemdはログも管理しようとしているため、動作状態と一緒にログも少しだけ見られます。次のstatusコマンドで確認だけはしておきましょう。

# systemctl status httpd ↩︎           ・・・Apache HTTP Serverサービスの動作状態を確認
* httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2019-06-02 11:34:33 JST; 1 weeks 2 days ago
     Docs: man:httpd(8)
           man:apachectl(8)
 Main PID: 22978 (httpd)
   Status: "Total requests: 0; Current requests/sec: 0; Current traffic:   0 B/sec"
   CGroup: /system.slice/httpd.service
           |- 4383 /usr/sbin/httpd -DFOREGROUND
           |- 4384 /usr/sbin/httpd -DFOREGROUND
           |- 4389 /usr/sbin/httpd -DFOREGROUND
           |- 6986 /usr/sbin/httpd -DFOREGROUND
           |-22978 /usr/sbin/httpd -DFOREGROUND
           |-27831 /usr/sbin/httpd -DFOREGROUND
           |-27832 /usr/sbin/httpd -DFOREGROUND
           |-27833 /usr/sbin/httpd -DFOREGROUND
           |-27834 /usr/sbin/httpd -DFOREGROUND
           |-27835 /usr/sbin/httpd -DFOREGROUND
           `-29055 /usr/sbin/httpd -DFOREGROUND

 6月 13 13:59:38 www00000xx.sakura.ne.jp systemd[1]: Starting The Apache HTTP Server...
 6月 13 13:59:39 www00000xx.sakura.ne.jp systemd[1]: Started The Apache HTTP Server.

本来の入門であれば、この部分をより詳しく説明しておきたいところですが、現状ではstatusコマンドの結果で「Active: active (running)」と動いているところだけでも確認しておきましょう。また、この例ではApacheサーバーが開始メッセージ(「6月 13 13:59:38 www00000xx.sakura.ne.jp systemd[1]: Starting The Apache HTTP Server...」)が出ており、エラーは出ていません。もし、開始に失敗などしたら、最後の2行が赤く染まって表示されるので、その時はより詳しくログファイルを調べて対応すれば良いだけです(なんて初心者の方には更なる冒険が始まりそうですね……)。

以上、かなり駆け足で端折りつつ書いたとはいえ、今回の説明はこれまでです。ポイントとしては動かさないサービスを発見したら、systemctlコマンドで即時停止してしまうことです。できれば、systemctlコマンドにdisableを指定してLinux起動時にも動かない様に設定してください。

コマンド 動作内容
systemctl list-units --type service 起動中のサービス一覧
systemctl stop サービス名 サービスの即時停止
systemctl disable サービス名 Linux起動時にサービスを開始しない設定
systemctl start サービス名 サービスの即時開始
systemctl enable サービス名 Linux起動時にサービスを開始する設定
systemctl restart サービス名 サービスの即時停止・再開始
systemctl is-enabled サービス名 Linux起動時にサービスを開始する設定か確認
systemctl status サービス名 サービスが動いているか確認

表3:コマンドのまとめ