【发布时间】:2014-06-05 20:16:20
【问题描述】:
如何构建递归查询以帮助我找到所有可通过 SSH 公钥授权访问的服务器到服务器跳转?
对于给定的 SSH 公钥指纹,首先找到该密钥被授权的服务器/帐户列表。对于找到的每个服务器,遍历该服务器上的私钥,并找到每个这些被授权的服务器/帐户的列表。
重复此过程,直到出现死胡同,即授权密钥路径结束。每行返回一个完整的授权密钥路径(作为一个数组)。
简化示例:
CREATE TABLE sshkeys (
server text, -- server UUID
username text, -- authorized username
privkey_owner text, -- owner of private key
fingerprint text, -- SSH key fingerprint
keytype text, -- "public" or "private"
)
Server Username Owner Fingerprint Keytype
banana root key_id_james public
banana james key_id_james public
banana root key_id_root@banana private
apple root key_id_root@banana public
apple fred fred key_id_fred private
mango fred key_id_fred public
James 使用他的 ID 为 key_id_james 的密钥可以访问 root@banana。从那里,root@banana 私钥被授权给 root@apple。在苹果上,root 可以访问 key_id_fred,因此获得了 fred@mango 的授权。
所以最终,詹姆斯可以通过香蕉和苹果的根访问权限访问 Fred 在芒果上的帐户。他还可以访问 james@banana。两个输出行将由 {source, keyid, target} 元素的数组组成,看起来像:
{{NULL, key_id_james, root@banana},
{banana, key_id_root@banana, root@apple},
{apple, key_id_fred, fred@mango}},
{{NULL, key_id_james, james@banana}}
我计划添加应考虑的限制和启发式方法,包括私钥是否加密以及给定用户是否对另一个用户的私钥具有组或 chmod 访问权限(通过加入数据库中的其他表)。不过,这应该很容易添加到一个有效的基础查询中。
至于查询,我无法弄清楚如何进行第二步,即:对于最初发现可以通过给定密钥访问的每个服务器,遍历每个服务器上的所有私钥并递归。我没有比这个无效的查询更进一步:
WITH RECURSIVE initial_authkeys AS (
SELECT
server, username, privkey_owner, fingerprint, keytype
FROM
sshkeys
WHERE
fingerprint = 'key_id_james' AND
keytype = 'public'
UNION ALL
SELECT
ak.server, ak.username, ak.privkey_owner, ak.fingerprint, ak.keytype
FROM
sshkeys,
initial_authkeys ak
WHERE
sshkeys.fingerprint = ak.fingerprint AND
sshkeys.keytype = 'private'
)
SELECT * FROM initial_authkeys;
有什么建议吗?
【问题讨论】:
标签: postgresql recursion common-table-expression recursive-query