内核代码

内核中对绑定非本地地址的相关判断代码,位于net/ipv4/af_inet.c中:

int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{chk_addr_ret = inet_addr_type(net, addr->sin_addr.s_addr);if (!net->ipv4_sysctl_ip_nonlocal_bind &&!(inet->freebind || inet->transparent) &&addr->sin_addr.s_addr != htonl(INADDR_ANY) &&chk_addr_ret != RTN_LOCAL &&chk_addr_ret != RTN_MULTICAST &&chk_addr_ret != RTN_BROADCAST)goto out;
}

由代码可见,需要满足以下三个条件中的一个,才能绑定成功:
1)此socket所属的net namespace设置了全局的ipv4_sysctl_ip_nonlocal_bind;
2)此socket设置了IP_FREEBIND选项;

3)此socket设置了IP_TRANSPARENT选项;

条件1可通过proc文件设置,条件2和3可通过setsockopt设置:

echo 1 > /proc/sys/net/ipv4/ip_nonlocal_bind

int    on = 1;
setsockopt(sock, SOL_IP, IP_FREEBIND, (char *)&on, sizeof(on))

setsockopt(sock, SOL_IP, IP_TRANSPARENT, (char *)&on, sizeof(on))

三者的区别

ip_nonlocal_bind和freebind功能相同,绑定地址的时候不要求本地接口已经获得该地址,但是在随后收发报文时还是需要该地址,只是可以提前进行地址绑定。二者区别仅在于作用范围不同。
IP_TRANSPARENT不仅是允许绑定非本地地址,更重要的是与netfilter一起实现透明代理功能。

透明代理

实现透明代理的前提是,1)本机能够接收目的地址非本机的数据包,2)和发送源地址非本地地址的数据包。

a) 接收

利用transparent选项,本机已经建立了socket监听客户端到服务器的连接,需要iptables在IP层把外出流量导入到本机。

iptables -t mangle -N DIVERT
iptables -t mangle -A PREROUTING -p tcp -m socket --transparent -j DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT

在PREROUTING hook点上,提前检查是否有本机socket在监听此连接,transparent选项忽略未设置此选项的socket。另外一个有用的选项--nowildcard,可用于将此连接关联到监听在INADDR_ANY的socket上。如果找到socket,设置mark等于1,路由到本机。

ip rule add fwmark 1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100

b)发送

主要涉及到查找出口路由函数,其中要对源地址做检查,非本机地址导致查找失败,代码文件net/ipv4/route.c:

struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
{if (fl4->saddr) {...if (!(fl4->flowi4_flags & FLOWI_FLAG_ANYSRC)) {/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */if (!__ip_dev_find(net, fl4->saddr, false))goto out;}}
}

针对此问题,IP_TRANSPARENT选项关闭了源地址检查include/net/inet_sock.h:

static inline __u8 inet_sk_flowi_flags(const struct sock *sk)
{__u8 flags = 0;if (inet_sk(sk)->transparent || inet_sk(sk)->hdrincl)flags |= FLOWI_FLAG_ANYSRC;return flags;
}

c)重定向

利用TPROXY目标,将目的端口为80的tcp连接重定向到本机监听在192.168.1.1:50080上的sock,不改变数据包的内容,即透明模式。

iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-ip 192.168.1.1 --on-port 50080

另外一种改变数据包目的地址的重定向为nat方式,如下:

iptables -t nat -N MY_HTTP                               #在nat表上新建名为MY_HTTP自定义链
iptables -t nat -p tcp -A MY_HTTP -j REDIRECT --to-ports 50080          #将进入MY_HTTP链的数据包端口重定向到50080上
iptables -t nat -N MY_NAT                               #在nat表上新建名为MY_NAT自定义链
iptables -t nat -A PREROUTING -p tcp -j MY_NAT                  #将MY_NAT加入到PREROUTING链后
iptables -t nat -A MY_NAT -p tcp -m multiport --dports 80 -j MY_HTTP    #在端口为80时执行MY_HTTP链 

内核版本

Linux-3.10.0

绑定非本机地址与透明代理相关推荐

  1. Squid服务器应用(Squid传统代理、Squid透明代理、ACL访问控制、Squid日志分析、Squid反向代理)

    文章目录 一.缓存代理概述 二.Squid代理服务器 三.代理的工作机制 四.Squid代理的类型 五.部署Squid代理服务器步骤 (一).安装Squid服务 (二).构建传统代理服务器 (三).构 ...

  2. 缓存加速----Squid传统代理透明代理

    文章目录 前言 一:Squid代理服务概述 1.1:概述 1.2:工作机制 1.3:Squid基本类型 二:环境 三:传统代理试验过程 四:透明代理实验过程 前言 一:Squid代理服务概述 1.1: ...

  3. Squid之传统代理和透明代理解析实验步骤

    目录 一:squid概述 1.1:squid代理的作用 二:squid的代理类型 三:squid传统代理的部署 3.1: 项目介绍 3.2:部署过程 3.3:修改配置文件,编写脚本优化服务启动项 3. ...

  4. 学会Squid之传统代理和透明代理一篇就够了!

    文章目录 squid的概念 一:squid概述 1.1:squid代理的作用 1.2:缓存代理概述 1.21:Web代理的工作机制 二:squid的代理类型 三:squid传统代理的部署 3.1: 项 ...

  5. 用nginx搭建http透明代理

    背景 代理我们经常听,在技术层面我们谈论的代理往往是非透明代理,那么既然有非透明代理那就存在有透明代理.我们先看看什么是透明代理,引用百度百科的一句话可以描述明白 透明代理的意思是客户端根本不需要知道 ...

  6. 记玄妙莫测的透明代理

    本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可. 本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权. 若无特殊说明,内核源码版本为4.1 ...

  7. Linux 实现透明代理(使用开源项目 tproxy-example)

    一.透明代理概述 根据百度百科的资料:透明代理的意思是客户端根本不需要知道有代理服务器的存在,它改变你的 request fields(报文),并会传送真实IP,多用于路由器的NAT转发中. 透明代理 ...

  8. 正向代理/反向代理/透明代理/透明模式

    1.正向代理(forward)是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转 ...

  9. Squid 正反向 / 透明代理

    squid是什么? Squid是一种用来缓冲Internet数据的软件.它是这样实现其功能的,接受来自人们需要下载的目标(object)的请求并适当地处理这些请求.也就是说,如果一个人想下载一web页 ...

最新文章

  1. python邮件发送哪个好_最全总结!聊聊 Python 发送邮件的几种方式
  2. 从全球最赚钱的20家公司,我们可以发现什么?
  3. ESP32模块的MicroPython的基本实验
  4. java 实现set_js 实现JAVASET
  5. 深度学习总结——CS231n课程深度学习(机器视觉相关)笔记整理
  6. 计算机本地连接怎么找不到了,网络,本地连接不见了解决办法
  7. 关于钩子(Hook)的使用
  8. java n%9==0_用C++实现求N!中末尾0的个数的方法详解
  9. Qt的特性——信号和槽
  10. Photon Release 4.8.0汉化(附图教程)
  11. python 间接处理webp图片文件
  12. 胡明浩 160809313 (我就会三个)
  13. python retry retrying使用
  14. 190109每日一句
  15. CHI 2016 2017 Paper Shared Gaze for Remote Collaboration
  16. discuz 3.1 修改浏览器顶部小图标
  17. Java Excel转图片
  18. 2021年全国计算机能力挑战赛C++决赛,题目分享
  19. USB-TO-TTL-(PL-2303)在Win10驱动无法识别问题解决方案
  20. 10年软件测试工作总结-有迷茫,有痛苦,有弯路,有捷径。

热门文章

  1. 选对群控系统究竟能不能吃香,未来能不能赚钱?
  2. 【Python_urllib学习笔记(四)】基于urllib和re,爬取豆瓣电影新片榜
  3. vite搭建vue2项目
  4. 沁恒 CH32V208(二): CH32V208的储存结构, 启动模式和时钟
  5. mysql 取每月最新一条数据
  6. C/C++中的移位运算你真的搞懂了吗?一文看懂移位运算
  7. Windows10永久关闭防火墙
  8. Java中的重写和重载区别
  9. 实战 Java 第5天:开发商品查询(模糊查询与条件查询)接口
  10. jni的使用---Java调用c语言