上一篇【第48篇】Oracle 11g在Windows下的安装与配置
下一篇【第50篇】Oracle DBA日常工作与故障处理手册
摘要
数据库安全是Oracle DBA工作中不容忽视的重要职责。默认安装的Oracle数据库存在多种安全风险:默认账户未锁定、系统权限过度授予、审计未开启等。本文系统讲解Oracle数据库安全加固的核心内容:账户安全管理、权限最小化原则、网络访问控制、审计策略配置、数据加密,以及Oracle数据库安全基线检查的实战方法,帮助DBA建立完整的数据库安全防护体系。
一、账户安全管理
1.1 默认账户处理
Oracle安装后存在大量预置账户,其中许多有已知默认密码,是安全隐患的重灾区。
-- 查看所有账户状态SELECTusername,account_status,last_login,created,DECODE(account_status,'OPEN','⚠️ 需关注','LOCKED','✓ 已锁定','其他')noteFROMdba_usersORDERBYaccount_status,username;-- 查找所有OPEN状态的非业务账户SELECTusername,account_status,default_tablespaceFROMdba_usersWHEREaccount_status='OPEN'ANDusernameNOTIN('SYS','SYSTEM','你的业务账户')ORDERBYusername;高风险默认账户(安装后立即处理):
| 账户 | 默认密码 | 处置建议 |
|---|---|---|
| SCOTT | tiger | 锁定并过期(若无业务使用) |
| HR | hr | 锁定并过期 |
| OE | oe | 锁定并过期 |
| SH | sh | 锁定并过期 |
| DBSNMP | dbsnmp | 若不用EM则锁定;否则修改密码 |
| OUTLN | outln | 锁定 |
| MDSYS | mdsys | 锁定 |
| XDB | change_on_install | 锁定 |
-- 批量锁定不需要的示例账户BEGINFORuIN(SELECTusernameFROMdba_usersWHEREusernameIN('SCOTT','HR','OE','PM','SH','IX','BI')ANDaccount_status='OPEN')LOOPEXECUTEIMMEDIATE'ALTER USER '||u.username||' ACCOUNT LOCK PASSWORD EXPIRE';DBMS_OUTPUT.PUT_LINE('已锁定:'||u.username);ENDLOOP;END;/1.2 密码策略强化
-- 创建严格的密码策略函数-- 要求:最少8位、包含大小写+数字+特殊字符、不含用户名CREATEORREPLACEFUNCTIONverify_password(username VARCHAR2,password VARCHAR2,old_password VARCHAR2)RETURNBOOLEANISv_count NUMBER;BEGIN-- 最短长度检查(8位)IFLENGTH(password)<8THENraise_application_error(-20001,'密码长度不能少于8位');ENDIF;-- 不能包含用户名IFINSTR(UPPER(password),UPPER(username))>0THENraise_application_error(-20002,'密码不能包含用户名');ENDIF;-- 至少包含一个大写字母IFREGEXP_INSTR(password,'[A-Z]')=0THENraise_application_error(-20003,'密码必须包含至少一个大写字母');ENDIF;-- 至少包含一个小写字母IFREGEXP_INSTR(password,'[a-z]')=0THENraise_application_error(-20004,'密码必须包含至少一个小写字母');ENDIF;-- 至少包含一个数字IFREGEXP_INSTR(password,'[0-9]')=0THENraise_application_error(-20005,'密码必须包含至少一个数字');ENDIF;-- 与旧密码不同IFpassword=old_passwordTHENraise_application_error(-20006,'新密码不能与旧密码相同');ENDIF;RETURNTRUE;END;/-- 创建生产级PROFILECREATEPROFILE prod_profileLIMITFAILED_LOGIN_ATTEMPTS5-- 失败5次后锁定PASSWORD_LOCK_TIME1/24-- 锁定1小时(1天/24)PASSWORD_LIFE_TIME90-- 密码有效期90天PASSWORD_REUSE_TIME365-- 365天内不能复用旧密码PASSWORD_REUSE_MAX UNLIMITED PASSWORD_VERIFY_FUNCTION verify_password SESSIONS_PER_USER10-- 每用户最多10个并发会话CONNECT_TIME480-- 最大连接时间480分钟IDLE_TIME60;-- 空闲60分钟自动断开-- 将PROFILE应用到用户ALTERUSERscott PROFILE prod_profile;-- 对所有普通用户应用UPDATEdba_usersSETprofile='PROD_PROFILE'WHEREusernameNOTIN('SYS','SYSTEM');1.3 SYS和SYSTEM账户安全
-- 修改SYS密码(强密码)ALTERUSERsys IDENTIFIEDBY"StR0ng@Password2024";-- 修改SYSTEM密码ALTERUSERsystem IDENTIFIEDBY"StR0ng@Password2024";-- 限制SYSTEM账户权限(SYSTEM账户不应以SYSDBA连接)-- 检查:SYSTEM不应有SYSDBA权限SELECT*FROMv$pwfile_users;-- 理想状态:只有SYS在密码文件中有SYSDBA权限-- 禁用REMOTE_OS_AUTHENT(防止OS认证绕过)ALTERSYSTEMSETremote_os_authent=FALSESCOPE=SPFILE;二、权限最小化
2.1 权限审计
-- 查找拥有DBA角色的非DBA账户(高危)SELECTgranteeFROMdba_role_privsWHEREgranted_role='DBA'ANDgranteeNOTIN('SYS','SYSTEM')ORDERBYgrantee;-- 查找有SYSDBA权限的账户SELECT*FROMv$pwfile_users;-- 查找拥有ANY系统权限的账户(高危)SELECTgrantee,privilegeFROMdba_sys_privsWHEREprivilegeLIKE'%ANY%'ANDgranteeNOTIN('SYS','SYSTEM','DBA','IMP_FULL_DATABASE','EXP_FULL_DATABASE')ORDERBYgrantee,privilege;-- 查找直接赋予的对象权限SELECTgrantee,owner,table_name,privilegeFROMdba_tab_privsWHEREgranteeNOTIN(SELECTroleFROMdba_roles)ANDgranteeNOTIN('SYS','SYSTEM')ORDERBYgrantee;2.2 收回危险权限
-- 收回PUBLIC的execute权限(常见高危包)REVOKEEXECUTEONutl_fileFROMPUBLIC;REVOKEEXECUTEONutl_httpFROMPUBLIC;REVOKEEXECUTEONutl_tcpFROMPUBLIC;REVOKEEXECUTEONutl_smtpFROMPUBLIC;REVOKEEXECUTEONdbms_randomFROMPUBLIC;-- 查看PUBLIC的所有权限(需要择机评估)SELECTDISTINCTprivilege,object_type,owner||'.'||object_name objFROMdba_tab_privsWHEREgrantee='PUBLIC'ANDprivilege='EXECUTE'ANDobject_type='PACKAGE'ORDERBYobj;-- 收回危险系统权限REVOKECREATELIBRARYFROMapp_user;REVOKEALTERSYSTEMFROMapp_user;REVOKEBECOMEUSERFROMapp_user;2.3 应用账户权限设计原则
-- 应用账户设计模板(最小权限原则)-- 1. 创建Schema Owner(对象归属)CREATEUSERapp_owner IDENTIFIEDBY"App0wner@2024"DEFAULTTABLESPACEapp_data QUOTA UNLIMITEDONapp_data;-- Schema Owner只需要必要的创建权限GRANTCREATETABLE,CREATEVIEW,CREATESEQUENCE,CREATEPROCEDURE,CREATETRIGGER,CREATEINDEXTOapp_owner;-- 2. 创建应用运行账户(只有DML权限)CREATEUSERapp_runtime IDENTIFIEDBY"AppRun@2024"DEFAULTTABLESPACEapp_data QUOTA0ONapp_data;-- 运行账户不需要创建对象-- 只授予业务所需的权限(通过角色)CREATEROLE app_role;GRANTSELECT,INSERT,UPDATE,DELETEONapp_owner.ordersTOapp_role;GRANTSELECT,INSERTONapp_owner.order_itemsTOapp_role;GRANTEXECUTEONapp_owner.process_orderTOapp_role;GRANTapp_roleTOapp_runtime;三、网络安全
3.1 限制登录来源(Valid Node Checking)
# 编辑$ORACLE_HOME/network/admin/sqlnet.ora# 添加有效节点检查配置cat>>$ORACLE_HOME/network/admin/sqlnet.ora<<'EOF' # 只允许特定IP连接 TCP.VALIDNODE_CHECKING = YES TCP.INVITED_NODES = (192.168.1.100, 192.168.1.101, 10.0.0.0/8) # TCP.EXCLUDED_NODES = (192.168.1.200) # 也可以用黑名单 EOF3.2 加密网络传输(Oracle Native Encryption)
# 在sqlnet.ora中配置加密cat>>$ORACLE_HOME/network/admin/sqlnet.ora<<'EOF' # 启用网络加密 SQLNET.ENCRYPTION_SERVER = REQUIRED SQLNET.ENCRYPTION_TYPES_SERVER = (AES256, AES192, AES128, 3DES168) # 数据完整性验证 SQLNET.CRYPTO_CHECKSUM_SERVER = REQUIRED SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER = (SHA256) EOF3.3 监听器安全
# 设置监听器密码(防止未授权管理操作)lsnrctl LSNRCTL>change_password# 设置管理密码LSNRCTL>setpassword LSNRCTL>save_config# 保存配置# 在listener.ora中添加(禁止未授权的lsnrctl操作)# ADMIN_RESTRICTIONS_LISTENER = ON # 严格模式-- 关闭监听器中的外部过程支持(若不需要)-- 在listener.ora中删除或注释extproc相关条目-- 检查远程监听器管理(应该关闭)ALTERSYSTEMSETlocal_listener='(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))';四、审计配置
4.1 标准审计
Oracle的审计功能记录谁在什么时间做了什么操作。
-- 查看当前审计配置SHOWPARAMETER audit_trail;SHOWPARAMETER audit_sys_operations;-- 启用数据库审计(写入数据库表,需重启)ALTERSYSTEMSETaudit_trail=DB SCOPE=SPFILE;-- DB:审计记录写入AUD$表-- DB,EXTENDED:同上,并包含SQL全文-- OS:写入OS文件(安全性更高,防止DBA篡改)-- XML:XML格式写入文件-- 审计SYS操作(关键!)ALTERSYSTEMSETaudit_sys_operations=TRUESCOPE=SPFILE;重启后配置审计规则:
-- 审计登录/登出AUDITCREATESESSION;AUDITCREATESESSIONWHENEVERNOTSUCCESSFUL;-- 失败登录必须审计-- 审计高危DDL操作AUDITCREATETABLE,DROPTABLE,TRUNCATETABLE;AUDITCREATEUSER,DROPUSER,ALTERUSER;AUDITGRANT,REVOKE;AUDITCREATEROLE,DROPROLE;-- 审计高危系统操作AUDIT EXPORTFULLDATABASE;AUDITIMPORTFULLDATABASE;AUDITALTERDATABASE;AUDITALTERSYSTEM;-- 审计特定用户的所有操作AUDITALLBYscott;-- 审计特定对象的访问AUDITSELECTONhr.employeesBYACCESS;-- 每次访问记录一次AUDITINSERT,UPDATE,DELETEONhr.salaryBYACCESS;-- 查看已配置的审计策略SELECTaudit_option,success,failureFROMdba_stmt_audit_optsORDERBY1;SELECTobject_name,object_type,alt,aud,com,del,gra,ind,ins,lck,ren,sel,updFROMdba_obj_audit_opts;4.2 精细访问审计(FGA)
FGA(Fine-Grained Auditing)提供基于条件的精细审计。
-- 对高薪员工数据的查询进行审计BEGINdbms_fga.add_policy(object_schema=>'HR',object_name=>'EMPLOYEES',policy_name=>'AUDIT_HIGH_SAL',audit_condition=>'SALARY > 10000',-- 只审计高薪记录的访问audit_column=>'SALARY',-- 只有访问SALARY列时触发statement_types=>'SELECT',audit_trail=>dbms_fga.db+dbms_fga.extended);END;/-- 查看FGA审计记录SELECTdb_user,object_name,sql_text,timestampFROMdba_fga_audit_trailWHEREobject_name='EMPLOYEES'ORDERBYtimestampDESC;4.3 审计记录管理
-- 定期清理旧审计记录(保留90天)DELETEFROMsys.aud$WHEREntimestamp# < SYSTIMESTAMP - INTERVAL '90' DAY;COMMIT;-- 将审计记录导出归档-- 建议创建单独的审计表空间CREATETABLESPACEaudit_ts DATAFILE'/u01/app/oracle/oradata/ORCL/audit01.dbf'SIZE5G AUTOEXTENDONNEXT500M MAXSIZE50G;-- 将AUD$迁移到审计表空间ALTERTABLEsys.aud$ MOVETABLESPACEaudit_ts;ALTERINDEXsys.i_aud1 REBUILDTABLESPACEaudit_ts;五、安全基线检查
5.1 Oracle安全基线检查脚本
-- ===== Oracle安全基线检查报告 =====-- 运行此脚本可快速识别常见安全风险-- 检查1:是否有无限制的会话数SELECT'OPEN账户数'check_item,COUNT(*)||'个OPEN账户'result,CASEWHENCOUNT(*)>10THEN'⚠️ 请检查多余账户'ELSE'✓ 正常'ENDstatusFROMdba_usersWHEREaccount_status='OPEN'UNIONALL-- 检查2:DBA角色分配SELECT'DBA角色数量',COUNT(*)||'个用户拥有DBA角色',CASEWHENCOUNT(*)>3THEN'⚠️ DBA权限过多分配'ELSE'✓ 正常'ENDFROMdba_role_privsWHEREgranted_role='DBA'ANDgranteeNOTIN('SYS','SYSTEM')UNIONALL-- 检查3:审计是否开启SELECT'数据库审计',value,CASEWHENvalue='NONE'THEN'❌ 审计未开启'ELSE'✓ 审计已启用'ENDFROMv$parameterWHEREname='audit_trail'UNIONALL-- 检查4:SYS操作审计SELECT'SYS操作审计',value,CASEWHENvalue='FALSE'THEN'❌ SYS操作未审计'ELSE'✓ 已启用'ENDFROMv$parameterWHEREname='audit_sys_operations'UNIONALL-- 检查5:远程OS认证SELECT'远程OS认证',value,CASEWHENvalue='TRUE'THEN'❌ 存在安全风险'ELSE'✓ 已关闭'ENDFROMv$parameterWHEREname='remote_os_authent';5.2 安全检查清单
| 检查项 | 安全要求 | 检查命令 |
|---|---|---|
| 默认账户 | 全部锁定或修改密码 | SELECT username, account_status FROM dba_users |
| DBA权限 | 最少化 | SELECT grantee FROM dba_role_privs WHERE granted_role='DBA' |
| 审计策略 | 必须开启 | SHOW PARAMETER audit_trail |
| SYS审计 | 必须开启 | SHOW PARAMETER audit_sys_operations |
| 网络加密 | 生产环境启用 | 检查sqlnet.ora |
| 密码策略 | 强密码PROFILE | SELECT profile FROM dba_users WHERE username='SYS' |
| UTL包权限 | 从PUBLIC撤销 | SELECT * FROM dba_tab_privs WHERE grantee='PUBLIC' AND privilege='EXECUTE' |
| 监听器安全 | 设置密码 | 检查listener.ora |
| REMOTE_OS_AUTHENT | FALSE | SHOW PARAMETER remote_os_authent |
| O7_DICTIONARY_ACCESS | FALSE | SHOW PARAMETER o7_dictionary_accessibility |
六、数据加密(TDE)
Oracle 11g提供透明数据加密(TDE),对列或表空间进行透明加密。
-- 配置加密钱包(Wallet)-- 1. 在sqlnet.ora中指定钱包位置-- ENCRYPTION_WALLET_LOCATION=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=/etc/oracle/wallet/)))-- 2. 创建钱包ADMINISTERKEYMANAGEMENTCREATEKEYSTORE'/etc/oracle/wallet'IDENTIFIEDBY"WalletPass2024";-- 3. 设置主加密密钥ADMINISTERKEYMANAGEMENTSETKEYSTOREOPENIDENTIFIEDBY"WalletPass2024";ADMINISTERKEYMANAGEMENTSETKEYIDENTIFIEDBY"WalletPass2024"WITHBACKUP;-- 4. 对列加密ALTERTABLEhr.employeesMODIFY(salary ENCRYPTUSING'AES256');-- 5. 对表空间加密(11g R2新功能)CREATETABLESPACEencrypted_ts DATAFILE'/u01/oradata/ORCL/enc01.dbf'SIZE1G ENCRYPTIONUSING'AES256'DEFAULTSTORAGE(ENCRYPT);七、总结
Oracle数据库安全加固是一项系统工程,需要从多个层次构建防护:
应用层:绑定变量、输入验证 ───────────────────────────── 权限层:最小权限、角色管理 ───────────────────────────── 账户层:密码策略、账户锁定 ───────────────────────────── 审计层:登录审计、操作审计、FGA ───────────────────────────── 网络层:有效节点检查、传输加密 ───────────────────────────── 数据层:TDE列加密、表空间加密安全加固优先级:
- P0(立即处理):修改SYS/SYSTEM默认密码、锁定不用的示例账户、开启审计
- P1(本周处理):部署密码PROFILE、收回PUBLIC危险权限、关闭remote_os_authent
- P2(计划中):实施网络加密、细化审计策略、评估TDE加密需求
安全加固不是一次性工作,需要定期执行安全基线检查,及时应用Oracle安全补丁(CPU/PSU),才能持续保障数据库安全。
上一篇【第48篇】Oracle 11g在Windows下的安装与配置
下一篇【第50篇】Oracle DBA日常工作与故障处理手册
参考资料
- Oracle Database Security Guide 11g Release 2
- Oracle Database Vault Administrator’s Guide
- Oracle Label Security Administrator’s Guide
- CIS Oracle Database 11g Benchmark(安全基线配置参考)
- Oracle CPU(Critical Patch Updates)官方安全补丁