Oracle 19c Data Guard SSL加密传输必须主备库双向同步配置:两端均需启用TCPS监听、使用各自匹配主机名的Wallet、sqlnet.ora中WALLET_LOCATION与SSL_VERSION=1.2严格一致,且LOG_ARCHIVE_DEST_n须显式指向TCPS别名,否则归档静默降级为明文TCP。
oracle 19c data guard 的 ssl 加密传输不能只在主库或备库单侧配置,必须两端同步启用 tcps 监听、wallet 一致、sqlnet.ora 参数对齐,否则日志传输会静默降级为明文 tcp,抓包可见未加密流量。
TCPS 监听必须在主库和备库都独立配置
DG 场景下,主库向备库发送归档日志(ARCHIVELOG)或实时重做(LGWR/ASYNC),走的是 Oracle Net 连接,不是内部进程通信。这意味着主库的 LOG_ARCHIVE_DEST_n 指向备库时,若用的是 (DESCRIPTION=...) 形式,就必须指向备库的 TCPS 端口;若用 Easy Connect(如 host:port/service_name),则完全不支持 TCPS,会直接失败。
- 主库和备库各自的
$ORACLE_HOME/network/admin/listener.ora都要添加独立的(PROTOCOL=TCPS)ADDRESS,不能复用同一监听器混配 TCP/TCPS - 端口不能复用:比如主库监听 TCP 在 1521、TCPS 在 1522,备库也得配自己的 TCPS 端口(如 1522 或 2484),不能指望主库连过去用“对方的 1521”再协商加密
-
lsnrctl reload后,分别执行lsnrctl status,确认输出里有tcps://...:1522行,且状态为READY - 常见错误现象:
ORA-12537: TNS:connection closed或归档日志卡在ALERT日志中显示ERROR: ORA-12547: TNS:lost contact,大概率是备库监听器根本没起来 TCPS 实例
Wallet 路径与内容必须严格一致且可读
DG 不自动同步 Wallet 文件。主库生成的证书对备库无效,因为证书 DN(如 CN=standby-host)必须匹配备库主机名,否则 ALTER SYSTEM ARCHIVE LOG CURRENT 会报 ORA-29024: Certificate validation failure。
- 主库和备库各自用
orapki wallet create -auto_login创建本地 Wallet,路径建议统一为$ORACLE_BASE/admin/$ORACLE_SID/wallet,权限700,属主oracle:oinstall - 备库证书的
-dn必须设成自己真实主机名(hostname -f输出),不能照抄主库命令;自签名场景下,还需执行orapki wallet add_trusted_cert导入自身证书为可信根 -
sqlnet.ora中的WALLET_LOCATION必须写绝对路径,且主备库配置值完全一致(包括大小写、斜杠方向);它不继承环境变量,也不认~或$ORACLE_HOME - 验证方式:在主库上用
sqlplus /@'(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=standby-host)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=orcldg)))'手动测试能否连上备库实例 —— 这步通了,DG 归档才可能走 TCPS
LOG_ARCHIVE_DEST_n 必须显式使用 TCPS 描述符
Oracle DG 不会把 LOG_ARCHIVE_DEST_2='SERVICE=standby' 自动转成 TCPS。如果 tnsnames.ora 里 standby 条目仍是 PROTOCOL=TCP,那归档就一定走明文。
- 在主库的
$ORACLE_HOME/network/admin/tnsnames.ora中,为备库定义一个专用 TCPS 别名,例如:
STANDBY_TCPS =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCPS)(HOST = standby-host)(PORT = 1522))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcldg)
)
)
- 然后设置归档目标:
ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=STANDBY_TCPS VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=orcldg'; - 禁用任何隐式 fallback:确保
LOG_ARCHIVE_DEST_STATE_2=ENABLE,且不要配ALTERNATE或其他兜底地址 - 检查生效:
SELECT DESTINATION, TRANSMIT_MODE, PROTECTION_MODE FROM V$ARCHIVE_DEST WHERE DEST_ID = 2;——TRANSMIT_MODE应为SYNC或ASYNC,但关键看连接是否实际加密,可用tshark -i any port 1522抓包确认 payload 是否乱码
SSL 参数必须在 sqlnet.ora 中全局控制
SQLNET.ENCRYPTION_CLIENT 和 SQLNET.ENCRYPTION_SERVER 这类参数,在 DG 场景下作用于归档传输进程(ARCH, LNS),不是仅影响交互式 SQL*Plus。它们不能写在 JDBC URL 或 PL/SQL 匿名块里,必须由网络层强制介入。
- 主库和备库的
sqlnet.ora都需包含:
SQLNET.ENCRYPTION_SERVER = required SQLNET.ENCRYPTION_TYPES_SERVER = (AES256) SSL_VERSION = 1.2
-
SQLNET.ENCRYPTION_SERVER = required是关键:它让所有出站连接(含归档传输)必须加密,否则连接直接拒绝,不会降级 -
SSL_VERSION = 1.2必须写在sqlnet.ora,URL 中的oracle.net.ssl_version已废弃,DG 进程根本不读 - 注意:
SSL_CLIENT_AUTHENTICATION = TRUE会要求双向认证,DG 默认不支持客户端证书校验,设为FALSE更稳妥(除非你真部署了客户端证书并注入 Wallet)
最易被忽略的是:哪怕所有配置都对,只要主库 listener.ora 里漏了 WALLET_LOCATION 段,或者备库 sqlnet.ora 里没写 SSL_VERSION = 1.2,归档就会安静地退回 TCP,没有任何报错日志提示 —— 必须靠抓包或 V$DATAGUARD_STATS 中的加密字段交叉验证。

















