I am trying to transparently proxy traffic to specific hosts each listening on a different port. I would like to if at all possible run without having to specifically create iptables rules per host. the important parts of the code are below I listen to an ip:port pair using listento and then once I see an incoming connection attempt to connect to that host using the clients IP:port using connectas. what I am seeing is that I get the client connection then make the outbound connection but that does not have its source changed and its intercepted by the tproxyed listen so I get an loop of incoming connections I have 2 interfaces on my server and plan to run it as a router I bind to 2 the client facing IP for listening and the internet facing IP for connecting out I am using 2.6.20-wolk5.0 from here http://ftp.ticklers.org/ftp.kernel.org/linux/kernel/people/mcp/2.6-WOLK/?C=M... the tproxy version is 2.0.6 any help would be greatly appreciated. Kevin int listento(struct sockaddr_in *laddr, struct sockaddr_in *raddr){ int sock; int i; struct in_tproxy itp; struct sockaddr_in sin; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1){ perror("socket"); return -1; } i = 1; if (setsockopt(sock, SOL_IP, SO_REUSEADDR, &i, sizeof(i)) == -1){ perror("SO_REUSEADDR"); return -1; } /* check tproxy version */ itp.op = TPROXY_VERSION; itp.v.version = 0x02000000; if (setsockopt(sock, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) { perror("setsockopt(SOL_IP, IP_TPROXY, TPROXY_VERSION)"); return -1; } /* bind to local address */ if (bind(sock, (struct sockaddr *) laddr, sizeof(sin)) == -1) { perror("listento: bind"); return -1; } /* assign foreign address */ itp.op = TPROXY_ASSIGN; itp.v.addr.faddr=raddr->sin_addr; itp.v.addr.fport = raddr->sin_port; if (setsockopt(sock, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) { perror("setsockopt(SOL_IP, IP_TPROXY, TPROXY_ASSIGN)"); return -1; } /* set listen flag */ itp.op = TPROXY_FLAGS; itp.v.flags = ITP_LISTEN; if (setsockopt(sock, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) { perror("setsockopt(SOL_IP, IP_TPROXY, TPROXY_FLAGS)"); return -1; } /* listen */ if (listen(sock, BACKLOG) == -1) { perror("listen"); return -1; } return sock; } int connectas( struct sockaddr_in *laddr, struct sockaddr_in *faddr, struct sockaddr_in *daddr) { int sock; struct in_tproxy itp; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1){ perror("socket"); return(-1); } /* bind to local address */ if (bind(sock, (struct sockaddr*) laddr, sizeof(*laddr)) == -1){ perror("connectas: bind"); return -1; } /* assign foreign address */ itp.op = TPROXY_ASSIGN; itp.v.addr.faddr=faddr->sin_addr; itp.v.addr.fport=faddr->sin_port; if (setsockopt(sock, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1){ close(sock); printf("errno=%i\n",errno); perror("setsockopt(SOL_IP, IP_TPROXY, TPROXY_ASSIGN)"); return -1; } /* specify peer endpoint: the same address we will pass to connect() */ itp.op = TPROXY_FLAGS; itp.v.flags = ITP_CONNECT | ITP_ONCE; itp.v.addr.faddr=daddr->sin_addr; itp.v.addr.fport=daddr->sin_port; if (setsockopt(sock, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1){ close(sock); printf("errno=%i\n",errno); perror("setsockopt(SOL_IP, IP_TPROXY, TPROXY_FLAGS)"); return -1; } /* connect */ if (connect(sock, (struct sockaddr*) daddr, sizeof(*daddr)) == -1){ close(sock); perror("connect"); return -1; } return sock; }