【入門編】 VPNログを用いた地理的異常検知 – インシデントレスポンス & フォレンジック(DFIR)防御ガイド

こんにちは!セキュリティの世界へようこそ。
日々の開発やインフラの管理、本当にお疲れ様です。

突然ですが、みなさんは「家の鍵」をどうやって管理していますか?
頑丈なディンプルキーを作ったり、オートロックにしたり、あるいは最近流行りのスマートロックを導入したりしているかもしれませんね。では、もし「東京の自宅にいたはずのあなた」が、ほんの数分後に「地球の裏側のブラジルで部屋の鍵を開けていた」としたら……?

「えっ、瞬間移動なんてできるわけない!」って思いますよね。そうです、物理的に不可能です。

実はこれ、サイバーセキュリティの世界でも全く同じことが起きます。インターネットの「合鍵(パスワード)」をこっそり盗み見た悪い泥棒たちが、あなたの知らないどこか遠い国から、会社のネットワークにログインしようと企むのです。

今回は、そんな「物理的に不可能な移動(インポッシブル・トラベル)」を、VPN(仮想プライベートネットワーク)のログを使ってどうやって見破るのか、現場の裏側を覗き見ながら一緒に優しく学んでいきましょう!

—

1. 泥棒は「遠くの国」からやってくる? VPNログが教えてくれること

そもそもVPNとは、会社の外にいても、まるで社内にいるかのように安全に仕事ができる「秘密のトンネル」のようなものです。リモートワークが当たり前になった今、なくてはならない便利な仕組みですよね。

このVPNにログインするとき、システムには様々な「足あと」が記録されます。これが VPNログ です。ログには主に次のような情報が残ります。

  • 誰が(ユーザー名)
  • 何時何分に(タイムスタンプ)
  • どこから(IPアドレス)

この中で特に重要なのが「どこから」という情報です。インターネットの世界では、IPアドレス(例: 203.0.113.195 のような数字の並び)を見ることで、その人が大体どの国からアクセスしているのか(ジオロケーション情報)を割り出すことができます。

「あり得ない移動」はどうやって見つかるの?

想像してみてください。
あなたが今、東京のオフィス(または自宅)で、お昼の12:00にVPNにログインして仕事をしたとします。
そして、そのわずか「2時間後(14:00)」に、今度は南米のアルゼンチンから同じアカウントでログインがあったと記録されました。

飛行機に乗っても、東京からアルゼンチンまで丸一日以上かかりますよね。光の速さで移動したとしても、人間がたった2時間で地球の裏側へ行くことは不可能です。

これが、私たちが「Impossible Travel(インポッシブル・トラベル)」と呼ぶ、超定番かつ強力な不正アクセスの検知手法です。

—

2. Impossible Travelを判定する仕組みを覗いてみよう

「じゃあ、どうやってそれをシステムで見つけ出すの?」気になりますよね。
基本のロジックは、実はとてもシンプルです。算数の距離と時間の問題に少し似ています。

判定のステップは以下の3つです。

1. 前回のログイン場所と時間を記憶する
ユーザーがログインするたびに、「いつ、どこの国(または緯度・経度)からアクセスしたか」をデータベースにメモしておきます。
2. 今回のログイン場所と時間を確認する
新しくログインがあったら、その場所と時間をチェックします。
3. 「移動速度」を計算する
「前回の場所から今回の場所までの距離」を、「かかった時間」で割ります。もし、そのスピードが新幹線や飛行機の限界を超えていたら……「アラート(警報)」を鳴らします!

—

3. 実践!Pythonで書く「インポッシブル・トラベル検知ロジック」

百聞は一見に如かず。実際に、インシデントレスポンスの現場で使われている判定ロジックの簡易版を、Pythonというプログラミング言語を使って覗いてみましょう。

初心者の方でも読めるように、日本語のコメントをたっぷり入れておきますね。

from datetime import datetime
from geopy.distance import geodesic

# ざっくりとした移動速度の限界(時速km)
# 音速(旅客機より少し速いくらい)を超える移動は「人間には不可能」とみなします
MAX_POSSIBLE_SPEED_KMH = 1000.0

def check_impossible_travel(last_login, current_login):
    """
    前回のログイン情報と今回のログイン情報を比較し、
    物理的に不可能な移動(Impossible Travel)かどうかを判定する関数
    
    last_login: 辞書型 {'time': ログイン時刻, 'lat': 緯度, 'lon': 経度}
    current_login: 辞書型 {'time': ログイン時刻, 'lat': 緯度, 'lon': 経度}
    """
    
    # 1. 時間の差を計算する(時間単位)
    time_format = "%Y-%m-%d %H:%M:%S"
    t1 = datetime.strptime(last_login['time'], time_format)
    t2 = datetime.strptime(current_login['time'], time_format)
    
    hours_diff = (t2 - t1).total_seconds() / 3600.0
    
    # 時間が全く経っていない、または過去に戻っている場合はスキップ(多重同時ログイン等の考慮)
    if hours_diff <= 0:
        return False, "同時間帯または不正なタイムスタンプです"

    # 2. 2点間の距離を計算する(キロメートル単位)
    # geopyライブラリを使って、地球上の緯度・経度から直線距離を割り出します
    point_a = (last_login['lat'], last_login['lon'])
    point_b = (current_login['lat'], current_login['lon'])
    distance_km = geodesic(point_a, point_b).kilometers

    # 3. 必要な移動速度を計算する(距離 ÷ 時間)
    required_speed = distance_km / hours_diff

    # 4. 判定
    if required_speed > MAX_POSSIBLE_SPEED_KMH:
        # 限界速度を超えている=インポッシブル・トラベル発生!
        return True, f"異常検知! 距離: {distance_km:.1f}km を {hours_diff:.1f}時間 で移動(必要時速: {required_speed:.1f}km/h)"
    else:
        return False, f"正常な移動範囲です(時速換算: {required_speed:.1f}km/h)"

# --- テスト実行のサンプル ---
if __name__ == "__main__":
    # 前回のログイン:東京(新宿あたり)
    previous_access = {
        'time': '2023-10-25 10:00:00',
        'lat': 35.6895, 
        'lon': 139.6917
    }

    # 今回のログイン:たった2時間後にアメリカ・ロサンゼルスから!?
    current_access = {
        'time': '2023-10-25 12:00:00',
        'lat': 34.0522, 
        * 'lon': -118.2437
    }

    is_anomaly, message = check_impossible_travel(previous_access, current_access)
    print(f"判定結果: {message}")

コードのイメージは掴めましたでしょうか?
このように、コンピュータに「距離」と「時間」を計算させるだけで、泥棒がこっそり海外から侵入しようとした瞬間を鋭く見つけ出すことができるのです。

—

4. 現場のプロが教える「本当は怖い落とし穴」と対策

さて、ここからがセキュリティの現場の面白いところ(そして悩ましいところ)です。
実は、この便利なインポッシブル・トラベル検知、「本当に泥棒のとき」と「実は正常なとき」の区別がつきにくいケースがいくつか存在します。

現場でよくある「偽の警報(誤検知)」の代表例を見ていきましょう。

落とし穴1:VPNやプロキシサービスの利用

最近のプライバシー意識の高いユーザーや、社内ポリシーによっては、VPN接続サービスやクラウド経由のプロキシ(中継サーバー)を使っていることがあります。
これを使うと、「本当は日本の自宅にいるのに、アクセス元のIPアドレスはオランダになっている」といった現象が起きます。そのため、ユーザーが移動していなくても、中継するサーバーが変わっただけで「地球の裏側にワープした!」と誤検知されてしまうのです。

落とし穴2:モバイル回線のIPアドレスの変動

スマートフォンでテザリングをしながら移動したり、地下鉄に乗ったりすると、携帯キャリアの基地局が変わるタイミングでIPアドレスが一気に遠くの地域のものに変わることがあります。これもシステム側からは「突然のワープ」に見えてしまいます。

一歩ずつ進める対策のステップ

こうした誤検知に振り回されないために、現場のエンジニアやSOCアナリストは次のような工夫をしています。

  • 「いつもと違う国」に注目する

単に距離が離れているだけでなく、「普段そのユーザーが絶対にアクセスしない国(例えば、普段は日本からしか繋がないのに突然北朝鮮や東欧からアクセスがあった等)」を重く評価する。

  • 多要素認証(MFA)を組み合わせる

パスワードが万が一盗まれて海外から入力されても、スマホに届くプッシュ通知やワンタイムパスワード(MFA)がなければログインできないようにしておけば、インポッシブル・トラベルが発生した時点で「パスワードが漏れている!」という強力な証拠になります。すぐに対象のアカウントをロックしましょう。

—

おわりに

今回は、VPNログを使った地理的異常検知(Impossible Travel)について、身近な例えを交えてお話ししました。

セキュリティの対策は、一度に完璧な要塞を作る必要はありません。
「家の鍵を閉める」のと同じように、まずは「誰が、どこから、いつ入ってきたか」というログに目を向け、おかしな動きがあったら「あれ?」と気づける仕組みを一つずつ育てていくことが何よりも大切です。

日々の開発やインフラ運用の片隅で、この記事があなたのセキュリティに対する「新しい視点」のヒントになればとても嬉しいです。
それでは、また次のセキュリティの冒険でお会いしましょう!一歩ずつ、安全なシステム作りを楽しんでいきましょうね。

コメント

タイトルとURLをコピーしました