EBS スナップショットから、ログインできない EC2 の役割を無停止で調べてみる

EBS スナップショットから、ログインできない EC2 の役割を無停止で調べてみる

用途不明なEC2インスタンスの実体を調査する必要があったため、EBSスナップショットから別のインスタンスに読み取り専用でマウントし、ファイルとログから役割・利用履歴・定期処理を特定する方法を試してみました。
2026.10.31

はじめに

かつまたです。

運用を引き継いだ AWS 環境で、用途のわからない EC2 インスタンスが見つかることがあります。ログインに必要な鍵やパスワードが手元になく、SSMエージェントも入っていないと、OS の中を直接確認できません。止めてよいかどうかもわからないため、再起動を伴う調べ方も選べません。

そこで、EBS スナップショットから作ったボリュームを別の EC2 に読み取り専用でつなぎ、ファイルとログから役割を調べました。

やりたいこと

  • 対象の EC2 を止めず、OS にもログインせずに、次のことを調べる
    • 何のサーバーか(入っているソフトウェア、動いているサービス、設定)
    • 最後に人が使ったのはいつか(ログオン履歴)
    • 定期的に何をしているか(スケジュールされたタスク、cron)

検証環境

用途がわからないサーバーの代わりに、検証用の EC2 を 2 台用意し、それらしい役割を仕込みました。

  • Windows Server 2022: コンピューター名 FILESV01。7-Zip を入れ、DNS サーバーにセカンダリゾーンを作り、夜間に動くスケジュールタスクを登録しました
  • Ubuntu 24.04: nginx を入れ、/etc/cron.d に定期処理を置きました

スナップショット取得前に、Windows には Fleet Manager のリモートデスクトップで、Ubuntu には EC2 Instance Connect の SSH でログインを何回か試行しました。

やってみた

1. スナップショットを作成する

対象の EC2 は動かしたまま、ルートボリュームのスナップショットを作成します。

aws ec2 create-snapshot --volume-id <対象のボリューム ID> \
  --description "offline investigation" \
  --tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=investigation}]'

2. スナップショットからボリュームを作り、調査用 EC2 につなぐ

aws ec2 create-volume --snapshot-id <スナップショット ID> \
  --availability-zone <調査用 EC2 の AZ> --volume-type gp3
aws ec2 attach-volume --volume-id <作成したボリューム ID> \
  --instance-id <調査用 EC2 の ID> --device /dev/sdf

3. 読み取り専用でマウントする

デバイス名は環境によって変わるので、つないだあと lsblk -f で確認しました。

Windows(NTFS)は ntfs-3g でマウントしました。

sudo mkdir -p /mnt/win && sudo mount -t ntfs-3g -o ro /dev/nvme1n1p1 /mnt/win

Linux(ext4)は、noload を付けずにマウントし、ジャーナルを適用してから読みました。

sudo mkdir -p /mnt/linux && sudo mount -o ro,noexec,nosuid,nodev /dev/nvme2n1p1 /mnt/linux

4. Windows

Windows の情報は、主にレジストリのファイル(ハイブ)とイベントログに残っています。

知りたいこと 場所
OS の版、インストール日 Windows/System32/config/SOFTWARE の Microsoft\Windows NT\CurrentVersion
コンピューター名 SYSTEM の ControlSet001\Control\ComputerName\ComputerName
インストール済みのソフトウェア SOFTWARE の Microsoft\Windows\CurrentVersion\Uninstall(32 ビット版は WOW6432Node\...)
自動起動するサービス SYSTEM の ControlSet001\Services(Start が 0〜2 で、ImagePath が Windows 標準以外のもの)
スケジュールされたタスク Windows/System32/Tasks 配下の XML(UTF-16)
ログオン履歴 Windows/System32/winevt/Logs/Security.evtx のイベント ID 4624
リモートデスクトップの接続履歴 Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx のイベント ID 21(ログオン)・25(再接続)
DNS サーバーとしての設定 SOFTWARE の Microsoft\Windows NT\CurrentVersion\DNS Server\Zones

レジストリは hivexregedit で書き出せます。まず、インストール済みのソフトウェアを見ました。

hivexregedit --export /mnt/win/Windows/System32/config/SOFTWARE \
  'Microsoft\Windows\CurrentVersion\Uninstall' | grep '"DisplayName"'

文字列の値の多くは、そのままでは読めない形で出力されます(長いので途中で省略しています)。

"DisplayName"=hex(1):37,00,2d,00,5a,00,69,00,70,00,20,00,32,00,34,00,2e,00,30,00,39,00,20,00,28,00,78,00,36,00,...

hex(1)(文字列)や hex(2)(環境変数を含む文字列)は、UTF-16LE のバイト列を 16 進数で並べたものです。次のスクリプト(regdec.py)を通して文字列に戻しました。

#!/usr/bin/env python3
# hivexregedit の hex(1)/hex(2)/hex(7) を UTF-16LE の文字列に戻す
import sys, re

def dec(m):
    b = bytes.fromhex(m.group(2).replace(',', '').replace('\\', ''))
    return '"' + b.decode('utf-16le', 'ignore').replace('\x00', '|').strip('|') + '"'

for line in sys.stdin:
    print(re.sub(r'hex\((1|2|7)\):([0-9a-f,\\]+)', dec, line.rstrip('\n')))
hivexregedit --export /mnt/win/Windows/System32/config/SOFTWARE \
  'Microsoft\Windows\CurrentVersion\Uninstall' | python3 regdec.py | grep '"DisplayName"'
"DisplayName"="7-Zip 24.09 (x64 edition)"
"DisplayName"="Microsoft Visual C++ 2022 X64 Minimum Runtime - 14.44.35211"
"DisplayName"="AWS PV Drivers"
"DisplayName"="Microsoft Visual C++ 2022 X64 Additional Runtime - 14.44.35211"
"DisplayName"="aws-cfn-bootstrap"
"DisplayName"="Amazon SSM Agent"
"DisplayName"="Amazon EC2Launch"

DNS サーバーのゾーンの設定です。

hivexregedit --export /mnt/win/Windows/System32/config/SOFTWARE \
  'Microsoft\Windows NT\CurrentVersion\DNS Server\Zones' | python3 regdec.py \
  | grep -E '^\[|"Type"|"MasterServers"'
[\Microsoft\Windows NT\CurrentVersion\DNS Server\Zones\corp.example.internal]
"MasterServers"="192.0.2.10"
"Type"=dword:00000002

corp.example.internal がセカンダリゾーン(Type=2)で、上流のサーバーは 192.0.2.10 です。

スケジュールされたタスクは、Windows/System32/Tasks 配下にタスクごとのファイルがありました。NightlyShareBackup の定義は UTF-16 の XML なので、iconv で UTF-8 にしてから読みました。

iconv -f UTF-16 -t UTF-8 /mnt/win/Windows/System32/Tasks/NightlyShareBackup \
  | grep -E '<(Command|Arguments|StartBoundary|UserId)>'
      <StartBoundary>2026-10-31T01:00:00Z</StartBoundary>
      <UserId>SYSTEM</UserId>
      <Command>powershell.exe</Command>
      <Arguments>-File C:\scripts\nightly-backup.ps1</Arguments>

毎日 1:00 に、SYSTEM 権限で C:\scripts\nightly-backup.ps1 を実行するタスクなことを確認しました。

#!/usr/bin/env python3
# evtx のレコードを、ファイルヘッダーのチャンク数に頼らず全チャンクから読む
# 使い方: logons.py Security.evtx                     -> 4624 のうち LogonType 10・7
#         logons.py <LocalSessionManager の evtx> lsm -> イベント ID 21・25
import sys, re
from Evtx.Evtx import ChunkHeader

def data(xml, name):
    m = re.search(r'<Data Name="%s">([^<]*)</Data>' % name, xml)
    return m.group(1) if m else ''

def tag(xml, name):
    m = re.search(r'<%s[^>]*>([^<]*)</%s>' % (name, name), xml)
    return m.group(1) if m else ''

buf = open(sys.argv[1], 'rb').read()
lsm = len(sys.argv) > 2
rows = set()
for m in re.finditer(b'ElfChnk\x00', buf):
    for rec in ChunkHeader(buf, m.start()).records():
        xml = rec.xml()
        eid = tag(xml, 'EventID')
        t = re.search(r'SystemTime="([^"]+)"', xml).group(1)
        if lsm and eid in ('21', '25'):
            rows.add((t, eid, tag(xml, 'User'), tag(xml, 'Address')))
        elif not lsm and eid == '4624' and data(xml, 'LogonType') in ('10', '7'):
            rows.add((t, data(xml, 'LogonType'), data(xml, 'TargetUserName'), data(xml, 'IpAddress')))
for r in sorted(rows):
    print(*r)
python3 logons.py /mnt/win/Windows/System32/winevt/Logs/Security.evtx
2026-10-31 13:52:18.017977 10 Administrator ::1
2026-10-31 13:53:22.100441 7 Administrator ::1

LogonType 10(リモートデスクトップ)でログオンし、LogonType 7(切断したセッションへの再接続)を確認できました。
Fleet Manager のリモートデスクトップは SSM エージェント経由でインスタンスの中から接続するため、接続元は ::1 になります。通常の RDP であれば、ここにクライアントの IP アドレスが入ります。

リモートデスクトップの接続は、TerminalServices-LocalSessionManager のイベント ID 21・25 でも確認しました。

python3 logons.py \
  "/mnt/win/Windows/System32/winevt/Logs/Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx" lsm
2026-10-31 13:52:20.972511 21 FILESV01\Administrator ::%16777216
2026-10-31 13:53:21.805639 25 FILESV01\Administrator ::%16777216
2026-10-31 13:54:04.592886 25 FILESV01\Administrator ::%16777216

5. Linux

知りたいこと 場所
OS の版 etc/os-release
ログイン履歴 var/log/auth.log*、var/log/wtmp(last -f)
ユーザーごとの最終ログイン var/log/lastlog(wtmp が空でも残っていることがある)
定期処理 var/spool/cron/crontabs/、etc/cron.d/、etc/systemd/system/*.timer
自動起動するサービス etc/systemd/system/multi-user.target.wants/
待ち受けているポート・アプリの設定 etc/ssh/sshd_config、etc/nginx/ など

定期処理は etc/cron.d に置かれていました。

cat /mnt/linux/etc/cron.d/reports-backup
30 2 * * * root /opt/reports/backup.sh

毎日 2:30 に、root で /opt/reports/backup.sh を実行していることがわかりました。

ログイン履歴も確認しました。

last -f /mnt/linux/var/log/wtmp
ubuntu   pts/0        <接続元 IP>   Sat Oct 31 14:09 - 14:09  (00:00)
ubuntu   pts/0        <接続元 IP>   Sat Oct 31 14:08 - 14:08  (00:00)
reboot   system boot  7.0.0-1014-aws   Sat Oct 31 13:45   still running
#!/usr/bin/env python3
# lastlog(1 レコード 292 バイト、ユーザー ID 順)からユーザーごとの最終ログインを読む
import sys, struct, datetime

root = sys.argv[1]
log = open(root + '/var/log/lastlog', 'rb').read()
for line in open(root + '/etc/passwd'):
    name, _, uid = line.split(':')[:3]
    off = int(uid) * 292
    if off + 292 > len(log):
        continue
    t, tty, host = struct.unpack_from('<i32s256s', log, off)
    if t:
        when = datetime.datetime.fromtimestamp(t, datetime.timezone.utc)
        print(name, when.isoformat(), tty.rstrip(b'\0').decode(), host.rstrip(b'\0').decode())
python3 lastlog.py /mnt/linux
ubuntu 2026-10-31T14:09:11+00:00 pts/0 <接続元 IP>

結果

知りたいこと Windows Linux
何のサーバーか 7-Zip、DNS サーバーのセカンダリゾーン(上流 192.0.2.10)、コンピューター名 FILESV01 Ubuntu 24.04、ホスト名 web-reports、nginx(:80)
最後に人が使った日時 13:52 の RDP ログオンと、その後の再接続 ubuntu の SSH ログイン(14:08・14:09)
定期的な処理 NightlyShareBackup(毎日 1:00) cron.d のバックアップ(毎日 2:30)

対象の EC2 は止めず、OS にもログインせずに、役割・最後に使われた日時・定期的な処理を確認できました。

クラスメソッドオペレーションズ株式会社について

クラスメソッドグループのオペレーション企業です。
運用・保守開発・サポート・情シス・バックオフィスの専門チームが、IT・AIをフル活用した「しくみ」を通じて、お客様の業務代行から課題解決や高付加価値サービスまでを提供するエキスパート集団です。
当社は様々な職種でメンバーを募集しています。
「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、クラスメソッドオペレーションズ株式会社 コーポレートサイト をぜひご覧ください。
※2026年1月 アノテーション㈱から社名変更しました

この記事をシェアする

関連記事