update
This commit is contained in:
parent
6dd06b9141
commit
fac9447910
124
CHANGELOG.md
124
CHANGELOG.md
@ -1,62 +1,62 @@
|
|||||||
## [2.0.0-beta](https://github.com/chaos-zhu/easynode/releases) (2024-07-13)
|
## [2.0.0-beta](https://github.com/chaos-zhu/easynode/releases) (2024-07-13)
|
||||||
|
|
||||||
底层代码重构
|
底层代码重构
|
||||||
|
|
||||||
## [1.2.1](https://github.com/chaos-zhu/easynode/releases) (2022-12-12)
|
## [1.2.1](https://github.com/chaos-zhu/easynode/releases) (2022-12-12)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* 新增支持终端长命令输入模式 ✔
|
* 新增支持终端长命令输入模式 ✔
|
||||||
* 新增前端静态文件缓存 ✔
|
* 新增前端静态文件缓存 ✔
|
||||||
* 【重要】v1.2.1开始移除创建https服务 ✔
|
* 【重要】v1.2.1开始移除创建https服务 ✔
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* v1.2的若干bug...
|
* v1.2的若干bug...
|
||||||
|
|
||||||
## [1.2.0](https://github.com/chaos-zhu/easynode/releases) (2022-09-12)
|
## [1.2.0](https://github.com/chaos-zhu/easynode/releases) (2022-09-12)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* 新增邮件通知: 包括登录面板、密码修改、服务器到期、服务器离线等 ✔
|
* 新增邮件通知: 包括登录面板、密码修改、服务器到期、服务器离线等 ✔
|
||||||
* 支持服务器分组(为新版UI作准备的) ✔
|
* 支持服务器分组(为新版UI作准备的) ✔
|
||||||
* 面板功能调整,支持http延迟显示、支持服务器控制台直达与到期时间字段 ✔
|
* 面板功能调整,支持http延迟显示、支持服务器控制台直达与到期时间字段 ✔
|
||||||
* 优化终端输入、支持状态面板收缩 ✔
|
* 优化终端输入、支持状态面板收缩 ✔
|
||||||
* **全新SFTP功能支持,上传下载进度条展示** ✔
|
* **全新SFTP功能支持,上传下载进度条展示** ✔
|
||||||
* **支持在线文件编辑与保存** ✔
|
* **支持在线文件编辑与保存** ✔
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* v1.1的若干bug...
|
* v1.1的若干bug...
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## [1.1.0](https://github.com/chaos-zhu/easynode/releases) (2022-06-27)
|
## [1.1.0](https://github.com/chaos-zhu/easynode/releases) (2022-06-27)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* ssh密钥/密码(采用对称AES+RSA非对称双加密传输与存储)、jwtToken(服务端对称加密传输) ✔
|
* ssh密钥/密码(采用对称AES+RSA非对称双加密传输与存储)、jwtToken(服务端对称加密传输) ✔
|
||||||
* 加密储存登录密码 ✔
|
* 加密储存登录密码 ✔
|
||||||
* 登录IP检测机制&历史登录查询✔
|
* 登录IP检测机制&历史登录查询✔
|
||||||
* 终端多tab支持✔
|
* 终端多tab支持✔
|
||||||
* 终端页左侧栏信息✔
|
* 终端页左侧栏信息✔
|
||||||
* 客户端支持ARM实例✔
|
* 客户端支持ARM实例✔
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* 修复终端展示异常的Bug✔
|
* 修复终端展示异常的Bug✔
|
||||||
* 修复保存私钥时第二次选择无效的bug✔
|
* 修复保存私钥时第二次选择无效的bug✔
|
||||||
* 修复面板客户端探针断开更新不及时的bug✔
|
* 修复面板客户端探针断开更新不及时的bug✔
|
||||||
* 修复移除主机未移除ssh密钥信息的bug✔
|
* 修复移除主机未移除ssh密钥信息的bug✔
|
||||||
* 修复服务器排序bug✔
|
* 修复服务器排序bug✔
|
||||||
* 解决https下无法socket连接到客户端bug✔
|
* 解决https下无法socket连接到客户端bug✔
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## [1.0.0](https://github.com/chaos-zhu/easynode/releases) (2022-06-08)
|
## [1.0.0](https://github.com/chaos-zhu/easynode/releases) (2022-06-08)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* 通过`websocker实时更新`服务器基本信息: 系统、公网IP、CPU、内存、硬盘、网卡等
|
* 通过`websocker实时更新`服务器基本信息: 系统、公网IP、CPU、内存、硬盘、网卡等
|
||||||
* 解决`SSH跨端同步`问题——Web SSH
|
* 解决`SSH跨端同步`问题——Web SSH
|
||||||
|
40
Q&A.md
40
Q&A.md
@ -1,20 +1,20 @@
|
|||||||
# Q&A
|
# Q&A
|
||||||
|
|
||||||
## CentOS7/8启动服务失败
|
## CentOS7/8启动服务失败
|
||||||
|
|
||||||
> 先关闭SELinux
|
> 先关闭SELinux
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
vi /etc/selinux/config
|
vi /etc/selinux/config
|
||||||
SELINUX=enforcing
|
SELINUX=enforcing
|
||||||
// 修改为禁用
|
// 修改为禁用
|
||||||
SELINUX=disabled
|
SELINUX=disabled
|
||||||
```
|
```
|
||||||
|
|
||||||
> 重启:`reboot`,再使用一键脚本安装
|
> 重启:`reboot`,再使用一键脚本安装
|
||||||
|
|
||||||
> 查看SELinux状态:sestatus
|
> 查看SELinux状态:sestatus
|
||||||
|
|
||||||
## 客户端服务启动成功,无法连接?
|
## 客户端服务启动成功,无法连接?
|
||||||
|
|
||||||
> 端口未开放:`iptables -I INPUT -s 0.0.0.0/0 -p tcp --dport 22022 -j ACCEPT` 或者 `rm -rf /etc/iptables && reboot`
|
> 端口未开放:`iptables -I INPUT -s 0.0.0.0/0 -p tcp --dport 22022 -j ACCEPT` 或者 `rm -rf /etc/iptables && reboot`
|
||||||
|
12
README.md
12
README.md
@ -1,6 +1,6 @@
|
|||||||
# 重构中, 老版本切换v1.2分支部署
|
# 重构中, 老版本切换v1.2分支部署
|
||||||
|
|
||||||
## EasyNode
|
## EasyNode
|
||||||
|
|
||||||
> 一个简易的个人Linux服务器管理面板.
|
> 一个简易的个人Linux服务器管理面板.
|
||||||
|
|
||||||
|
@ -1,67 +1,67 @@
|
|||||||
const { Server } = require('socket.io')
|
const { Server } = require('socket.io')
|
||||||
const schedule = require('node-schedule')
|
const schedule = require('node-schedule')
|
||||||
const axios = require('axios')
|
const axios = require('axios')
|
||||||
let getOsData = require('../utils/os-data')
|
let getOsData = require('../utils/os-data')
|
||||||
|
|
||||||
let serverSockets = {}, ipInfo = {}, osData = {}
|
let serverSockets = {}, ipInfo = {}, osData = {}
|
||||||
|
|
||||||
async function getIpInfo() {
|
async function getIpInfo() {
|
||||||
try {
|
try {
|
||||||
let { data } = await axios.get('http://ip-api.com/json?lang=zh-CN')
|
let { data } = await axios.get('http://ip-api.com/json?lang=zh-CN')
|
||||||
console.log('getIpInfo Success: ', new Date())
|
console.log('getIpInfo Success: ', new Date())
|
||||||
ipInfo = data
|
ipInfo = data
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('getIpInfo Error: ', new Date(), error)
|
console.log('getIpInfo Error: ', new Date(), error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ipSchedule() {
|
function ipSchedule() {
|
||||||
let rule1 = new schedule.RecurrenceRule()
|
let rule1 = new schedule.RecurrenceRule()
|
||||||
rule1.second = [0, 10, 20, 30, 40, 50]
|
rule1.second = [0, 10, 20, 30, 40, 50]
|
||||||
schedule.scheduleJob(rule1, () => {
|
schedule.scheduleJob(rule1, () => {
|
||||||
let { query, country, city } = ipInfo || {}
|
let { query, country, city } = ipInfo || {}
|
||||||
if(query && country && city) return
|
if(query && country && city) return
|
||||||
console.log('Task: start getIpInfo', new Date())
|
console.log('Task: start getIpInfo', new Date())
|
||||||
getIpInfo()
|
getIpInfo()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 每日凌晨两点整,刷新ip信息(兼容动态ip服务器)
|
// 每日凌晨两点整,刷新ip信息(兼容动态ip服务器)
|
||||||
let rule2 = new schedule.RecurrenceRule()
|
let rule2 = new schedule.RecurrenceRule()
|
||||||
rule2.hour = 2
|
rule2.hour = 2
|
||||||
rule2.minute = 0
|
rule2.minute = 0
|
||||||
rule2.second = 0
|
rule2.second = 0
|
||||||
schedule.scheduleJob(rule2, () => {
|
schedule.scheduleJob(rule2, () => {
|
||||||
console.log('Task: refresh ip info', new Date())
|
console.log('Task: refresh ip info', new Date())
|
||||||
getIpInfo()
|
getIpInfo()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
ipSchedule()
|
ipSchedule()
|
||||||
|
|
||||||
module.exports = (httpServer) => {
|
module.exports = (httpServer) => {
|
||||||
const serverIo = new Server(httpServer, {
|
const serverIo = new Server(httpServer, {
|
||||||
path: '/client/os-info',
|
path: '/client/os-info',
|
||||||
cors: {
|
cors: {
|
||||||
origin: '*'
|
origin: '*'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
serverIo.on('connection', (socket) => {
|
serverIo.on('connection', (socket) => {
|
||||||
serverSockets[socket.id] = setInterval(async () => {
|
serverSockets[socket.id] = setInterval(async () => {
|
||||||
try {
|
try {
|
||||||
osData = await getOsData()
|
osData = await getOsData()
|
||||||
socket && socket.emit('client_data', Object.assign(osData, { ipInfo }))
|
socket && socket.emit('client_data', Object.assign(osData, { ipInfo }))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('客户端错误:', error)
|
console.error('客户端错误:', error)
|
||||||
socket && socket.emit('client_error', { error })
|
socket && socket.emit('client_error', { error })
|
||||||
}
|
}
|
||||||
}, 1500)
|
}, 1500)
|
||||||
|
|
||||||
socket.on('disconnect', () => {
|
socket.on('disconnect', () => {
|
||||||
if(serverSockets[socket.id]) clearInterval(serverSockets[socket.id])
|
if(serverSockets[socket.id]) clearInterval(serverSockets[socket.id])
|
||||||
delete serverSockets[socket.id]
|
delete serverSockets[socket.id]
|
||||||
socket.close && socket.close()
|
socket.close && socket.close()
|
||||||
socket = null
|
socket = null
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,35 @@
|
|||||||
{
|
{
|
||||||
"name": "easynode-client",
|
"name": "easynode-client",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "easynode-client",
|
"description": "easynode-client",
|
||||||
"bin": "./bin/www",
|
"bin": "./bin/www",
|
||||||
"pkg": {
|
"pkg": {
|
||||||
"outputPath": "dist"
|
"outputPath": "dist"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"client": "nodemon ./app/main.js",
|
"client": "nodemon ./app/main.js",
|
||||||
"pkgwin": "pkg . -t node16-win-x64",
|
"pkgwin": "pkg . -t node16-win-x64",
|
||||||
"pkglinux:x86": "pkg . -t node16-linux-x64",
|
"pkglinux:x86": "pkg . -t node16-linux-x64",
|
||||||
"pkglinux:arm": "pkg . -t node16-linux-arm64"
|
"pkglinux:arm": "pkg . -t node16-linux-arm64"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"nodemonConfig": {
|
"nodemonConfig": {
|
||||||
"ignore": [
|
"ignore": [
|
||||||
"*.json"
|
"*.json"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.21.4",
|
"axios": "^0.21.4",
|
||||||
"koa": "^2.13.1",
|
"koa": "^2.13.1",
|
||||||
"node-os-utils": "^1.3.6",
|
"node-os-utils": "^1.3.6",
|
||||||
"node-schedule": "^2.1.0",
|
"node-schedule": "^2.1.0",
|
||||||
"socket.io": "^4.4.1"
|
"socket.io": "^4.4.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"nodemon": "^2.0.15",
|
"nodemon": "^2.0.15",
|
||||||
"pkg": "5.6"
|
"pkg": "5.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user