Skip to content

fix(api): restore reverse-proxy IP resolution for /api/me#78

Open
bashrusakh wants to merge 4 commits into
ruhex:mainfrom
bashrusakh:fix/api-me-reverse-proxy-ip
Open

fix(api): restore reverse-proxy IP resolution for /api/me#78
bashrusakh wants to merge 4 commits into
ruhex:mainfrom
bashrusakh:fix/api-me-reverse-proxy-ip

Conversation

@bashrusakh

@bashrusakh bashrusakh commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Restore X-Real-IP / X-Forwarded-For resolution in /api/me before peer lookup.
  • Keep ?asn= disambiguation for shared-IP peers.
  • Add regression tests for client-IP resolution.

Why

  • Reverse-proxied deployments (nginx) were seeing the proxy IP instead of the real client.

Validation

  • dotnet test BGPLite.Tests/BGPLite.Tests.csproj --no-restore
  • dotnet format BGPLite.sln --verify-no-changes

Risk

  • /api/me again trusts standard reverse-proxy headers when present, matching the prior behavior.

Closes #23

Summary by CodeRabbit

  • New Features

    • Improved peer lookup for the “me” endpoint, including support for identifying the correct peer when multiple peers share an IP by using an ASN filter.
    • Client IP detection is now more reliable behind proxies, using forwarded headers before falling back to the remote address.
  • Bug Fixes

    • Communities are now returned from the correct peer record, ensuring peer-specific data is shown accurately.
    • Peer records are now treated as unique per IP and ASN combination, reducing ambiguity and duplicate matches.

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR reworks peer identity to be scoped by (Ip, Asn) instead of Ip alone. It adds a unique database index migration, a GetPeersByIp store method, ASN-based disambiguation in /api/me (with 409 on ambiguity) and peer-id-based community lookup, a ResolveClientIp helper, associated tests, and README updates.

Changes

Peer identity by IP+ASN

Layer / File(s) Summary
Peer index migration and GetPeersByIp storage
BGPLite.Api/BgpDbContext.cs, BGPLite.Api/PeerStore.cs, BGPLite.Tests/PeerStoreKeyingTests.cs
Adds unique (Ip, Asn) index migration replacing the legacy IP-only index, a new GetPeersByIp method, and tests for idempotent peer creation, scoped session status, and per-peer-id community storage.
/api/me and /api/peer ASN disambiguation
BGPLite.Api/ManagementApi.cs, README.md
HandleGetMe filters peers by optional ?asn= query param, returning null for no match and 409 for ambiguous matches; HandleGetPeer retrieves communities by peer id; README documents the updated /api/me endpoint.
Client IP resolution helper
BGPLite.Api/ManagementApi.cs, BGPLite.Tests/ManagementApiClientIpTests.cs
Adds ResolveClientIp prioritizing X-Real-IP, X-Forwarded-For, then remote endpoint, with tests for all three cases.
Test project wiring
BGPLite.Api/BGPLite.Api.csproj, BGPLite.Tests/BGPLite.Tests.csproj
Adds InternalsVisibleTo for BGPLite.Tests and reorders project references.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ManagementApi
  participant PeerStore
  participant Database
  Client->>ManagementApi: GET /api/me?asn=...
  ManagementApi->>ManagementApi: ResolveClientIp(headers, remoteEndpoint)
  ManagementApi->>PeerStore: GetPeersByIp(clientIp)
  PeerStore->>Database: Query Peers by Ip
  Database-->>PeerStore: Matching rows
  PeerStore-->>ManagementApi: List of PeerInfo
  ManagementApi->>ManagementApi: Filter by asn
  alt no match
    ManagementApi-->>Client: peer: null
  else multiple matches
    ManagementApi-->>Client: 409 Ambiguous peer
  else single match
    ManagementApi-->>Client: peer info with communities
  end
Loading

Related issues: #23 — /api/me disambiguation for peers sharing a source IP is addressed via optional ?asn= filtering and a 409 response on ambiguity.

Suggested labels: enhancement, api, database

Suggested reviewers: ruhex

🐰 A rabbit hops where IPs collide,

Now ASN whispers pick the right guide,

Indexes swapped, unique and clean,

No more mixing peers unseen,

Hop, hop — the network's tidy tide.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately describes the main user-facing change to /api/me behind reverse proxies.
Linked Issues check ✅ Passed The PR adds ASN-based disambiguation for /api/me and regression tests for shared-IP peers, which matches #23's expected fix.
Out of Scope Changes check ✅ Passed The changes stay focused on /api/me peer resolution, related storage/index updates, tests, and documentation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
BGPLite.Tests/ManagementApiClientIpTests.cs (1)

1-36: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Tests only cover the currently-implemented (unconditionally-trusting) behavior.

These tests validate the current header precedence but don't exercise a scenario where headers should be ignored (e.g., request not from a trusted proxy). Once trusted-proxy validation is added per the ResolveClientIp comment, add regression coverage for the "untrusted source falls back to remote endpoint despite spoofed headers" case.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@BGPLite.Tests/ManagementApiClientIpTests.cs` around lines 1 - 36, Add a
regression test in ManagementApiClientIpTests for the untrusted-source case:
when ResolveClientIp receives spoofed X-Real-IP / X-Forwarded-For values but the
request is not from a trusted proxy, it should ignore those headers and return
the remote endpoint. Reuse the existing ResolveClientIp test pattern, but
introduce a scenario that exercises the trusted-proxy validation path once it is
implemented.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@BGPLite.Tests/ManagementApiClientIpTests.cs`:
- Around line 1-36: Add a regression test in ManagementApiClientIpTests for the
untrusted-source case: when ResolveClientIp receives spoofed X-Real-IP /
X-Forwarded-For values but the request is not from a trusted proxy, it should
ignore those headers and return the remote endpoint. Reuse the existing
ResolveClientIp test pattern, but introduce a scenario that exercises the
trusted-proxy validation path once it is implemented.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a3dbb06c-8e8c-4e6e-b73b-83d83b81d958

📥 Commits

Reviewing files that changed from the base of the PR and between 5ecd70c and 27c5aef.

📒 Files selected for processing (8)
  • BGPLite.Api/BGPLite.Api.csproj
  • BGPLite.Api/BgpDbContext.cs
  • BGPLite.Api/ManagementApi.cs
  • BGPLite.Api/PeerStore.cs
  • BGPLite.Tests/BGPLite.Tests.csproj
  • BGPLite.Tests/ManagementApiClientIpTests.cs
  • BGPLite.Tests/PeerStoreKeyingTests.cs
  • README.md
💤 Files with no reviewable changes (1)
  • BGPLite.Api/BgpDbContext.cs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P3/api] /api/me resolves the peer by client IP — ambiguous when several peers share a source IP

1 participant