如何为Oracle配置SSL加密监听_Wallet配置与TCPS协议开启

5次阅读

监听器必须配置TCPS协议并正确设置Wallet,仅修改sqlnet.ora无效;需在listener.ora中定义TCPS地址、显式指定WALLET_LOCATION、用orapki创建并导入证书链,且客户端tnsnames.ora须使用TCPS协议。

监听器必须用 TCPS 协议,不能只改 sqlnet.ora

oracle ssl 加密不是靠客户端配置单方面生效的,监听器本身得听 tcps 端口。只在 sqlnet.ora 里加 ssl_version = 1.2sqlnet.encryption_server = required 没用——连接还是走 tcp,根本碰不到证书校验环节。

实操要点:

  • listener.ora 中必须定义一个 ADDRESS 类型为 (PROTOCOL = TCPS),比如:
    ADDRESS = (PROTOCOL = TCPS)(HOST = myhost)(PORT = 2484)
  • 对应地址不能和已有 TCP 监听端口冲突;TCPS 默认不启用 Oracle 自带的 Wallet 查找逻辑,必须显式指定 WALLET_LOCATION
  • 监听器启动后,用 lsnrctl status 看输出里有没有 TCPS 行,没有说明配置未加载或语法错(常见是括号不匹配或缩进导致解析失败)

Wallet 必须用 orapki 创建,且需包含完整证书链

Oracle 不认 OpenSSL 生成的 PEM 文件直传,也不接受把 server.crtca.crt 手动拼成一个文件。Wallet 是二进制容器,必须用 orapki 工具初始化、导入、标记信任。

常见错误现象:

  • 连接时报 ORA-29024: Certificate validation failure —— 大概率是 CA 证书没导入,或没执行 orapki wallet add_trusted_cert
  • 监听器启动报 TNS-01190: The user is not authorized to execute the requested listener command —— 实际常因 Wallet 权限太松(如 755),应设为 600 且属主为 oracle
  • Wallet 路径含空格或中文,listener.ora 里又没加引号,会导致监听器静默忽略该 ADDRESS

关键步骤示例(假设 Wallet 存于 /u01/app/oracle/admin/WALLETS/mydb):

orapki wallet create -wallet "/u01/app/oracle/admin/WALLETS/mydb" -auto_login orapki wallet add_cert -wallet "/u01/app/oracle/admin/WALLETS/mydb" -cert server.crt -trusted_cert -cert ca.crt

sqlnet.ora 的 WALLET_LOCATION 必须绝对路径 + 与监听器一致

客户端和服务器端的 sqlnet.ora 都要配 WALLET_LOCATION,但这里容易漏掉一个事实:监听器进程读的是 $ORACLE_HOME/network/admin/sqlnet.ora(不是数据库实例目录下的),而且它**不继承环境变量**,所以路径必须写死、不能用 $ORACLE_HOME~

典型配置:

WALLET_LOCATION = (SOURCE = (METHOD = FILE) (METHOD_DATA = (Directory = /u01/app/oracle/admin/WALLETS/mydb))) SSL_CLIENT_AUTHENTICATION = FALSE

注意点:

  • DIRECTORY 值末尾不要加斜杠,否则 Wallet 找不到
  • 如果启用了双向认证(SSL_CLIENT_AUTHENTICATION = TRUE),客户端也得有 Wallet,且服务端 Wallet 中必须提前导入客户端 CA 证书
  • SSL_CIPHER_SUITES 若指定太严(如只留 SSL_RSA_WITH_AES_256_CBC_SHA256),老客户端可能连不上,建议初期先不设,验证通后再收紧

tnsnames.ora 连接串必须显式写 TCPS,且 SERVICE_NAME 不能错

客户端用 sqlplus 或应用连接时,如果 tnsnames.ora 里还用 (PROTOCOL = TCP),哪怕监听器开了 TCPS,也会绕过去直连明文端口。必须改协议、换端口、确认服务名。

正确写法示例:

MYDB_SSL =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCPS)(HOST = myhost)(PORT = 2484))     (CONNECT_DATA =       (SERVICE_NAME = mydb.example.com)     )   )

容易踩的坑:

  • SERVICE_NAME 必须和服务端 V$database.NAMEDB_DOMAIN 拼接结果一致;用 SID 在 SSL 场景下大概率失败
  • 测试时别用 localhost,Wallet 中证书的 CN 或 SAN 若是 myhost.example.com,而连接串写 localhost,会触发证书主机名不匹配(ORA-29024
  • Java 应用要用 oracle.jdbc.ssl.WalletLocation jvm 参数,不能只靠 tnsnames.ora;.NET 需在连接字符串ENCRYPTION=REQUIRED 并确保 Oracle Data Provider 版本支持 TCPS

证书 CN、监听 HOST、tnsnames HOST、DNS 解析结果这四者对不上,是调试阶段最耗时间的一类问题。

text=ZqhQzanResources