index.html

SmokePing + NGINX 搭建多点网络质量监控

字数统计: 3.2k阅读时长: 15 min
2018/11/03 Share

介绍

SmokePing是一款网络质量检测工具,可以在网页上用图形显示各项数据,官方介绍如下:

SmokePing keeps track of your network latency:

  • Best of breed latency visualisation.
  • Interactive graph explorer.
  • Wide range of latency measurement plugins.
  • Master/Slave System for distributed measurement.
  • Highly configurable alerting system.
  • Live Latency Charts with the most ‘interesting’ graphs.
  • Free and OpenSource Software written in Perl written by Tobi Oetiker, the creator of MRTG and RRDtool

这是官方的Demo

还有个我常用的网站Ping.cat也是用SmokePing搭的。

SmokePing并不算多么难配的服务,然而坑很多,我在网上找的教程很多都过时了,甚至还有写错的。

安装

APT安装

在友帮脱环境下,安装就是sudo apt install smokeping一把梭,不过这种安装一般不是最新版本。

编译安装

先安装一些必要组件:
这里简直是大坑,官方也没说清楚到底要那些依赖,只能一遍遍在编译错误中摸索。

1
sudo apt install rrdtool librrds-perl perl make build-essential libnet-ssleay-perl zlib1g-dev

从Gayhub下载最新Release

1
wget https://github.com/oetiker/SmokePing/releases/download/2.7.2/smokeping-2.7.2.tar.gz

编译前检查,prefix参数指定安装路径:
1
./configure --prefix=/opt/smokeping

没有问题接下来就编译安装:
1
sudo make install

我在编译2.7.2版本时发现CPAN死活无法安装Mozilla::CA,只好把官方的release拆开,手动将这个模块打包进去😩

建立配置文件:新建/etc/smokeping/config

/etc/init.d/建立管理脚本smokeping(apt安装就不用了),内容如下(搬运apt版本的🐟):
其中二进制路径与配置文件路径等变量依实际情况修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#!/bin/sh
#
# /etc/init.d/smokeping
#
### BEGIN INIT INFO
# Provides: smokeping
# Required-Start: $syslog $network $remote_fs
# Should-Start: sshd apache
# Required-Stop: $syslog $network $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start or stop the smokeping latency logging system daemon
# Description: SmokePing is a latency logging and graphing system
# that consists of a daemon process which organizes
# the latency measurements and a CGI which presents
# the graphs. This script is used to start or stop
# the daemon.
### END INIT INFO
#

set -e

# Source LSB init functions
. /lib/lsb/init-functions

DAEMON=/opt/smokeping/bin/smokeping # apt安装的二进制路径为/usr/sbin/smokeping
NAME=smokeping
DESC="latency logger daemon"
# 配置文件位置
CONFIG=/opt/smokeping/etc/config # apt安装的配置文件路径为/etc/smokeping/config
PIDFILE=/var/run/smokeping/$NAME.pid
DAEMON_USER=smokeping
DEFAULTS=/etc/default/smokeping # 编译安装版把这一行和下面的if分支注释掉
MODE=master
DAEMON_ARGS="--config=$CONFIG"

# LC_ALL prevents resetting LC_NUMERIC which in turn interferes
# with Smokeping internal regexps matching floating point numbers
unset LC_ALL

# Check whether the binary is still present:
test -f "$DAEMON" || exit 0

# source defaults for master vs. slave mode
if [ -f "$DEFAULTS" ]
then
. "$DEFAULTS"
fi

check_slave() {
if [ "$MODE" != "slave" ]
then
return
fi
if [ -z "$SHARED_SECRET" ]
then
log_progress_msg "(missing \$SHARED_SECRET setting)"
log_end_msg 6 # program is not configured
exit 6
fi
if [ ! -r "$SHARED_SECRET" ]
then
log_progress_msg "(invalid \$SHARED_SECRET setting)"
log_end_msg 2 # invalid or excess argument(s)
exit 2
fi
if [ -z "$MASTER_URL" ]
then
log_progress_msg "(missing \$MASTER_URL setting)"
log_end_msg 6 # program is not configured
exit 6
fi
DAEMON_ARGS="$DAEMON_ARGS --master-url $MASTER_URL --shared-secret $SHARED_SECRET"
if [ -n "$SLAVE_NAME" ]
then
DAEMON_ARGS="$DAEMON_ARGS --slave-name $SLAVE_NAME"
fi
DAEMON_ARGS="$DAEMON_ARGS --cache-dir /var/lib/smokeping"
DAEMON_ARGS="$DAEMON_ARGS --pid-dir /var/run/smokeping"
}

check_config () {
echo "Checking smokeping configuration file syntax..."
# Check whether the configuration file is available
if [ ! -r "$CONFIG" ] && [ "$MODE" = "master" ]
then
log_progress_msg "($CONFIG does not exist)"
log_end_msg 6 # program is not configured
exit 6
fi
if [ ! -d /var/run/smokeping ]; then
mkdir /var/run/smokeping
chown ${DAEMON_USER}.root /var/run/smokeping
chmod 0755 /var/run/smokeping
fi
${DAEMON} --config=${CONFIG} --check || exit 6
}

case "$1" in
start)
check_config
log_daemon_msg "Starting $DESC" $NAME
check_slave
set +e
pidofproc -p "$PIDFILE" "$DAEMON" > /dev/null
STATUS=$?
set -e
if [ "$STATUS" = 0 ]
then
log_progress_msg "already running"
log_end_msg $STATUS
exit $STATUS
fi

set +e
start-stop-daemon --start --quiet --exec $DAEMON --oknodo \
--chuid $DAEMON_USER --pidfile $PIDFILE \
-- $DAEMON_ARGS \
| logger -p daemon.notice -t $NAME
STATUS=$?
set -e

log_end_msg $STATUS
exit $STATUS
;;


stop)
log_daemon_msg "Shutting down $DESC" $NAME

set +e
start-stop-daemon --oknodo --stop --retry 3 --quiet --pidfile /var/run/smokeping/$NAME.pid --signal 15
STATUS=$?
set -e

log_end_msg $STATUS
exit $STATUS
;;


restart)
# Restart service (if running) or start service
$0 stop
$0 start
;;


reload|force-reload)
check_config
log_action_begin_msg "Reloading $DESC configuration"
set +e
$DAEMON --reload $DAEMON_ARGS | logger -p daemon.notice -t smokeping
STATUS=$?
set -e

if [ "$STATUS" = 0 ]
then
log_action_end_msg 0 "If the CGI has problems reloading, see README.Debian."
else
log_action_end_msg $STATUS
fi
exit $STATUS
;;

check)
check_config
;;

status)
log_daemon_msg "Checking $DESC status" $NAME
# Use pidofproc to check the status of the service,
# pidofproc returns the exit status code of 0 when it the process is
# running.

# LSB defined exit status codes for status:
# 0 program is running or service is OK
# 1 program is dead and /var/run pid file exists
# 2 program is dead and /var/lock lock file exists
# 3 program is not running
# 4 program or service status is unknown
# 5-199 reserved (5-99 LSB, 100-149 distribution, 150-199 applications)

set +e
pidofproc -p "$PIDFILE" "$DAEMON" > /dev/null
STATUS=$?
log_progress_msg "(status $STATUS)"
log_end_msg 0
set -e
exit $STATUS
;;


*)
echo "Usage: $0 {start|stop|status|restart|force-reload|reload}"
exit 1
;;
esac

之后就可以愉快地使用systemctlservice来控制SmokePing了。

配置

APT安装的SmokePing所有的配置文件都存放在/etc/smokeping/config.d/这个目录下。注意,部分参数在被General引用的/etc/smokeping/config.d/pathnames中配置,不应重复定义,否则会报错。

编译安装的版本配置文件用/opt/smokeping/etc拿dist后缀的样例直接套。

这里附上官方Renference

General

通常配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
*** General ***
# 网站Admin的名字
owner = M0n0Kuma
# Admin邮箱地址,默认页面会有mailto
contact = [email protected]
# 如果不用sendmail而用perl Net::SMTP,可以手动指定邮件服务器
mailhost = my.mail.host
mailuser = username
mailpass = Passw0rd
# Smokemial邮件模板位置
smokemail = /opt/smokeping/etc/smokemail # APT版默认为/etc/smokeping/smokemail
# tSmoke邮件模板位置
tmail = /opt/smokeping/etc/tmail # APT版默认为/etc/smokeping/tmail
# 本机的名称
display_name = PornHub
# 允许同时探测
concurrentprobes = yes
# 与`concurrentprobes`搭配,子进程名称追加探针名
changeprocessnames = yes
# 图片缓存位置
imgcache = /var/cache/smokeping/image
# 图片URL,应该与web部署位置对应
imgurl = ../monitor/image
# 页面超链接风格,可以为absolute,relative或original
linkstyle = original
# 数据存储位置,本机及从属服务器数据位置
datadir = /var/lib/smokeping
# 动态相关的数据,必须保证web服务器可以读写(比如group为www-data)
dyndir = /var/lib/cgi-bin/smokeping/__cgi
# 页面静态文件地址
pagedir =
# PID文件
piddir = /var/run/smokeping
# 运行多个实例时的探测时间差
offset = random
# CGI路径
cgiurl = https://asdasd.page/monitor/smokeping.fcgi
# 日志功能
syslogfacility = local0

Database

数据库配置

数据库配置后必须删除datadir下的所有*.rrd文件并重启smokeping服务,所以在一开始就应该认真配置好,避免更改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
*** Database ***
# 每60秒探测一次,每次发送10个Ping
step = 60
pings = 10

# rrdtool的一些不知道干嘛的参数,没事就不戳它了🙄
# consfn mrhb steps total

AVERAGE 0.5 1 1008
AVERAGE 0.5 12 4320
MIN 0.5 12 4320
MAX 0.5 12 4320
AVERAGE 0.5 144 720
MAX 0.5 144 720
MIN 0.5 144 720

Presentation

展示设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
*** Presentation ***
# 模板的位置,以及字符集
template = /etc/smokeping/basepage.html
charset = utf-8

# +是一级菜单,++是二级菜单,以此类推
# 这个charts是一个概览页面,把丢包、延时等参数最高的线路拎出来显示
# 以下所有菜单的名字都不能改(title随意)
+ charts

menu = Summary
title = Summary

++ stddev
sorter = StdDev(entries=>4)
title = Top Standard Deviation
menu = Std Deviation
format = Standard Deviation %f

++ max
sorter = Max(entries=>5)
title = Top Max Roundtrip Time
menu = by Max
format = Max Roundtrip Time %f seconds

++ loss
sorter = Loss(entries=>5)
title = Top Packet Loss
menu = Loss
format = Packets Lost %f

++ median
sorter = Median(entries=>5)
title = Top Median Roundtrip Time
menu = by Median
format = Median RTT %f seconds

# 主页节点概览的图片大小
+ overview

width = 800
height = 100

# 节点详情显示的图片大小
+ detail

width = 800
height = 200
unison_tolerance = 2

# 为每个节点用不同时间轴绘制多幅图像
"Last 3 Hours" 3h
"Last 24 Hours" 24h
"Last 7 Days" 7d

Probes

探针设置

1
2
3
4
5
6
7
8
9
10
11
12
13
*** Probes ***
# 每种探针有自己不同的参数,详见官方Doc
+ FPing
# this value is common for the two subprobes
binary = /usr/bin/fping

# ++ FPingLarge
# packetsize = 1000
# step = 300

# ++ FPingSmall
# packetsize = 64
# step = 30

Alerts

警告设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
*** Alerts ***
# 警报邮件设置
to = [email protected],[email protected]
from = [email protected]

#以下是一些样例,详见官方Doc

+lossdetect
type = loss
# in percent
pattern = ==0%,==0%,==0%,==0%,>20%,>20%,>20%
comment = suddenly there is packet loss

+miniloss
type = loss
# in percent
pattern = >0%,*12*,>0%,*12*,>0%
comment = detected loss 3 times over the last two hours

+rttdetect
type = rtt
# in milliseconds
pattern = <10,<10,<10,<10,<10,<100,>100,>100,>100
comment = routing messed up again ?

+rttbadstart
type = rtt
# in milliseconds
pattern = ==S,==U
comment = offline at startup

Targets

用于监测的目标主机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
*** Targets ***
# 使用的探针
probe = FPing

# 菜单(菜单名和menu不能有空格)
menu = Top
title = Network Latency & Connectivity Monitoring
remark = Across the Great Wall we can reach every corner in the world.

# 一级菜单
+ PornHub
menu = PornHub
title = PornHub

# 节点可以放在任何一级菜单下
++ Target_Node
menu = Target-Node-1
title = Taget Node
# 节点地址
host = target.host.com
# 应用的警报,默认为无(定义在Alert中)
alerts = someloss

+ XVideos
menu = XVideos
title = XVideos

++ XVideos_Server_1
menu = XVideos-Server-1
title = XVideos Server 1
host = xvideos.com

Slaves

主从监控配置小节

basepage.html

编译安装页面模板默认位置为/opt/smokeping/etc/basepage.html.dist,APT版在/etc/smokeping/basepage.html

可以做一些美化,但重点是要改一下的脚本位置,因为本例中SmokePing是部署在网站子目录/monitor下的。
新的编译安装已经不需要改了,因为它是用相对路径引用的

1
2
3
4
<script src="/monitor/prototype/prototype.js" type="text/javascript"></script>
<script src="/monitor/scriptaculous/scriptaculous.js?load=builder,effects,dragdrop" type="text/javascript"></script>
<script src="/monitor/cropper/cropper.js" type="text/javascript"></script>
<script src="/monitor/smokeping-zoom.js" type="text/javascript"></script>

FcgiWrap与NGINX

SmokePing官方钦定了Apache,但我是用NGINX配置的。

SmokePing用FastCGI开发,而NGINX没法像Apache那样直接运行fcgi,所以还需要fcgiwrap这个插件。当然这也不是唯一的选择,还可用spawn-fcgi。

安装NGINX与FcgiWrap:

1
sudo apt install nginx fcgiwrap

复制FcgiWrap的样例配置:
1
cp /usr/share/doc/fcgiwrap/examples/nginx.conf /etc/nginx/fcgiwrap.conf

检查FcgiWrap服务是否成功开启:
1
2
systemctl is-enabled fcgiwrap.service
systemctl is-enabled fcgiwrap.socket

没有问题的话就可以配置NGINX了。假设要将SmokePing部署在https://asdasd.page/monitor。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
server {
#21世纪不用HTTPS的都应该被绑到火刑柱上
listen 443 ssl;
listen [::]:443 ssl;
server_name asdasd.page;
ssl_certificate /etc/nginx/ssl/asdasd.page/fullchain;
ssl_certificate_key /etc/nginx/ssl/asdasd.page/private.key;

include /etc/nginx/fcgiwrap.conf; #这里引用FcgiWrap配置

#这里假设将smokeping放在主站的/monitor路径下
location ^~ /monitor {
alias /opt/smokeping/htdocs; #APT版SmokePing默认位置是/usr/share/smokeping/www/
index smokeping.fcgi;
}

#向fcgi传递参数。我是照网上抄的,不知道为什么,但是能用,所以什么都没敢改😂
location /monitor/smokeping.fcgi {
fastcgi_intercept_errors on;
fastcgi_pass unix:/var/run/fcgiwrap.socket; #FcgiWrap默认监听请求
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME /opt/smokeping/bin/smokeping_cgi # APT版本的位置是/usr/lib/cgi-bin/smokeping.cgi;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param HTTPS $https if_not_empty;
}
}

配置到这里,不出问题已经可以访问 https://asdasd.page/monitor 进入SmokePing界面了。

主从监控配置

我个人认为先配置Slave服务器再配置Master服务器是比较好的顺序。
官方的配置文档点此进入

Slave服务器

安装过程略,详见安装小节

安装后首先建立密码文件,用于和Master服务器通信,本例中密码文件在/etc/smokeping/smokeping_secrets
用文本编辑器写一行,例如thequickbrownfoxjumpsoveralazydog,dalao可以用vim,我等渣渣就用nano。

密码文件的权限交给smokeping:

1
2
sudo chown smokeping:root /etc/smokeping/smokeping_secrets
sudo chmod 0600 /etc/smokeping/smokeping_secrets

Slave服务器位于/etc/init.d/smokeping的管理脚本要做一些调整:

1
2
3
4
5
6
7
8
9
MODE=slave
# Master服务器FCGI地址
MASTER_URL=https://asdasd.page/monitor/smokeping.fcgi
# Slave服务器密码文件
SHARED_SECRET=/etc/smokeping/smokeping_secrets
CACHE_DIR=/var/lib/smokeping
# Slave服务器IP或主机名,必须可访
SLAVE_NAME=slave-1.asdasd.page
DAEMON_ARGS="--master-url=$MASTER_URL --shared-secret=$SHARED_SECRET --cache-dir=$CACHE_DIR --slave-name=$SLAVE_NAME"

变更配置后重启服务生效
注意:Slave服务必须在Master服务之后启动,否则会因无法从Master服务获取配置而出错,所以如果Master还没配置好,可以先不启动Slave

1
sudo systemctl daemon-reload && sudo systemctl restart smokeping

也可以不用管理脚本,但必须保证--master-url --shared-secret --cache-dir --slave-name这几个参数被传入smokeping

Master服务器

同样先建立密码文件,假设在/etc/smokeping/smokeping_secrets
这里文件内容格式略有不同,每行对应一台Slave的主机名和密码,slave主机名应和Slave服务的--slave-name参数一致。

1
2
3
slave-1.asdasd.page:thequickbrownfoxjumpsoverthelazydog
slave-2.asdasd.page:icaneatglassitdoesnthurtme
# slavename:password

注意,密码文件的权限要交给web服务器,否则Slave会报错(Permission Denied)

1
2
sudo chown www-data:www-data /etc/smokeping/smokeping_secrets
sudo chmod 0600 /etc/smokeping/smokeping_secrets

配置文件的Slave板块如下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
*** Slaves ***
# Master密码文件位置
secrets=/etc/smokeping/smokeping_secrets

# 添加一台Slave,名称为slave主机名或IP
+ slave-1.asdasd.page
# Slave显示在图例中的名称
display_name = Slave-1
# 地理位置
location = Canada
# 显示在图像里的颜色,因为默认是白底图片,所以尽量用显眼的颜色。
color = ff6b9e

# 添加另一台Slave
+slave-2.asdasd.page
display_name = Slave-2
location = India
color = ff6600

Slave配置之后,就可以在Targets的主机里添加slaves参数,告诉SmokePing除了主机外,还要从这些指定的Slave获取到目的地的ping监测信息。
如果要为一个节点添加多个slave,用空格隔开多个slave地址。

1
2
3
4
5
++ XVideos_Server_1
menu = XVideos-Server-1
title = XVideos Server 1
host = xvideos.com
slaves = slave-1.asdasd.page slave-2.asdasd.page

重启Master服务后,再重启Slave服务

1
sudo systemctl restart smokeping


EOF

CATALOG
  1. 1. 介绍
  2. 2. 安装
    1. 2.1. APT安装
    2. 2.2. 编译安装
  3. 3. 配置
    1. 3.1. General
    2. 3.2. Database
    3. 3.3. Presentation
    4. 3.4. Probes
    5. 3.5. Alerts
    6. 3.6. Targets
    7. 3.7. Slaves
    8. 3.8. basepage.html
  4. 4. FcgiWrap与NGINX
  5. 5. 主从监控配置
    1. 5.1. Slave服务器
    2. 5.2. Master服务器