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

Fix IPv6 client IPs when the proxy uses KeepAlive #45

Merged
merged 1 commit into from
Dec 20, 2016

Conversation

BenSjoberg
Copy link
Contributor

@BenSjoberg BenSjoberg commented Dec 10, 2016

I think I figured out #37. It's because of how the original apr_sockaddr_t object is restored to the request_rec object during the cleanup process.

When a request is being processed, the original IP address is saved and the apr_sockaddr_t object is overwritten with a new one based on the IP in X-Forwarded for:

rpaf_cleanup_rec *rcr = (rpaf_cleanup_rec *)apr_pcalloc(r->pool, sizeof(rpaf_cleanup_rec));
rcr->old_ip = apr_pstrdup(r->DEF_POOL, r->DEF_IP);
rcr->r = r;
apr_pool_cleanup_register(r->pool, (void *)rcr, rpaf_cleanup, apr_pool_cleanup_null);
r->DEF_IP = apr_pstrdup(r->DEF_POOL, last_val);
memcpy(&rcr->old_addr, r->DEF_ADDR, sizeof(apr_sockaddr_t));

tmppool = r->DEF_ADDR->pool;
tmpport = r->DEF_ADDR->port;
apr_sockaddr_t *tmpsa;
int ret = apr_sockaddr_info_get(&tmpsa, r->DEF_IP, APR_UNSPEC, tmpport, 0, tmppool);
if (ret == APR_SUCCESS)
    memcpy(r->DEF_ADDR, tmpsa, sizeof(apr_sockaddr_t));

Then during the cleanup, rcr->old_ip is used to put the original IP address back into r->DEST_ADDR:

rcr->r->DEF_ADDR->sa.sin.sin_addr.s_addr = apr_inet_addr(rcr->r->DEF_IP);

The problem is that when X-Forwarded-For contains an IPv6 address, r->DEF_ADDR->family is set to APR_INET6. When the connection is reused, r->DEF_ADDR is checked against RPAF_ProxyIPs to see if it's an authorized proxy, but it thinks it's checking against an IPv6 address, so it doesn't match. (If RPAF_ProxyIPs isn't set, this problem doesn't happen.)

Another problem is that apr_inet_addr() doesn't support IPv6 addresses, so the current code would also have issues when IPv6 is used to communicate with the proxy. Instead of reconstructing the address from r->DEF_IP, my solution is to just copy r->DEF_ADDR into a new member of rpaf_cleanup_rec, then copy it back during the cleanup process.

@gnif
Copy link
Owner

gnif commented Dec 20, 2016

Nice clean solution! Thanks!

@gnif gnif merged commit 669c3d2 into gnif:stable Dec 20, 2016
@BenSjoberg BenSjoberg deleted the fix_ipv6 branch December 20, 2016 17:30
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