数据库是企业最核心的资产之一,但很多运维人员在部署Oracle时,为了方便远程维护或省去VPN配置,直接把监听器端口开放到公网。安全研究机构的扫描结果表明,暴露在公网的Oracle实例数量常年维持在数万个的规模,其中相当一部分运行着早已停止补丁支持的老版本。攻击者只需要简单的端口扫描加字典爆破,就有机会拿到DBA权限,进而拖库、篡改甚至勒索加密整个实例。本文将系统分析Oracle公网暴露的风险点和典型攻击路径,并给出一套可以落地的加固方案。

一、Oracle公网暴露会带来哪些实际风险
Oracle默认监听1521端口,TNS监听器是客户端与数据库之间的入口。一旦这个端口对公网开放,数据库就等于把大门直接摆在了互联网上。攻击者通过Shodan、FOFA等空间测绘引擎搜索port:1521,几秒钟就能拿到一份候选目标清单,接下来就是自动化攻击流程:先识别版本,再尝试默认账号和弱口令,最后利用已知漏洞拿权限。
具体的风险可以分为几类。第一类是弱口令和默认账号,Oracle历史上存在大量默认账户,例如SCOTT、OUTLN、 dbsnmp等,很多管理员建库后忘记锁定这些账号,或者给SYSTEM、SYS设置了简单密码。第二类是监听器自身的漏洞,老版本的TNS监听器存在拒绝服务、未授权控制等缺陷,攻击者甚至可以通过监听器命令直接注册外部服务。第三类是信息泄露,监听器的服务状态会暴露数据库版本、SID、操作系统平台等信息,为后续精准攻击提供了便利。第四类是勒索风险,近几年针对Oracle的勒索团伙非常活跃,一旦DBA账号失守,整个数据库文件可能被加密,业务直接停摆。
还有一个容易被忽视的风险是内部账号权限过大。很多应用直接用SYS或者SYSTEM连接数据库,应用侧一旦存在SQL注入漏洞,攻击者就能借助数据库管理员权限执行操作系统命令(例如通过DBMS_SCHEDULER结合外部脚本),从数据库层面攻破整台服务器,这就是典型的数据库到操作系统的横向渗透。
二、网络层隔离:最有效的第一道防线
防范公网暴露,最直接有效的手段不是在数据库本身上做文章,而是在网络层面彻底切断不必要的访问路径。原则很简单:数据库应该只被应用服务器访问,绝不应该对互联网开放。生产环境的标准架构是应用服务器与数据库处于同一内网或专用VPC,应用通过内网地址连接,运维人员则通过VPN或堡垒机进入内网后再操作数据库。
如果使用的是云环境,应该在安全组层面只放行应用服务器IP到1521端口的访问,其他来源一律拒绝。自建机房的可以用防火墙规则实现同样的效果,下面是一个Linux iptables的示例:
# 只允许应用服务器 10.0.1.20 访问Oracle监听端口,其余全部拒绝 iptables -A INPUT -p tcp --dport 1521 -s 10.0.1.20 -j ACCEPT iptables -A INPUT -p tcp --dport 1521 -j DROP # 保存规则使其重启后仍然生效 service iptables save
对于确实有外部访问需求的场景,例如合作伙伴需要抽取数据,推荐的做法不是开放数据库端口,而是通过以下方式替代:提供API接口由应用层转发、使用只读账号配合IP白名单、或者部署数据库网关做代理转发。这样即使代理层出问题,数据库本身依然不可直达。另外,监听器也可以配置有效的节点检查参数,在sqlnet.ora中限制允许连接的客户端:
# sqlnet.ora 中配置IP白名单 TCP.VALIDNODE_CHECKING = YES TCP.INVITED_NODES = (10.0.1.20, 10.0.1.21, db-server-internal)
配置后需要重启监听器才能生效。需要注意,INVITED_NODES必须包含监听器所在主机自身的名字或地址,否则本地连接也会被拒绝,这是很多DBA踩过的坑。
三、数据库与监听器层面的加固措施
网络隔离之后,还要假设攻击者已经进入了内网,在这个前提下继续加固数据库本身。第一步是清理账号体系。执行下面的查询,找出所有默认账户和处于开放状态的账号:
-- 查询所有已开通的账号
SELECT username, account_status, created
FROM dba_users
WHERE account_status LIKE 'OPEN';
-- 锁定不需要的默认账号
ALTER USER OUTLN ACCOUNT LOCK;
ALTER USER SCOTT ACCOUNT LOCK;
-- 检查是否有账号使用默认表空间但不属于业务账号
SELECT username, profile FROM dba_users WHERE username IN
('DBSNMP','APPQOSSYS','ORACLE_OCM','XS$NULL');第二步是强化密码策略。通过profile设置密码复杂度、有效期和失败锁定次数,配合内置的密码校验函数可以有效对抗暴力破解:
-- 创建安全profile CREATE PROFILE SECURE_PROFILE LIMIT FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LIFE_TIME 90 PASSWORD_REUSE_MAX 5 PASSWORD_REUSE_TIME 30 PASSWORD_LOCK_TIME 1/48; -- 应用到DBA账号 ALTER USER SYSTEM PROFILE SECURE_PROFILE; ALTER USER APP_USER PROFILE SECURE_PROFILE;
第三步是关闭监听器的信息泄露。默认情况下,执行lsnrctl status或恶意请求会返回版本、SID等敏感信息,可以通过监听器参数和sqlnet.ora关闭这些输出:
# listener.ora 中限制监听器管理命令的执行 ADMIN_RESTRICTIONS_LISTENER = ON # sqlnet.ora 中隐藏版本信息 # 该参数需要密码文件支持,可配合 local_listener 设置
同时要给监听器本身设置密码,防止攻击者远程执行lsnrctl管理命令注册恶意服务。第四步是开启审计,至少要对所有以SYSDBA身份登录的行为、DDL操作和失败登录进行记录,便于事后追溯:
-- 开启统一审计(12c及以上版本推荐) AUDIT unified; -- 审计所有DBA登录 CREATE AUDIT POLICY dba_login_audit ACTIONS LOGON; AUDIT POLICY dba_login_audit BY sys, system;
四、数据加密与持续监控
即使前面的措施都做到位,仍然要为最坏情况做准备。透明数据加密(TDE)可以在数据文件层面加密敏感表空间,即使攻击者拿到数据文件或磁盘,没有密钥也无法读取数据,这对勒索攻击和数据泄露都有显著的缓解作用:
-- 配置钱包路径(sqlnet.ora中设置ENCRYPTION_WALLET_LOCATION后执行) ADMINISTER KEY MANAGEMENT CREATE KEYSTORE 'C:\oracle\wallet' IDENTIFIED BY WalletPwd123; ADMINISTER KEY MANAGEMENT SET KEY IDENTIFIED BY WalletPwd123; -- 对敏感表启用列加密或对表空间启用加密 ALTER TABLE customer MODIFY (id_card ENCRYPT); CREATE TABLESPACE secure_ts DATAFILE 'secure_ts01.dbf' SIZE 1G ENCRYPTION USING 'AES256' DEFAULT STORAGE(ENCRYPT);
除了加密,还需要持续的监控手段。建议部署数据库审计设备或开启Oracle的Audit Vault,重点关注的告警事件包括:同一IP在短时间内的多次失败登录、非工作时间段的DBA登录、监听器异常重启、以及大批量数据导出操作(expdp导出日志应纳入监控)。这些行为组合出现时,往往意味着正在发生爆破或拖库。
最后要强调补丁管理。Oracle每个季度发布关键补丁更新(CPU),其中包含大量高危漏洞修复。很多被攻破的案例,追根溯源都是多年未打补丁的老版本。对于已经停止支持的版本(如11g之前的版本),应该制定升级计划,暂时无法升级的可以通过上述网络隔离手段把风险降到最低,但不能长期依赖这种临时方案。安全防护从来不是单点措施,网络隔离、账号加固、加密、审计和补丁这五层措施结合起来,才能真正降低Oracle数据库被攻陷的概率。