27 个稳定版本 (3 个主要版本)

3.6.6 2022年11月21日
3.6.3 2022年3月29日
3.6.1 2021年11月3日
3.5.0 2021年3月25日
0.1.0 2019年4月23日

#96网络编程

每月 39 次下载

MIT 许可证

240KB
1.5K SLoC

Prometheus WireGuard 导出器

legal stability-stable

Crate cratedown cratelastdown

release tag

Rust build commitssince

Docker build

dockeri.co

简介

这是一个用 Rust 编写的 Prometheus 导出器,用于 WireGuard。此工具将 wg show all dump(或如果您指定了配置文件,则为 wg show <interface> dump)的结果导出为 Prometheus 可以理解的格式。导出器对您的服务器资源非常轻量,无论是内存还是 CPU 使用。它还针对以下 CPU 架构构建了 Docker:amd64386arm64armv7armv6

更新日志

  • 从版本 3.6.4 开始,导出器可选地计算自上次握手以来的秒数差值。指标为 wireguard_latest_handshake_delay_seconds。感谢 mmahacek 提出 该想法
  • 从版本 3.6.3 开始,导出器自动解析 systemd-networkd 的 peer 语法([WireGuardPeer] 而不是 [Peer])。感谢 mbonino 的 PR(见 https://github.com/MindFlavor/prometheus_wireguard_exporter/pull/92)。
  • 从版本 3.6.1 开始,导出器正确转义了 friendly_name 中的双引号。感谢 Steven Wood 在 #82 中找到的 bug。
  • 重大更新 从版本 3.6.0 开始,导出器将从环境变量中获取后备配置值。感谢 j_r0dd 提出这个想法。这改变了导出器评估命令行参数的方式:请务必查阅有关如何将您的命令行转换为新格式的文档。基本上,每个不带值的开关(例如,详细 -v)要么是 true,要么是 false。这是必要的,因为没有方法可以区分空环境变量和未设置的环境变量。
  • 从版本 3.5.1 开始,导出器支持多个对等文件。感谢 Tobias Krischer 提出这个想法。
  • 从版本 3.5.0 开始,导出器支持 friendly_json 标签。以 friendly_json 标签开头的内容将输出指定 json 中的所有条目作为 Prometheus 属性。感谢 DrProxyProSupport 提出这个想法。
  • 从版本 3.4.1 开始,导出器支持在 wg 命令前添加 sudo。这使得您可以用非 root 用户运行导出器(尽管是无需密码的 sudoer)。感谢 Jonas Seydel 提出这个想法。
  • 重大更新 从版本 3.4.0 开始,导出器要求您以特定格式指定友好名称(当然,如果您想使用它们的话)。这允许您在文件中使用任意注释,同时保留友好名称功能。感谢 Miloš Bunčić 提出这个想法。这也为未来的元数据铺平了道路。为了迁移,您可以使用以下 sed 命令:sed -'s/#/# friendly_name=/' peers.conf。请在使用之前确保进行备份!
  • 从版本 3.3.1 开始,导出器接受命令行选项中的多个接口。只需多次传递 - 参数。注意,不指定接口等同于指定所有接口(导出器将 all 参数传递给 wg show 命令)。
  • 紧急新闻 从版本 3.3.0 开始,导出器允许您从文件名指定不同的接口。之前,如果您指定了文件名(即 -n 标志),程序会从文件名推断接口名称。现在,这两项已经解耦:您需要单独指定文件名(使用 -n)和接口名称(使用 -)。感谢 Vincent Debergue 在此方面的帮助(见问题 #22)。从 3.2.4 升级:请注意,-n 标志不再自动从文件名推断接口名称。我们现在有 - 参数。为了保持之前的行为(如果您使用 - 标志),请将 - 标志也添加到命令行参数中。例如,如果您有 prometheus_wireguard_exporter -n /etc/wireguard/wg0.conf,您必须指定 prometheus_wireguard_exporter -n /etc/wireguard/wg0.conf - 以保持相同的行为。
  • 从版本 3.0.0 开始,导出器允许两种标签模式:一种是将每个允许的 IP 在单个标签中输出(称为 allowed_ips)及其子网。第二种是为每个允许的 IP/子网对创建一对标签(称为 allowed_ip_0/allowed_subnet_0allowed_ip_1/allowed_subnet_1 等,每个允许的 IP)。默认模式是单个标签模式,但您可以通过在启动时指定 - 开关来启用第二种模式。感谢 Toon Schoenmakers 提供此解决方案(见问题 #8)。
  • 从版本 2.0.2 开始,此导出器也支持 IPv6 地址(感谢 Maximilian Bosch 的 PR #5)。

设置

预构建的二进制文件

即将推出,订阅 #59

Docker

  1. 您需要安装 Docker

  2. 您需要在您的宿主内核中安装 WireGuard

  3. 您需要运行一些 WireGuard 接口

  4. 使用以下命令下载并运行容器:

    docker run -d --net=host --cap-add=NET_ADMIN --name wgexporter mindflavor/prometheus-wireguard-exporter
    

    ⚠️ 如果您在 32 位操作系统上遇到时间问题,请 检查此信息

  5. 通过访问 https://127.0.0.1:9586/metrics 来检查它是否启动

然后您可以使用以下命令更新镜像:

docker pull mindflavor/prometheus_wireguard_exporter

或者使用带有标签的镜像,例如 :3.5.1

如果您的宿主具有 amd64686 CPU,您还可以使用以下命令从源代码构建 Docker 镜像(您需要 git):

docker build -t mindflavor/prometheus_wireguard_exporter https://github.com/MindFlavor/prometheus_wireguard_exporter.git#master

从源代码构建

  1. 您需要安装 Rust

  2. 您需要在主机上安装 WireGuard

  3. 您需要在您的路径中可以访问到 wg。工具将调用 wg show <interface(s)>|all dump,如果找不到 wg 可执行文件,当然会失败。

  4. 您需要运行一些 WireGuard 接口

  5. 您需要安装 git

  6. 使用以下命令克隆仓库

    git clone https://github.com/MindFlavor/prometheus_wireguard_exporter.git
    cd prometheus_wireguard_exporter
    
  7. 使用以下命令编译程序

    cargo install --path .
    

    💁 如果您遇到错误,请尝试使用 rustup update 更新您的 rust 安装。代码应该可以使用任何相对较新的、符合 2018 年规范的 rustc 版本编译。作为参考,最后的发布版本是使用 Rust Docker 图像使用 rustc 1.53.0 (53cb7b09b 2021-06-17) 编译的。

  8. 运行程序

    ./prometheus_wireguard_exporter
    
  9. 通过访问 https://127.0.0.1:9586/metrics 来检查它是否启动

用法

可用的标志

使用 -h 启动二进制文件以获取完整的语法。参数如下。

重要 ❗:从 3.6.0 版本开始,每个参数都需要一个值。换句话说,即使是 -v(详细)参数也需要 truefalse 后面。传递不带值的参数(例如 -v)等同于根本不传递参数:将使用默认值(在详细选项的情况下,意味着 false)。

例如,如果您想启用详细模式并启用 prepend sudo 选项,您将使用以下命令行

prometheus_wireguard_exporter -a true -v true <...>
参数 环境 必需 有效值 默认 接受多个发生? 描述
-v PROMETHEUS_WIREGUARD_EXPORTER_VERBOSE_ENABLED truefalse false 启用详细模式。
-a PROMETHEUS_WIREGUARD_EXPORTER_PREPEND_SUDO_ENABLED truefalse false wg 命令前添加 sudo。
-l PROMETHEUS_WIREGUARD_EXPORTER_ADDRESS 任何有效的 IP 地址 0.0.0.0 指定服务地址。这是 Prometheus 实例应指向的地址。
-p PROMETHEUS_WIREGUARD_EXPORTER_PORT 任何有效的端口号 9586 指定服务端口。这是 Prometheus 实例应指向的端口。
-n PROMETHEUS_WIREGUARD_EXPORTER_CONFIG_FILE_NAMES WireGuard 配置文件的路径 此标志将 friendly_name 属性或 friendly_json 属性添加到导出的条目中。有关更多详细信息,请参阅 友好标签。允许多个文件(它们将在内存中合并为单个文件,因此请避免重复)。
-s PROMETHEUS_WIREGUARD_EXPORTER_SEPARATE_ALLOWED_IPS_ENABLED truefalse false 为标签启用允许的 ip + 子网拆分模式。
-r PROMETHEUS_WIREGUARD_EXPORTER_EXPORT_REMOTE_IP_AND_PORT_ENABLED truefalse false 导出对等方的远程 ip 和端口作为标签(如果可用)。
-i PROMETHEUS_WIREGUARD_EXPORTER_INTERFACES 您的接口名称 all 指定传递给 wg show <interface> dump 参数的接口。允许多个参数。
-d EXPORT_LATEST_HANDSHAKE_DELAY truefalse false 添加 wireguard_latest_handshake_delay_seconds 指标,该指标会自动计算自上次握手以来经过的秒数。

请注意,命令行值比环境变量具有优先级。

一旦启动,该工具将监听指定的端口(如果没有指定,则为默认端口9586)并在URL /metrics 返回有效的Prometheus响应。因此,要检查工具是否正常工作,只需浏览 https://127.0.0.1:9586/metrics(或您选择的任何端口)。

友好的标签

从版本3.5开始,您可以指示导出器向导出条目附加一个友好名称或一个friendly_json。这可以使输出比使用公共键更容易理解。例如,这是标准输出

# HELP wireguard_sent_bytes_total Bytes sent to the peer
# TYPE wireguard_sent_bytes_total counter
wireguard_sent_bytes_total{interface="wg0",public_key="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowed_ips="10.70.0.2/32,10.70.0.66/32"} 3208804
wireguard_sent_bytes_total{interface="wg0",public_key="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowed_ips="10.70.0.3/32"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowed_ips="10.70.0.4/32"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowed_ips="10.70.0.50/32"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowed_ips="10.70.0.40/32"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowed_ips="10.70.0.80/32"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowed_ips="10.70.0.5/32"} 0
# HELP wireguard_received_bytes_total Bytes received from the peer
# TYPE wireguard_received_bytes_total counter
wireguard_received_bytes_total{interface="wg0",public_key="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowed_ips="10.70.0.2/32,10.70.0.66/32"} 71420072
wireguard_received_bytes_total{interface="wg0",public_key="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowed_ips="10.70.0.3/32"} 0
wireguard_received_bytes_total{interface="wg0",public_key="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowed_ips="10.70.0.4/32"} 0
wireguard_received_bytes_total{interface="wg0",public_key="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowed_ips="10.70.0.50/32"} 0
wireguard_received_bytes_total{interface="wg0",public_key="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowed_ips="10.70.0.40/32"} 0
wireguard_received_bytes_total{interface="wg0",public_key="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowed_ips="10.70.0.80/32"} 0
wireguard_received_bytes_total{interface="wg0",public_key="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowed_ips="10.70.0.5/32"} 0
# HELP wireguard_latest_handshake_seconds Seconds from the last handshake
# TYPE wireguard_latest_handshake_seconds gauge
wireguard_latest_handshake_seconds{interface="wg0",public_key="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowed_ips="10.70.0.2/32,10.70.0.66/32"} 1562834127
wireguard_latest_handshake_seconds{interface="wg0",public_key="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowed_ips="10.70.0.3/32"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowed_ips="10.70.0.4/32"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowed_ips="10.70.0.50/32"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowed_ips="10.70.0.40/32"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowed_ips="10.70.0.80/32"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowed_ips="10.70.0.5/32"} 0

这是添加了友好名称的一个

# HELP wireguard_sent_bytes_total Bytes sent to the peer
# TYPE wireguard_sent_bytes_total counter
wireguard_sent_bytes_total{interface="wg0",public_key="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowed_ips="10.70.0.2/32,10.70.0.66/32",friendly_name="OnePlus 6T"} 3208804
wireguard_sent_bytes_total{interface="wg0",public_key="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowed_ips="10.70.0.3/32",friendly_name="varch.local (laptop)"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowed_ips="10.70.0.4/32",friendly_name="cantarch"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowed_ips="10.70.0.50/32",friendly_name="frcognoarch"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowed_ips="10.70.0.40/32",friendly_name="frcognowin10"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowed_ips="10.70.0.80/32",friendly_name="OnePlus 5T"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowed_ips="10.70.0.5/32",friendly_name="folioarch"} 0
# HELP wireguard_received_bytes_total Bytes received from the peer
# TYPE wireguard_received_bytes_total counter
wireguard_received_bytes_total{interface="wg0",public_key="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowed_ips="10.70.0.2/32,10.70.0.66/32",friendly_name="OnePlus 6T"} 71420072
wireguard_received_bytes_total{interface="wg0",public_key="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowed_ips="10.70.0.3/32",friendly_name="varch.local (laptop)"} 0
wireguard_received_bytes_total{interface="wg0",public_key="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowed_ips="10.70.0.4/32",friendly_name="cantarch"} 0
wireguard_received_bytes_total{interface="wg0",public_key="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowed_ips="10.70.0.50/32",friendly_name="frcognoarch"} 0
wireguard_received_bytes_total{interface="wg0",public_key="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowed_ips="10.70.0.40/32",friendly_name="frcognowin10"} 0
wireguard_received_bytes_total{interface="wg0",public_key="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowed_ips="10.70.0.80/32",friendly_name="OnePlus 5T"} 0
wireguard_received_bytes_total{interface="wg0",public_key="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowed_ips="10.70.0.5/32",friendly_name="folioarch"} 0
# HELP wireguard_latest_handshake_seconds Seconds from the last handshake
# TYPE wireguard_latest_handshake_seconds gauge
wireguard_latest_handshake_seconds{interface="wg0",public_key="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowed_ips="10.70.0.2/32,10.70.0.66/32",friendly_name="OnePlus 6T"} 1562834127
wireguard_latest_handshake_seconds{interface="wg0",public_key="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowed_ips="10.70.0.3/32",friendly_name="varch.local (laptop)"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowed_ips="10.70.0.4/32",friendly_name="cantarch"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowed_ips="10.70.0.50/32",friendly_name="frcognoarch"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowed_ips="10.70.0.40/32",friendly_name="frcognowin10"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowed_ips="10.70.0.80/32",friendly_name="OnePlus 5T"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowed_ips="10.70.0.5/32",friendly_name="folioarch"} 0

为了使这可行,您需要将friendly_name键值添加到在特定元数据之前的一个对等方的注释中(在您的WireGuard配置文件中)。以下是一个[Peer]定义的示例。标签名为friendly_name,它将被添加到导出到Prometheus的条目中。请注意,这不是一个标准,但因为它是一个注释,所以不会以任何方式干扰WireGuard。从版本 3.5.0 开始,您可以可选地指定一个friendly_json标签,后跟一个扁平的json(即,只有一个顶级,简单条目的json)。如果找到friendly_json标签,则每个条目都将作为属性用于导出的Prometheus实例。不会进行合规性检查。此外,数字将被转换为字符串(如Prometheus属性所期望的)。

例如,这是您如何编辑您的WireGuard配置文件的

[Peer]
PublicKey = lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=
AllowedIPs = 10.70.0.40/32

[Peer]
# Custom comment
PublicKey = 928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=
AllowedIPs = 10.70.0.80/32
[Peer]
# friendly_name = frcognowin10
PublicKey = lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=
AllowedIPs = 10.70.0.40/32

[Peer]
# friendly_name = OnePlus 5T
# Custom comment
PublicKey = 928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=
AllowedIPs = 10.70.0.80/32

如您所见,您只需要在某个对等方的注释中添加友好名称(并且因为此功能是可选的,所以需要启用标志)。

这是标签拆分模式的示例

# HELP wireguard_sent_bytes_total Bytes sent to the peer
# TYPE wireguard_sent_bytes_total counter
wireguard_sent_bytes_total{interface="wg0",public_key="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowed_ip_0="10.70.0.2",allowed_subnet_0="32",allowed_ip_1="10.70.0.66",allowed_subnet_1="32",friendly_name="OnePlus 6T"} 3208804
wireguard_sent_bytes_total{interface="wg0",public_key="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowed_ip_0="10.70.0.3",allowed_subnet_0="32",friendly_name="varch.local (laptop)"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowed_ip_0="10.70.0.4",allowed_subnet_0="32",friendly_name="cantarch"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowed_ip_0="10.70.0.50",allowed_subnet_0="32",friendly_name="frcognoarch"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowed_ip_0="10.70.0.40",allowed_subnet_0="32",friendly_name="frcognowin10"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowed_ip_0="10.70.0.80",allowed_subnet_0="32",friendly_name="OnePlus 5T"} 0
wireguard_sent_bytes_total{interface="wg0",public_key="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowed_ip_0="10.70.0.5",allowed_subnet_0="32",friendly_name="folioarch"} 0
# HELP wireguard_received_bytes_total Bytes received from the peer
# TYPE wireguard_received_bytes_total counter
wireguard_received_bytes_total{interface="wg0",public_key="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowed_ip_0="10.70.0.2",allowed_subnet_0="32",allowed_ip_1="10.70.0.66",allowed_subnet_1="32",friendly_name="OnePlus 6T"} 71420072
wireguard_received_bytes_total{interface="wg0",public_key="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowed_ip_0="10.70.0.3",allowed_subnet_0="32",friendly_name="varch.local (laptop)"} 0
wireguard_received_bytes_total{interface="wg0",public_key="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowed_ip_0="10.70.0.4",allowed_subnet_0="32",friendly_name="cantarch"} 0
wireguard_received_bytes_total{interface="wg0",public_key="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowed_ip_0="10.70.0.50",allowed_subnet_0="32",friendly_name="frcognoarch"} 0
wireguard_received_bytes_total{interface="wg0",public_key="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowed_ip_0="10.70.0.40",allowed_subnet_0="32",friendly_name="frcognowin10"} 0
wireguard_received_bytes_total{interface="wg0",public_key="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowed_ip_0="10.70.0.80",allowed_subnet_0="32",friendly_name="OnePlus 5T"} 0
wireguard_received_bytes_total{interface="wg0",public_key="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowed_ip_0="10.70.0.5",allowed_subnet_0="32",friendly_name="folioarch"} 0
# HELP wireguard_latest_handshake_seconds Seconds from the last handshake
# TYPE wireguard_latest_handshake_seconds gauge
wireguard_latest_handshake_seconds{interface="wg0",public_key="2S7mA0vEMethCNQrJpJKE81/JmhgtB+tHHLYQhgM6kk=",allowed_ip_0="10.70.0.2",allowed_subnet_0="32",allowed_ip_1="10.70.0.66",allowed_subnet_1="32",friendly_name="OnePlus 6T"} 1562834127
wireguard_latest_handshake_seconds{interface="wg0",public_key="qnoxQoQI8KKMupLnSSureORV0wMmH7JryZNsmGVISzU=",allowed_ip_0="10.70.0.3",allowed_subnet_0="32",friendly_name="varch.local (laptop)"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="L2UoJZN7RmEKsMmqaJgKG0m1S2Zs2wd2ptAf+kb3008=",allowed_ip_0="10.70.0.4",allowed_subnet_0="32",friendly_name="cantarch"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="MdVOIPKt9K2MPj/sO2NlWQbOnFJ6L/qX80mmhQwsUlA=",allowed_ip_0="10.70.0.50",allowed_subnet_0="32",friendly_name="frcognoarch"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="lqYcojJMsIZXMUw1heAFbQHBoKjCEaeo7M1WXDh/KWc=",allowed_ip_0="10.70.0.40",allowed_subnet_0="32",friendly_name="frcognowin10"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="928vO9Lf4+Mo84cWu4k1oRyzf0AR7FTGoPKHGoTMSHk=",allowed_ip_0="10.70.0.80",allowed_subnet_0="32",friendly_name="OnePlus 5T"} 0
wireguard_latest_handshake_seconds{interface="wg0",public_key="wTjv6hS6fKfNK+SzOLo7O6BQjEb6AD1TN9GjwZ08IwA=",allowed_ip_0="10.70.0.5",allowed_subnet_0="32",friendly_name="folioarch"} 0

Systemd服务文件

现在,像往常一样将导出器添加到Prometheus导出器。我建议将其作为服务启动。必须以root用户运行或配置sudo规则(如果有非root方式可以调用wg show all dump,请告诉我)。我的systemd服务文件如下所示

[Unit]
Description=Prometheus WireGuard Exporter
Wants=network-online.target
After=network-online.target

[Service]
User=root
Group=root
Type=simple
ExecStart=/usr/local/bin/prometheus_wireguard_exporter -n /etc/wireguard/peers.conf -i wg0 -i wg1

[Install]
WantedBy=multi-user.target

以普通用户+加固方式运行

[Unit]
Description=Prometheus WireGuard Exporter
Wants=network-online.target
After=network-online.target

[Service]
User=wireguard_exporter
Group=wireguard_exporter
Type=simple
Restart=on-failure
EnvironmentFile=-/etc/conf.d/prometheus-wireguard-exporter
ExecStart=/usr/local/bin/prometheus-wireguard-exporter $WIREGUARD_EXPORTER_ARGS
PrivateTmp=yes
ProtectHome=yes
ProtectControlGroups=yes
UMask=077
RemoveIPC=yes
BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout
ProtectSystem=strict
ProtectProc=noaccess

[Install]
WantedBy=multi-user.target

大多数其他systemd加固选项都不会工作,因为它们会阻止sudo。使用上述单元,您可以使用以下sudo规则

wireguard_exporter ALL=(root) NOPASSWD: /usr/bin/wg

如果您对更多加固感兴趣,可以使用以下命令分析单元

systemd-analyze security prometheus-wireguard-exporter.service

开发

本地

  1. 安装Rust
  2. 安装Rust Analyzer并将其与您的编辑器一起设置
  3. 安装Clippyrustup clippy

您可能还想安装Docker来构建和运行Docker镜像。

以下命令可用

# Download dependencies
cargo fetch
# Build the program
cargo build
# Run tests
cargo test
# Run clippy to lint
cargo clippy
# Build the Docker image
docker build -t mindflavor/prometheus_wireguard_exporter .

VSCode开发容器

这是一个基于Docker和VSCode的即插即用解决方案。

.devcontainer/README.md

依赖项

~17–30MB
~525K SLoC