Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: get client IP from the request headers #233

Merged
merged 104 commits into from
Jan 30, 2025
Merged

Conversation

sbruens
Copy link

@sbruens sbruens commented Jan 29, 2025

This checks the headers for common client IP forwarding headers, falling back to the request's RemoteAddr if they don't exist.

I started with the most common headers: Forwarded, X-Forwarded-For, and X-Client-IP. I think that covers most cases, but we can add more in a future PR.

This will allow us to re-use the handling of packets in the Caddy
server where serving is handled separately.
Instead, make the connection an association by wrapping it with the
client address and pass that to the `Handle()` function. Each connection
will call `Handle()` only once.
@sbruens sbruens requested a review from a team as a code owner January 29, 2025 22:13
@sbruens sbruens requested a review from fortuna January 29, 2025 22:13
// GetClientIPFromRequest retrieves the client's IP address from the request.
// This checks common headers that forward the client IP, falling back to the
// request's `RemoteAddr`.
func GetClientIPFromRequest(r *http.Request) (net.IP, error) {
Copy link

Choose a reason for hiding this comment

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

Pass a header instead

Copy link
Author

Choose a reason for hiding this comment

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

I need the request to fallback to the RemoteAddr. I could move that out of this function, but I think I'll leave this right now and revisit in a refactor that will likely do away with this function altogether.

// `Forwarded` (RFC 7239).
forwardedHeader := r.Header.Get("Forwarded")
if forwardedHeader != "" {
parts := strings.Split(forwardedHeader, ",")
Copy link

Choose a reason for hiding this comment

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

This is acceptable for this PR, but you need to update it later to use proper libraries to parse this format.
I believe https://pkg.go.dev/net/textproto#Reader.ReadMIMEHeader will give you the list of values, which you can then split. We need to figure out what the format is based on the RFC. We can look into what the net lib does.

Copy link
Author

Choose a reason for hiding this comment

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

Yeah I think the gorilla library actually has some basic function for this as well: https://github.com/gorilla/handlers/blob/9c61bd81e701cf500437e1b516b675cdd3b73ca7/proxy_headers.go#L21 I'll likely revisit this when moving to that.

Base automatically changed from sbruens/websocket to master January 30, 2025 00:27
@sbruens sbruens merged commit b7d1c7a into master Jan 30, 2025
5 checks passed
@sbruens sbruens deleted the sbruens/fwd-address branch January 30, 2025 01:28
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.

2 participants