
Google CloudのCompute Engine(GCE)や各種VPSでLinuxサーバーを運用していると、「身に覚えのないCPU高負荷が続いている」「外部から不審な接続が試みられている」「サーバーから見知らぬ宛先へ大量のパケットが送信されている」といった侵入・不正アクセスの兆候に直面することがあります。
クラウドの管理画面側で異常を察知した後に必須となるのが、実際にLinuxサーバー内部へログインし、OSレベルで「どこまで侵入されているのか」「どのファイルや公開鍵が改ざんされたのか」「不審なプロセスが常駐していないか」を調査する作業です。
この記事では、最新のUbuntu 26.04 LTSおよび24.04 LTS(22.04 LTS含む)を主対象に、ログイン履歴の確認、SSH認証ログの徹底調査、バックドアとなるSSH公開鍵の改ざん点検、稼働プロセス・待ち受けポートの洗い出し、自動起動設定(cron/systemd)の調査手順を体系的に解説します。記事の後半には、サーバー上でコピペするだけで重要項目を一括診断できる「Linux不正侵入簡易点検ワンライナー」も用意していますので、迅速な現状把握にご活用ください。
- この記事で行うこと
- 前提条件・対象読者
- 1. Quick Reference:Linux不正アクセス調査コマンド早見表
- 2. 手順1:ログイン履歴・現在接続中ユーザーの確認
- 3. 手順2:SSH認証ログの徹底調査(Ubuntu 24.04対応)
- 4. 手順3:不審なユーザーとSSH公開鍵(バックドア)の点検
- 5. 手順4:稼働プロセスと不審なネットワーク接続の点検
- 6. 手順5:自動起動設定(永続化メカニズム)の点検
- 7. 手順6:Webサーバーログと直近の更新ファイル点検
- 8. 【キラー特典】コピペで1発点検できるLinux侵入点検シェルスクリプト
- 9. OS内部調査で「確認できること」と「限界・注意点」
- よくある質問(FAQ)
- まとめ
この記事で行うこと
- 現在接続中のセッションおよび過去のログイン履歴(成功・失敗)を特定する
- Ubuntu 24.04 LTSにおけるSSH認証ログ(journalctl / auth.log)を調査する
- 不審なローカルアカウント、UID 0ユーザー、sudo権限の付与状況を点検する
- 各ユーザーの
authorized_keysファイルを走査し、不正なSSH公開鍵をあぶり出す psやtop、ssコマンドで異常なプロセスや不審な待ち受けポートを検出する- cronやsystemdタイマーに仕掛けられた自動起動バックドアを特定する
- Nginx等のWebサーバーログで脆弱性スキャンと実侵入突破(200 OK)を識別する
- 直近で作成・更新された不審ファイルやSUIDファイルを検索する
- 読み取り専用で安全に実行できる「簡易点検ワンライナー・シェルスクリプト」を実行する
- root権限奪取後におけるログ改ざんリスクと調査の限界を理解する
前提条件・対象読者
- GCEやVPS、クラウド環境でLinuxサーバー(Ubuntu 26.04 LTS、24.04 LTS、22.04 LTS等)を運用している管理者・開発者
- サーバーに不正アクセスやマルウェア侵入の疑いがあり、OS内部を迅速に調査したい方
- Linuxの標準コマンド(SSH、Bash)を使った実践的な調査手順を求めている方
- 必要な権限:調査対象サーバーへのSSHログイン権限および管理者権限(
sudo)
1. Quick Reference:Linux不正アクセス調査コマンド早見表
まずは、サーバーにSSHログインした直後に実行すべき重要コマンドと調査の狙いを一覧表でまとめました。
| 点検項目 | 実行コマンド例 | 調査の目的と着目ポイント |
|---|---|---|
| 現在接続中のユーザー | w who | 現在サーバーに侵入者がリアルタイムで接続していないか確認 |
| 過去のログイン成功履歴 | last -F -i -n 20 (26.04: wtmpdb last または journalctl) | 直近のログイン日時、接続元IP、端末、セッション継続時間 |
| ログイン失敗の履歴 | sudo lslogins –failed (または journalctl -u ssh) | ブルートフォース攻撃や不正ログイン試行の頻度と接続元IP |
| SSH認証ログ(ジャーナル) | sudo journalctl -u ssh -n 50 | SSHデーモンの最新認証イベント(Ubuntu 24.04標準) |
| SSH認証ログ(テキスト) | sudo grep “Accepted” /var/log/auth.log | 実際に認証が成功してログインされた記録の抽出(rsyslog環境) |
| 不審なユーザー点検 | awk -F: ‘($3 == 0) {print $1}’ /etc/passwd | root以外の不正な特権UID 0ユーザーが存在しないか |
| SSH公開鍵の点検 | sudo find /home /root -name authorized_keys | バックドアとして埋め込まれた不審なSSH公開鍵を全探索 |
| 稼働プロセスの点検 | ps auxf top | 高負荷プロセス、/tmp等の怪しい場所から起動されたバイナリ |
| 開放ポート・通信の点検 | sudo ss -tulpen | 不審な外部LISTENポート、確立された外部不審通信(ESTAB) |
| 自動起動(cron)の点検 | sudo ls -la /etc/cron* /var/spool/cron/crontabs | 定期実行で再感染させる仕組みが仕込まれていないか |
| 直近更新ファイルの点検 | sudo find / -mtime -3 -type f | 過去3日以内に新設・改ざんされたファイルの洗い出し |
2. 手順1:ログイン履歴・現在接続中ユーザーの確認
サーバーにログインしたら、最初に行うべきは「いま現在、侵入者が同居していないか」と「過去に誰がどこからログインしたか」の確認です。
現在接続中のユーザーを確認する
w コマンドまたは who コマンドを実行します。
w
実行結果には、ログインしているユーザー名、接続元IPアドレス、ログイン時刻、アイドル時間、現在実行しているコマンド(WHAT 列)が表示されます。自分以外の身に覚えのないセッションが存在する場合は、リアルタイムで侵入者が操作を行っている可能性があります。
過去のログイン履歴(last)を確認する
過去に誰がログインに成功したかの履歴を確認します。
last -F -i -n 30
オプションの解説
-F(--fulltimes):ログイン・ログアウトの日時を秒単位まで完全表示します。-i(--ip):ホスト名ではなく接続元IPアドレスを数値形式で表示します。-n 30:直近30件に絞り込んで表示します。
着目ポイント
自分が接続した覚えのない時間帯のログインや、海外IPアドレス・見知らぬプロバイダからのログインが成功(still logged in や通常のセッション終了)として記録されていないかを精査します。
Ubuntu 26.04等で「command not found: last」と表示される原因と対処法
Ubuntu 26.04 LTS(および24.10以降)では、2038年問題(Y2038)に対応するため、従来の32ビット時刻ベースの /var/log/wtmp および last コマンド(util-linux パッケージ内)が標準構成から削除されました。 そのため、新規インストールしたUbuntu 26.04環境では last: command not found となります。 この場合、以下のいずれかの方法で調査を行います。
対処法A:追加インストール不要の標準コマンドで確認する
追加パッケージをインストールしたくない場合は、journalctl を用いて直近のSSHログイン成功履歴を抽出します。
sudo journalctl -u ssh -g "Accepted" -n 30 --no-pager
対処法B:現代の後継パッケージ「wtmpdb」を導入して last を復活させる
SQLite3ベース(/var/log/wtmp.db)のY2038対応ロギングパッケージ wtmpdb をインストールすると、従来の last コマンド(および wtmpdb last)が利用可能になります。
sudo apt update
sudo apt install wtmpdb libpam-wtmpdb
インストール後は、従来通り last -n 30 や wtmpdb last でログイン履歴を確認できます。
ログイン失敗履歴(lastb)を確認する
パスワード誤りなどで弾かれた不正ログインの試行履歴を点検します。
Ubuntu 26.04・24.04における推奨コマンド
従来の lastb コマンド(/var/log/btmp)はUbuntu 26.04などの最新Linuxディストリビューションで完全に廃止されています。そのため、コマンドを実行すると sudo: lastb: command not found となります。 最新環境では、lslogins コマンドまたは journalctl を使用してログイン失敗履歴を調査します。
# ログイン失敗履歴を確認する標準コマンド
sudo lslogins --failed
# SSHデーモンに対する認証失敗イベントを直接抽出する
sudo journalctl -u ssh -g "Failed" -n 30 --no-pager
インターネットにポート22を開放しているサーバーでは、世界中の攻撃ボットから root や admin、ubuntu といったユーザー名に対する辞書攻撃が大量に記録されるのが通常です。大量の失敗履歴があること自体は日常的なノイズですが、その中に「自作の特定ユーザー名」が含まれていないか、また直後にそのユーザーでログイン成功(Accepted)していないかを確認することが重要です。
従来のUbuntu 22.04 LTS等の場合
旧バージョンの環境では、従来通り lastb が利用可能です。
sudo lastb -n 30
3. 手順2:SSH認証ログの徹底調査(Ubuntu 24.04対応)
SSH認証の詳細は、システムログからより詳細に追跡できます。Ubuntu 24.04 LTSでは、従来の rsyslog によるテキストファイル(/var/log/auth.log)への書き出しに代わり、systemd-journald による管理が標準となっています。
Ubuntu 24.04 LTSにおける journalctl でのSSHログ調査
SSHサービス(ssh.service)のログを journalctl で抽出します。
直近のSSH認証成功イベントのみを抽出する
sudo journalctl -u ssh -g "Accepted" -n 50 --no-pager
実行すると、以下のような行が表示されます。
May 10 14:23:01 gce-server sshd[12345]: Accepted publickey for ubuntu from 203.0.113.15 port 52341 ssh2: RSA SHA256:abc...
ログの確認ポイント
- 認証方式:
Accepted publickey(公開鍵認証)なのか、Accepted password(パスワード認証)なのか。パスワード認証を禁止しているはずの環境でパスワードログインが成功している場合、設定が改ざんされたか別経路で侵入されています。 - ユーザー名:誰のアカウントでログインされたか。
- 接続元IPアドレスとポート番号:正当な管理者のIPアドレスか。
- キー指紋(SHA256:…):使用された公開鍵の指紋。
期間を指定して調査する場合
不正アクセスが疑われる日時に絞り込んでログを抽出します。
sudo journalctl -u ssh --since "2026-11-01 00:00:00" --until "2026-11-05 23:59:59" --no-pager
rsyslog が導入されている環境(/var/log/auth.log)での調査
Ubuntu 22.04以前や、明示的に rsyslog をインストールしている環境では、/var/log/auth.log を直接検索できます。
sudo grep "Accepted " /var/log/auth.log*
過去のローテーションされた圧縮ログ(auth.log.1, auth.log.2.gz)も含めて一括検索する場合は、zgrep を使用します。
sudo zgrep "Accepted " /var/log/auth.log*
4. 手順3:不審なユーザーとSSH公開鍵(バックドア)の点検
攻撃者がシステムに一度足場を作ると、再侵入を容易にするために「特権ユーザーの新規作成」や「既存アカウントへのSSH公開鍵の追加」を行います。
不審なアカウントとUID 0(特権)の点検
Linuxでは、ユーザーID(UID)が 0 のアカウントは名前にかかわらず root と同等の完全な権限を持ちます。root 以外のユーザー名で UID 0 が偽装登録されていないかを確認します。
awk -F: '($3 == 0) {print $1}' /etc/passwd
正常なシステムであれば、出力される結果は root の1行のみです。もし見知らぬアカウント名が表示された場合、管理者特権を持つバックドアアカウントが作成されています。
ログイン可能なシェルを持つユーザーの一覧化
システム用のアカウント(daemon, bin, nobody, www-data 等)は、通常 /usr/sbin/nologin または /bin/false がシェルとして設定されており、ログインできません。シェルとして /bin/bash や /bin/sh が設定されているユーザーを洗い出します。
grep -E '(/bin/bash|/bin/sh)$' /etc/passwd
出力結果を見て、自分が作成した正当なユーザー以外にシェルを持つアカウントが存在しないかを確認します。
sudo権限を持つグループの点検
一般ユーザーが sudo を使って管理者権限を実行できるように設定されていないかを点検します。
getent group sudo
また、/etc/sudoers.d/ ディレクトリ配下に不審な設定ファイルが置かれ、パスワードなしで全コマンドを実行(NOPASSWD: ALL)できるように細工されていないかも確認します。
sudo cat /etc/sudoers.d/*
SSH公開鍵(authorized_keys)の徹底点検
攻撃者が最も好む潜伏手口が、~/.ssh/authorized_keys への自身の公開鍵追記です。サーバー内のすべてのユーザーのホームディレクトリ、および /root を横断して authorized_keys を点検します。
sudo find /home /root -name authorized_keys -exec ls -la {} \;
見つかった各ファイルの中身を cat コマンドで確認します。
sudo cat /root/.ssh/authorized_keys
sudo cat /home/*/.ssh/authorized_keys
着目ポイント
- 公開鍵の末尾にあるコメント(
user@hostnameなど)が見慣れないものでないか。 - 登録した覚えのない公開鍵が勝手に追加されていないか。
- ファイルの最終更新日時(
ls -la)が、身に覚えのない日時に変更されていないか。
5. 手順4:稼働プロセスと不審なネットワーク接続の点検
侵入後、サーバーが暗号資産(仮想通貨)のマイニングやスパムメール送信、外部へのDDoS攻撃に利用されている場合、不審なプロセスや通信が活発に動いています。
プロセスの階層表示とCPU消費率の確認
まずは top コマンドでCPU・メモリを極端に消費しているプロセスを特定します。
top -b -n 1 | head -n 25
続いて、ps コマンドで親子関係をツリー状に可視化して確認します。
ps auxf
調査の着目ポイント
- 見慣れないプロセス名(ランダムな英数字、
xmrig,kworkerds,sysupdateなどシステムプロセスに似せた偽装名)。 - 実行ファイルのパスが不自然な場所にあるプロセス。特に
/tmp,/var/tmp,/dev/shmなどの誰でも書き込み可能な一時ディレクトリから直接実行されているバイナリは、マルウェアである可能性が極めて濃厚です。
一時ディレクトリから実行されているプロセスをピンポイントで検出するコマンド:
ls -l /proc/*/exe 2>/dev/null | grep -E '(/tmp|/var/tmp|/dev/shm)'
待ち受けポートと外部通信の点検(ssコマンド)
外部からの遠隔操作(バックドアシェル)や、外部C2(コマンド&コントロール)サーバーとの通信がないかを ss コマンドで調べます。
sudo ss -tulpen
オプションの解説
-t:TCPソケットを表示-u:UDPソケットを表示-l:LISTEN(接続待ち受け)状態のソケットを表示-p:対応するプロセス名とPIDを表示-e:ソケットの拡張情報(UID等)を表示-n:ポート番号やIPを数値で表示
着目ポイント
0.0.0.0や:::に対して、公開した覚えのないポート番号(例: 4444, 1337, 8888, 6667等)がLISTEN状態になっていないか。- そのポートを開いているプロセス名(
users:(("プロセス名",pid=1234,...)))と実行ユーザーのUIDを確認します。
現在確立されている外部とのアクティブな通信を確認する場合:
sudo ss -tanp state established
見知らぬ海外のIPアドレス宛に、SSHやWebサーバー以外のプロセスが持続的な接続を行っていないかを点検します。
6. 手順5:自動起動設定(永続化メカニズム)の点検
攻撃者は、サーバーが再起動されたりプロセスが強制終了されたりしても再びマルウェアが動き出すよう、OSの「自動起動設定」に不正なスクリプトを仕込みます。
cron設定の点検
定期実行タスク(cron)に不審なコマンドや外部ダウンロードスクリプト(curl http://... | sh 等)が登録されていないかを点検します。
システム全体のcron設定を確認する
sudo ls -la /etc/cron*
sudo cat /etc/crontab
sudo cat /etc/cron.d/*
各ユーザーの個人cron設定を確認する
sudo ls -la /var/spool/cron/crontabs/
sudo cat /var/spool/cron/crontabs/* 2>/dev/null
systemd サービス・タイマーの点検
近年はcronだけでなく、systemdのカスタムサービスやタイマー機能を使った永続化も増えています。
直近で新設された不審なサービスファイルがないか、ユニットファイルが配置される主要ディレクトリを確認します。
sudo ls -lt /etc/systemd/system/ | head -n 20
登録されているタイマー一覧を確認します。
systemctl list-timers --all
7. 手順6:Webサーバーログと直近の更新ファイル点検
WebサイトやAPIサーバーを公開している場合、侵入経路の多くはWebアプリケーションの脆弱性(WordPressプラグインの脆弱性やファイルアップロード機能の悪用)です。
Webサーバーアクセスログの点検(HTTP 200と404の区別)
NginxやApacheなどのWebサーバーを運用している場合、アクセスログの調査で最も重要なのが「ステータスコードの識別」です。
インターネット上のサーバーには、日常的に脆弱性スキャン(例: /.env, /wp-login.php, /phpmyadmin への機械的アクセス)が大量に届きます。その大部分は 404 Not Found や 403 Forbidden でブロックされており、これらは実害のないノイズです。
調査で最優先すべきは、それらの攻撃リクエストに対して 「HTTP 200 OK」を返してしまっている通信 です。
sudo grep -E '(\.php|\.env|\.git|cgi-bin)' /var/log/nginx/access.log | grep ' 200 '
見覚えのないPHPファイル(例: wso.php, alfa.php, 不自然なランダム文字列のファイル)へのアクセスでHTTP 200が記録されている場合、Webシェル(遠隔操作バックドア)がアップロードされ、実行に成功した痕跡となります。
「No such file or directory」と表示される場合の確認ポイント
コマンドを実行した際に grep: /var/log/nginx/access.log: No such file or directory と表示される場合、以下のいずれかの状況に該当します。
- サーバーにNginxがインストールされていない場合:SSH接続専用サーバーとして運用している場合や、自分専用のWebアプリ(Node.jsやPython等)をポート番号指定で直接起動している場合は、Nginx自体が存在しないためこのエラーになります(異常ではなく、この点検項目自体をスキップして構いません)。
- Apache等、別のWebサーバーを使用している場合:ログファイルの保存先が
/var/log/apache2/access.logになります。 - Dockerコンテナ内でWebサーバーを動かしている場合:ホストOSの
/var/log/nginx/ではなく、コンテナ内にログが記録されているため、docker logs [コンテナ名]で確認します。
どのWebサーバーが動いているか(または何も動いていないか)を確認するには、以下のコマンドを実行します。
# Webサーバーサービスの稼働状況を確認
systemctl is-active nginx apache2
# 80番(HTTP)や443番(HTTPS)ポートで待ち受けているプロセスを特定
sudo ss -tulpen | grep -E ':(80|443) '
ファイルが存在する場合のみ安全に調査を実行するには、以下のワンライナーを使用します。
# Nginxログが存在する場合のみ検索を実行する安全なコマンド
[ -f /var/log/nginx/access.log ] && sudo grep -E '(\.php|\.env|\.git|cgi-bin)' /var/log/nginx/access.log | grep ' 200 ' || echo "Nginxアクセスログは存在しません(Webサーバー未導入または別構成)"
# Apacheログが存在する場合のみ検索を実行する安全なコマンド
[ -f /var/log/apache2/access.log ] && sudo grep -E '(\.php|\.env|\.git|cgi-bin)' /var/log/apache2/access.log | grep ' 200 ' || echo "Apacheアクセスログは存在しません"
直近数日間に更新されたファイルの抽出
侵入者がシステム内にファイルを配置したり設定を変更したりした痕跡を見つけるため、find コマンドで直近3日以内(-mtime -3)に更新された通常ファイルを洗い出します。
sudo find /etc /var/www /tmp /var/tmp /dev/shm -mtime -3 -type f -ls
システム全体の検索を行う場合は、仮想ファイルシステム(/proc, /sys 等)を除外して実行します。
sudo find / -path /proc -prune -o -path /sys -prune -o -mtime -3 -type f -print
SUIDビットが設定されたファイルの点検
一般ユーザーからroot権限へ不正昇格するために、悪意あるバイナリにSUID権限(実行時に所有者権限で動作するフラグ)が付与されていないかを点検します。
sudo find / -path /proc -prune -o -path /sys -prune -o -type f -perm -4000 -ls
/tmp や /home 配下など、通常は存在しないはずのディレクトリにSUIDファイルが置かれていないかを確認します。
8. 【キラー特典】コピペで1発点検できるLinux侵入点検シェルスクリプト
ここまで紹介した膨大な確認項目を、ターミナル上で手動入力するのは大変な作業です。また、初動調査でシステムの状態を変更してしまうリスクも避けなければなりません。
そこで、「読み取り専用コマンドのみで構成され、システムに一切変更を加えない安全な一括点検スクリプト」を用意しました。
調査対象のLinuxサーバー上で以下のコードブロックをそのままコピー&ペーストして実行してください。
sudo bash -c '
echo "============================================================"
echo " Linux 不正アクセス・侵入簡易点検スクリプト (Read-Only) "
echo " 実行日時: $(date "+%Y-%m-%d %H:%M:%S")"
echo "============================================================"
echo ""
echo "--- [1] 現在接続中のアクティブセッション (w) ---"
w
echo ""
echo "--- [2] 直近のログイン成功履歴 (last または journalctl) ---"
if command -v last >/dev/null 2>&1; then
last -F -i -n 10
elif command -v wtmpdb >/dev/null 2>&1; then
wtmpdb last -n 10
else
echo "(Ubuntu 26.04標準: lastコマンド未導入のためjournalctlからSSHログイン成功を抽出)"
journalctl -u ssh -g "Accepted" -n 10 --no-pager 2>/dev/null || who
fi
echo ""
echo "--- [2-B] ログイン失敗履歴 (lslogins または journalctl) ---"
if command -v lslogins >/dev/null 2>&1; then
lslogins --failed 2>/dev/null || true
else
journalctl -u ssh -g "Failed" -n 10 --no-pager 2>/dev/null || true
fi
echo ""
echo "--- [3] UID 0 (root特権) ユーザーの点検 ---"
awk -F: '\''($3 == 0) {print "UID 0 ユーザー: " $1}'\'' /etc/passwd
echo ""
echo "--- [4] ログインシェルを持つ一般ユーザー ---"
grep -E '\''(/bin/bash|/bin/sh)$'\'' /etc/passwd | cut -d: -f1,7
echo ""
echo "--- [5] 登録されている SSH authorized_keys の点検 ---"
find /home /root -name authorized_keys -exec ls -la {} \; 2>/dev/null
echo ""
echo "--- [6] 不審な待ち受けポート (LISTEN) TOP 15 ---"
ss -tulpen | head -n 16
echo ""
echo "--- [7] 一時ディレクトリ (/tmp, /dev/shm) から実行中のプロセス ---"
SUSPICIOUS_PROC=$(ls -l /proc/*/exe 2>/dev/null | grep -E '\''(/tmp|/var/tmp|/dev/shm)'\'')
if [ -z "$SUSPICIOUS_PROC" ]; then
echo "該当なし(正常)"
else
echo "【警告】不審な実行ファイルを検出:"
echo "$SUSPICIOUS_PROC"
fi
echo ""
echo "--- [8] ユーザー登録 cron の点検 ---"
crontab -l 2>/dev/null || echo "実行ユーザーのcron登録なし"
ls -la /var/spool/cron/crontabs/ 2>/dev/null
echo ""
echo "--- [9] 直近3日間に /etc または /tmp で更新されたファイル ---"
find /etc /tmp /dev/shm -mtime -3 -type f 2>/dev/null | head -n 20
echo ""
echo "============================================================"
echo " 点検完了。不審な点が見つかった場合は詳細調査へ進んでください。"
echo "============================================================"
'
スクリプトの安全性について
このスクリプトは、情報の読み取り・表示(w, last, awk, grep, ss, find)のみを行っており、ファイルの編集、プロセスの停止、パッケージの導入などは一切行いません。調査作業そのものによってログを上書きしたりサーバーを破損させたりする心配がなく、安全に現状を把握できます。
9. OS内部調査で「確認できること」と「限界・注意点」
OS内部での調査は具体的な侵入状況を把握するために強力ですが、「root権限を完全に掌握された場合の限界」も正しく理解しておく必要があります。
【Linux内部調査で確認できること】
◎ 通常の不正アクセス・部分侵入の段階:
* 不正なログイン日時・接続元IP・使用された公開鍵
* 常駐している不審プロセス、マイニングプログラム、外部C2通信
* 改ざんされたファイル、配置されたWebシェル
* バックドアユーザーや自動起動cron設定
=============================================================
× root権限完全奪取後における調査の限界:
* ログ自体の改ざん・消去(/var/log や wtmp の部分削除・ゼロクリア)
* 基本コマンド自体の置き換え(psやssを細工して特定プロセスを不可視化するRootkit)
* カーネルモジュール(LKM Rootkit)による隠蔽
もし攻撃者にroot権限を取られていた場合、攻撃者は自身のログイン痕跡(wtmp や syslog)を削除するツールを実行したり、ps コマンドを細工して不正プロセスを画面に表示させないようにしたりする可能性があります。
侵入が確定的になった場合の安全な対処手順
もし明らかな侵入痕跡(不審なUID 0ユーザー、未知のSSH公開鍵、暗号資産マイニングプロセス等)が確認された場合、そのサーバーを稼働させたまま手動でファイルを消して使い続けるのは極めて危険です。見えない場所に別のバックドアが残されている可能性が極めて高いためです。
推奨される対処フロー
- クラウドコンソール側から直ちにインスタンスのスナップショット(証拠保全用)を取得する
- インスタンスのネットワーク接続を切断(ファイアウォールで通信遮断、またはインスタンス停止)して被害の拡大と外部への攻撃加担を防ぐ
- 感染したインスタンスは破棄(廃棄)し、クリーンなOSイメージからサーバーを新しく再構築する
- 再構築の際は、SSH鍵の更新、OS Loginの適用、不要なポートの完全閉鎖など、侵入原因となった脆弱性を根本から塞ぐ
よくある質問(FAQ)
Q1:Ubuntu 26.04で「last」や「lastb」が「command not found」になります。なぜですか?
Ubuntu 26.04 LTS(および24.10以降)では、2038年問題(Y2038)に対応するために従来の32ビットバイナリログ /var/log/wtmp および /var/log/btmp が廃止され、標準構成から last / lastb が削除されました。ログイン成功履歴は sudo journalctl -u ssh -g "Accepted"、失敗履歴は sudo lslogins --failed で確認できます。従来の last コマンドを使用したい場合は、sudo apt install wtmpdb libpam-wtmpdb をインストールしてください(なお lastb は完全廃止されたため lslogins --failed を使用します)。
Q2:「grep: /var/log/nginx/access.log: No such file or directory」と出ました。異常でしょうか?
異常ではありません。サーバーにNginxがインストールされていない環境(SSH専用サーバーや、自分用のWebアプリを直接ポート起動している場合、またはDockerコンテナ内でWebサーバーを動かしている場合)は、このファイルが存在しません。Webサーバーを運用していない場合はこの点検手順をスキップしてください。また、Apacheを使用している場合は /var/log/apache2/access.log にログが保存されます。
Q3:SSHのログイン失敗(Failed password)が毎日大量に出ています。これは侵入されている証拠ですか?
いいえ、これだけで侵入されているとは言えません。インターネット上にポート22を開放しているサーバーには、世界中の攻撃ボットから24時間自動で無差別な辞書攻撃が届くため、数百〜数万件の失敗ログが記録されるのは一般的な現象です。注意すべきは「ログイン成功(Accepted publickey や Accepted password)」のログです。失敗ログではなく、成功ログに見知らぬ接続がないかを重点的に確認してください。
Q4:攻撃者にroot権限を取られた場合、調査用のLinuxコマンドは信用できますか?
高度な侵入者の場合、ps や netstat、ls などのバイナリを改ざんするRootkit(ルートキット)を仕込み、自身のプロセスやファイルを隠蔽することがあります。疑わしい場合は、パッケージマネージャの整合性確認(dpkg -V procps coreutils)を実行してコマンドファイルが改ざんされていないか検査するか、インスタンスのディスクを別の健全な調査用インスタンスに読み取り専用でアタッチして外部から調査する手法が有効です。
Q5:不正アクセスを受けたインスタンスは、不審なファイルを削除すればそのまま使い続けても良いですか?
おすすめできません。攻撃者が一度root権限を取得した場合、cron、systemd、SSH公開鍵、シェル設定ファイル(.bashrc)、共有ライブラリなど、OS内の無数の場所にバックドアを多重に仕込んでいることが多く、手動ですべてを完全に除去するのは極めて困難です。重要なデータファイルのみを安全に吸い出してウイルススキャンを行った上で、インスタンス自体は破棄し、最初からクリーンな状態で再構築するのが業界標準の安全な対応手順です。
まとめ
Linuxサーバーにおける不正アクセス調査では、客観的な痕跡が残るログとOSの現状を体系的に確認していく冷静なアプローチが求められます。
調査の要点
wとlastで現在接続中のユーザーおよび過去のログイン履歴(成功・失敗)を確認する- Ubuntu 24.04 LTSでは
journalctl -u sshでSSH認証の成功・失敗を迅速に抽出する /etc/passwdを点検し、UID 0の不正アカウントや不審なログインシェルがないか確認する- サーバー内の
authorized_keysを網羅的に走査し、未知のSSH公開鍵をあぶり出す ps auxfとss -tulpenで、一時ディレクトリからの不審プロセスや未知の外部通信を特定する- cronやsystemdに仕掛けられた自動起動の永続化バックドアを点検する
- Webサーバーログでは、スキャン(404)と実侵入突破(200 OK)を厳密に区別する
- 提供した「簡易点検ワンライナー」を活用し、安全かつ迅速に初動診断を完了させる
- root権限を奪取された疑いがある場合は、除染を過信せずインスタンスの破棄と再構築を選択する
サーバーの安全性を維持するためには、OS内部の点検だけでなく、クラウド基盤側(Google Cloudコンソール)の監査ログやIAM設定、ファイアウォールルールの定期点検もあわせて実施しましょう。
次に読むおすすめ記事
Linuxサーバー内部の調査とあわせて、Google Cloud管理コンソール側からCloud Audit LogsやIAM、VPCファイアウォールを調査する手順は、以下の記事で詳しく解説しています。
サーバー運用の安全性を高め、個人でできるセキュリティ対策を基礎から体系的に見直したい方は、以下の完全ガイドもあわせて参考にしてください。


