Sign inSign up

boro/squid-ipv6

By boro

•Updated over 2 years ago

Custom squid build that supports specifying an outgoing IPv4 or IPv6 address via request headers.

Image
Web servers
0

4.6K

boro/squid-ipv6 repository overview

⁠Squid with IPv4/IPv6 Freebind (specify outgoing IP via HTTP Header)

Custom Squid Proxy container with "IPv4-Bind" and "IPv6-Bind" header support for routing requests via a specific IPv4/IPv6 address (specified via request headers).

⁠Required Environment Variables

Variable NameExample Value
SQUID_USERNAMEmyusername
SQUID_PASSWORDsupersecret123
SQUID_PORT3128
SQUID_MAX_CHILDREN100

⁠What was done to add IPv4-Bind and IPv6-Bind Header Support

In src/FwdState.cc, at the very beggining of the getOutgoingAddress() function, I added this:

// IPv4 Freebind (via HTTP Header)
String ipv4;
ipv4 = request->header.getByName("IPv4-Bind");
if (ipv4 != "") {
    Acl::Address l;
    struct sockaddr_in sa;
    inet_pton(AF_INET, ipv4.rawBuf(), &(sa.sin_addr));
    /* don't do conn->local = sa because of operator overloading */
    l.addr = sa;
    conn->local = l.addr;
    ipv4.clean();
    conn->flags |= COMM_FREEBIND;
    return;
}
ipv4.clean();

// IPv6 Freebind (via HTTP Header)
String ipv6;
ipv6 = request->header.getByName("IPv6-Bind");
if (ipv6 != "") {
  Acl::Address l;
  struct sockaddr_in6 sa6;
  inet_pton(AF_INET6, ipv6.rawBuf(), &(sa6.sin6_addr));
  /* don't do conn->local = sa6 because of operator overloading */
  l.addr = sa6;
  conn->local = l.addr;
  ipv6.clean();
  conn->flags |= COMM_FREEBIND;
  return;
}
ipv6.clean();

I also added the header file #include <arpa/inet.h> at the top of src/FwdState.cc.

Then, in src/comm.cc, I added this block of code in comm_openex(), right after the creation of the socket (i.e. after new_socket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol);):

if ((flags & COMM_FREEBIND)) {
  int v = 1;
  if (setsockopt(new_socket, SOL_IP, IP_FREEBIND, (char *) &v, sizeof(v)) < 0) {
    debugs(50, DBG_IMPORTANT, "comm_openex: setsockopt() on FD " << new_socket << ": " << xstrerr(xerrno));
  }
}

Finally, in src/comm/Connection.h, I added this:

#define COMM_FREEBIND           0x40

These modifications allow you to choose your IPv6 source address by adding an HTTP header named IPV6-Bind to the request. For example: IPv4-Bind: 182.21.26.153 and IPv6-Bind: 20fc:5d9b:fec:3d7:753f:36a0:c1db:c162

You can test with wget:

http_proxy='http://localhost:3128' wget -4 --header="IPv4-Bind: 182.21.26.153" http://ipv4.icanhazip.com/

http_proxy='http://localhost:3128' wget -4 --header="IPv6-Bind: 20fc:5d9b:fec:3d7:753f:36a0:c1db:c162" http://ipv6.icanhazip.com/

Note: you should be able to prevent the IPv6-Bind header to be sent to the website by using the request_header_access directive in your squid.conf:

request_header_access IPv4-Bind deny all

request_header_access IPv6-Bind deny all

Tag summary

Content type

Image

Digest

sha256:47e7bc9e1…

Size

596.4 MB

Last updated

over 2 years ago

docker pull boro/squid-ipv6