GNUnet
GNUnet 是一个用于安全且匿名点对点网络的框架,它不使用任何中心化或受信任的服务。目前,该框架提供抗审查的文件共享、消息传递、VPN、GNS(一种去中心化的 DNS 版本)等功能。
参阅 https://gnunet.org/en/use.html 和 Wikipedia:GNUnet。
安装
配置
默认的 GNUnet 配置是多用户配置。这意味着系统服务由 gnunet 系统用户运行,而属于 gnunet 组的用户可以与守护进程进行交互——例如搜索和下载文件。
因此,在使用 GNUnet 之前,必须确保将您的用户添加到 gnunet 组以获得必要的权限。
默认配置在大多数情况下应可直接使用。如需更改系统配置,请参阅 /etc/gnunet.conf;如需更改当前用户配置,请参阅 ~/.config/gnunet.conf。
有关更多信息,请参阅手册中的 配置手册 (Configuration Handbook)。另请参阅 #在多用户设置中以当前用户身份启动守护进程。
用法
进入 GNUnet 网络
启动并根据需要启用 gnunet 系统服务。某些操作还需要启动 gnunet 用户服务。
检查网络
您可以通过以普通用户身份运行 gnunet-peerinfo 命令来检查当前网络状态。
$ gnunet-peerinfo
要了解您的节点身份,请运行
$ gnunet-peerinfo -s
要列出与您直接连接的节点(称为“邻居”),请运行
$ gnunet-core
文件共享
默认情况下,文件共享服务是按用户运行的,这意味着系统和用户 gnunet 服务都需要启动。如果您想更改此选项并改为按机器运行文件共享,请相应地编辑 /etc/gnunet.conf。
[fs] ... RUN_PER_USER = NO ... UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-fs.sock ...
搜索文件
使用 gnunet-search 通过关键字搜索文件(这些关键字不一定与文件名相关)。例如,要搜索使用“commons”关键字索引的文件,请运行
$ gnunet-search --timeout='10 s' 'commons'
如果不指定超时(上述示例中为 10 秒),gnunet-search 将一直运行,等待用户按下 CTRL-C。
gnunet-search 命令具有 --printf 选项用于处理输出,类似于 find 工具的 -printf 选项。更多详细信息请键入 man gnunet-search。
将搜索结果保存为“GNUnet 目录”
使用 gnunet-search 的 -o 选项将搜索结果保存为“GNUnet 目录”(.gnd 文件)——在这种情况下,您可能还希望禁止打印输出(使用 -s 选项)。
例如,要搜索三秒钟并将“commons”关键字产生的搜索结果保存到名为 three-seconds-commons.gnd 的文件中,请运行
$ gnunet-search -s -t 3s -o three-seconds-commons.gnd 'commons'
如果您以后想查看 three-seconds-commons.gnd 的内容,可以运行
$ gnunet-directory three-seconds-commons.gnd
下载
gnunet-search 的默认输出是一系列 gnunet-download 命令,您可以直接将其作为普通用户复制并运行。
例如,使用 gnunet-search 'commons' 生成的输出,
$ gnunet-search 'commons'
#1: gnunet-download -o "Liotard (2017)_ Fablab - a new space for commons based peer production.pdf" gnunet://fs/chk/C6369DRQ3S8RYK1FD5VDE666W2HVEJ5G5GJRX29BH6ZM08CBRWS7FY9326RBJ4G0N8V1RJ2N802KBYZT7RJT2EDK1J9JR2DXK5MTVM0.4SXJCK9NT5XGCZ0YAJ0ETXJJGY3P2SMNZ0Q94N775YEX9SXS2RW5FWRFK4GMBTP668Z3R8QZZ4WSHW1KG1AVQ5VFC1VF5T3WF57GT58.336423 #2: gnunet-download -o "Rose, Carol (1986)_ The Comedy of the Commons_ Commerce, Custom, and inherently Public Property.pdf" gnunet://fs/chk/TQK3A2C279EJQ50B1TQWFNTPMGQZJJ4JXYTF2D88D03H038TB7SVVSRBT74FMYPNZ47YZSV096PVVZH0TQ3B8KBVBV2H8GN9VAASTJR.CQ7M7843MGPZCV8M26NKH6EB5MBGZAXRWCF39YS668WM6F22D214GSXNTJ4RYGE7XF68VPZM4C19XR48TT4J8WH8S2E00C96Q8K6790.1593230 #3: gnunet-download -o "Hardin, Garett (1968)_ Tragedy of the Commons.pdf" gnunet://fs/chk/Y1FD7D123CEGWDW544YDEP15YA5E7ZD2XRSJBNP0847A5JXMMZEZ0XACGRG42BBBTGKZ0ZCBW0A9T6196Z5N26HA6SP1T8GDAT5H5SG.RN38G25DMYG3TBQJEGWDZT2B84N1JYYJZ8VRJ8HG2G1A4EFD4GH5TZXB0RXV7QEMZBSKWCCEF736FXNH6C5BYKG9DSTV99ETFGC93R0.1520328 ...
您可以运行,
$ gnunet-download -o "Hardin, Garett (1968)_ Tragedy of the Commons.pdf" gnunet://fs/chk/Y1FD7D123CEGWDW544YDEP15YA5E7ZD2XRSJBNP0847A5JXMMZEZ0XACGRG42BBBTGKZ0ZCBW0A9T6196Z5N26HA6SP1T8GDAT5H5SG.RN38G25DMYG3TBQJEGWDZT2B84N1JYYJZ8VRJ8HG2G1A4EFD4GH5TZXB0RXV7QEMZBSKWCCEF736FXNH6C5BYKG9DSTV99ETFGC93R0.1520328
这将在当前目录中下载 Hardin, Garett (1968)_ Tragedy of the Commons.pdf。
挂载远程 GNUnet 目录而不进行下载
名为 gnunet-fuseAUR 的模块已被开发用于挂载 GNUnet 网络中的远程目录。使用 gnunet-fuse,可以以只读文件系统的形式挂载在 GNUnet 网络上发布的目录,并使用常规文件操作进行访问。与通过 gnunet-download 递归下载目录相比,它的优势在于文件是按需下载的。只有您访问的文件(或目录)才会被下载。有关更多信息,请安装该模块并输入 man gnunet-fuse。
上传
在 GNUnet 文件共享网络上发布文件需要选择关键字,以便其他人稍后能搜索到该文件。
关键字不是必须的,但建议使用。这是因为 GNUnet 不允许按文件名搜索,而是按关键字搜索。作为 GNUnet 依赖项的 libextractor 库可以自动从文件中提取关键字,但您可能希望自己输入关键字。
在下面的示例中,我们使用关键字“commons”和“state”来发布一个名为 ostrom.pdf 的文件。
$ gnunet-publish -k 'commons' -k 'state' ostrom.pdf
Publishing `/srv/filesharing/gnunet/ostrom.pdf' done. URI is `gnunet://fs/chk/M57S...
现在,其他 GNUnet 用户可以使用 gnunet-search 命令找到该文件。
$ gnunet-search 'commons'
#1: gnunet-download -o "ostrom.pdf" gnunet://fs/chk/M57S...
要列出所有当前发布的文件,请运行 gnunet-fs -i。如果您以后想停止共享文件,可以使用 gnunet-unindex 文件名(在我们的示例中为 gnunet-unindex 'ostrom.pdf')。
文件一旦发布,就无法检索索引该文件时使用的关键字(即反向搜索)。但是,始终可以向其添加更多关键字。
请注意,您的节点可能需要一些时间(长达数小时)才能看到您刚刚上传的文件。
gnunet-publish 必须被视为不可逆操作。gnunet-publish 命令提供了一个选项——-n 或等效的 --noindex——用于发布文件而不对其进行索引。使用该选项时,GNUnet 将执行完整插入并将整个文件以加密形式存储在 GNUnet 数据库中。
创建此选项的目的是为了防止在某些言论审查严苛的国家,物理接触运行 GNUnet 的计算机的人发现当前正在发布哪些文件。使用 --noindex 选项发布的文件将表现为从网络下载的块,因此无法取消发布/取消索引(它们最初从未被索引过);但是,在发布时始终可以指定较低的内容优先级 (--prio),并告知 GNUnet 当数据库变满时,所发布的内容可以轻松被丢弃。
有关更多信息,请阅读 手册中的文件共享章节。另请参阅 https://gnunet.org/en/use.html#filesharing。
修改和移除索引文件
- 当您修改文件时,文件的 URI 会发生变化。因此,GNUnet 会将其视为完全不同的文件,而索引文件将被视为缺失。因此,请确保先取消索引原始文件(使用
gnunet-unindex命令),修改文件,然后对新文件进行索引,以使其可通过网络访问。 - 如果您想从文件系统中移除文件,则应首先取消其索引。
- 如果您预先知道已发布的文件可能需要频繁更新,请参阅 #发布可更新文件。
下载 + 共享
GNUnet 文件共享网络是一个 DHT(参见 Wikipedia:分布式哈希表)。作为 DHT 中的节点,用户会在磁盘上存储各种文件的块,即使是那些他们未下载或尚未下载完成的文件。存储哪些文件取决于 DHT 距离度量/算法。
从技术上讲,除非文件已完全下载,否则仅存储其部分内容。这些内容存储在缓存中(通常位于 /var/lib/gnunet/.local/share/gnunet)。如果 DHT 查询在某个节点中找到了缓存的某些部分,该节点将提供这些部分。用于存储文件共享块的数据库是有限的(低于可配置的配额),所有缓存部分都可以过期以腾出空间用于新文件。
如果有人在 GNUnet 网络中共享文件,该文件的分布式块将在网络缓存中保留一段时间,即使共享者离线,该文件也将保持可用。但如果原始发布者消失且没有人明确共享该文件(使用 gnunet-publish),随着节点缓存过期或节点离线,该文件最终将变得不可用。
因此,确保文件在 GNUnet 网络中持续存在的唯一方法是在下载后明确地重新发布它(使用 gnunet-publish),并让发布该文件的机器定期访问网络。
下载后发布文件将始终生成下载该文件时所用的相同 URI(在下例中为 gnunet://fs/chk/Y1FD...),而与用于重新发布它的关键字无关。
$ gnunet-download -o 'Hardin, Garett (1968)_ Tragedy of the Commons.pdf' gnunet://fs/chk/Y1FD...
100% [============================================================] Downloading `Hardin, Garett (1968)_ Tragedy of the Commons.pdf' done (160 b/s).
$ gnunet-publish -k 'tragedy' 'Hardin, Garett (1968)_ Tragedy of the Commons.pdf'
Publishing `/srv/filesharing/gnunet/Hardin, Garett (1968)_ Tragedy of the Commons.pdf' done. URI is `gnunet://fs/chk/Y1FD...
VPN
GNUnet 提供了一个 VPN,可用于共享您的互联网连接(是的,这可能很危险,就像运行 Tor 出口节点一样),或者提供对主机上服务的访问(只要这些服务是安全的,这应该不太危险)。
有关如何使用 GNUnet 设置 VPN 的信息,请参阅 https://gnunet.org/en/use.html#vpn。
GNU 命名服务 (GNS)
GNU 命名服务 (GNS) 是 域名系统 (DNS) 的完全去中心化替代方案,它不会遭受与后者相同的重大安全漏洞(参见 Wikipedia:Domain Name System#Security issues)。
有关如何使用 GNS 的信息,请参阅 https://gnunet.org/en/use.html#gns_cli 和 https://gnunet.org/en/use.html#gns_browser。
与其他 GNUnet 用户聊天
要与 GNUnet 用户聊天,可以使用 gnunet-messenger 工具,该工具需要启动 gnunet.service 用户单元(可能需要与 gnunet.service 系统单元一起启动——请参阅 #在多用户设置中以当前用户身份启动守护进程)。例如,要以 "archie" 为昵称进入 "miscellanea" 聊天室,请运行
$ gnunet-messenger -e archie -r miscellanea
* Welcome to the messenger, 'archie'! * You try to open a room... * You joined the room. [EHDA8T] * 'anonymous' opened the room on: 2ABN944E16FTWFMOKTMQ5JMPQ233YSPBKC47XR2DHSPQCQ8GYK80 [EHDA8T] * 'anonymous' gets renamed to 'archie' █
应用生态系统
GNUnet GTK
GNUnet GTK 是 GNUnet 框架的图形界面集合。它包含以下 GTK 应用程序
gnunet-conversation-gtkgnunet-fs-gtkgnunet-namestore-gtkgnunet-peerinfo-gtkgnunet-setupgnunet-statistics-gtk
要安装 GNUnet GTK,请下载 gnunet-gtkAUR 软件包。
Messenger GTK
目前正在开发几种用于在 GNUnet 网络上聊天的图形用户界面。其中之一是 messenger-gtkAUR,这是一个移动友好的 GTK 图形界面,用于与 GNUnet 用户聊天。要通过命令行聊天,请参阅 messenger-cliAUR。
Web 用户界面
存在一个 GNUnet Web 界面,可作为 gnunet-webui-gitAUR 获取。
re:claimID
re:claimID 是一个构建在 GNU 命名系统之上的去中心化身份提供商 (IdP) 服务。它允许用户使用标准化协议 (OpenID Connect) 与网站安全地共享个人信息。
对于用户,re:claimID 提供 Firefox 扩展 和 Chromium 扩展,用于在 Web 浏览器中管理 re:claimID 身份(需要安装 gnunetAUR 软件包)。
安装扩展后,可以通过访问 https://ui.reclaim/ 为本地 re:claimID 实例添加新身份并为其添加一些属性(如果不安装扩展,该链接将无法工作)。
有关更多信息,请参阅 手册。
GNU Taler
GNU Taler 是一个构建在 GNUnet 之上的微交易和电子支付系统。与其他分布式支付系统不同,Taler 不基于区块链,而是基于盲签名。
有关更多信息,请查阅 官方文档。另请参阅 syncAUR, taler-exchangeAUR, taler-mdbAUR, taler-merchantAUR 和 taler-twisterAUR 等软件包。
GNU Anastasis
GNU Anastasis 是一个协议及实现,允许用户将核心密钥安全地存放在一组托管提供商处,并在丢失原始副本时恢复这些密钥。Anastasis 可从 AUR 获取(anastasisAUR 和 anastasis-gtkAUR)。有关更多信息,请查阅 https://gnu.net.cn/software/anastasis/ 和 https://anastasis.lu/。
故障排除
GNUnet 无法发布文件
对于不了解 GNUnet 服务如何工作的人来说,一个常见的错误是试图在当前用户没有运行文件共享服务时,发布位于家目录(或其子目录)中的文件。问题在于 gnunet 系统用户(运行 GNUnet 系统服务)通常无法访问其他用户的家目录。
一个简单的解决方案是创建一个共享目录,只有属于 gnunet 组的用户才拥有写入权限,并使用它来放置将要发布的文件。例如,/srv/filesharing/gnunet 可能是一个不错的选择。
# install -dm775 -g gnunet -o gnunet /srv/filesharing/gnunet
每个属于 gnunet 组的用户都可以在他们的家目录中创建指向该目录的链接,
$ ln -s /srv/filesharing/gnunet ~/Publishing
它可以被 gnunet-publish 解引用。
$ (cd ~/Publishing && gnunet-publish -k commons ostrom.pdf) && gnunet-fs -i
/srv/filesharing/gnunet/ostrom.pdf
如果您更倾向于以当前用户身份运行文件共享服务,请相应地编辑 /etc/gnunet.conf。
[fs] ... RUN_PER_USER = YES ... UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-fs.sock ...
带宽过低
建议针对文件共享提高 GNUnet 的带宽限制,因为其默认值确实非常低。下面的示例将 WAN 和 LAN 限制设置为 unlimited。
$ gnunet-config -s ats -o WAN_QUOTA_IN -V unlimited $ gnunet-config -s ats -o WAN_QUOTA_OUT -V unlimited $ gnunet-config -s ats -o LAN_QUOTA_IN -V unlimited $ gnunet-config -s ats -o LAN_QUOTA_OUT -V unlimited
/var/lib/gnunet/ 变得过大
GNUnet 的缓存是有限的,不能无限增长。但是,其默认保留的配额并不小(目前为 5 GB)。要减少此数值,必须将您首选的值分配给 /etc/gnunet.conf 中 datastore 部分的 QUOTA 键。
/etc/gnunet.conf
... [datastore] ... QUOTA = 2 GB ...
卸载后保留了 /var/lib/gnunet/
/var/lib/gnunet/ 目录是 gnunet 系统用户的家目录,在卸载 GNUnet 后它会被保留。如果您确定永远不再使用 GNUnet,请运行
# userdel -r gnunet # groupdel gnunetdns
网络过于静态
默认情况下,GNUnet 每次连接网络时都会使用从互联网下载的 hostlist 文件(纯 https)进行自举。如果您想让它学习并记住其他节点提供的节点列表,您需要在 /etc/gnunet.conf 的 hostlist 下的 OPTIONS 键中添加 -e 选项。更多选项也可用。
/etc/gnunet.conf
... [hostlist] ... # Options: # -p : provide a hostlist as a hostlist servers # -b : bootstrap using configured hostlist servers # -e : enable learning advertised hostlists # -a : advertise hostlist to other servers OPTIONS = -b -e -a -p ...
技巧与提示
在多用户设置中以当前用户身份启动守护进程
全新安装后,用户配置文件缺失。在多用户设置中,此文件几乎仅用于(如果需要)在系统守护进程运行时启动和停止 gnunet.service 用户单元,因此通常只需创建一个包含以下内容的最小配置文件即可:
~/.config/gnunet.conf
[arm] START_SYSTEM_SERVICES = NO START_USER_SERVICES = YES
如果不将 START_SYSTEM_SERVICES 设置为 NO,则在系统守护进程运行时以当前用户身份启动守护进程将导致重复进程。
有关更多信息,请参阅手册中的 多用户设置 (The Multi-User Setup)。
开关 GNUnet 的按钮
如果您使用 GNOME,可能需要安装 Systemd Manager shell 扩展 (gnome-shell-extension-systemd-managerAUR) 并将 GNUnet 添加进去。
$ dconf write /org/gnome/shell/extensions/systemd-manager/systemd \
'['\''{"name":"GNUnet system service","service":"gnunet.service","type":"system"}'\'', '\''{"name":"GNUnet user service","service":"gnunet.service","type":"user"}'\'']'
(安装扩展后,您可能需要重启会话。)
单用户设置
GNUnet 节点也可以在不运行 gnunet 系统服务的情况下从当前用户启动。对于单用户设置,请确保 ~/.config/gnunet.conf 中的 START_SYSTEM_SERVICES 和 START_USER_SERVICES 设置为 YES。
~/.config/gnunet.conf
[arm] START_SYSTEM_SERVICES = YES START_USER_SERVICES = YES
要以当前用户身份启动节点,请启动 gnunet.service 用户单元。要停止以当前用户身份运行的节点,请停止 gnunet.service 用户单元。
有关更多信息,请参阅手册中的 单用户设置章节。
发布可更新文件
可以发布“可更新”文件(即您将来可能想发布不同版本的文件,并声明它是同一个文件——只是已更新——而不是不同的文件)。要发布可更新文件,您需要创建一个“自我 (ego)”并使用它来对文件进行签名。这是确保恶意方无法提供伪造更新的唯一方法。
要创建自我,可以使用 gnunet-identity 工具,该工具需要启动 gnunet.service 用户单元(可能需要与 gnunet.service 系统单元一起启动——请参阅 #在多用户设置中以当前用户身份启动守护进程)。例如,要创建一个名为 "caroline" 的自我,请启动 gnunet 用户单元并运行
$ gnunet-identity -C caroline
gnunet-identity -D caroline。现在您已经创建了一个自我,您需要指定一个标识当前文件版本的字符串(-t 选项),以及立即指定一个标识您计划的下一个版本的字符串(-N 选项)——您必须记住后者。这两个字符串可以是任何内容。
$ gnunet-publish -P caroline -t 'diary version 1' -N 'diary version 2' -k 'diary' until-2020/my_diary.md
Publishing `/srv/filesharing/gnunet/until-2020/my_diary.md' done. URI is `gnunet://fs/chk/AF26...'. Namespace URI is `gnunet://fs/sks/V3TK.../diary version 1'.
当更新准备好时,您将必须使用之前选择的相同字符串(在我们的示例中为 "diary version 2"),并可能附带另一个用于进一步更新的名称(如果适用)。
$ gnunet-publish -P caroline -t 'diary version 2' -N 'diary version 3' -k 'diary' until-2021/my_diary.md
Publishing `/srv/filesharing/gnunet/until-2021/my_diary.md' done. URI is `gnunet://fs/chk/5Y7V...'. Namespace URI is `gnunet://fs/sks/V3TK.../diary version 2'.
如果您决定某个更新是最后一个更新,则省略 -N 选项(将不允许任何未来的更新)。
请注意,GNUnet 的更新不会使旧内容不可用,GNUnet 只是允许发布者将用户指向更新的版本。
在没有 systemd 的情况下启动和停止 GNUnet
GNUnet 自带一套守护进程管理系统,即自动重启管理器 (Automatic Restart Manager)(仅限于 GNUnet 服务)。
要在没有 systemd 的情况下手动启动系统服务,请以 gnunet 用户身份运行 gnunet-arm 工具。
[gnunet]$ gnunet-arm -c /etc/gnunet.conf -s
要在没有 systemd 的情况下手动结束系统服务,请运行
[gnunet]$ gnunet-arm -c /etc/gnunet.conf -e
要在没有 systemd 的情况下手动启动用户服务,请以当前用户身份运行 gnunet-arm 工具。
$ gnunet-arm -c ~/.config/gnunet.conf -s
要在没有 systemd 的情况下手动结束用户服务,请运行
$ gnunet-arm -c ~/.config/gnunet.conf -e