Apache Ranger系列十一:PrestoDB审计日志显示异常分析

发布时间 2023-04-06 14:23:37作者: 我爱吃胡萝卜

问题描述:如下图所示,Access Type显示出现异常

 

原因分析:

PrestoDB的日志输出调用逻辑

1 RangerBasedAccessControl.class

    enum HiveAccessType
    {
        NONE, CREATE, ALTER, DROP, INDEX, LOCK, SELECT, UPDATE, USE, ALL, ADMIN
    }    

private boolean checkAccess(ConnectorIdentity identity, SchemaTableName tableName, String column, HiveAccessType accessType)
    {
        return rangerAuthorizer.authorizeHiveResource(tableName.getSchemaName(), tableName.getTableName(), column,
                accessType.toString(), identity.getUser(), getGroupsForUser(identity.getUser()), getRolesForUser(identity.getUser()));
    }

2 RangerAuthorizer.class

plugin.setResultProcessor(new RangerDefaultAuditHandler());

public boolean authorizeHiveResource(String database, String table, String column, String accessType, String user, Set<String> userGroups, Set<String> userRoles)
{
    updateRangerPolicies();
    RangerAccessResourceImpl resource = new RangerAccessResourceImpl();
    if (!isNullOrEmpty(database)) {
        resource.setValue(KEY_DATABASE, database);
    }

    if (!isNullOrEmpty(table)) {
        resource.setValue(KEY_TABLE, table);
    }

    if (!isNullOrEmpty(column)) {
        resource.setValue(KEY_COLUMN, column);
    }

    RangerAccessRequest request = new RangerAccessRequestImpl(resource, accessType.toLowerCase(ENGLISH), user, userGroups, userRoles);

    RangerAccessResult result = plugin.isAccessAllowed(request);

    return result != null && result.getIsAllowed();
}

  

3 RangerBasePlugin.class

	public RangerAccessResult isAccessAllowed(RangerAccessRequest request) {
		return isAccessAllowed(request, resultProcessor);
	}

  

上面是PrestoDB的ranger审计日志的输出逻辑,问题就出在RangerDefaultAuditHandler处,两个变量赋值错误。

ret.setAction(request.getAccessType());
ret.setAccessType(request.getAction());

                        ret.setRepositoryName(result.getServiceName());
                        ret.setRepositoryType(result.getServiceType());
                        ret.setResourceType(resourceType);
                        ret.setResourcePath(resourcePath);
                        ret.setRequestData(request.getRequestData());
                        ret.setEventTime(request.getAccessTime() != null ? request.getAccessTime() : new Date());
                        ret.setUser(request.getUser());
                        ret.setAction(request.getAccessType());
                        ret.setAccessResult((short) (result.getIsAllowed() ? 1 : 0));
                        ret.setPolicyId(result.getPolicyId());
                        ret.setAccessType(request.getAction());
                        ret.setClientIP(request.getClientIPAddress());
                        ret.setClientType(request.getClientType());
                        ret.setSessionId(request.getSessionId());
                        ret.setAclEnforcer(moduleName); 

但在创建request的时候,RangerDefaultAuditHandler只set了access type

RangerDefaultAuditHandler.class

        RangerAccessRequest request = new RangerAccessRequestImpl(resource, accessType.toLowerCase(ENGLISH), user, userGroups, userRoles);

 RangerAccessRequestImpl.class

	public RangerAccessRequestImpl(RangerAccessResource resource, String accessType, String user, Set<String> userGroups, Set<String> userRoles) {
		setResource(resource);
		setAccessType(accessType);
		setUser(user);
		setUserGroups(userGroups);
		setUserRoles(userRoles);
		setForwardedAddresses(null);

		// set remaining fields to default value
		setAccessTime(null);
		setRemoteIPAddress(null);
		setClientType(null);
		setAction(null);
		setRequestData(null);
		setSessionId(null);
		setContext(null);
		setClusterName(null);
	}

  

对比Hive(正常)

Hive对上述两个异常的值重新设置

RangerHiveAuditHandler.class

                AuthzAuditEvent auditEvent = super.getAuthzEvents(result);

                auditEvent.setAccessType(accessType);
                auditEvent.setResourcePath(resourcePath);
                auditEvent.setResourceType("@" + resourceType); // to be consistent with earlier release

                String action = request.getAction();
                        if (hiveResource.getObjectType() == HiveObjectType.GLOBAL && isRoleOperation(action)) {
                                auditEvent.setAccessType(action);
                        }