Lynisで行うLinuxサーバーのセキュリティスキャンと堅牢化の実践ガイド

Security tutorial - IT technology blog
Security tutorial - IT technology blog

導入背景と必要性

午前2時、突如スマホが激しく振動しました。Prometheusのアラートが鳴り響き、本番データベースサーバーのCPU使用率が98%に急上昇したことを知らせています。htop でSSHログインすると、www-data ユーザー配下で見知らぬプロセスが次々とforkを繰り返している光景が目に飛び込んできました。UFWファイアウォールは稼働中で、SSHログにもブルートフォース攻撃の痕跡はありません。このような緊迫した状況で、/etc/ 配下のファイルを一つひとつ探ったり、netstat でポートをしらみつぶしに確認していては、徹夜になっても脆弱性を見落としてしまうリスクがあります。

そんな緊急時に最も頼りになる救世主が、Linuxシェル上で直接動作するオープンソースのセキュリティ監査スキャナー「Lynis」です。NessusやOpenVASなどのリモートスキャナーは外部からのネットワークサーフェスしか検査できません。一方、LynisはOS内部から徹底的な検査(ローカルスキャン)を実施します。ファイル権限、Kernelのsysctlパラメーター、PAM設定、SSHデーモン、隠れたcronジョブ、さらには権限昇格(Privilege Escalation)のリスクに至るまで、システム全体をくまなく精査します。

最大のメリットは、極めて軽量でバックグラウンド常駐デーモンを必要としない点です。Lynisは実行後にプロセスが終了するため、メモリを消費し続けたりサービスを圧迫したりすることがありません。約2分のスキャンが完了すると、システムの堅牢度を示す「Hardening Index」スコアと、早急に対応すべき修正リストが即座に出力されます。

インストール手順

本番環境のサーバーでは、不要なパッケージを極力導入しないことが鉄則です。Lynisの導入には、緊急障害対応用と長期運用管理用の2つのアプローチがあります。

方法1:Gitから直接実行(緊急対応時に推奨)

深夜の緊急監査などでは、システムにサードパーティ製のリポジトリを追加すべきではありません。最も手軽で安全な方法は、公式ソースコードを /opt ディレクトリにクローンすることです:

cd /opt
sudo git clone --depth=1 https://github.com/CISOfy/lynis
cd lynis
sudo chown -R root:root .
sudo chmod 700 lynis

バージョンのクイック確認:

sudo ./lynis show version

方法2:パッケージマネージャー経由でのインストール(長期管理向け)

Ubuntu/Debian環境で apt 経由によりLynisを定期的に自動アップデートしたい場合は、CISOfyの公式リポジトリを設定します:

# CISOfyのGPGキーを追加
curl -fsSL https://packages.cisofy.com/keys/cisofy-software-public.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/cisofy-software-public.gpg

# 公式リポジトリを追加
echo "deb [arch=amd64,arm64 signed-by=/etc/apt/trusted.gpg.d/cisofy-software-public.gpg] https://packages.cisofy.com/community/lynis/deb/ stable main" | sudo tee /etc/apt/sources.list.d/cisofy-lynis.list

# パッケージリストの更新とインストール
sudo apt-get update
sudo apt-get install lynis -y

詳細設定とプロファイル構築

デフォルトの lynis audit system コマンドを実行すると、膨大なログが出力されて圧倒されてしまいます。実務で効率的に運用するには、カスタムプロファイルを作成して誤検知(False Positives)を除外し、重要項目に集中できるようにします。

カスタムプロファイル custom.prf の作成

Lynisは基本設定を default.prf から読み込みます。このファイルはアップデート時に上書きされるため、絶対に直接編集してはいけません。代わりに /etc/lynis/ 配下に上書き用の独自ファイルを作成します:

sudo mkdir -p /etc/lynis
sudo nano /etc/lynis/custom.prf

スキャンの高速化と、無関係なテスト(例:KVM仮想化VPSにおけるブートローダーのハードウェアテストなど)をスキップするオプションを追記します:

# クラウド/VPSで不要なテストをスキップ
skip-test=KRNL-5695
skip-test=BOOT-5121

# 対話入力(Enterキー待機)なしで自動実行
quick=yes

# ログおよびレポートの出力先
log_file=/var/log/lynis.log
report_file=/var/log/lynis-report.dat

初回スキャンの実行

以下のコマンドで全体スキャンを開始します:

sudo lynis audit system --profile /etc/lynis/custom.prf

スキャンは通常1〜3分程度で完了します。結果として Hardening Index のスコアが表示されます(セットアップ直後のUbuntuサーバーでは通常55〜65ポイント程度)。その直後に出力される Warnings(重大な脆弱性)と Suggestions(推奨される改善策)の2つのセクションは、必ず目を通す必要があります。

監査後すぐに修正すべき3大脆弱性

当時の障害対応時、Lynisはサーバークラスターにおける3つの致命的な弱点を指摘しました:

  1. SSHのroot直接ログイン許可および脆弱なパスワード認証(Test ID: SSH-7408):
    利便性のためにパスワード認証を有効にしたまま運用している現場は少なくありませんが、これはボットネットにとって格好の標的です。直ちに /etc/ssh/sshd_config を編集し、SSHキー認証のみを許可するように設定します:

    PermitRootLogin no
    PasswordAuthentication no
    MaxAuthTries 3

    SSHデーモンを再起動します:sudo systemctl restart sshd。
    なお、交代要員のスタッフに新規sudoerアカウントを発行する際、私は toolcraft.app/ja/tools/security/password-generator のパスワード生成ツールを活用して24文字以上のセキュアな文字列を生成しています。このサイトはブラウザ上のJavaScriptのみでオフライン暗号化処理を行うため、パスワードがネットワーク経由で漏洩したり、一般的なオンラインサイトに潜むロガーのリスクを気にする必要がありません。

  2. Kernelネットワークパラメーターの未堅牢化(Test ID: KRNL-6000):
    Linuxカーネルのデフォルトのネットワーク構成は、SYN flood攻撃やIPスプーフィング攻撃に対して脆弱です。/etc/sysctl.d/99-security.conf を開き、以下のパラメーター群を追記します:

    # SYN flood攻撃対策
    net.ipv4.tcp_syncookies = 1
    # IPスプーフィング対策
    net.ipv4.conf.all.rp_filter = 1
    net.ipv4.conf.default.rp_filter = 1
    # MITM攻撃防止のためICMPリダイレクトを拒否
    net.ipv4.conf.all.accept_redirects = 0
    net.ipv6.conf.all.accept_redirects = 0
    # IPフォワーディングを無効化(ルーター/NAT用途を除く)
    net.ipv4.ip_forward = 0

    再起動なしで設定を即座に反映します:

    sudo sysctl --system
  3. cronディレクトリの異常な書き込み権限(Test ID: FILE-7524):
    Lynisにより、/etc/cron.daily/ 配下のスクリプトファイルに誤って 777 権限が付与されていることが検出されました。サービスアカウントの1つでも侵害された場合、攻撃者にシェルコードを上書きされ、翌日にはroot権限を奪取される危険性がありました。直ちに権限を修正します:

    sudo chmod 700 /etc/cron.daily/backup-script.sh
    sudo chown root:root /etc/cron.daily/backup-script.sh

上記の3項目を修正して再スキャンしたところ、サーバーのHardening Indexは61から79ポイントへと一気に跳ね上がりました。

自動化による定期監視と監査

セキュリティ対策は一度実施して放置してしまっては意味がありません。数週間も運用すれば、開発者による追加モジュールの導入や管理者の暫定的な権限変更などにより、システムは再び脆弱な状態に戻ってしまいます。そのため、定期的な監査を自動化することが不可欠です。

lynis-report.dat からのデータ抽出

Lynisは実行ごとに、すべての結果を /var/log/lynis-report.dat にキー・バリュー形式で記録します。短いコマンドライン数行で、必要な情報を素早く抽出できます:

# 重要な警告(Warning)の総数をカウント
grep -c "^warning\[\]" /var/log/lynis-report.dat

# 現在のセキュリティスコア(Hardening Index)を確認
grep "^hardening_index=" /var/log/lynis-report.dat | cut -d '=' -f2

自動スキャン&Telegram通知スクリプトの作成

/usr/local/bin/auto-lynis.sh に監視用スクリプトを作成します:

#!/bin/bash
set -euo pipefail

REPORT_FILE="/var/log/lynis-report.dat"
TELEGRAM_BOT_TOKEN="123456789:ABCdefGHIjklMNOpqrSTUvwxYZ"
TELEGRAM_CHAT_ID="-1001234567890"

# バックグラウンドで非対話モードの監査を実行
/usr/sbin/lynis audit system --profile /etc/lynis/custom.prf --cronjob > /dev/null 2>&1

if [ -f "$REPORT_FILE" ]; then
    HARDENING_INDEX=$(grep "^hardening_index=" "$REPORT_FILE" | cut -d '=' -f2 || echo "0")
    WARNINGS_COUNT=$(grep -c "^warning\[\]" "$REPORT_FILE" || true)

    # 警告が検出された場合に通知を送信
    if [ "$WARNINGS_COUNT" -gt 0 ]; then
        MESSAGE="⚠️ [セキュリティ警告] サーバー $(hostname) に問題が発生しました!%0A- Hardening Index: ${HARDENING_INDEX}/100%0A- 危険な警告数: ${WARNINGS_COUNT}%0A詳細ログを確認してください: /var/log/lynis.log"
        curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
            -d chat_id="${TELEGRAM_CHAT_ID}" \
            -d text="${MESSAGE}" > /dev/null
    fi
fi

実行権限を付与し、毎週日曜日の午前3時に自動実行されるようcronを設定します:

sudo chmod 700 /usr/local/bin/auto-lynis.sh
sudo crontab -e

cron設定の末尾に以下を追記します:

0 3 * * 0 /usr/local/bin/auto-lynis.sh

これで安心して夜を迎えることができます。万が一誰かが誤って不審なポートを開放したり、rootディレクトリの権限を緩和したり、悪意あるスクリプトを残してしまっても、攻撃者に悪用される前にTelegram botがアラートを通知してくれます。

Share: