mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-12-02 20:08:40 +08:00
fix SSH 新增超时时间配置
This commit is contained in:
parent
63f9dc7528
commit
75cd1f66a9
@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
### 🐣 新增功能
|
### 🐣 新增功能
|
||||||
|
|
||||||
|
1. 【server】SSH 终端新增全屏方式打开
|
||||||
|
(感谢[@jaseeon](https://gitee.com/jaseeon) [Gitee issues I5BS52](https://gitee.com/dromara/Jpom/issues/I5BS52) )
|
||||||
|
2. 【server】SSH 新增超时时间配置(感谢@带刺的玫瑰)
|
||||||
|
|
||||||
### 🐞 解决BUG、优化功能
|
### 🐞 解决BUG、优化功能
|
||||||
|
|
||||||
1. 【server】升级 h2 版本,低版本存在漏洞(CVE-2021-23463)
|
1. 【server】升级 h2 版本,低版本存在漏洞(CVE-2021-23463)
|
||||||
|
@ -25,6 +25,7 @@ package io.jpom.controller.ssh;
|
|||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.core.text.StrSplitter;
|
import cn.hutool.core.text.StrSplitter;
|
||||||
|
import cn.hutool.core.util.CharsetUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.core.util.URLUtil;
|
import cn.hutool.core.util.URLUtil;
|
||||||
@ -53,6 +54,7 @@ import io.jpom.permission.SystemPermission;
|
|||||||
import io.jpom.service.dblog.BuildInfoService;
|
import io.jpom.service.dblog.BuildInfoService;
|
||||||
import io.jpom.service.dblog.SshTerminalExecuteLogService;
|
import io.jpom.service.dblog.SshTerminalExecuteLogService;
|
||||||
import io.jpom.service.node.ssh.SshService;
|
import io.jpom.service.node.ssh.SshService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@ -71,6 +73,7 @@ import java.util.List;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(value = "node/ssh")
|
@RequestMapping(value = "node/ssh")
|
||||||
@Feature(cls = ClassFeature.SSH)
|
@Feature(cls = ClassFeature.SSH)
|
||||||
|
@Slf4j
|
||||||
public class SshController extends BaseServerController {
|
public class SshController extends BaseServerController {
|
||||||
|
|
||||||
private final SshService sshService;
|
private final SshService sshService;
|
||||||
@ -176,6 +179,8 @@ public class SshController extends BaseServerController {
|
|||||||
sshModel.setConnectType(connectType.name());
|
sshModel.setConnectType(connectType.name());
|
||||||
// 获取允许编辑的后缀
|
// 获取允许编辑的后缀
|
||||||
String allowEditSuffix = getParameter("allowEditSuffix");
|
String allowEditSuffix = getParameter("allowEditSuffix");
|
||||||
|
int timeOut = getParameterInt("timeOut", 5);
|
||||||
|
sshModel.setTimeOut(timeOut);
|
||||||
List<String> allowEditSuffixList = AgentWhitelist.parseToList(allowEditSuffix, "允许编辑的文件后缀不能为空");
|
List<String> allowEditSuffixList = AgentWhitelist.parseToList(allowEditSuffix, "允许编辑的文件后缀不能为空");
|
||||||
sshModel.allowEditSuffix(allowEditSuffixList);
|
sshModel.allowEditSuffix(allowEditSuffixList);
|
||||||
try {
|
try {
|
||||||
@ -205,6 +210,7 @@ public class SshController extends BaseServerController {
|
|||||||
Session session = SshService.getSessionByModel(sshModel);
|
Session session = SshService.getSessionByModel(sshModel);
|
||||||
JschUtil.close(session);
|
JschUtil.close(session);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
log.warn("ssh连接失败", e);
|
||||||
return JsonMessage.getString(505, "ssh连接失败:" + e.getMessage());
|
return JsonMessage.getString(505, "ssh连接失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
if (add) {
|
if (add) {
|
||||||
|
@ -80,6 +80,10 @@ public class SshModel extends BaseWorkspaceModel {
|
|||||||
* 允许编辑的后缀文件
|
* 允许编辑的后缀文件
|
||||||
*/
|
*/
|
||||||
private String allowEditSuffix;
|
private String allowEditSuffix;
|
||||||
|
/**
|
||||||
|
* 节点超时时间
|
||||||
|
*/
|
||||||
|
private Integer timeOut;
|
||||||
|
|
||||||
public SshModel(String id) {
|
public SshModel(String id) {
|
||||||
this.setId(id);
|
this.setId(id);
|
||||||
@ -118,6 +122,18 @@ public class SshModel extends BaseWorkspaceModel {
|
|||||||
return pas;
|
return pas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 超时时间
|
||||||
|
*
|
||||||
|
* @return 最小值 1 分钟
|
||||||
|
*/
|
||||||
|
public int timeOut() {
|
||||||
|
if (this.timeOut == null) {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
return Math.max(1, this.timeOut);
|
||||||
|
}
|
||||||
|
|
||||||
public Charset getCharsetT() {
|
public Charset getCharsetT() {
|
||||||
Charset charset;
|
Charset charset;
|
||||||
try {
|
try {
|
||||||
|
@ -30,6 +30,7 @@ import cn.hutool.core.io.resource.ResourceUtil;
|
|||||||
import cn.hutool.core.util.*;
|
import cn.hutool.core.util.*;
|
||||||
import cn.hutool.crypto.SecureUtil;
|
import cn.hutool.crypto.SecureUtil;
|
||||||
import cn.hutool.extra.ssh.ChannelType;
|
import cn.hutool.extra.ssh.ChannelType;
|
||||||
|
import cn.hutool.extra.ssh.JschRuntimeException;
|
||||||
import cn.hutool.extra.ssh.JschUtil;
|
import cn.hutool.extra.ssh.JschUtil;
|
||||||
import cn.hutool.extra.ssh.Sftp;
|
import cn.hutool.extra.ssh.Sftp;
|
||||||
import cn.jiangzeyin.common.spring.SpringUtil;
|
import cn.jiangzeyin.common.spring.SpringUtil;
|
||||||
@ -69,16 +70,16 @@ public class SshService extends BaseWorkspaceService<SshModel> {
|
|||||||
data.setPrivateKey(null);
|
data.setPrivateKey(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* 获取 ssh 回话
|
// * 获取 ssh 回话
|
||||||
*
|
// *
|
||||||
* @param sshId id
|
// * @param sshId id
|
||||||
* @return session
|
// * @return session
|
||||||
*/
|
// */
|
||||||
public static Session getSession(String sshId) {
|
// public static Session getSession(String sshId) {
|
||||||
SshModel sshModel = SpringUtil.getBean(SshService.class).getByKey(sshId, false);
|
// SshModel sshModel = SpringUtil.getBean(SshService.class).getByKey(sshId, false);
|
||||||
return getSessionByModel(sshModel);
|
// return getSessionByModel(sshModel);
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 ssh 回话
|
* 获取 ssh 回话
|
||||||
@ -88,9 +89,10 @@ public class SshService extends BaseWorkspaceService<SshModel> {
|
|||||||
*/
|
*/
|
||||||
public static Session getSessionByModel(SshModel sshModel) {
|
public static Session getSessionByModel(SshModel sshModel) {
|
||||||
Session session = null;
|
Session session = null;
|
||||||
|
int timeOut = (int) TimeUnit.SECONDS.toMillis(sshModel.timeOut());
|
||||||
SshModel.ConnectType connectType = sshModel.connectType();
|
SshModel.ConnectType connectType = sshModel.connectType();
|
||||||
if (connectType == SshModel.ConnectType.PASS) {
|
if (connectType == SshModel.ConnectType.PASS) {
|
||||||
session = JschUtil.openSession(sshModel.getHost(), sshModel.getPort(), sshModel.getUser(), sshModel.getPassword());
|
session = JschUtil.openSession(sshModel.getHost(), sshModel.getPort(), sshModel.getUser(), sshModel.getPassword(), timeOut);
|
||||||
|
|
||||||
} else if (connectType == SshModel.ConnectType.PUBKEY) {
|
} else if (connectType == SshModel.ConnectType.PUBKEY) {
|
||||||
File rsaFile = null;
|
File rsaFile = null;
|
||||||
@ -126,8 +128,13 @@ public class SshService extends BaseWorkspaceService<SshModel> {
|
|||||||
if (session == null) {
|
if (session == null) {
|
||||||
// 简要私钥文件是否存在
|
// 简要私钥文件是否存在
|
||||||
Assert.state(FileUtil.isFile(rsaFile), "私钥文件不存在:" + FileUtil.getAbsolutePath(rsaFile));
|
Assert.state(FileUtil.isFile(rsaFile), "私钥文件不存在:" + FileUtil.getAbsolutePath(rsaFile));
|
||||||
session = JschUtil.openSession(sshModel.getHost(),
|
session = JschUtil.createSession(sshModel.getHost(),
|
||||||
sshModel.getPort(), sshModel.getUser(), FileUtil.getAbsolutePath(rsaFile), sshModel.password());
|
sshModel.getPort(), sshModel.getUser(), FileUtil.getAbsolutePath(rsaFile), sshModel.password());
|
||||||
|
try {
|
||||||
|
session.connect(timeOut);
|
||||||
|
} catch (JSchException e) {
|
||||||
|
throw new JschRuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("不支持的模式");
|
throw new IllegalArgumentException("不支持的模式");
|
||||||
|
@ -97,4 +97,9 @@ ALTER TABLE NODE_INFO
|
|||||||
ALTER TABLE NODE_INFO
|
ALTER TABLE NODE_INFO
|
||||||
ADD IF NOT EXISTS httpProxyType VARCHAR(20) comment 'http 代理类型';
|
ADD IF NOT EXISTS httpProxyType VARCHAR(20) comment 'http 代理类型';
|
||||||
|
|
||||||
|
ALTER TABLE SSH_INFO
|
||||||
|
ADD IF NOT EXISTS timeOut int default 0 comment '节点超时时间';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ export function editSsh(params) {
|
|||||||
fileDirs: params.fileDirs,
|
fileDirs: params.fileDirs,
|
||||||
notAllowedCommand: params.notAllowedCommand,
|
notAllowedCommand: params.notAllowedCommand,
|
||||||
allowEditSuffix: params.allowEditSuffix,
|
allowEditSuffix: params.allowEditSuffix,
|
||||||
|
timeOut: params.timeOut,
|
||||||
};
|
};
|
||||||
return axios({
|
return axios({
|
||||||
url: "/node/ssh/save.json",
|
url: "/node/ssh/save.json",
|
||||||
|
@ -137,9 +137,7 @@
|
|||||||
|
|
||||||
<a-textarea v-model="temp.privateKey" :auto-size="{ minRows: 3, maxRows: 5 }" placeholder="私钥内容,不填将使用默认的 $HOME/.ssh 目录中的配置。支持配置文件目录:file:/xxxx/xx" />
|
<a-textarea v-model="temp.privateKey" :auto-size="{ minRows: 3, maxRows: 5 }" placeholder="私钥内容,不填将使用默认的 $HOME/.ssh 目录中的配置。支持配置文件目录:file:/xxxx/xx" />
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item label="编码格式" prop="charset">
|
|
||||||
<a-input v-model="temp.charset" placeholder="编码格式" />
|
|
||||||
</a-form-model-item>
|
|
||||||
<a-form-model-item prop="fileDirs">
|
<a-form-model-item prop="fileDirs">
|
||||||
<template slot="label">
|
<template slot="label">
|
||||||
文件目录
|
文件目录
|
||||||
@ -175,6 +173,16 @@
|
|||||||
placeholder="请输入允许编辑文件的后缀及文件编码,不设置编码则默认取系统编码,多个使用换行。示例:设置编码:txt@utf-8, 不设置编码:txt"
|
placeholder="请输入允许编辑文件的后缀及文件编码,不设置编码则默认取系统编码,多个使用换行。示例:设置编码:txt@utf-8, 不设置编码:txt"
|
||||||
/>
|
/>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
|
<a-collapse>
|
||||||
|
<a-collapse-panel key="1" header="其他配置">
|
||||||
|
<a-form-model-item label="编码格式" prop="charset">
|
||||||
|
<a-input v-model="temp.charset" placeholder="编码格式" />
|
||||||
|
</a-form-model-item>
|
||||||
|
<a-form-model-item label="超时时间(s)" prop="timeOut">
|
||||||
|
<a-input-number v-model="temp.timeOut" :min="1" placeholder="单位秒,最小值 1 秒" style="width: 100%" />
|
||||||
|
</a-form-model-item>
|
||||||
|
</a-collapse-panel>
|
||||||
|
</a-collapse>
|
||||||
</a-form-model>
|
</a-form-model>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
<!-- 安装节点 -->
|
<!-- 安装节点 -->
|
||||||
@ -554,6 +562,7 @@ export default {
|
|||||||
type: "add",
|
type: "add",
|
||||||
charset: "UTF-8",
|
charset: "UTF-8",
|
||||||
port: 22,
|
port: 22,
|
||||||
|
timeOut: 5,
|
||||||
connectType: "PASS",
|
connectType: "PASS",
|
||||||
};
|
};
|
||||||
this.editSshVisible = true;
|
this.editSshVisible = true;
|
||||||
@ -563,9 +572,16 @@ export default {
|
|||||||
// 修改
|
// 修改
|
||||||
handleEdit(record) {
|
handleEdit(record) {
|
||||||
this.temp = Object.assign({}, record);
|
this.temp = Object.assign({}, record);
|
||||||
this.temp.fileDirs = record.fileDirs ? JSON.parse(record.fileDirs).join("\r\n") : "";
|
// this.temp.;
|
||||||
this.temp.allowEditSuffix = record.allowEditSuffix ? JSON.parse(record.allowEditSuffix).join("\r\n") : "";
|
this.temp.allowEditSuffix = record.allowEditSuffix ? JSON.parse(record.allowEditSuffix).join("\r\n") : "";
|
||||||
this.temp.type = "edit";
|
// this.temp.type = "edit";
|
||||||
|
this.temp = {
|
||||||
|
...this.temp,
|
||||||
|
fileDirs: record.fileDirs ? JSON.parse(record.fileDirs).join("\r\n") : "",
|
||||||
|
type: "edit",
|
||||||
|
allowEditSuffix: record.allowEditSuffix ? JSON.parse(record.allowEditSuffix).join("\r\n") : "",
|
||||||
|
timeOut: record.timeOut || 5,
|
||||||
|
};
|
||||||
this.editSshVisible = true;
|
this.editSshVisible = true;
|
||||||
// @author jzy 08-04
|
// @author jzy 08-04
|
||||||
this.$refs["editSshForm"] && this.$refs["editSshForm"].resetFields();
|
this.$refs["editSshForm"] && this.$refs["editSshForm"].resetFields();
|
||||||
|
Loading…
Reference in New Issue
Block a user