内核代码

内核中对绑定非本地地址的相关判断代码,位于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. 你能说出多线程中 sleep、yield、join 的用法及 sleep与wait区别吗?
  2. MySQL设置某一字段默认为0,但是插入数据化却显示为null
  3. a表两个字段都与b表一个字段关联_数据库表的主键实例分析
  4. 操作系统 第四章【存储器管理】【MOOC答案】
  5. python中的bs4怎么导入_在Python 3.5导入BS4
  6. JAVA自定义变量_Java 系统自定义变量-D
  7. React中的三种类型组件介绍
  8. 接口文档模板(Markdown)
  9. 内蒙古自治区通辽市谷歌高清卫星地图下载(百度网盘离线包下载)
  10. STM32L476入坑-2-STM32CubeMX安装
  11. latex引用图标出现问号
  12. 按键控制le灯c语言程序,C语言按键控制led灯和蜂鸣器
  13. 神经网络训练梯度算法详解
  14. 视频画中画制作,一键合并多个视频,简单又专业
  15. LeetCode:387.字符串中的第一个唯一字符
  16. 汽车日行灯做E-mark认证必须接受要工厂审核吗?
  17. 计算机常用软件实验报告,计算机常用应用软件的安装和使用实验报告.doc
  18. 【数据挖掘】2022年2023届秋招知能科技公司机器学习算法工程师 笔试题
  19. 基本数据结构(算法导论)与python
  20. linux卸载java_Linux安装卸载jdk1.8

热门文章

  1. window升级版本
  2. 6个超酷的 Python 技巧
  3. Ubuntu查看内存的命令
  4. 检索框/输入框测测试用例
  5. PaperBack:如何在一张A4纸上存储数据
  6. Game Engine Architecture by Jason Gregory:1.6 实时游戏引擎架构(3)
  7. python construct_python--二进制处理之construct库
  8. C# EF框架增加和查询
  9. c++中stoi函数
  10. salt加盐MD5加密代码