当前位置:首页 > 问答 > 正文

ORA-24244报错,远程连不上,ACL权限配置出问题了咋整?

ORA-24244报错,远程连不上,ACL权限配置出问题了咋整?

这个问题说白了,就是你的数据库(比如Oracle)想出去“串个门”,访问一下外面的网络服务(比如调用个外部API、发个邮件啥的),结果被保安(数据库的安全机制)给拦住了,说你没有“出门条”,这个“出门条”在Oracle里就叫ACL(访问控制列表)。

第一部分:这个错误到底是咋回事?

你别看ORA-24244这个错误代码挺吓人,它的核心意思很简单,根据Oracle官方文档的描述,这个错误通常发生在你尝试使用UTL_MAIL(发邮件)、UTL_HTTP(访问网页)、UTL_SMTP等这些需要连接网络的程序包时,数据库会检查你有没有权限去访问你指定的那个网络地址(比如一个IP地址或者一个网址)。

如果检查发现,你的用户没有被授予访问这个特定目标的权限,或者ACL的配置根本不存在、配置错了,它就会抛出这个ORA-24244错误,简单讲就是:“你想访问的那个地方,名单上没你名字,不准去!”

第二部分:为啥会出现这个问题?

这通常不是你的代码写错了,而是数据库的“安保系统”需要额外配置,主要原因有以下几个:

  1. 根本就没配ACL: 这是最常见的情况,在Oracle 11g及以后的版本里,安全加强了,默认情况下任何用户都不能随意访问网络,你必须显式地、手动地给用户授权,告诉他可以去哪里。
  2. ACL配置不完整或错了: 你可能配了ACL,但是配得不对。
    • 权限给错了: 你只给了“连接”的权限,但可能还需要“解析”权限。
    • 用户没加对: 你可能是用SCOTT用户执行的程序,但ACL里只授权给了HR用户。
    • 主机地址写错了: 你想访问的是“www.example.com”,但ACL里你写成了“example.com”或者IP地址不对。
    • 端口范围没覆盖: 你访问的服务用的是8080端口,但你的ACL只允许80端口。

第三部分:一步一步教你咋整(解决方案)

别慌,一步一步来排查和解决,整个过程就像是在给保安写一张详细的“出门条”。

第一步:确认问题

你得百分之百确定问题是出在ACL上,当你执行一个需要网络访问的程序(比如一个调用UTL_HTTP的程序)时,明确收到了ORA-24244的错误提示,这就对上了。

第二步:检查现有的ACL配置(看看有没有“出门条”)

在动手修改之前,先看看现在系统里已经有哪些ACL配置了,你需要以DBA权限的用户(比如SYS或SYSTEM)登录数据库,然后执行一些查询。

  • 查询所有ACL列表: 可以运行 SELECT * FROM DBA_NETWORK_ACLS; 这个语句,这会告诉你目前系统里已经创建了哪些ACL策略文件,以及它们对应哪个XML文件。
  • 查询具体的ACL权限分配详情: 更详细的是查询 SELECT * FROM DBA_NETWORK_ACL_PRIVILEGES; 这个视图,这里能看到每条ACL规则的具体信息:哪个用户(PRINCIPAL)被授予了什么样的权限(PRIVILEGE),是允许(IS_GRANT)还是拒绝,以及针对哪个主机(HOST)和端口范围。

通过查看这些信息,你可以判断是完全没有相关配置,还是现有的配置有错误。

第三步:创建或修改ACL配置(开始写“出门条”)

现在开始动手解决,我们需要使用Oracle提供的DBMS_NETWORK_ACL_ADMIN这个包来操作。

  • 情况A:如果完全没有配置,需要新建一个ACL。

    BEGIN
      DBMS_NETWORK_ACL_ADMIN.CREATE_ACL (
        acl          => 'your_acl_name.xml', -- 给你的ACL起个文件名,#39;utl_http_permissions.xml'
        description  => 'Permissions for UTL_HTTP access', -- 写个描述,说明这个ACL是干啥的
        principal    => 'YOUR_USERNAME', -- 填写那个需要连外网的用户名,#39;SCOTT'
        is_grant     => TRUE, -- 设置为TRUE,表示授予权限
        privilege    => 'connect', -- 最基本的网络连接权限,通常还需要'resolve'
        start_date   => NULL, -- 可以不设,表示立即生效
        end_date     => NULL  -- 可以不设,表示永久有效
      );
    END;
    /

    重要提示: 上面这个操作只是创建了一个ACL文件,并且只给了用户一个“connect”权限,通常我们还需要给他“resolve”权限(解析域名),并且指定他能访问哪些网站。

  • 情况B:为已有的ACL添加权限或修改权限。

    更常见的做法是使用ASSIGN_ACL过程,它既能创建新的ACL分配,也能覆盖已有的,这样更直接:

    BEGIN
      DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL (
        acl         => 'your_acl_name.xml', -- 如果这个文件不存在,它会自动创建
        host        => 'www.example.com', -- 允许访问的目标主机,可以是域名、IP地址,用'*'表示所有主机(危险!谨慎!)
        lower_port  => 80,   -- 允许访问的起始端口号(比如HTTP是80)
        upper_port  => 443   -- 允许访问的结束端口号(比如HTTPS是443),如果只访问一个端口,上下端口设成一样就行。
      );
    END;
    /

    在这之后,你还需要确保你的用户在这个ACL文件中拥有足够的权限,你可能需要额外再执行一次添加权限的操作,或者使用ADD_PRIVILEGE过程。

第四步:一个更稳妥、更完整的配置示例

假设我们要让用户SCOTT能够通过UTL_HTTP访问https://api.weixin.qq.com(端口443),一个相对完整的配置步骤是这样的:

  1. 创建ACL并分配主机和端口:

    BEGIN
      -- 分配ACL,指定主机和端口
      DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL (
        acl         => 'scott_http_api.xml',
        host        => 'api.weixin.qq.com',
        lower_port  => 443,
        upper_port  => 443
      );
    END;
    /
  2. (如果用户不在ACL内)授予用户权限:

    BEGIN
      -- 授予SCOTT用户connect和resolve权限
      DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE (
        acl        => 'scott_http_api.xml',
        principal  => 'SCOTT',
        is_grant   => TRUE,
        privilege  => 'connect'
      );
      DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE (
        acl        => 'scott_http_api.xml',
        principal  => 'SCOTT',
        is_grant   => TRUE,
        privilege  => 'resolve'
      );
    END;
    /

第五步:提交和测试

千万记住! 执行完以上的PL/SQL代码块后,一定要执行 COMMIT; 命令!因为ACL的配置是在一个事务里的,不提交就不会真正生效。

提交之后,最好退出当前会话,重新用你的业务用户(比如SCOTT)登录,然后再一次执行之前报错的网络访问操作,看看ORA-24244错误是否已经消失了。

处理ORA-24244就是一个“开权限”的过程,核心思路就是:以DBA身份,使用DBMS_NETWORK_ACL_ADMIN包,创建一个ACL规则文件,在这个文件里明确写明“谁”(用户)可以“在什么时间范围内”“以什么方式”(权限)去“哪里”(主机和端口),配置完后务必提交,并重新测试,只要每一步都做对了,这个让人头疼的报错就能解决。

ORA-24244报错,远程连不上,ACL权限配置出问题了咋整?