首页 > 系统相关 >Linux让远程服务器代理IPv6流量

Linux让远程服务器代理IPv6流量

时间:2024-07-28 11:28:45浏览次数:12  
标签:sudo tap ip Linux IPv6 服务器 netns spacename

使用场景

本地机器只能访问IPv4网络。远程服务器能访问IPv4网络,也能访问IPv6网络。这篇博客介绍如何让远程服务器代理本地机器的IPv6流量,从而让本地机器也能访问IPv6网络。

主要思路

在远程服务器上创建一个netns,搭IPv6 NAT,这样netns里面就能通过IPv6 NAT访问公网。

然后在netns和本地机器分别建立一个tap,用SSH把两个tap连接起来,本地机器就能通过tap连接到netns。由于IPv6的路由是自动配置的,所以本地机器的tap会自动获得一个IPv6并且配置好路由,然后本地机器的IPv6流量就自动通过tap路由到netns里,然后通过netns的IPv6 NAT访问公网了。

创建netns

# spacename不能带数字,否则之后${spacename}veth1会创建失败。
spacename=纯字母的名字
sudo ip netns add $spacename
sudo ip netns exec $spacename ip link set lo up

可以开一个netns里的bash在netns里执行命令,方便调试:

sudo ip netns exec $spacename bash

连接宿主机和netns

创建一根虚拟以太网线,一头是${spacename}veth1,另一头是${spacename}veth2

sudo ip link add ${spacename}veth1 type veth peer name ${spacename}veth2

将一头放入netns:

sudo ip link set ${spacename}veth2 netns $spacename

Router Advertisement Daemon

我们在宿主机上配置好Router Advertisement Daemon之后,宿主机上的IPv6子网就可以通过router advertisement自动配置路由:https://askubuntu.com/a/676543

安装radvd

# Debian 12
sudo apt install radvd

配置文件路径:/etc/radvd.conf。官方文档:https://linux.die.net/man/5/radvd.conf

我们这里这样配置就可以了:

sudo bash -c "echo \"interface ${spacename}veth1 {
	AdvSendAdvert on;
	prefix fd00::/64 {
		AdvOnLink on;
		AdvAutonomous on;
	};
};\" > /etc/radvd.conf"

然后启动daemon:

sudo systemctl start radvd

给veth配置静态IP

fd开头的地址是unique local address。我们把veth1的IPv6地址设置为fd00::1

sudo ip link set dev ${spacename}veth1 up
sudo ip -6 addr add fd00::1/64 dev ${spacename}veth1

veth2打开:

sudo ip netns exec $spacename ip link set dev ${spacename}veth2 up

等几秒钟,radvd会自动给veth2基于它的MAC地址配置IPv6地址并且配置路由。然后我们就可以在netns里ping通fd00::1了。

配置NAT

通过ip a查看宿主机用来连接到公网的接口,把名字放入outdev变量中。我的机器是end0

outdev=end0

打开宿主机的IPv6转发功能:

sudo sysctl -w net.ipv6.conf.$outdev.accept_ra=2
sudo sysctl -w net.ipv6.conf.all.forwarding=1

然后我们配置NAT,将从outdev转发出去的流量的IP都换成outdev上的IP:

sudo ip6tables -t nat -A POSTROUTING -o $outdev -j MASQUERADE

让防火墙不要拦截从veth1outdev的流量:

sudo ip6tables -t filter -A FORWARD -o $outdev -i ${spacename}veth1 -j ACCEPT

先确保/etc/resolv.conf里有IPv6的nameserver,没有的话在这里挑一个写进去:纯ipv6的linux服务器网络配置方案

然后在netns里就可以正常访问IPv6公网了:

sudo ip netns exec $spacename curl -6 https://ip.gs

如果打印出来的地址是outdev的IPv6地址,说明IPv6 NAT配置成功了。

在netns里建立桥接

我们需要在netns里建立一个tap。netns里的tap需要桥接到veth上。为此我们需要先建立bridge,然后将veth2和tap分别桥接上去。

新建bridge,命名为br0

sudo ip netns exec $spacename ip link add name br0 type bridge

veth2桥接到br0上:

sudo ip netns exec $spacename ip link set ${spacename}veth2 master br0

启动br0

sudo ip netns exec $spacename ip link set br0 up

br0配置静态IP fd00::2

sudo ip netns exec $spacename ip -6 addr add fd00::2/64 dev br0

以后veth2只用作br0veth1之间的通信,所以我们删除veth2自动配置的IPv6地址:

sudo ip netns exec $spacename ip address flush dev ${spacename}veth2

并且删除IPv6路由表中veth2相关的项:

sudo ip netns exec $spacename ip -6 route flush dev seekstarveth2

检查一下现在netns里能不能访问IPv6公网:

sudo ip netns exec $spacename curl -6 https://ip.gs

连接本地机器和netns

首先,即使tap是通过桥接的方式连接到veth2,也必须要在netns里把IPv6的forwarding开起来:

sudo ip netns exec $spacename sysctl -w net.ipv6.conf.br0.accept_ra=2
sudo ip netns exec $spacename sysctl -w net.ipv6.conf.all.forwarding=1

不然最后本地机器转发到netns里的tap的流量似乎不会被转发给veth1。

然后在netns中创建一个tap,这里命名为tap0(也可修改成别的):

sudo ip netns exec $spacename ip tuntap add dev tap0 mode tap

将tap连接到br0上:

sudo ip netns exec $spacename ip link set tap0 master br0

确认一下是不是连上去了:

sudo ip netns exec $spacename brctl show br0
bridge name     bridge id               STP enabled     interfaces
br0             8000.162344e2cdc6       no              seekstarveth2
                                                        tap0

然后尽快在netns中将这个tap跟netns的localhost:6301连接起来,不然tap会从br0断开:

# 保持打开
# iff-up: immediately activate the interface
# tun-name=tap0: tap0可以换成别的名字
sudo ip netns exec $spacename socat TUN,tun-type=tap,tun-name=tap0,iff-up TCP6-LISTEN:6301,fork,reuseaddr

上面的命令会占用一个终端。接下来我们开一个新终端继续操作。

然后在宿主机上监听6301端口,并将流量转发给netns的6301端口:

# 保持打开
socat tcp-listen:6301,reuseaddr,fork tcp:[fd00::2]:6301

然后我们在本地机器上把远程服务器的6301端口映射到本地机器的6301端口:

# 保持打开
ssh -NL 6301:localhost:6301 远程服务器

最后,在本地机器创建一个tap,并将它跟6301端口连接起来:

# https://gist.github.com/cfra/752d6e761225fd5bf783b44abe30f707
# 保持打开
sudo socat TUN,tun-type=tap,iff-up TCP:localhost:6301

然后等几秒钟,本地机器的tap会收到route advertisement然后自动配置IP和路由。接着我们就可以在本地机器访问IPv6了:

curl -6 https://ip.gs

可以看到输出的是远程服务器outdev的IPv6地址。

相关:https://superuser.com/questions/879498/make-socat-listen-on-both-ipv4-and-ipv6-stacks

撤销所有更改

sudo ip link delete ${spacename}veth1
sudo ip netns exec $spacename ip link delete tap0
sudo ip netns exec $spacename ip link delete br0
sudo ip netns delete $spacename

注意事项

一个tap似乎只能用于一台机器,共用tap的话连接会非常不稳定。因此如果有多台机器都需要让远程服务器代理IPv6流量,只能在远程服务器创建多个tap,然后让这些机器分别连接到一个tap上。

标签:sudo,tap,ip,Linux,IPv6,服务器,netns,spacename
From: https://www.cnblogs.com/searchstar/p/18328007

相关文章

  • Linux工作原理11 Shell脚本
    11shell脚本如果你能在shell中输入命令,你就能编写shell脚本。shell脚本(也称为Bourneshell脚本)是写在文件中的一系列命令;shell会从文件中读取这些命令,就像在终端中输入命令一样。11.1shell脚本基础Bourneshell脚本一般以下面一行开始,表示/bin/sh程序应执行脚本文......
  • Clickhouse服务器CPU 99.99%的处理过程
    进入服务器,查询正在执行任务的语句SELECTquery_id,user,queryFROMsystem.processes;--通过上面指令获取到进程相关信息后,可以用query_id条件kill进程KILLQUERYWHEREquery_id='67cadc87-34b2-4b81-8f8c-087485c922af'--杀死default用户下的所有进程KILLQUERY......
  • 文件服务器caddy
    官网deb问题sudoaptinstallcaddy默认会创建caddy用户,卸载不会删除使用caddy用户启动服务,访问目录/data/xxx报错403forbidden额外启动caddy-api.service二进制文件/usr/loca/bin/caddyhttp://mirrors.ustc.edu.cn/debian/pool/main/c/caddy/https://github.com/caddys......
  • 当我们创建一个在 https 服务器上获取和发送数据的 python 应用程序时,我们应该如何处
    python脚本使用Urllib3,我的服务器是在Node.js上编写的脚本。我担心(并且不清楚)证书:我是否需要将我的python应用程序上的证书另存为变量?例如我这样做了,http=urllib3.PoolManager(cert_reqs="CERT_REQUIRED",ca_certs='client-cert.pem')并且我不知道......
  • Linux文件系统相关知识:存储设备、文件系统、分区、挂载、块设备、部分相关简单指令。
    1.存储设备是什么?怎么理解分区和格式化?存储设备:指物理硬件设备,‌用于存储数据。‌这包括硬盘驱动器(‌HDD)‌、‌固态驱动器(‌SSD)‌、‌USB闪存驱动器、‌RAID阵列等。‌这些设备提供了实际的存储空间,‌可以用来存储操作系统、‌应用程序、‌文件、‌数据等。‌存储设备的容量......
  • linux centos7环境下通过rpm部署MySQL
    一、环境准备环境:centos7,确保虚拟机内存足够,不然无法上传数据包和解压mysql包:mysql-8.0.25-1.el7.x86_64.rpm-bundle.tar这个包去MySQL官网可以下载,此链接可以直达:https://downloads.mysql.com/archives/community/二、打开远程连接,连上自己的虚拟机1.连上自己的虚拟机后......
  • 如何解决用socket实现通讯,即使服务器与客户端链接得到客户端信息却仍报错的问题?
     以上分别是服务器和客户端的代码展示,方便后续大家对运行结果的了解 可以发现当服务器与客户端连接时,客户端的信息已经被服务器接收到了,但仍然报错。此时 可以调用shutdownOutput(),关闭输出流,使服务器端口得到-1值,从而关闭流。目的是告知服务器信息已经输出完毕。再次......
  • Linux 最常用命令!
    Linux最常用命令![点击下载文档]Linux是目前应用最广泛的服务器操作系统,基于Unix,开源免费,由于系统的稳定性和安全性,市场占有率很高,几乎成为程序代码运行的最佳系统环境。linux不仅可以长时间的运行我们编写的程序代码,还可以安装在各种计算机硬件设备中,如手机、路由器等,And......
  • Linux的fork和vfork
    fork用于创建子进程。在调用时,返回两次:子进程的返回值是0,父进程的返回值的新建子进程的ID。子进程是父进程的副本。子进程和父进程继续执行fork之后的指令。子进程获得父进程的数据空间、堆、栈的副本共享的是:文件描述符、mmap建立的映射区子进程和父进程共享的......
  • [AI]在家中使用日常设备运行您自己的 AI 集群.适用于移动、桌面和服务器的分布式 LLM
    创作不易只因热爱!!热衷分享,一起成长!“你的鼓励就是我努力付出的动力”AI发展不可谓不快,从ollama个人电脑CPU运行到现在,日常设备AI集群.下面对比一下,两款开源AI大模型的分布式推理应用,exo和cake.1.AI集群推理应用exo和cake的简单对比......