温馨提示:要看高清无码套图,请使用手机打开并单击图片放大查看。 Fayson的github:https://github.com/fayson/cdhproject 提示:代码块部分可以左右滑动查看噢
1.文档编写目的
前面Fayson也介绍过《如何在集群外节点跨网段向HDFS写数据》和《如何使用Java代码访问HDFS》。在非Kerberos的环境中,使用HttpFS是不需要输入用户密码的,为了集群数据安全考虑可以考虑配置HttpFS的SSL。本篇文章主要介绍如何为HttpFS服务配置SSL。但Fayson依旧建议在开启HttpFS服务的集群里必须开启Kerberos。
- 内容概述
1.生成Keystore文件
2.配置HttpFS服务SSL并验证
3.Java客户端访问及测试
4.总结
- 测试环境
1.CentOS7.2
- 前置条件
1.集群未启用Kerberos
2.生成KeyStore文件
在keystore里,包含两种数据:
- 密钥实体(Key entity)——密钥(secret key)又或者是私钥和配对公钥(采用非对称加密)
- 可信任的证书实体(trusted certificate entries)——只包含公钥
这里我们使用Java提供的Keytool证书管理工具来生成一个Keystore文件。
在部署了HttpFS服务的节点上,执行如下命令生成KeyStore文件
代码语言:txt复制[root@cdh01 ~]# sudo -u httpfs /usr/java/jdk1.7.0_67-cloudera/bin/keytool -genkey -alias tomcat -keyalg RSA
Enter keystore password: (输入密码)
Re-enter new password: (再次输入密码)
What is your first and last name?
[Unknown]: cdh01.macro.com
What is the name of your organizational unit?
[Unknown]: fayson
What is the name of your organization?
[Unknown]: fayson
What is the name of your City or Locality?
[Unknown]: fayson
What is the name of your State or Province?
[Unknown]: fayson
What is the two-letter country code for this unit?
[Unknown]: fason
Is CN=fayson, OU=cloudera, O=cloudera, L=shanghai, ST=shanghai, C=shanghai correct?
[no]: yes
Enter key password for <tomcat>
(RETURN if same as keystore password): (输入密码)
Re-enter new password: (再次输入密码)
[root@cdh01 ~]#
(可左右滑动)
这里需要注意几个地方,需要输入密码和CN(CN必须为HttpFS服务所在节点的hostname)。
执行成功后证书文件默认生成在/var/lib/hadoop-httpfs目录下的 .keystore文件:
完成证书文件的生成后,接下来通过ClouderaManager界面为HttpFS服务配置SSL。
3.配置SSL
1.使用管理员用户登录Cloudera Manager的WEB界面
进入HDFS服务配置页面,范围选择“HttpFS”,类别选择“安全性”
2.配置启用SSL和Keystore文件
保存配置,回到CM主页根据提示重启相应服务。
4.验证配置是否生效
1.浏览器验证是否能正常访问HDFS文件列表,查看HDFS根目录下所有文件
请求成功,使用的是https
2.通过curl查看是否正常访问
代码语言:txt复制[root@cdh01 ~]# curl -k "https://192.168.10.4:14000/webhdfs/v1/?op=liststatus&user.name=hdfs"
(可左右滑动)
5.Java客户端访问
1.将HttpFS服务器上的.keystore证书下载至本地命名为httpfs.keystore
2.使用Maven创建一个java工程,pom.xml文件中增加如下依赖
代码语言:txt复制<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.4</version>
</dependency>
(可左右滑动)
3.编写访问HttpFS的示例代码
代码语言:txt复制package com.cloudera.hdfs.nonekerberos;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
/**
* package: com.cloudera.hdfs.nonekerberos
* describe: Java使用HttpClient访问启用SSL的HttpFS服务
* creat_user: Fayson
* email: htechinfo@163.com
* creat_date: 2018/1/13
* creat_time: 下午9:56
* 公众号:Hadoop实操
*/
public class HttpFSSSLDemo {
private static String HTTPFS_HOST = "cdh01.macro.com";
public static void main(String[] args) {
try{
SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(new File("/Volumes/Transcend/keytab/ssl/httpfs-server.keystore"), "123456".toCharArray(), new TrustSelfSignedStrategy()).build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[] { "TLSv1" },
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
System.out.println("===========Case No.1 List resources==========");
String getRequest = "https://" HTTPFS_HOST ":14000/webhdfs/v1/?op=liststatus&user.name=hdfs";
HttpGet httpget = new HttpGet(getRequest);
System.out.println("executing request " httpget.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httpget);
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
HttpEntity entity = response.getEntity();
BufferedReader br =
new BufferedReader(new InputStreamReader((entity.getContent())));
String output;
while ((output = br.readLine()) != null) {
System.out.println(output);
}
EntityUtils.consume(entity);
} catch (Exception e) {
e.printStackTrace();
}
}
}
(可左右滑动)
4.示例运行结果
6.常见问题
运行时报如下异常
代码语言:txt复制javax.net.ssl.SSLPeerUnverifiedException: Certificate for <114.119.11.142> doesn't match any of the subject alternative names: []
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:467)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:397)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:355)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:373)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:381)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
at com.cloudera.hdfs.nonekerberos.HttpFSSSLDemo.main(HttpFSSSLDemo.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
(可左右滑动)
异常原因:
1.在生成keystore文件时未指定CN为HttpFS服务所在节点的hostname
2.直接访问HttpFS服务的IP地址导致,需要配置hosts文件
7.总结
- 在生成HttpFS服务的keystore文件时CN信息必须为该服务的hostsname,否则会报错
- 在访问时需要配置本地的hosts文件
GitHub地址:
https://github.com/fayson/cdhproject/blob/master/hdfsdemo/src/main/java/com/cloudera/hdfs/nonekerberos/HttpFSSSLDemo.java
提示:代码块部分可以左右滑动查看噢 为天地立心,为生民立命,为往圣继绝学,为万世开太平。 温馨提示:要看高清无码套图,请使用手机打开并单击图片放大查看。
推荐关注Hadoop实操,第一时间,分享更多Hadoop干货,欢迎转发和分享。
原创文章,欢迎转载,转载请注明:转载自微信公众号Hadoop实操