1903 行是在打印 Last Check 的数据;
1904 行是在打印 Duration 的数据;
1905 行是在打印 Attempt 的数据;
1906~1907 行是在打印 Status Information 的数据;
我们需要注意的是1907行:为什么我们的插件输出被 html_encode 了?这个函数究竟做了什么?
(3)在 include/cgiutils.h 中找到 html_encode 函数:
454 char *html_encode(char *, int); /* encodes a string in HTML format (for what the user sees) */
(4)在 cgi/cgiutils.c 中找到 html_encode 的实现:
961 /* escapes a string used in HTML */
962 char * html_encode(char *input, int escape_newlines) {
...
977 /* end of string */
978 if((char)input[x] == (char)'\x0') {
979 encoded_html_string[y] = '\x0';
980 break;
981 }
...
983 /* alpha-numeric characters and spaces don't get encoded */
...
987 /* newlines turn to <BR> tags */
...
1026 /* for simplicity, all other chars represented by their numeric value */
简单看一下干了什么:初始化原字符串和目标字符串,983行过滤掉数字和空格,987行把 \n 转移成 <br>,然后,在1026行,我们终于看到那句让人喷血的话了:for simplicity, all other chars represented by their numeric value.
【解决方法】
(1)修改 nagios 配置文件 nagios-x.y.z/etc/cgi.cfg:
- escape_html_tags=1
+ escape_html_tags=0
(2)确保web容器支持UTF-8(以apache为例),修改配置文件 /etc/apache2/conf.d/charset:
+ AddDefaultCharset UTF-8
重启 nagios 和 apache 即可。
【原因】
(1)首先,问题肯定不在插件上,因为在shell下运行我们的插件是没有问题的,所以初步定位在nagios本身的BUG;
(2)cgi名字是status.cgi,在对应的status.c里面找到展示services的部分(nagios 3.4.3):
1903 行是在打印 Last Check 的数据;
1904 行是在打印 Duration 的数据;
1905 行是在打印 Attempt 的数据;
1906~1907 行是在打印 Status Information 的数据;
我们需要注意的是1907行:为什么我们的插件输出被 html_encode 了?这个函数究竟做了什么?
(3)在 include/cgiutils.h 中找到 html_encode 函数:
(4)在 cgi/cgiutils.c 中找到 html_encode 的实现:
简单看一下干了什么:初始化原字符串和目标字符串,983行过滤掉数字和空格,987行把 \n 转移成 <br>,然后,在1026行,我们终于看到那句让人喷血的话了:for simplicity, all other chars represented by their numeric value.
【几种解决办法】
大概思路我们已经有了,这是nagios的一个BUG,没有考虑到脚本输出是utf8的情况,从而捕获输出后进行了两次utf8转义,所以才会出现乱码,修改的方法就无非是这么几个了:
(1)修改配置,就是最上方的解决方法了;
(2)在源代码中干掉 html_encode 对捕获输出的转义,简单粗暴,本质上和(1)是一样的;
(3)如果我们真的需要对输出进行转义怎么办?那就自己 hack 一个 html_encode 函数,可以参考icinga的html_encode实现:
https://github.com/dnsmichi/icinga/bl...
注释写得很详尽,不多说。
(4)sourceforge上有一个nagios-3.2.3的中文版,里面是这样hack html_encode()的: