Goo*_*bot 7 network-manager networking google-chrome proxy 20.04
如何强制 Chrome 使用特定网络接口(例如 tun1)?
某些程序(例如)curl具有选择特定网络接口的选项。
在 Windows 中,ForceBindIP允许您强制应用程序使用特定的网络接口/IP 地址。
我想知道 Ubuntu/Linux 是否有解决方案可以做到这一点。
或者,因为我们可以在 Chrome 中设置代理;我们可以将本地 IP 重定向到网络接口,反之亦然吗?
这是网络命名空间的完美用例,网络命名空间自 2016 年或更早以来一直是 Linux 的一部分。这是一个带有注释的示例,可帮助您入门:
# enable forwarding
sysctl -w net.ipv4.ip_forward=1
# create the network namespace
ip netns add chrome
# create the virtual nic and it's peer
ip link add chrome type veth peer name chrome-peer
# assign the peer to the network namespace
ip link set chrome-peer netns chrome
# assign an ip address
ip addr add 192.0.2.1/24 dev chrome
# bring up interface
ip link set chrome up
# similar network setup for network namespace
ip netns exec chrome ip link set lo up
ip netns exec chrome ip addr add 192.0.2.2/24 dev chrome-peer
ip netns exec chrome ip route add default via 192.0.2.1
ip netns exec chrome ip link set chrome-peer up
# allow forwarding and add enable NAT
iptables -I FORWARD -s 192.0.2.0/24 -j ACCEPT
iptables -t nat -I POSTROUTING -s 192.0.2.0/24 -o tun1 -j MASQUERADE
# pop a shell in the namespace
ip netns exec chrome bash
# check that you're in the namespace
ip netns identify
# run the browser as your local user
runuser -u Barry google-chrome
Run Code Online (Sandbox Code Playgroud)
Linux 可以SO_BINDTODEVICE选择将套接字绑定到特定的网络接口。
Chromium 使用 libc 函数来调用系统调用,包括connect()用于执行网络请求的系统调用。我们可以在执行系统调用之前修补connect()要调用的函数。这可以通过环境变量预加载共享库来完成。setsockopt(SO_BINDTODEVICE)connect()LD_PRELOAD
#define _GNU_SOURCE
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#define IFACE_NAME "tun0"
#define IPV6_TO_BIND "fddd:bbbb::2"
static void set_bind_addr6(int fd)
{
struct sockaddr_in6 addr;
memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
inet_pton(AF_INET6, IPV6_TO_BIND, &addr.sin6_addr);
bind(fd, (struct sockaddr *)&addr, sizeof(addr));
}
int connect(int fd, const struct sockaddr *daddr, socklen_t addrlen)
{
int family = daddr->sa_family;
if (family == AF_INET || family == AF_INET6) {
if (family == AF_INET6)
set_bind_addr6(fd);
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, IFACE_NAME, sizeof(IFACE_NAME));
}
return syscall(__NR_connect, fd, daddr, addrlen);
}
Run Code Online (Sandbox Code Playgroud)
IFACE_NAME根据您的机器设置进行调整IPV6_TO_BIND。如果您不想使用 IPv6,可以省略 IPv6 绑定代码。
如果您希望使用 IPv6,则需要进行 IPv6 绑定,因为调用者设置了错误的绑定地址。它还可以帮助您选择要用于传出连接的 IPv6 地址。
IPv4 不需要绑定。
ammarfaizi2@integral2:/tmp$ gcc -fpic -fPIC -Wall -Wextra -shared -O3 connect.c -o connect.so
ammarfaizi2@integral2:/tmp$ export LD_PRELOAD="/tmp/connect.so"
ammarfaizi2@integral2:/tmp$ /opt/google/chrome/chrome
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9360 次 |
| 最近记录: |