Total Pageviews

Thursday, 11 February 2021

基于ipv6的vpn程序:yggdrasil-go


An experiment in scalable routing as an encrypted IPv6 overlay network。

https://yggdrasil-network.github.io/

Yggdrasil

CircleCI

Introduction

Yggdrasil is an early-stage implementation of a fully end-to-end encrypted IPv6 network. It is lightweight, self-arranging, supported on multiple platforms and allows pretty much any IPv6-capable application to communicate securely with other Yggdrasil nodes. Yggdrasil does not require you to have IPv6 Internet connectivity - it also works over IPv4.

Although Yggdrasil shares many similarities with cjdns, it employs a different routing algorithm based on a globally-agreed spanning tree and greedy routing in a metric space, and aims to implement some novel local backpressure routing techniques. In theory, Yggdrasil should scale well on networks with internet-like topologies.

Supported Platforms

We actively support the following platforms, and packages are available for some of the below:

  • Linux
    • .deb and .rpm packages are built by CI for Debian and Red Hat-based distributions
    • Arch, Nix, Void packages also available within their respective repositories
  • macOS
    • .pkg packages are built by CI
  • Ubiquiti EdgeOS
    • .deb Vyatta packages are built by CI
  • Windows
  • FreeBSD
  • OpenBSD
  • OpenWrt

Please see our Platforms pages for more specific information about each of our supported platforms, including installation steps and caveats.

You may also find other platform-specific wrappers, scripts or tools in the contrib folder.

Building

If you want to build from source, as opposed to installing one of the pre-built packages:

  1. Install Go (requires Go 1.13 or later)
  2. Clone this repository
  3. Run ./build

Note that you can cross-compile for other platforms and architectures by specifying the GOOS and GOARCH environment variables, e.g. GOOS=windows ./build or GOOS=linux GOARCH=mipsle ./build.

Running

Generate configuration

To generate static configuration, either generate a HJSON file (human-friendly, complete with comments):

./yggdrasil -genconf > /path/to/yggdrasil.conf

... or generate a plain JSON file (which is easy to manipulate programmatically):

./yggdrasil -genconf -json > /path/to/yggdrasil.conf

You will need to edit the yggdrasil.conf file to add or remove peers, modify other configuration such as listen addresses or multicast addresses, etc.

Run Yggdrasil

To run with the generated static configuration:

./yggdrasil -useconffile /path/to/yggdrasil.conf

To run in auto-configuration mode (which will use sane defaults and random keys at each startup, instead of using a static configuration file):

./yggdrasil -autoconf

You will likely need to run Yggdrasil as a privileged user or under sudo, unless you have permission to create TUN/TAP adapters. On Linux this can be done by giving the Yggdrasil binary the CAP_NET_ADMIN capability.

Documentation

Documentation is available on our GitHub Pages site, or in the base submodule repository within doc/yggdrasil-network.github.io.

Community

Feel free to join us on our Matrix channel at #yggdrasil:matrix.org or in the #yggdrasil IRC channel on Freenode.


from https://github.com/yggdrasil-network/yggdrasil-go

https://yggdrasil-network.github.io/configuration.html

-----

我的补充说明:

在linux vps上,先安装go环境。然后,

cd $GOPATH

go get -u -v github.com/yggdrasil-network/yggdrasil-go/cmd/yggdrasil/

显示:

...

golang.zx2c4.com/wireguard/rwcancel

golang.zx2c4.com/wireguard/tun

github.com/yggdrasil-network/yggdrasil-go/src/tuntap

github.com/yggdrasil-network/yggdrasil-go/cmd/yggdrasil


运行:

which yggdrasil

显示:

/root/go/gopath/bin/yggdrasil

说明yggdrasil安装成功。


[root@racknerd-7b97d8 gopath]# cd ~

[root@racknerd-7b97d8 ~]# yggdrasil -genconf > /etc/yggdrasil.conf

[root@racknerd-7b97d8 ~]# yggdrasil -useconffile /etc/yggdrasil.conf

2021/02/11 05:19:37 Starting up...

2021/02/11 05:19:37 Starting switch

2021/02/11 05:19:37 Starting router

2021/02/11 05:19:37 Startup complete

2021/02/11 05:19:37 Starting multicast module

2021/02/11 05:19:37 UNIX admin socket listening on /var/run/yggdrasil.sock

2021/02/11 05:19:37 Interface name: tun1

2021/02/11 05:19:37 Interface IPv6: 201:878b:1c83:3c3f:83fd:89db:ff50:12e9/7

2021/02/11 05:19:37 Interface MTU: 65535

2021/02/11 05:19:37 Your IPv6 address is 201:878b:1c83:3c3f:83fd:89db:ff50:12e9

2021/02/11 05:19:37 Your IPv6 subnet is 301:878b:1c83:3c3f::/64

2021/02/11 05:19:37 Listening for TCP on: [fe80::2b2d:b994:e6dd:482d%eth0]:40605


这是基于ipv6的vpn,不太熟悉怎么使用。

------------------


使用Yggdrasil进行远程访问

关于 Yggdrasil网络

Yggdrasil 是一种新的实验性紧凑路由方案,设计用于网状或类似互联网的网络。它主要是一种最短路径方案,网络将尝试找到最直接的路径到目的地。

与今天许多网络上使用的结构化和通常层次化的路由方案相比,Yggdrasil是强烈的分散式和自动排列的。网络上的每个节点都由一个加密公钥标识,在实现中,IPv6地址是从该密钥生成的。网络拓扑是自适应的,旨在利用可用的任何链接,以提供所有网络参与者之间的完全路由能力。这是因为所有Yggdrasil节点都是路由器,共享路由知识并代表其他网络参与者转发流量。

下表说明了传统网络(如互联网)和Yggdrasil网络之间的差异:

传统网络 Yggdrasil

网络上所有流量的端到端加密 否 是

使用DHT共享分散式路由信息 否 是

具有密码绑定的寻址,没有中央机构 否 是

节点知道其与其他节点的相对位置 否 是

移动寻址随设备移动而保持不变 否 是

拓扑图在不同媒介上优雅扩展,如网状 否 是

今天存在哪些问题?

我们今天所知的互联网并不符合明确定义的拓扑结构。这在很大程度上是随着互联网的发展而发生的,越来越多的网络通过服务提供商之间的互联安排“拼凑”在一起。缺乏明确定义的拓扑给我们带来了一些不可避免的问题:

  • 存储“互联网地图”的路由表非常庞大且低效,因为每个提供商都必须传递有关所有其他提供商的IP前缀的信息

  • 计算机实际上没有办法知道它在互联网上相对于其他任何东西的位置 - 大多数计算机只知道一个“默认网关”

  • 很难在不实际发送数据包的情况下检查它从源到目的地的路径

这些问题已经在一定程度上得到缓解(但并没有真正解决) - 与其在家中的计算机上保存全局路由表的副本相比,您的服务提供商代表您这样做。您的计算机和网络设备只需配置为“将流量发送到上游”,并让您的提供商决定流量的去向。这使您完全受制于您的ISP,他们可以将您的流量重定向到任何地方,并对其进行检查、操作或拦截。

ISP网络通常具有结构化的设计,并且通常是层次化的,因此许多现有的路由协议都是根据此设计的。一些优化,如前缀聚合,用于尝试减少提供商必须发送到世界各地的路由条目数量。这些协议通常不适用于拓扑不明确或经常变化的网络 - 例如无线网状网络,因此过去很难让社区根据需要构建自己的无线网状基础设施。

Yggdrasil有什么不同之处?

Yggdrasil在共享路由知识方面采取了非常不同的方法。与通过集中分配自治系统的路径来分发地址范围不同,Yggdrasil以分布式方式建立一个单一的全局网络拓扑。

使用生成树提供同步,并允许节点分配一组树坐标,这些坐标用于交换和建立引导和路径设置消息。然后,节点通过网络设置到其键空间邻居的路径,有效地将网络排列成一个由公钥排序的虚拟线。然后,中间节点使用这些路径填充其路由表,使节点能够将数据包转发到更接近其目标公钥的位置。

此外,节点可以使用生成树路由进行路径查找,以建立比通过键空间的路径更短的路径,然后切换流量会话到源路由。只要源路由路径可用,通常更直接的源路由将继续使用,并在源路由路径中断时回退到键空间路由。

使用加密签名来保护树公告、引导和路径消息,防止篡改或伪造。

有什么好处?

这种路由方案有许多好处:

  • 设备只需要维护相对较少的状态以便正常工作和转发数据包 - 没有任何Yggdrasil节点需要像BGP那样维护“完整的路由表”,大多数节点总共只有少数几个路由表条目

  • 路径会自动发现和建立,因此不需要手动配置路由条目 - 唯一需要配置的是节点之间的对等连接

  • 网络可以快速建立和拆除路径,而无需丢弃所有路由状态,这在处理节点移动事件时有助于显着减少丢包

  • 我们可以轻松地将可靠/静态网络与动态/非静态网络桥接,而无需洪泛大量状态

  • 当任何两个或更多个Yggdrasil节点相互连接时,网络会自动形成,即使这些连接完全是临时的

  • 稀疏的路由知识和仅有少量的协议流量应该意味着Yggdrasil能够高效地扩展到非常大的网络

取代传统的VPN

到目前为止,我最喜欢也是最常使用Yggdrasil的一个用例是从远程位置(比如工作地点或我随身携带的笔记本电脑所在的任何地方)访问我的机器。最近,我主要关注的是通过VNC使用Yggdrasil连接到我家里的iMac,而VNC恰好内置在macOS中。我发现Yggdrasil是一款出色的工具,它有效地取代了我对传统VPN的需求。

使用Yggdrasil进行远程访问的一些优点包括:

  • 端到端加密,为通常在开箱即用的情况下并不安全的协议(如VNC或FTP)提供传输安全性

  • TCP-over-TCP性能优越 - 显著优于OpenVPN或SSH转发!

  • 源可验证性,可以根据源IPv6地址进行白名单验证,并阻止其他所有人

  • 可在网络的任何地方进行路由

端到端加密

所有通过Yggdrasil的隧道流量都在加密的“会话”中进行。当你试图向该节点发送流量时,会在你和远程节点之间建立一个会话。作为会话握手的一部分,你的公钥加密密钥被交换,这些密钥用于对所有封装的网络流量进行完全的端到端加密。

即使是纯文本协议,在跨Yggdrasil网络传输时也会被加密,确保没有中间路由器或对手可以窥探你的流量,使得像VNC这样的协议更安全,因为它们本身可能并不安全。

这也意味着,你可以在Yggdrasil上发送和接收流量,而不必过于担心在给定位置的网络的安全性。公共场所的开放Wi-Fi网络对于任何类型的连接安全性来说都是一场噩梦,因为它们通常没有受到无线加密的保护,但是对于Yggdrasil来说,这并不是一个问题。

TCP-over-TCP性能

过去,我曾尝试使用OpenVPN和SSH隧道作为一种回家的方法,通过在我的EdgeRouter X上终止VPN连接。我的工作地点的网络允许在少数端口上进行出站TCP连接,并且在互联网边界完全丢弃UDP,因此我被限制在TCP模式下使用OpenVPN,而不是UDP模式。

对于传输少量信息,这种方法是可行的,但肯定不是特别好。OpenVPN并未对TCP流量进行任何优化,因此,对于任何对延迟敏感的内容,性能都很糟糕 - 回到我的iMac上的VNC根本无法使用。SSH转发也没有好多少。

相反,我在我的EdgeRouter X上安装了Yggdrasil,并将其作为网关来直接路由到我的家庭机器(这是未来博客文章的一个主题)。每个Yggdrasil节点都有一个路由的/64子网,这在我的情况下,使用iptables将NETMAP'd映射到我的家庭IPv6 ULA范围。这实际上使我的整个家庭网络在Yggdrasil网络上可路由(即使是那些不知道Yggdrasil的设备或没有安装它的设备),只需遵守一些防火墙限制,我将在后面讨论。

主要的好处在于,Yggdrasil使用LIFO队列进行会话流量,并利用巨大的MTUs(如我之前的博客文章中所讨论的)来减少TCP控制消息放大的影响,并改善拥塞处理。这使得在TCP Yggdrasil对等连接上隧道TCP时,连接的可用性和稳定性得到了大大的改善 - VNC的稳定性和响应性在这种设置下比在OpenVPN或SSH上得到了大大的改善。

防火墙和源可验证性

当然,Yggdrasil网络上还有其他人,你不能确定他们是谁,或者他们可能是恶意的。因此,就像在互联网上一样,使用防火墙是明智的。源可验证性在这里特别有用,因为它使得只允许特定的机器通过你的防火墙发送流量,并将所有其他人排除在外变得相当容易。

在Yggdrasil中,你的IPv6地址与你的加密密钥对直接关联,因此,对你的密钥对的任何更改都会导致你的IPv6地址随之更改。当你生成一个配置(使用yggdrasil -genconf)时,你实际上是在生成一个新的IPv6地址。只要你继续在给定的机器上使用相同的Yggdrasil配置和相同的加密密钥对,那么该机器将永远保持相同的Yggdrasil IPv6地址。

这意味着我可以在我的EdgeRouter防火墙上创建一个白名单,除非它来自我已知的特定Yggdrasil IPv6地址列表,比如我的工作电脑和我的笔记本电脑,否则我会丢弃指向我的网络的连接。任何来自这个白名单之外的地址的意外连接都会被丢弃,从网络上隐藏我的机器。

以下是我在我的EdgeRouter X上实现这个的一个例子:

set firewall group ipv6-address-group YGG_TRUSTED ipv6-address 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'

set firewall group ipv6-network-group YGG_TRUSTEDNETS ipv6-network 'xxx:xxx:xxx::/48'

set firewall ipv6-name YGG_IN default-action drop

set firewall ipv6-name YGG_IN rule 10 action accept

set firewall ipv6-name YGG_IN rule 10 state established enable

set firewall ipv6-name YGG_IN rule 10 state related enable

set firewall ipv6-name YGG_IN rule 20 action drop

set firewall ipv6-name YGG_IN rule 20 state invalid enable

set firewall ipv6-name YGG_IN rule 30 action accept

set firewall ipv6-name YGG_IN rule 30 source group ipv6-address-group YGG_TRUSTED

set firewall ipv6-name YGG_IN rule 40 action accept

set firewall ipv6-name YGG_IN rule 40 source group ipv6-network-group YGG_TRUSTEDNETS

set firewall ipv6-name YGG_LOCAL default-action drop

set firewall ipv6-name YGG_LOCAL rule 10 action accept

set firewall ipv6-name YGG_LOCAL rule 10 state established enable

set firewall ipv6-name YGG_LOCAL rule 10 state related enable

set firewall ipv6-name YGG_LOCAL rule 20 action drop

set firewall ipv6-name YGG_LOCAL rule 20 state invalid enable

set firewall ipv6-name YGG_LOCAL rule 30 action accept

set firewall ipv6-name YGG_LOCAL rule 30 source group ipv6-address-group YGG_TRUSTED

set interfaces yggdrasil tun0 firewall in ipv6-name YGG_IN

set interfaces yggdrasil tun0 firewall local ipv6-name YGG_LOCAL

从整个网络路由

你不需要直接与一个节点进行对等连接就能远程访问它 - 你可以从Yggdrasil网络的任何地方路由流量。最好总是与地理位置接近你自己的节点进行对等连接,因为这有助于减少网络延迟。然而,你可以在一个新的位置(例如,使用笔记本电脑)设置,并连接到你最近的Yggdrasil节点,仍然能够像以前一样访问你的机器。

结论

Yggdrasil已经证明是一种非常有能力的方法,可以远程访问我的家庭网络,并且非常正常化了所有网络流量都应该被加密并被视为私有的观念,即使在连接安全性不能保证的地方也是如此。

-------------

Using Yggdrasil for remote access

15 July 2018 by Neil Alexander

Replacing the traditional VPN

One of my favourite and most common use-cases for Yggdrasil to date has been reaching back to my own machines from remote locations, like from work or wherever I happen to have taken my laptop on a given day. My main point of interest lately has been connecting to my iMac at home using VNC - which happens to be built into macOS - over Yggdrasil. I have found Yggdrasil to be an excellent tool for the job and it effectively replaces my need for a traditional VPN entirely.

Some of the benefits of using Yggdrasil for remote access are:

  1. End-to-end encryption, which provides transport security for protocols that are normally not very secure out of the box (like VNC or FTP)
  2. Superior TCP-over-TCP performance - remarkably better than over OpenVPN or SSH forwarding!
  3. Source verifiability, for being able to whitelist based on source IPv6 address and firewall everyone else out
  4. Routable from anywhere on the network

End-to-end encryption

All tunnelled traffic over Yggdrasil takes place within encrypted “sessions”. A session is established between you and a remote node when you attempt to send traffic to that node. As a part of the session handshake, your public encryption keys are exchanged, which are used to provide complete end-to-end encryption of all encapsulated network traffic.

Even plain-text protocols will appear to be encrypted in transit across the Yggdrasil network, ensuring that no intermediate routers or adversaries can spy on your traffic, and making it much safer to use protocols like VNC which may not be robustly secure by themselves.

It also means that it is possible to send and receive traffic over Yggdrasil with confidence, without worrying so much about the security of the network in a given location. Open Wi-Fi networks in public places are particularly a nightmare for any kind of connection security, as they are often not protected with wireless encryption, but this is less of a concern with Yggdrasil.

TCP-over-TCP performance

In the past I had tried using OpenVPN and SSH tunnelling as a method of reaching back home by terminating the VPN connection on my EdgeRouter X. The network at my workplace allows outbound TCP connection on a small number of ports and seemingly drops UDP at the internet boundary altogether, therefore I was restricted to using OpenVPN in TCP mode rather than UDP mode.

For transferring small amounts of information, this turned out to be functional but certainly not exceptional. OpenVPN doesn’t perform any kind of optimisation on TCP traffic, therefore the performance on anything latency-sensitive was awful - VNC back to my iMac was simply unusable. SSH forwarding was no better.

Instead, I installed Yggdrasil onto my EdgeRouter X and used this as a gateway to route to my home machines directly (a topic for a future blog post). Every Yggdrasil node has a routed /64 subnet which, in my case, was NETMAP‘d using iptables to my home IPv6 ULA range. This effectively makes my entire home network routable on the Yggdrasil network (even devices that are not Yggdrasil-aware or do not have it installed), subject to some firewall restrictions which I will discuss shortly.

The main benefits here are that Yggdrasil uses a LIFO queue for session traffic and also takes advantage of huge MTUs (as discussed in my previous blog post) to lessen the effect of TCP control message amplification and improved congestion handling. This results in a much more usable and stable connection when tunnelling TCP over a TCP Yggdrasil peering - the stability and the responsiveness of VNC proved to be much improved in this setup than over OpenVPN or SSH.

Firewalls and source verifiability

Of course, there are other people on the Yggdrasil network and you can’t be certain who they are or if they may or may not be malicious. Therefore just like on the Internet, it is wise to make use of a firewall. Source verifiability comes in particularly useful here as it makes it quite easy to allow only specific machines to send traffic through your firewall and to keep everyone else out.

In Yggdrasil, your IPv6 address is directly associated with your encryption keypair, therefore any changes to your keypair result in your IPv6 address changing with it. When you generate a configuration (using yggdrasil -genconf) then you are effectively deriving a new IPv6 address. As long as you continue to use the same Yggdrasil configuration with the same encryption keypair on a given machine, then that machine will keep the same Yggdrasil IPv6 address forever.

This meant that I could create a whitelist on my EdgeRouter firewall to drop connection headed towards my network unless it came from a specific list of Yggdrasil IPv6 addresses known to me already, i.e. my work computer and my laptop. Any other unexpected connections from addresses outside of this whitelist are dropped, hiding my machines from anyone else on the network.

An example of how I achieved this on my EdgeRouter X:

set firewall group ipv6-address-group YGG_TRUSTED ipv6-address 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx'
set firewall group ipv6-network-group YGG_TRUSTEDNETS ipv6-network 'xxx:xxx:xxx::/48'

set firewall ipv6-name YGG_IN default-action drop
set firewall ipv6-name YGG_IN rule 10 action accept
set firewall ipv6-name YGG_IN rule 10 state established enable
set firewall ipv6-name YGG_IN rule 10 state related enable
set firewall ipv6-name YGG_IN rule 20 action drop
set firewall ipv6-name YGG_IN rule 20 state invalid enable
set firewall ipv6-name YGG_IN rule 30 action accept
set firewall ipv6-name YGG_IN rule 30 source group ipv6-address-group YGG_TRUSTED
set firewall ipv6-name YGG_IN rule 40 action accept
set firewall ipv6-name YGG_IN rule 40 source group ipv6-network-group YGG_TRUSTEDNETS

set firewall ipv6-name YGG_LOCAL default-action drop
set firewall ipv6-name YGG_LOCAL rule 10 action accept
set firewall ipv6-name YGG_LOCAL rule 10 state established enable
set firewall ipv6-name YGG_LOCAL rule 10 state related enable
set firewall ipv6-name YGG_LOCAL rule 20 action drop
set firewall ipv6-name YGG_LOCAL rule 20 state invalid enable
set firewall ipv6-name YGG_LOCAL rule 30 action accept
set firewall ipv6-name YGG_LOCAL rule 30 source group ipv6-address-group YGG_TRUSTED

set interfaces yggdrasil tun0 firewall in ipv6-name YGG_IN
set interfaces yggdrasil tun0 firewall local ipv6-name YGG_LOCAL

Routable from the whole network

You don’t need to be directly peered to a node to be able to remotely access it - you can route traffic from anywhere on the Yggdrasil network. It is preferable to always peer with nodes that are geographically close to your own location, as this helps to reduce latency across the network. You can, however, set up in a new location (for example, with a laptop) and connect to your nearest Yggdrasil node and still be able to reach your machines like before.

Conclusion

Yggdrasil has proven to be a more-than-capable method for remotely accessing my home network and very much normalises the idea that all network traffic should be encrypted and treated as if it is private, even in locations where connection security would not otherwise be guaranteed.


from https://yggdrasil-network.github.io/2018/07/15/remote-access.html


No comments:

Post a Comment