由于疫情的影响,最近一段时间大家运程办公,购买腾讯云主机、mysql、redis、es等作为项目的开发环境。然后使用腾讯云主机远程办公带来了一些的问题,项目的团队成员在50人左右,使用腾讯云作为开发环境,为了安全腾讯云主机的开发环境不对外开放,使用时需要给每个人开通个人开发机的ip权限,然而腾讯云的服务智能开通最多10个ip白名单,因此50个人最多只有10个同时使用某一个服务,大家每天会有各种环境不通的问题,然后运维用腾讯文档来登记每天开通权限请求, 新的ip开通需求覆盖旧的ip,周而复始。明显有问题:
1、重复登记工作、开通工作繁杂;
2、开通后容易被覆盖,开通要多次确认,开通有生效时间等多种问题,运程的这种沟通成本非常高;
3、由于上面2个原因,一些团队内部自己搭建小团队的开发环境,到底开发环境不一致,容易出现问题,排查不同人和团队的问题也增加了复杂的环境因素。
问题核心在于远程大家都在公网环境,腾讯云服务不能对这么多个人的动态ip定向开通安全策略,这和裸奔没啥区别。因此需要解决的核心是提供一个固定的出口ip,腾讯云的开发环境对该ip开放。其他远程开发者通过安全的方式接入该固定出口的服务器做跳板机。 这个点没有问题,远程开发者通过ssh 密钥方式来访问跳板机,跳板机再到开发环境,开发者上来看日志、看数据库都没问题,已经这么做了。而还要一个要解决的问题是个人的应用程序怎么和开发环境打通呢?通过类似跳板机的方式? 如下图所示,在跳板机上面部署一个代理服务,对外开通1080端口, 代理通过用户名和密码的方式进行验证,或者自定义多个ip白名单,每个人自己可以上去添加。应用程序访问 redis、es、mysql时通过代理转发。
需要一个代理跳板机,该机器不属于腾讯云开发环境内网, 是独立的外部环境,腾讯云服务通过ip白名单的方式对开服务器开发指定服务的端口例如:3306,9200,6379等等。该服务对外开发代理端口:80,1080等。
1、部署代理,找了一个非常简单的代理程序(sock5):git://github.com/sequoiar/socks5.git,支持tcp、http(s)等通信。
2、配置启动时参数,指定使用代理通信:
-DsocksProxyHost=xxx.xxx.xxx.xxx -DsocksProxyPort=1080
-Djava.net.socks.username=xxx -Djava.net.socks.password=xxx
详细可以参考:
jdk8:
https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html
jdk11:
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/doc-files/net-properties.html#Proxies
配置参数使用的地方:DefaultProxySelector.java
由于我用的是jdk8,因此配置用户名和密码无效,也尝试了其他的方式,都没生效,后面放弃了使用来源ip白名单的方式:
Authenticator.setDefault (new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication ("username", "password".toCharArray());
}
});
设置了socks 代理之后es 客户端还是有问题,我这边用的是:
org.elasticsearch.client
elasticsearch-rest-high-level-client
6.4.3
这个版本,client 请求es没有走代理,初次发现问题是.es实例化http客户端时,没有用到系统属性,需要显示调用。
builder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.useSystemProperties(); //显示调用使用系统属性。
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
});
显示调用之后,发现该客户端还是无法使用socks代理,最后我这边又在跳板机加了一个http代理,新增了jvm的启动参数, es客户端才能正常使用代理。
-DhttpsProxyHost=xxx.xxx.xxx.xxx -DhttpsProxyPort=80
到此开发环境可以比较方便且安全的连上腾讯云服务了。
1、我的本意是希望http(s), socket 通信都通过我搭建的HTTP代理路由, 所以设置了这三种通信的代理都指向一个host&port, 虽然说其他socket通信业可以通过http隧道转发,但是一些客户端(mysql、redis)不会应用到system.setPropety, 导致设置的代理无效。
2、es client的实现也是有些问题的,跟进去看,请求开始是选到了http做代理,可对代理创建socket的时候还会选一次代理因为又配置了socks proxy,所有代理又使用了代理来进行转发,而我搭建的代理是http的,所有最后看上去都用了socks proxy,都会失败。
3、我这边使用httpclient4 配置sockets 就直接生效了使用es client 不知道为何一只不生效;
4、还有没有解决的问题就是jdk启动参数使用代理的用户名和密码一只设置无效。