对透明代理,需要使用几个功能,首先IP_TRANSPARENT,内核2.6.28就已经支持, centos6.3及以上是肯定支持的。

它的作用是,如果某个ip在本机不存在,监听0.0.0.0一样可以收到数据,而发送的时候,可以bind任意一个不存在的ip(当然这个bind你使用netstat是看不见的),这样你就可以伪造任意客户端的报文。


代码也很简单

监听增加

setsockopt(fd, SOL_IP, IP_TRANSPARENT, &value, sizeof(value))

发送增加

setsockopt(fd, SOL_IP, IP_TRANSPARENT, &value, sizeof(value))
if(getsockname( s->client_sock , (struct sockaddr *)&server_addr, &addrlen ) )
{
  http_close_stream(s,"adns_transparent_client");
  return;
}

这里获取真正的服务器地址,写入server_addr

if (bind(s->server_sock, (struct sockaddr*)&s->client_addr, addrlen ) == -1)
{
    http_close_stream(s, "adns_transparent_bind");
return;
}

绑定客户端地址(虽然本机没有这个ip)

r = connect_nonb(sock, (struct sockaddr *)&server_addr);

连接真正的服务器地址。


当然如果想收到报文,还是需要做一些操作的,比如我们收到路由器转发的80端口的请求。

然后

iptables -t mangle -N DIVERT
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT
       
ip rule add fwmark 1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 81

注意你的服务器的监听端口改成非80,比如81端口,这样就能收到数据了。


可是我发现能收到数据,握手成功,但是服务器像真正的源站发送的握手又被交换机给转发回来了。

因为对于交换机来说,客户端发的握手和服务器发的握手在ip层面都一模一样,源地址和目的地址都相同。

这里需要对交换机做一个限制,对于服务器mac地址的包,走默认路由。


透明代理学习_第1张图片

如下是路由器配置

10.0.30.100是客户端

10.0.3.15是服务器

ip access-list extended ppc
 permit tcp host 10.0.30.100 any eq www
ip access-list extended ppc-15
 permit tcp any eq www host 10.0.30.100
route-map ppc-15 permit 10
 match ip address ppc-15
 set ip next-hop 10.0.3.15
!
route-map ppc permit 10
 match ip address ppc
 set ip next-hop 10.0.3.15
!
route-map ppc permit 20
interface Vlan300
 ip address 10.0.30.1 255.255.255.0
 ip policy route-map ppc
interface GigabitEthernet0/24
 no switchport
 ip address 10.0.0.2 255.255.255.252
 no ip proxy-arp
 ip policy route-map ppc-15