云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

免备案CDN_华为云服务网址_排行榜

小七 141 0

mmproxy-在L7代理中保留客户端IP地址的创造性Linux路由

在之前的博客文章中,我们讨论了如何使用TPROXY iptables模块来增强Cloudflare频谱。有了TPROXY,我们解决了服务器端的一个主要技术问题,我们认为可以在产品的客户端找到它的另一个用途。这是地址簿。来源:维基百科在构建应用程序级代理时,首先要考虑的始终是保留真实的客户端源IP地址。有些协议使它变得容易,例如HTTP有一个定义的X-Forwarded-For头[1],但是对于一般的TCP隧道没有类似的东西。其他人也面临着这个问题,他们想出了三个普遍的解决办法:(1) 忽略客户端IP对于某些应用程序,可以忽略真实的客户端IP地址。例如,有时客户机无论如何都需要用用户名和密码来标识自己,所以源IP并不重要。一般来说,这不是一个好的做法,因为。。。(2) 非标准TCP头Akamai开发了第二种方法:客户端IP保存在SYN数据包的TCP头的自定义选项中。该方法的早期实现不符合任何标准,例如使用选项字段28,但最近RFC7974被批准用于此选项。我们不支持此方法的原因有很多:TCP标头中的空间非常有限。它不足以存储完整的128位客户端IPv6地址,尤其是Cloudflare 15%以上的流量是IPv6。但软件不支持RFC74。在实际应用程序中添加对RFC7947的支持非常困难。一个选项是修补操作系统并覆盖getpeername(2)和accept4(2)syscalls,另一个选项是使用getsockopt(TCP_SAVED_SYN)从用户空间应用程序中的SYN数据包中提取客户机IP。这两种方法都不简单。(3) 使用代理协议最后,还有最后一种方法。HAProxy的开发者,面对这个问题开发了代理协议。该协议的前提是在原始数据流之前预先添加客户端元数据。例如,可以在代理数据之前将此字符串发送到源服务器:代理服务器TCP4 192.0.2.123 104.16.112.25 19235 80\r\n如您所见,代理协议的实现非常简单,对于大多数用例来说已经足够了。但是,它需要应用程序支持。Cloudflare Spectrum支持代理协议(v1),我们强烈建议使用它来代替其他保留客户端源IP地址的方法。嗯救援代理但有时向应用程序添加代理协议支持并不是一种选择。当应用程序不是开源的,或者很难编辑时,可能会出现这种情况。一个很好的例子是"sshd"-它不支持代理协议,添加支持将远远不是小事。对于此类应用程序,可能根本不可能使用任何应用程序级别的负载平衡器。这很不幸。幸运的是我们找到了解决办法。请允许我介绍mmproxy,一个代理协议网关。mmproxy侦听来自应用程序级负载平衡器的远程连接,如频谱。然后它读取代理协议头,打开到目标应用程序的本地主机连接,并适当地代理数据进出。如果没有一个特性(从mmproxy到目标应用程序的本地主机连接是用真实的客户端源IP发送的),那么这样的代理就不会太有用。没错,mmproxy欺骗了客户机的IP地址。从应用程序的角度来看,这种通过频谱和mmproxy进行的欺骗连接与直接连接到应用程序的真实连接无法区分。这种技术需要一些Linux路由技巧。mmproxy守护进程将引导您了解必要的详细信息,但其中有一些重要内容:mmproxy仅适用于Linux。因为它通过环回接口转发流量,所以它必须与目标应用程序在同一台计算机上运行。它需要内核2.6.28或更高版本。它指导用户添加4个iptables防火墙规则和4个iproute2路由规则,包括IPv4和IPv6。对于IPv4,mmproxy要求设置路由\u localnet sysctl。对于IPv6,它需要一个有效的IPv6配置。正在工作的ping6cloudflare.com网站是先决条件。mmproxy需要root或CAP_NET_RAW权限才能设置IP帴TRANSPARENT socket选项。一旦启动,它就用seccomp bpf来监禁自己,以增加一点安全性。如何运行mmproxy要运行mmproxy,请先下载源代码并编译它:git克隆https://github.com/cloudflare/mmproxy.git--递归的cd内存代理制作请在GitHub上报告任何问题。然后设置所需的配置:sudo iptables-t mangle-I预路由-m mark--mark 123-j CONNMARK--save marksudo iptables-t mangle-I输出-m connmark--mark 123-j connmark--restore marksudo ip rule add fwmark 123查找100sudo ip route add local 0.0.0.0/0 dev lo表100sudo ip6tables-t mangle-I预路由-m mark--mark 123-j CONNMARK--save marksudo ip6tables-t mangle-I输出-m connmark--mark 123-j connmark--restore marksudo ip-6规则添加fwmark 123查找100sudo ip-6路由添加本地::/0 dev lo table 100您还需要在默认出站接口上设置route_localnet,例如eth0:echo 1 | sudo tee/proc/sys/net/ipv4/conf/eth0/route_localnet最后,验证您的IPv6连接:$平6cloudflare.com网站发出砰的声响cloudflare.com网站(2400:cb00:2048:1::c629:d6a2)56个数据字节从2400:cb00:2048:1::c629:d6a2:icmp_seq=1 ttl=61时间=0.650毫秒的64个字节现在,您可以运行mmproxy了。例如,转发localhost SSH如下所示:$sudo./mmproxy——允许的子网/cloudflare ip-范围.txt\-l 0.0.0.0:2222\-4 127.0.0.1:22-6'[::1]:22'根@ubuntu:~#./mmproxy-cloudflare ip-范围.txt-l 0.0.0.0:2222-4 127.0.0.1:22-6[::1]:22[]记住正确设置反向路由规则:iptables-t mangle-I PREROUTING-m mark--mark 123-m comment--comment mmproxy-j CONNMARK--save mark#[+]已验证iptables-t mangle-I输出-m connmark--mark 123-m comment--comment mmproxy-j connmark--restore mark#[+]已验证ip6tables-t mangle-I PREROUTING-m mark--mark 123-m comment--comment mmproxy-j CONNMARK--save mark#[+]已验证ip6tables-t mangle-I输出-m connmark--mark 123-m comment--comment mmproxy-j connmark--restore mark#[+]已验证ip规则添加fwmark 123查找100#[+]已验证ip路由添加本地0.0.0.0/0 dev-lo表100已验证ip-6规则添加fwmark 123查找100#[+]已验证ip-6路由添加本地::/0 dev lo table 100已验证[+]好的。路由到127.0.0.1指向本地计算机。[+]好的。目标服务器127.0.0.1:22已启动,可以使用常规连接进行访问。[+]好的。目标服务器127.0.0.1:22已启动,并且可以使用欺骗连接进行访问。[+]好的。路由到::1指向本地计算机。[+]好的。目标服务器[::1]:22已启动,可以使用常规连接进行访问。[+]好的。目标服务器[::1]:22已启动,可以使用欺骗连接进行访问。[+]收听0.0.0.0:2222启动时,mmproxy会执行许多自检。由于我们准备了必要的路由和防火墙规则,它的自检通过时带有"已验证"标记。确认这些通行证很重要。我们马上就要出发了!最后一步是创建一个频谱应用程序,它向mmproxy端口2222发送代理协议流量。下面是一个配置示例[2]:通过频谱,我们在域上转发TCP/22"ssh.example.org",我们的出发地是192.0.2.1,2222号港。我们已经启用了代理协议切换。mmproxy正在运行现在我们可以看看它是否有效。我的测试VPS的IP地址是79.1.2.3。让我们看看整个设置是否正常:副总裁$ncssh.example.org22SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.1万岁,这个成功了!"的"ssh.example.org"在22号港确实是超光谱隧道。让我们看看mmproxy日志:[+]172.68.136.1:32654已连接,代理协议源79.1.2.3:0,本地目的地127.0.0.1:22日志确认了所发生的情况—Cloudflare IP 172.68.136.1已连接,通过代理协议公布了客户端IP 79.1.2.3,并建立了到127.0.0.1:22的欺骗连接。ssh守护程序日志显示:$tail/var/log/验证日志Apr 15 14:39:09 ubuntu sshd[7703]:未收到标识79.1.2.3中的字符串万岁!一切正常!sshd记录了真实的客户端IP地址,在mmproxy的帮助下,我们从未看到它实际上是通过Cloudflare频谱传输的流量。引擎盖下面在幕后,mmproxy依赖于两次黑客攻击。第一次黑客攻击是在传出连接上设置源IP。我们使用众所周知的"先绑定后连接"技术来实现这一点。通常,只能设置一个由本地计算机实际处理的有效源IP。我们可以通过使用IP廑TRANSPARENT socket选项来覆盖此选项。有了它,我们可以在建立由内核处理的合法连接之前选择任意源IP地址。例如,我们可以在8.8.8.8和127.0.0.1之间有一个localhost套接字,即使8.8.8.8可能没有显式地分配给我们的服务器。值得一提的是,IP帴u TRANSPARENT不是为这个用例创建的。这个socket选项是专门添加来支持TPROXY模块的。第二次黑客攻击是关于路由。通常,来自应用程序的响应包通过默认网关路由到Internet。我们必须防止这种情况发生,而是将这些包定向到环回接口。为此,我们依赖CONNMARK和fwmark选择的附加路由表。mmproxy在它发送的数据包上设置一个标记值123(默认情况下),该值保留在CONNMARK层,并为返回的数据包还原。然后,我们将MARK==123的数据包路由到一个特定的路由表(默认为数字100),该表强制将所有内容路由回环回接口。我们完全滥用AnyIP技巧,并将0.0.0.0/0分配给"local",这意味着整个互联网将被视为属于我们的机器。摘要mmproxy并不是唯一一个使用这种IP欺骗技术来保存真实客户端IP地址的工具