【网络排障/自签证书踩坑】curl: (35) OpenssL SSL connect: Connection reset by peer in connection to

EasyJax 2024-07-29 12:07:04 阅读 89

前言

最近在对接业务的时候,需要请求云上厂家的接口。

首先说明一点,云是属于内网环境的,且调用是HTTPS协议的,所以厂家使用到了自签证书。而自签证书在对于不处于同一内部网络的机器,在进行HTTPS请求的时候,就会遇到SSL验证无法通过的问题,如以下。

<code>curl: (35) OpenssL SSL connect: Connection reset by peer in connection to ip:port

第一步

你要确定的是,你的请求只是因为绕不过去SSL验证。如果你中间还套了一层网闸,或者其他网络转发的话,那么即时你使用下方的解决思路,也是错误的。因为很有可能你的本机地址映射出去的IP并不是你用 ip addr命令输出的地址,这点你要确定好。

第二步

非常重要的事,使用telnet ip port,测试网络连接情况,如果能够正常建立起连接,那么说明你的请求是可以出去你所处的云网络的。

第三步

简单测试,使用curl命令进行排障,先把接口使用postman等工具编辑好后生成curl语句,并且在生成的语句内添加上 -k 或者 --insecure,如果能正常返回业务结果,那么就可以开始尝试写绕过SSL验证的代码了。

具体代码下方已经给出。

工具类:

import java.security.cert.CertificateException;

import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;

import javax.net.ssl.HttpsURLConnection;

import javax.net.ssl.SSLContext;

import javax.net.ssl.SSLSession;

import javax.net.ssl.TrustManager;

import javax.net.ssl.X509TrustManager;

public class SslUtils {

private static void trustAllHttpsCertificates() throws Exception {

TrustManager[] trustAllCerts = new TrustManager[1];

TrustManager tm = new miTM();

trustAllCerts[0] = tm;

SSLContext sc = SSLContext.getInstance("SSL");

sc.init(null, trustAllCerts, null);

HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

}

static class miTM implements TrustManager,X509TrustManager {

public X509Certificate[] getAcceptedIssuers() {

return null;

}

public boolean isServerTrusted(X509Certificate[] certs) {

return true;

}

public boolean isClientTrusted(X509Certificate[] certs) {

return true;

}

public void checkServerTrusted(X509Certificate[] certs, String authType)

throws CertificateException {

return;

}

public void checkClientTrusted(X509Certificate[] certs, String authType)

throws CertificateException {

return;

}

}

/**

* 忽略HTTPS请求的SSL证书

*/

public static void ignoreSsl() throws Exception{

HostnameVerifier hv = new HostnameVerifier() {

public boolean verify(String urlHostName, SSLSession session) {

log.debug("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());

return true;

}

};

trustAllHttpsCertificates();

HttpsURLConnection.setDefaultHostnameVerifier(hv);

}

}

POST请求方法:

import java.io.OutputStreamWriter;

import java.net.URL;

import java.net.URLConnection;

public class SolutionServiceImpl {

//post 请求,自动绕开SSL验证

public String postRequest(String urlAddress,String args,int timeOut) throws Exception{

URL url = new URL(urlAddress);

if("https".equalsIgnoreCase(url.getProtocol())){

SslUtils.ignoreSsl();//忽略掉SSL异常

}

URLConnection u = url.openConnection();

u.setRequestProperty("Content-Type", "application/json");

u.setRequestProperty("Authorization", "Bearer *****");

//设置请求头

u.setDoInput(true);

u.setDoOutput(true);

u.setConnectTimeout(timeOut);

u.setReadTimeout(timeOut);

OutputStreamWriter osw = new OutputStreamWriter(u.getOutputStream(), "UTF-8");

osw.write(args);

osw.flush();

osw.close();

u.getOutputStream();

return IOUtils.toString(u.getInputStream());

}

}

写一个Api结果构造类:

import lombok.AllArgsConstructor;

import lombok.Data;

@Data

@AllArgsConstructor

public class ApiResultVO<T> {

private String code;

private String msg;

private List<T> data;

}

使用方法:

import cn.hutool.core.lang.TypeReference;

private static final String baseUrl = "https://ip:port/api";

//接口偏移

private static final String requestUrl = "/requestData";

private static Integer timeout = 10000;

public class SolutionServiceImpl {

public Map<String,Object> getAlarmJqListByTime(RequestForm form) throws Exception {

String apiresult = postRequest(baseUrl+requestUrl, parseJSON(form), timeout);

ApiResultVO<APIVO> resList = JSONUtil.toBean(apiresult,new TypeReference<ApiResultVO<APIVO>>(){ },false);//ApiResultVO使用的是泛型,APIVO就是你的实体类了

///

///

}

private String parseJSON(RequestForm form) {

JSONObject param = new JSONObject();

param.put("param",form.getParam());

return param.toString();

}

}

总结:

有一种情况,是某个机构已经把你的云主机IP映射到接口厂家的同一片网络上,但这并不代表你就能直接HTTPS请求对方的接口,这一点是需要注意的。当然这中间怎么做的网络映射,笔者也没有完全了解,可能观点是片面的,欢迎指点。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。