Oracle数据库的网络访问默认通过Oracle Net的TCP协议完成,如果没有额外安全配置,客户端与服务端交互的数据包可以被抓包工具直接解析,涉及敏感查询时风险很高。要解决传输安全问题,通常会在原生网络加密和SSL/TLS证书加密之间做选择或组合。前者只对数据加密,后者还能验证端点身份,尤其适合跨机房或云上部署的场景。本文将按照从原理到落地的顺序,说明如何用orapki工具创建Wallet、生成证书,并调整监听器、客户端和服务端参数,最终将连接切换为TCPS。

一、Oracle网络加密机制与SSL/TLS的关系
Oracle Net在10g以后就内置了原生网络加密能力,通过sqlnet.ora中的SQLNET.ENCRYPTION_SERVER和SQLNET.ENCRYPTION_CLIENT参数控制。服务端和客户端协商一个共同支持的加密算法,例如AES256或3DES168,协商成功后后续数据包会以加密形式传输。这套机制的优点是无需证书和Wallet,配置成本极低,只需要在文本文件中增加几行参数并重启监听即可。但它有一个明显短板:不提供身份认证。攻击者如果能够劫持网络路径,仍然可能通过中间人方式介入连接,因为双方并没有交换可验证身份的数字证书。
SSL/TLS方案则建立在X.509证书体系之上。Oracle通过Wallet保存私钥、证书和可信CA列表,监听器使用Wallet中的服务器证书完成TLS握手。握手过程中客户端可以验证服务器证书是否由受信任的CA签发,服务器也可以选择验证客户端证书。相比原生加密,SSL不仅保护数据机密性,还提供完整性校验和端点身份认证,能够有效防范中间人攻击。两个机制也可以同时启用,但通常生产环境会优先落地SSL证书加密,原生加密作为备用或内部兼容方案。
SQLNET.ENCRYPTION_SERVER = REQUIRED SQLNET.ENCRYPTION_TYPES_SERVER = (AES256) SQLNET.ENCRYPTION_CLIENT = REQUIRED SQLNET.ENCRYPTION_TYPES_CLIENT = (AES256)
二、使用orapki创建Wallet并生成服务器证书
Wallet是Oracle存储证书、私钥和信任列表的目录结构。可以使用orapki工具或Oracle Wallet Manager来管理。下面以Linux环境为例,先创建自动登录Wallet。自动登录Wallet在数据库和监听启动时不需要人工输入密码,适合服务器端使用;但意味着拿到Wallet文件就能读取私钥,所以必须严格限制目录权限。更安全的做法是使用带密码的Wallet,并在启动或配置时提供密码。
执行命令前先确认ORACLE_HOME和PATH变量,orapki通常位于$ORACLE_HOME/bin目录。创建Wallet目录后,生成自签名证书时需要注意DN字段中的CN应当与客户端连接时使用的主机名或服务名匹配,否则后续可能触发证书主机名校验失败。如果是正式环境,建议由企业内部CA或公共CA签发证书,并将根证书导入到客户端Wallet。
mkdir -p /u01/app/oracle/wallet orapki wallet create -wallet /u01/app/oracle/wallet -pwd WalletPass123 -auto_login orapki wallet add_certificate -wallet /u01/app/oracle/wallet -self_signed -dn "CN=oracledb01.ipipp.com" -keysize 2048 -validity 730 orapki wallet display -wallet /u01/app/oracle/wallet
如果使用CA签发证书,流程会多几步:先用orapki wallet add_certificate生成证书请求,导出请求文件交给CA签名,然后将CA根证书和签名后的用户证书导入Wallet。命令如下:
orapki wallet add_certificate -wallet /u01/app/oracle/wallet -dn "CN=oracledb01.ipipp.com" -keysize 2048 -validity 730 orapki wallet export -wallet /u01/app/oracle/wallet -dn "CN=oracledb01.ipipp.com" -request /tmp/server.csr # CA签发后得到 server.crt 和 ca.crt,再导入 orapki wallet add_certificate -wallet /u01/app/oracle/wallet -trusted_cert -cert /tmp/ca.crt orapki wallet add_certificate -wallet /u01/app/oracle/wallet -user_cert -cert /tmp/server.crt
三、服务端sqlnet.ora与listener.ora的SSL参数配置
证书和Wallet准备好之后,需要让Oracle Net在建立连接时实际使用它们。服务端的关键配置位于$ORACLE_HOME/network/admin/sqlnet.ora,需要指定Wallet路径以及SSL相关行为。其中SQLNET.WALLET_OVERRIDE表示监听器使用这里指定的Wallet覆盖默认位置;SSL_CLIENT_AUTHENTICATION决定是否强制客户端出示证书。当该值为FALSE时,只验证服务器证书,客户端可以不配置证书,适合大多数单边SSL场景;如果设为TRUE,客户端必须提供有效证书,适用于双向认证。
另一个容易忽略的参数是SSL_SERVER_DN_MATCH,它影响客户端对服务器证书DN的校验。如果客户端配置了该参数为TRUE,服务器证书中的DN必须与连接串中的主机名一致,否则会报ORA-29024。建议在受控环境中开启,以增强防伪造能力。加密套件可以通过SSL_CIPHER_SUITES限制,推荐只保留TLS1.2以上的强加密套件,避免使用已被标记为弱算法的RC4或3DES。
SQLNET.WALLET_OVERRIDE = TRUE SSL_CLIENT_AUTHENTICATION = FALSE SSL_SERVER_DN_MATCH = TRUE SSL_CIPHER_SUITES = (SSL_ECDHE_RSA_WITH_AES_256_GCM_SHA384)
监听器配置文件listener.ora需要新增一个TCPS协议的监听端点。通常保留原有TCP端口以兼容内部连接,同时增加2484端口的SSL监听。Wallet位置在监听器级别也需要声明,否则监听器无法读取服务器证书。示例如下:
WALLET_LOCATION =
(SOURCE =
(METHOD = FILE)
(METHOD_DATA =
(DIRECTORY = /u01/app/oracle/wallet)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
)
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCPS)(HOST = 0.0.0.0)(PORT = 2484))
)
)
ADR_BASE_LISTENER = /u01/app/oracle
保存后执行lsnrctl stop和lsnrctl start重启监听,再使用lsnrctl status确认已经出现TCPS端口且状态为READY。如果监听启动失败,优先检查Wallet目录权限,Oracle用户需要对该目录具有读写权限,通常设置为700。
四、客户端Wallet配置与TCPS连接验证
客户端要连接启用SSL的Oracle数据库,不能直接修改原来的TCP连接串,需要把协议改为TCPS,并在连接描述中指定2484端口。如果服务端SSL_CLIENT_AUTHENTICATION为FALSE,客户端可以不提供自己的证书,但仍然需要验证服务器证书。Oracle客户端通过本地Wallet中的可信根证书来完成这一验证,因此客户端也需要创建Wallet并导入服务端证书链的根证书。
客户端sqlnet.ora中同样需要设置Wallet位置,并可以设置SSL_SERVER_DN_MATCH为TRUE或FALSE。如果证书是自签名且主机名与证书DN不完全一致,测试阶段可以临时设为FALSE,但生产建议导入与证书CN匹配的DNS解析,或者使用通配符证书。tnsnames.ora示例:
ORCLSSL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCPS)(HOST = oracledb01.ipipp.com)(PORT = 2484))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orclpdb1)
)
)
导入服务端自签名证书到客户端Wallet时,可以先将服务器Wallet中的证书导出,再在客户端使用orapki导入为trusted_cert。命令如下:
orapki wallet create -wallet /u01/app/oracle/client_wallet -pwd ClientPass123 -auto_login orapki wallet add_certificate -wallet /u01/app/oracle/client_wallet -trusted_cert -cert /tmp/server_cert.crt
测试连接使用sqlplus或应用连接串。连接时如果出现SSL错误,先检查客户端Wallet是否可读,再确认监听器TCPS端口是否被防火墙放行。还可以通过tnsping ORCLSSL 10来验证连接解析,再进一步用sqlplus实际登录。
五、证书更新、双向认证与常见故障排查
证书有有效期,到期前需要更换,否则所有SSL连接会突然失败。更新标准做法是:在服务器Wallet中重新生成证书或导入新签证书,重启监听;客户端若保存的是旧根证书则通常无需改动,但如果服务器证书由中间CA签发,还需要同步更新根证书或中间证书。为了减少停机,可以准备两个Wallet目录,先在新目录中部署新证书,修改目录后重启监听,失败时可快速回退。
双向认证配置要求服务端将SSL_CLIENT_AUTHENTICATION设为TRUE,同时客户端Wallet必须包含客户端证书和私钥,服务端Wallet也必须导入客户端证书对应的根证书。双向认证能确认客户端身份,适合数据库账号之外再增加一层网络身份控制。缺点是证书分发和续期工作量更大,并且所有客户端都必须正确配置,否则连接会被拒绝。
常见故障包括ORA-28860、ORA-28864、ORA-29024等。ORA-28860往往说明TLS握手没有完成,可能是加密套件不兼容或Wallet权限问题;ORA-28864表示SSL连接被对端关闭,常见于客户端未导入服务器证书链;ORA-29024代表证书验证失败,通常是证书已过期、CN不匹配或CA不受信任。排错时可以先使用openssl s_client -connect 服务器:2484查看证书链,再检查服务端$ORACLE_HOME/network/log/listener.log,定位握手失败阶段。