zoco

Zabbix怎么搞一个永不过期的session

2017-01-19


zabbix的session会隔一段时间就不可用了,查一下原因

zabbix的session什么时候过期?

看zabbix的数据库,session相关的表有两个:

mysql> desc users;
+----------------+---------------------+------+-----+---------+-------+
| Field          | Type                | Null | Key | Default | Extra |
+----------------+---------------------+------+-----+---------+-------+
| userid         | bigint(20) unsigned | NO   | PRI | NULL    |       |
| alias          | varchar(100)        | NO   | MUL |         |       |
| name           | varchar(100)        | NO   |     |         |       |
| surname        | varchar(100)        | NO   |     |         |       |
| passwd         | char(32)            | NO   |     |         |       |
| url            | varchar(255)        | NO   |     |         |       |
| autologin      | int(11)             | NO   |     | 0       |       |
| autologout     | int(11)             | NO   |     | 900     |       |
| lang           | varchar(5)          | NO   |     | en_GB   |       |
| refresh        | int(11)             | NO   |     | 30      |       |
| type           | int(11)             | NO   |     | 0       |       |
| theme          | varchar(128)        | NO   |     | default |       |
| attempt_failed | int(11)             | NO   |     | 0       |       |
| attempt_ip     | varchar(39)         | NO   |     |         |       |
| attempt_clock  | int(11)             | NO   |     | 0       |       |
| rows_per_page  | int(11)             | NO   |     | 50      |       |
+----------------+---------------------+------+-----+---------+-------+
mysql> desc sessions;
+------------+---------------------+------+-----+---------+-------+
| Field      | Type                | Null | Key | Default | Extra |
+------------+---------------------+------+-----+---------+-------+
| sessionid  | varchar(32)         | NO   | PRI |         |       |
| userid     | bigint(20) unsigned | NO   | MUL | NULL    |       |
| lastaccess | int(11)             | NO   |     | 0       |       |
| status     | int(11)             | NO   |     | 0       |       |
+------------+---------------------+------+-----+---------+-------+

登录时验证sql为

$userInfo = DBfetch(DBselect(
	'SELECT u.userid,u.autologout,s.lastaccess'.
	' FROM sessions s,users u'.
	' WHERE s.sessionid='.zbx_dbstr($sessionid).
		' AND s.status='.ZBX_SESSION_ACTIVE.
		' AND s.userid=u.userid'.
		' AND (s.lastaccess+u.autologout>'.$time.' OR u.autologout=0)'
));

sessions中的lastaccess为上一次登录的时间,status有两个值

define('ZBX_SESSION_ACTIVE',	0);
define('ZBX_SESSION_PASSIVE',	1);

passive是每次logout的时候把status置为passive,然后下一次删除。

所以session并没有一个过期的标志,那么session为什么会过期?

那肯定是有定时任务喽。

搜索代码delete from session,出现下面的

rc = DBexecute("delete from sessions where lastaccess<%d", now - SEC_PER_DAY * hk_config.sessions);

这个会把小于now - SEC_PER_DAY * hk_config.sessions的都干掉,顾名思义,now就是现在的时间,SEC_PER_DAY是一天多少秒,那么看看hk_config.sessions是多少就行了。

搜索代码hk.sessions,出现下面的

config->config->hk.sessions = 365;

会自动删除一年未登录的session

zabbix常规登陆验证流程:

分析./include/classes/user/CWebUser.php中的login和logout可以了解到zabbix的常规验证流程。 主要逻辑如下:

login

logout

API验证流程

包括api_jsonrpc.php的几乎每一个zabbix的展示页面或者api的php代码都会在开头包含一个config.inc.php,且并无其他验证相关代码存在,config.inc.php中只有一行主要代码Z::getInstance()->run(),追踪到这个run函数里,就能找到疑似的验证流程入口$this->authenticateUser()。 该函数位于 ./include/classes/core/ZBase.php 中。

checkAuthentication

ZBase.php中的函数,是对./include/classes/user/CWebUser.php中同名函数的封装,CWebUser.php中的checkAuthentication又是对zabbix API即./include/classes/api/services/CUser.php中的同名函数的封装。

具体流程如下:

分析得出结论,如果要实现在任何环境下的一次URL跳转都能成功以管理员的权限进入zabbix,关键在于以上流程的第2步,不能以访客模式进入zabbix,即需要让sessionId不为空且可用,自然得出的办法就是,提前保存好一个可用的sessionId到cookie中。

多番测试后,证实了以上方案是可行的,于是,实施方案如下:

手动在zabbix增加一个session记录,每次直接请求URL的时候,先调用一个自定义php,存入这个session的id,再继续访问,bingo!