为 MS SQL 数据库启用 ssl 的 Sqoop 中的 InvalidAlgorithmParameterException 问题
Posted
技术标签:
【中文标题】为 MS SQL 数据库启用 ssl 的 Sqoop 中的 InvalidAlgorithmParameterException 问题【英文标题】:InvalidAlgorithmParameterException issue in Sqoop with ssl enabled for MS SQLdatabase 【发布时间】:2018-01-22 15:33:12 【问题描述】:我正在运行 Sqoop 命令从启用 SSL 的 MS SQL 导入数据。 我已经创建了密钥库并将证书添加到密钥库中。我使用的是 Sqoop 版本 1.4.6-cdh5.11.2
下面是我的 Sqoop 命令:
sqoop import -Dfile.encoding=UTF-8
--driver "com.microsoft.sqlserver.jdbc.SQLServerDriver"
--connect "jdbc:sqlserver://xxxxxx:1433;databaseName=xxx-example;encrypt=True;TrustServerCertificate=False;hostNameInCertificate=xxxxxx.xxxx.net;trustStore=/home/user1/trust.jks;trustStorePassword=xxxx"
--username User1
--password 'xxxxx'
--null-string '\\N'
--null-non-string '\\N' -delete-target-dir
--target-dir "/home/john/PROGRAMS"
--table programs
--fields-terminated-by "\001"
--hive-drop-import-delims
--split-by 'ID'
--outdir 'temp/john/tables'
--bindir '/usr/john/PROGRAMS' -m 1
我已将加密设置为 true ,将 TrustServerCertificate 设置为 false ,将 trustStore= 和 trustStorePassword 设置为密钥库密码。
encrypt=True;TrustServerCertificate=False
以下是我在运行 sqoop 命令时遇到的错误:
18/01/22 10:12:10 INFO mapreduce.Job: Task Id : attempt_1516292804343_13212_m_000001_0, Status : FAILED
Error: java.lang.RuntimeException: java.lang.RuntimeException: com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty".
at org.apache.sqoop.mapreduce.db.DBInputFormat.setDbConf(DBInputFormat.java:170)
at org.apache.sqoop.mapreduce.db.DBInputFormat.setConf(DBInputFormat.java:161)
at org.apache.hadoop.util.ReflectionUtils.setConf(ReflectionUtils.java:73)
at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:133)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:755)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:164)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1920)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158)
Caused by: java.lang.RuntimeException: com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty".
at org.apache.sqoop.mapreduce.db.DBInputFormat.getConnection(DBInputFormat.java:223)
at org.apache.sqoop.mapreduce.db.DBInputFormat.setDbConf(DBInputFormat.java:168)
... 10 more
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty".
at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1667)
at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1668)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1323)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:991)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:827)
at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1012)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at org.apache.sqoop.mapreduce.db.DBConfiguration.getConnection(DBConfiguration.java:302)
at org.apache.sqoop.mapreduce.db.DBInputFormat.getConnection(DBInputFormat.java:216)
... 11 more
Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1906)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1889)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1410)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1618)
我该如何解决这个问题?
我尝试添加 -Djavax.net.ssl.trustStore= ,但没有成功。
【问题讨论】:
尝试从 sqoop 命令中删除 SSL 部分,您无需提及它适用于 TCP 的 SSL 证书。 @rob 这样做的全部目的是引入 SSL,避免中间人攻击并遍历证书链以验证信任。我设置了 encrypt=true ,TrustServerCertificate=false。 【参考方案1】:Microsoft 文档说,要使 SSL 完全正常工作,绝对有必要为您正在使用的 JRE 正确配置 JSSE 提供程序。有两个步骤:
1) 查看 JRE 安装中的 java.security 文件 (通常在 jre\lib\security 目录中找到)。安装的 安全提供程序在该文件中列为 security.provider.x=... 其中“x”是使用的优先级。对于 Sun JRE 安装,第一个 优先供应商应该是 Sun 的。例如:你应该有这条线 该文件中的“security.provider.1=sun.security.provider.Sun”。为了 其他 JRE,请参阅 JRE 的文档,了解他们的 默认提供者名称。我们建议在使用 IBM JRE 时指定 “com.ibm.jsse.IBMJSSEProvider”作为第一个安全提供商 使用。
2) 接下来,确保类路径指向正确的 JAR 与这些提供程序一起使用的文件(在 jre\lib 目录中)。为了 Sun,类路径应该包括 jsse.jar。对于 IBM,应包括 ibmjsse.jar。
请参阅thisMicrosoft 文档,该文档由您遇到的相同错误解释(“驱动程序无法通过使用安全套接字层 (SSL) 加密建立与 SQL Server 的安全连接。错误)
看起来你必须在 sqoop 作业中传递以下 java 参数
-Djavax.net.ssl.trustStore=C:\MyCertificates\storeName
-Djavax.net.ssl.trustStorePassword=storePassword
【讨论】:
以上是关于为 MS SQL 数据库启用 ssl 的 Sqoop 中的 InvalidAlgorithmParameterException 问题的主要内容,如果未能解决你的问题,请参考以下文章