Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.*;
import java.security.cert.CertificateException;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
Expand All @@ -31,8 +29,9 @@ public static SSLContext createSSLContext() {
public SSLContext initSSLContext() {
logger.info("Checking SSL configuration properties...");
final String jksPath = Config.getInstance().getStringValue("ssl.jksPath");
logger.info("Initializing SSL context. KeystorePath = {}.", jksPath);
if (jksPath == null || jksPath.isEmpty()) {
final String caPath = Config.getInstance().getStringValue("ssl.TrustkeyStorePath");
logger.info("Initializing SSL context. KeystorePath = {}.{}", jksPath,caPath);
if (jksPath == null || jksPath.isEmpty() ||caPath == null || caPath.isEmpty()) {
// key_store_password or key_manager_password are empty
logger.warn("The keystore path is null or empty. The SSL context won't be initialized.");
return null;
Expand All @@ -48,22 +47,29 @@ public SSLContext initSSLContext() {
try {
logger.info("Loading keystore. KeystorePath = {}.", jksPath);
InputStream jksInputStream = jksDatastore(jksPath);
InputStream caInputStream = jksDatastore(caPath);
SSLContext clientSSLContext = SSLContext.getInstance("TLS");
final KeyStore ks = KeyStore.getInstance("JKS");
final KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(jksInputStream, keyStorePassword.toCharArray());

final KeyStore caks = KeyStore.getInstance("JKS");
caks.load(caInputStream, keyStorePassword.toCharArray());

final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, keyStorePassword.toCharArray());

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
tmf.init(caks);
TrustManager[] trustManagers = tmf.getTrustManagers();

// init sslContext
logger.info("Initializing SSL context...");
clientSSLContext.init(null, trustManagers, null);
clientSSLContext.init(kmf.getKeyManagers(), trustManagers, null);
logger.info("The SSL context has been initialized successfully.");

return clientSSLContext;
} catch (NoSuchAlgorithmException | CertificateException | KeyStoreException | KeyManagementException
| IOException ex) {
} catch (NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException | KeyStoreException
| KeyManagementException | IOException ex) {
logger.error("Unable to initialize SSL context. Cause = {}, errorMessage = {}.", ex.getCause(),
ex.getMessage());
return null;
Expand Down
Binary file added proxy-client/src/main/resources/RootCA.jks
Binary file not shown.
11 changes: 6 additions & 5 deletions proxy-client/src/main/resources/config.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
client.key=client
ssl.enable=false
ssl.jksPath=test.jks
client.key=6e9a51ca84ac465a82b0e0182285fe59
ssl.enable=true
ssl.jksPath=lanproxyClient.pfx
ssl.TrustkeyStorePath=RootCA.jks
ssl.keyStorePassword=123456

server.host=127.0.0.1
server.host=180.102.133.252

#default ssl port is 4993
server.port=4900
server.port=4993
Binary file not shown.
Binary file removed proxy-client/src/main/resources/test.jks
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public synchronized void onChanged() {
List<Integer> inetPorts = new ArrayList<Integer>(ProxyConfig.getInstance().getClientInetPorts(clientKey));
Set<Integer> inetPortSet = new HashSet<Integer>(inetPorts);
List<Integer> channelInetPorts = new ArrayList<Integer>(proxyChannel.attr(CHANNEL_PORT).get());
ProxyConfig.Client cli = ProxyConfig.getInstance().getClients(clientKey);
if(cli == null) continue;

synchronized (portCmdChannelMapping) {

Expand All @@ -77,7 +79,7 @@ public synchronized void onChanged() {

// 判断是否是同一个连接对象,有可能之前已经更换成其他client的连接了
if (proxyChannel == channel) {
if (!inetPortSet.contains(chanelInetPort)) {
if (!inetPortSet.contains(chanelInetPort) || !cli.isProxyEnable(chanelInetPort)) {

// 移除新配置中不包含的端口
portCmdChannelMapping.remove(chanelInetPort);
Expand All @@ -92,8 +94,10 @@ public synchronized void onChanged() {

// 将新配置中增加的外网端口写入到映射配置中
for (int inetPort : inetPorts) {
portCmdChannelMapping.put(inetPort, proxyChannel);
proxyChannel.attr(CHANNEL_PORT).get().add(inetPort);
if(cli.isProxyEnable(inetPort)) {
portCmdChannelMapping.put(inetPort, proxyChannel);
proxyChannel.attr(CHANNEL_PORT).get().add(inetPort);
}
}

checkAndClearUserChannels(proxyChannel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,13 @@ public SSLContext initSSLContext() {
// use keystore as truststore, as server needs to trust
// certificates signed by the
// server certificates
final String caPath = Config.getInstance().getStringValue("server.ssl.TrustkeyStorePath");
InputStream caInputStream = jksDatastore(caPath);
final KeyStore caks = KeyStore.getInstance("JKS");
caks.load(caInputStream, keyStorePassword.toCharArray());

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
tmf.init(caks);
trustManagers = tmf.getTrustManagers();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ public List<Client> getClients() {
return clients;
}

public Client getClients(String clientKey) {
for (Client cli: clients) {
if(cli.getClientKey().equals(clientKey))return cli;
}
return null;
}

/**
* 解析配置文件
*/
Expand Down Expand Up @@ -202,7 +209,9 @@ public void update(String proxyMappingConfigJson) {
throw new IllegalArgumentException("一个公网端口只能映射一个后端信息,不能重复: " + port);
}

inetPortLanInfoMapping.put(port, mapping.getLan());
if(mapping.getEnable() && client.isProxyEnable(port)) {
inetPortLanInfoMapping.put(port, mapping.getLan());
}
}
}

Expand Down Expand Up @@ -354,6 +363,12 @@ public void setStatus(int status) {
this.status = status;
}

public Boolean isProxyEnable(int inetPort) {
for (ClientProxyMapping cli:proxyMappings) {
if(cli.getInetPort() == inetPort) return cli.getEnable();
}
return false;
}
}

/**
Expand All @@ -373,6 +388,9 @@ public static class ClientProxyMapping {
/** 备注名称 */
private String name;

/** 是否启用 */
private Boolean enable;

public Integer getInetPort() {
return inetPort;
}
Expand All @@ -397,6 +415,13 @@ public void setName(String name) {
this.name = name;
}

public Boolean getEnable() {
return enable;
}

public void setEnable(Boolean enable) {
this.enable = enable;
}
}

/**
Expand Down
7 changes: 4 additions & 3 deletions proxy-server/src/main/resources/config.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ server.port=4900
server.ssl.enable=true
server.ssl.bind=0.0.0.0
server.ssl.port=4993
server.ssl.jksPath=test.jks
server.ssl.jksPath=lanproxyServer.pfx
server.ssl.TrustkeyStorePath=RootCA.jks
server.ssl.keyStorePassword=123456
server.ssl.keyManagerPassword=123456
server.ssl.needsClientAuth=false

config.server.bind=0.0.0.0
config.server.port=8090
config.server.port=9090
config.admin.username=admin
config.admin.password=admin
config.admin.password=Abs@15732
Binary file removed proxy-server/src/main/resources/test.jks
Binary file not shown.
3 changes: 3 additions & 0 deletions proxy-server/webpages/i18n/lang_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public.back=返回
public.notice.updatesuccess=更新成功
public.notice.addsuccess=添加成功
public.tips=提示
public.enable=启用
public.disable=禁用

client.list=客户端列表
client.name=客户端名称
Expand All @@ -44,6 +46,7 @@ lan.name=代理名称
lan.inetport=公网端口
lan.inetport.placeholder=请输入公网出口端口,请确保端口没有被其他程序占用
lan.ip=后端IP端口
lan.enable=是否开启
lan.ip.placeholder=请输入后端代理信息,格式:127.0.0.1:80
lan.notice.inputname=请输入代理信息备注名称
lan.notice.inputinetport=请输入公网出口端口
Expand Down
3 changes: 2 additions & 1 deletion proxy-server/webpages/lanproxy-config/html/lan/add.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
clientList[clientIndex].proxyMappings.push({
name:name,
inetPort:inetPort,
lan:lan
lan:lan,
enable:true
});

api_invoke("/config/update", clientList, function(data) {
Expand Down
91 changes: 62 additions & 29 deletions proxy-server/webpages/lanproxy-config/html/lan/edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,64 @@
<ul class="layui-tab-title site-demo-title">
<li class="layui-this i18n-lan-title"></li>
</ul>
<div class="main-content">
<div class="layui-form-item">
<label class="layui-form-label i18n-lan-name"></label>
<div class="layui-input-block">
<input type="text" name="name" autocomplete="off" placeholder="" class="layui-input">
</div>
</div>
<form class="layui-form" action="" lay-filter="example">
<div class="main-content">
<div class="layui-form-item">
<label class="layui-form-label i18n-lan-name"></label>
<div class="layui-input-block">
<input type="text" name="name" autocomplete="off" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label i18n-lan-inetport"></label>
<div class="layui-input-block">
<input type="text" name="inetPort" autocomplete="off" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label i18n-lan-ip"></label>
<div class="layui-input-block">
<input type="text" name="lan" autocomplete="off" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label i18n-lan-inetport"></label>
<div class="layui-input-block">
<input type="text" name="inetPort" autocomplete="off" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label i18n-lan-ip"></label>
<div class="layui-input-block">
<input type="text" name="lan" autocomplete="off" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn update"></button>
<button class="layui-btn layui-btn-primary back"></button>
</div>
</div>
</div>
<label class="layui-form-label i18n-lan-enable"></label>
<div class="layui-input-block">
<input type="checkbox" name="switch" lay-skin="switch">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn update"></button>
<button class="layui-btn layui-btn-primary back"></button>
</div>
</div>
</div>
</form>
</div>
<script>

layui.use('form', function () {

var form = layui.form; //ֻ��ִ������һ�������ֱ���Ԫ�زŻ��Զ����γɹ�

form.val('example', {
"name": clientList[clientIndex].proxyMappings[mappingIndex].name
,"inetPort": clientList[clientIndex].proxyMappings[mappingIndex].inetPort
,"lan": clientList[clientIndex].proxyMappings[mappingIndex].lan
,"switch": clientList[clientIndex].proxyMappings[mappingIndex].enable
});

form.render();

});

$(function(){
$("input[name='name']").val(clientList[clientIndex].proxyMappings[mappingIndex].name);
$("input[name='inetPort']").val(clientList[clientIndex].proxyMappings[mappingIndex].inetPort);
$("input[name='lan']").val(clientList[clientIndex].proxyMappings[mappingIndex].lan);
$(".i18n-lan-title").html($.i18n.prop('lan.editconfig'));
$(".i18n-lan-name").html($.i18n.prop('lan.name'));
$(".i18n-lan-inetport").html($.i18n.prop('lan.inetport'));
$(".i18n-lan-ip").html($.i18n.prop('lan.ip'));
$(".i18n-lan-enable").html($.i18n.prop('lan.enable'));
$("input[name='inetPort']").attr("placeholder", $.i18n.prop('lan.inetport.placeholder'));
$("input[name='lan']").attr("placeholder", $.i18n.prop('lan.ip.placeholder'));
$(".update").html($.i18n.prop('public.submit'));
Expand Down Expand Up @@ -65,10 +87,21 @@
return;
}

//var form = layui.form;
//var data = form.val('example');
//alert(JSON.parse(data));
var enable = false;
$("[name='switch']:checkbox").each(function () {
if ($(this).is(":checked")) {
enable = true;
}
});

clientList[clientIndex].proxyMappings[mappingIndex]= {
name:name,
inetPort:inetPort,
lan:lan
lan:lan,
enable:enable
};

api_invoke("/config/update", clientList, function(data) {
Expand Down
Loading