SSLHandshakeException通过Apache Knox发送curl命令

时间:2017-03-20 18:57:59

标签: ssl curl knox-gateway

我创建了一个简单的REST Web服务,它从{"code":4,"type":"ok","message":"hello there!"}

返回curl -k -u admin:admin -X GET "https://server.running.service:8447/demo/v1/test"

我想让所有用户通过Apache Knox访问Web服务,以便对其进行身份验证。但是,当我使用curl -k -u admin:admin -X GET "https://server.running.knox:8443/gateway/platform//hello/v1/test"时,我会回来:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>Error 500 Server Error</title>
</head>
<body><h2>HTTP ERROR 500</h2>
<p>Problem accessing /gateway/platform/hello/v1/test. Reason:
<pre>    Server Error</pre></p><hr /><i><small>Powered by Jetty://</small></i><br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>

</body>
</html>

查看Knox gateway.log文件,我可以看到此错误:

INFO  hadoop.gateway (KnoxLdapRealm.java:getUserDn(556)) - Computed userDn: uid=admin,ou=people,dc=hadoop,dc=apache,dc=org using dnTemplate for principal: admin
2017-03-20 14:15:53,289 INFO  hadoop.gateway (AclsAuthorizationFilter.java:doFilter(85)) - Access Granted: true
2017-03-20 14:15:53,296 WARN  hadoop.gateway (DefaultDispatch.java:executeOutboundRequest(138)) - Connection exception dispatching request: https://server.running.knox:8443/gateway/platform/hello/v1/test?user.name=admin javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
        at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:290)
        at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:259)
        at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:125)
        at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:319)
        at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:363)
        at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219)
        at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
        at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
        at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
        at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
        at org.apache.hadoop.gateway.dispatch.DefaultDispatch.executeOutboundRequest(DefaultDispatch.java:127)
        at org.apache.hadoop.gateway.dispatch.DefaultDispatch.executeRequest(DefaultDispatch.java:114)
        at org.apache.hadoop.gateway.dispatch.DefaultDispatch.doGet(DefaultDispatch.java:294)
        at org.apache.hadoop.gateway.dispatch.GatewayDispatchFilter$GetAdapter.doMethod(GatewayDispatchFilter.java:145)
        at org.apache.hadoop.gateway.dispatch.GatewayDispatchFilter.doFilter(GatewayDispatchFilter.java:117)
        at org.apache.hadoop.gateway.filter.AbstractGatewayFilter.doFilter(AbstractGatewayFilter.java:61)
        at org.apache.hadoop.gateway.GatewayFilter$Holder.doFilter(GatewayFilter.java:315)
        at org.apache.hadoop.gateway.GatewayFilter$Chain.doFilter(GatewayFilter.java:215)
        at org.apache.hadoop.gateway.filter.AclsAuthorizationFilter.doFilter(AclsAuthorizationFilter.java:89)
        at org.apache.hadoop.gateway.GatewayFilter$Holder.doFilter(GatewayFilter.java:315)
        at org.apache.hadoop.gateway.GatewayFilter$Chain.doFilter(GatewayFilter.java:215)

我不确定在向Knox添加服务时是否犯了错误。我用以下内容创建了一个rewrite.xml:

<rules>
  <rule dir="IN" name="HELLOSERVICE/hello/inbound/root" pattern="*://*:*
/**/hello/">
    <rewrite template="{$serviceUrl[HELLOSERVICE]}/"/>
  </rule>
  <rule dir="IN" name="HELLOSERVICE/hello/inbound/path" pattern="*://*:*/**/hello/{**}">
    <rewrite template="{$serviceUrl[HELLOSERVICE]}/{**}"/>
  </rule>
  <rule dir="IN" name="HELLOSERVICE/hello/inbound/query" pattern="*://*:*/**/hello/{**}?{**}">
    <rewrite template="{$serviceUrl[HELLOSERVICE]}/{**}?{**}"/>
  </rule>

  <rule dir="OUT" name="HELLOSERVICE/hello/outbound/demo/v1">
    <match pattern="*://*:*/demo/v1/{**}"/>
    <rewrite template="{$frontend[url]}/hello/v1/{**}"/>
  </rule>

</rules>

以及包含以下内容的service.xml:

<service role="HELLOSERVICE" name="hello" version="0.0.1">
    <routes>
        <route path="/hello/"/>
        <route path="/hello/**"/>
        <route path="/hello/**?**"/>
    </routes>
</service>

platform.xml文件包含:

<topology>
    <gateway>    
        <provider>
            <role>authentication</role>
            <name>ShiroProvider</name>
            <enabled>true</enabled>
            <param>
                <name>sessionTimeout</name>
                <value>30</value>
            </param>
            <param>
                <name>main.ldapRealm</name>
              <value>org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm</value>
            </param>
            <param>
                <name>main.ldapRealm.userDnTemplate</name>
                <value>uid={0},ou=people,dc=hadoop,dc=apache,dc=org</value>
            </param>
            <param>
                <name>main.ldapRealm.contextFactory.url</name>
                <value>ldap://server.running.knox:33389</value>
            </param>
            <param>
       <name>main.ldapRealm.contextFactory.authenticationMechanism</name>
                <value>simple</value>
            </param>
            <param>
                <name>urls./**</name>
                <value>authcBasic</value>
            </param>
        </provider>
        <provider>
            <role>identity-assertion</role>
            <name>Default</name>
            <enabled>true</enabled>
        </provider>
        <provider>
            <role>authorization</role>
            <name>AclsAuthz</name>
            <enabled>true</enabled>
        </provider>
        <provider>
            <role>webappsec</role>
            <name>WebAppSec</name>
            <enabled>true</enabled>
            <param><name>csrf.enabled</name><value>false</value></param> <!-- CSRF Disabled -->
            <param><name>csrf.customHeader</name><value>X-XSRF-Header</value></param>
            <param><name>csrf.methodsToIgnore</name><value>GET,OPTIONS,HEAD</value></param>
            <param><name>cors.enabled</name><value>true</value></param>
            <param><name>cors.allowOrigin</name><value>*</value></param>
            <param><name>cors.allowSubdomains</name><value>false</value></param>
            <param><name>cors.supportedMethods</name><value>GET,POST,HEAD,OPTIONS,PUT,DELETE</value></param>
        </provider>
    </gateway>
    <service>
        <role>HELLOSERVICE</role>
        <url>http://server.running.service:8088/demo</url>
    </service>    
</topology>

设置Knox时我犯了错误吗?我需要做一些其他配置才能通过Knox向我的服务发送命令吗?

2 个答案:

答案 0 :(得分:2)

对Sandeep的答案进行了轻微修正,确定了问题。您需要将后端服务的公共证书导入Apache Knox服务器的cacerts文件。

答案 1 :(得分:1)

查看日志,看来Knox正在尝试连接到https网址(https://server.running.knox:8443/gateway/platform/hello/v1/test?user.name=admin

但我发现您的拓扑文件中确实有http url,因此可能会发生https升级。

此处的问题似乎是您的后端使用https,因此您可能需要将后端证书配置到您的Knox群集中,即需要将https://server.running.knox的证书添加到Knox信任存储区(gateway.jks)

HTH