Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Preserve viewer source port in audit log for MAP-E client identification#39

Merged
ogadra merged 1 commit into
mainfrom
fix/audit-log-viewer-port
Mar 27, 2026
Merged

Preserve viewer source port in audit log for MAP-E client identification#39
ogadra merged 1 commit into
mainfrom
fix/audit-log-viewer-port

Conversation

@ogadra

@ogadra ogadra commented Mar 27, 2026

Copy link
Copy Markdown
Owner

Summary

  • Preserve the full ip:port from CloudFront-Viewer-Address header in audit logs instead of stripping the port
  • Source port is needed to identify clients behind MAP-E or DS-Lite where multiple households share a single global IP and are distinguished by port ranges
  • Remove unused net import and simplify clientIP() function

Test plan

  • docker build --target test runner/ passes with 100% coverage
  • After deploy, verify remote= in audit logs shows ip:port format

🤖 Generated with Claude Code

Summary by CodeRabbit

リリースノート

  • バグ修正
    • CloudFront経由のアクセスログに記録されるクライアントアドレスが、IPアドレスとポート番号の両方を含むようになりました。ソースポート情報が監査ログに正確に保持されるようになります。

@ogadra ogadra added the runner Runner microservice label Mar 27, 2026
@coderabbitai

coderabbitai Bot commented Mar 27, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

ウォークスルー

CloudFront-Viewer-Addressヘッダーの処理ロジックを変更しました。従来のnet.SplitHostPortでホスト部分のみを抽出する代わりに、ヘッダー値全体(ip:port形式)をそのまま返すようにしました。関連するコメントを更新し、未使用のnetインポートを削除しました。テストも期待値を更新して、完全なアドレス文字列を検証するようにしました。

変更内容

コホート / ファイル(s) 概要
CloudFrontクライアントIP処理
runner/handler.go
clientIP関数を修正し、CloudFront-Viewer-Addressヘッダーをip:port形式で完全に返すようにしました。ホストのみの抽出ロジックを削除し、コメントを更新し、未使用のnetインポートを削除しました。
監査ログテスト更新
runner/handler_test.go
TestExecuteCloudFrontViewerAddressを修正してremoteフィールドが完全なip:port値を含むことを検証するようにしました。ポート情報なしの単独IPのテストケースTestExecuteCloudFrontViewerAddressWithoutPortを削除しました。

推奨コード レビュー対象領域

  • clientIP関数の戻り値がIPアドレスのみからip:port形式に変更されたことによる、他の呼び出し箇所への影響確認
  • 監査ログのremoteフィールドが完全なアドレス形式で記録されることの動作検証

推定コード レビュー工数

🎯 2 (Simple) | ⏱️ ~10 minutes

関連の可能性があるPR

ウサギからのお祝い詩

🐰✨
CloudFrontのアドレスは、
ポートを握りしめて、
ip:portの完全な姿で飛び込む。
監査ログも喜び、
真実の足跡を刻む。 🎉

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: preserving the viewer source port in audit logs for MAP-E client identification, which aligns with the core objective of the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/audit-log-viewer-port

Comment @coderabbitai help to get the list of available commands and usage tips.

@ogadra ogadra marked this pull request as ready for review March 27, 2026 10:16

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
runner/handler_test.go (1)

665-700: 🧹 Nitpick | 🔵 Trivial

LGTM! テストが新しい動作を正しく検証しています。

ip:port形式のフルアドレスがauditログに記録されることを確認するテストに更新されており、handler.goの変更と整合しています。

AI生成サマリーによるとTestExecuteCloudFrontViewerAddressWithoutPortが削除されていますが、CloudFrontは常にポートを含むため、この削除は妥当です。

IPv6アドレスのテストケースを追加すると、カバレッジがより包括的になります:

📝 IPv6テストケースの追加案
// TestExecuteCloudFrontViewerAddressIPv6 verifies that IPv6 addresses with port
// are preserved in the audit log remote field.
func TestExecuteCloudFrontViewerAddressIPv6(t *testing.T) {
	var buf bytes.Buffer
	log.SetOutput(&buf)
	defer log.SetOutput(os.Stderr)

	sm := NewSessionManager()
	defer sm.CloseAll()
	sm.newShell = func() (Shell, error) {
		return &mockShell{exitCode: 0}, nil
	}
	handler := newHandler(sm, nil)

	id, _, err := sm.Create()
	if err != nil {
		t.Fatalf("Create() error: %v", err)
	}

	body := strings.NewReader(`{"command":"ls"}`)
	req := httptest.NewRequest(http.MethodPost, "/api/execute", body)
	req.AddCookie(&http.Cookie{Name: "session_id", Value: id})
	req.Header.Set("CloudFront-Viewer-Address", "[2001:db8::1]:54321")
	w := httptest.NewRecorder()
	handler.ServeHTTP(w, req)

	if w.Code != http.StatusOK {
		t.Fatalf("status = %d, want %d", w.Code, http.StatusOK)
	}

	logOutput := buf.String()
	if !strings.Contains(logOutput, "remote=[2001:db8::1]:54321") {
		t.Fatalf("expected audit log to contain remote=[2001:db8::1]:54321, got:\n%s", logOutput)
	}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@runner/handler_test.go` around lines 665 - 700, Add an IPv6 test analogous to
TestExecuteCloudFrontViewerAddress to ensure bracketed IPv6+port values are
preserved in the audit remote field: create
TestExecuteCloudFrontViewerAddressIPv6 that sets up a SessionManager (sm), uses
sm.newShell to return a mockShell, creates a handler via newHandler(sm, nil),
issues an httptest POST to /api/execute with the session_id cookie and header
CloudFront-Viewer-Address set to "[2001:db8::1]:54321", calls handler.ServeHTTP,
asserts status OK, captures log output, and verifies it contains
"remote=[2001:db8::1]:54321" (matching the pattern used in the existing
TestExecuteCloudFrontViewerAddress).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@runner/handler_test.go`:
- Around line 665-700: Add an IPv6 test analogous to
TestExecuteCloudFrontViewerAddress to ensure bracketed IPv6+port values are
preserved in the audit remote field: create
TestExecuteCloudFrontViewerAddressIPv6 that sets up a SessionManager (sm), uses
sm.newShell to return a mockShell, creates a handler via newHandler(sm, nil),
issues an httptest POST to /api/execute with the session_id cookie and header
CloudFront-Viewer-Address set to "[2001:db8::1]:54321", calls handler.ServeHTTP,
asserts status OK, captures log output, and verifies it contains
"remote=[2001:db8::1]:54321" (matching the pattern used in the existing
TestExecuteCloudFrontViewerAddress).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: aec3bb85-d40e-4abf-821d-66c5cf1e15b5

📥 Commits

Reviewing files that changed from the base of the PR and between 4dbf5be and b2ec60a.

📒 Files selected for processing (2)
  • runner/handler.go
  • runner/handler_test.go

@ogadra ogadra merged commit 3e458c4 into main Mar 27, 2026
10 of 11 checks passed
@ogadra ogadra deleted the fix/audit-log-viewer-port branch March 27, 2026 10:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

runner Runner microservice

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant