mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 04:22:33 +08:00
feat: 优化ssh
This commit is contained in:
@@ -17,7 +17,7 @@ type ToolboxSSHPubKeyAuth struct {
|
||||
|
||||
// ToolboxSSHRootLogin Root 登录设置
|
||||
type ToolboxSSHRootLogin struct {
|
||||
Mode string `form:"mode" json:"mode" validate:"required|in:yes,no,without-password,prohibit-password"`
|
||||
Mode string `form:"mode" json:"mode" validate:"required|in:yes,no,prohibit-password,forced-commands-only"`
|
||||
}
|
||||
|
||||
// ToolboxSSHRootPassword Root 密码设置
|
||||
|
||||
@@ -454,9 +454,6 @@ func (route *Http) Register(r *chi.Mux) {
|
||||
|
||||
r.Route("/toolbox_ssh", func(r chi.Router) {
|
||||
r.Get("/info", route.toolboxSSH.GetInfo)
|
||||
r.Post("/start", route.toolboxSSH.Start)
|
||||
r.Post("/stop", route.toolboxSSH.Stop)
|
||||
r.Post("/restart", route.toolboxSSH.Restart)
|
||||
r.Post("/port", route.toolboxSSH.UpdatePort)
|
||||
r.Post("/password_auth", route.toolboxSSH.UpdatePasswordAuth)
|
||||
r.Post("/pubkey_auth", route.toolboxSSH.UpdatePubKeyAuth)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/acepanel/panel/pkg/os"
|
||||
"github.com/leonelquinteros/gotext"
|
||||
"github.com/libtnb/chix"
|
||||
"github.com/spf13/cast"
|
||||
@@ -16,12 +17,19 @@ import (
|
||||
)
|
||||
|
||||
type ToolboxSSHService struct {
|
||||
t *gotext.Locale
|
||||
t *gotext.Locale
|
||||
service string
|
||||
}
|
||||
|
||||
func NewToolboxSSHService(t *gotext.Locale) *ToolboxSSHService {
|
||||
// 沟槽的大便和乌班图喜欢搞特殊
|
||||
service := "sshd"
|
||||
if os.IsDebian() || os.IsUbuntu() {
|
||||
service = "ssh"
|
||||
}
|
||||
return &ToolboxSSHService{
|
||||
t: t,
|
||||
t: t,
|
||||
service: service,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,16 +42,6 @@ func (s *ToolboxSSHService) GetInfo(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// 获取 SSH 服务状态
|
||||
status, err := systemctl.Status("sshd")
|
||||
if err != nil {
|
||||
// 尝试 ssh 服务名
|
||||
status, err = systemctl.Status("ssh")
|
||||
if err != nil {
|
||||
status = false
|
||||
}
|
||||
}
|
||||
|
||||
// 解析端口
|
||||
port := 22
|
||||
portMatch := regexp.MustCompile(`(?m)^Port\s+(\d+)`).FindStringSubmatch(sshdConfig)
|
||||
@@ -73,7 +71,7 @@ func (s *ToolboxSSHService) GetInfo(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
Success(w, chix.M{
|
||||
"status": status,
|
||||
"service": s.service,
|
||||
"port": port,
|
||||
"password_auth": passwordAuth,
|
||||
"pubkey_auth": pubKeyAuth,
|
||||
@@ -81,45 +79,6 @@ func (s *ToolboxSSHService) GetInfo(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
}
|
||||
|
||||
// Start 启动 SSH 服务
|
||||
func (s *ToolboxSSHService) Start(w http.ResponseWriter, r *http.Request) {
|
||||
err := systemctl.Start("sshd")
|
||||
if err != nil {
|
||||
err = systemctl.Start("ssh")
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to start SSH service: %v", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
// Stop 停止 SSH 服务
|
||||
func (s *ToolboxSSHService) Stop(w http.ResponseWriter, r *http.Request) {
|
||||
err := systemctl.Stop("sshd")
|
||||
if err != nil {
|
||||
err = systemctl.Stop("ssh")
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to stop SSH service: %v", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
// Restart 重启 SSH 服务
|
||||
func (s *ToolboxSSHService) Restart(w http.ResponseWriter, r *http.Request) {
|
||||
err := systemctl.Restart("sshd")
|
||||
if err != nil {
|
||||
err = systemctl.Restart("ssh")
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to restart SSH service: %v", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
// UpdatePort 修改 SSH 端口
|
||||
func (s *ToolboxSSHService) UpdatePort(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := Bind[request.ToolboxSSHPort](r)
|
||||
@@ -133,9 +92,8 @@ func (s *ToolboxSSHService) UpdatePort(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// 重启 SSH 服务
|
||||
if err = s.restartSSH(); err != nil {
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to restart SSH service: %v", err))
|
||||
if err = systemctl.Restart(s.service); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -160,8 +118,8 @@ func (s *ToolboxSSHService) UpdatePasswordAuth(w http.ResponseWriter, r *http.Re
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.restartSSH(); err != nil {
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to restart SSH service: %v", err))
|
||||
if err = systemctl.Restart(s.service); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -186,8 +144,8 @@ func (s *ToolboxSSHService) UpdatePubKeyAuth(w http.ResponseWriter, r *http.Requ
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.restartSSH(); err != nil {
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to restart SSH service: %v", err))
|
||||
if err = systemctl.Restart(s.service); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -207,8 +165,8 @@ func (s *ToolboxSSHService) UpdateRootLogin(w http.ResponseWriter, r *http.Reque
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.restartSSH(); err != nil {
|
||||
Error(w, http.StatusInternalServerError, s.t.Get("failed to restart SSH service: %v", err))
|
||||
if err = systemctl.Restart(s.service); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -303,7 +261,7 @@ func (s *ToolboxSSHService) GenerateRootKey(w http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
}
|
||||
|
||||
_ = s.restartSSH()
|
||||
_ = systemctl.Restart(s.service)
|
||||
|
||||
Success(w, privateKey)
|
||||
}
|
||||
@@ -328,12 +286,3 @@ func (s *ToolboxSSHService) updateSSHConfig(key, value string) error {
|
||||
|
||||
return io.Write("/etc/ssh/sshd_config", sshdConfig, 0600)
|
||||
}
|
||||
|
||||
// restartSSH 重启 SSH 服务
|
||||
func (s *ToolboxSSHService) restartSSH() error {
|
||||
err := systemctl.Restart("sshd")
|
||||
if err != nil {
|
||||
err = systemctl.Restart("ssh")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -3,12 +3,6 @@ import { http } from '@/utils'
|
||||
export default {
|
||||
// 获取 SSH 信息
|
||||
info: (): any => http.Get('/toolbox_ssh/info'),
|
||||
// 启动 SSH 服务
|
||||
start: (): any => http.Post('/toolbox_ssh/start'),
|
||||
// 停止 SSH 服务
|
||||
stop: (): any => http.Post('/toolbox_ssh/stop'),
|
||||
// 重启 SSH 服务
|
||||
restart: (): any => http.Post('/toolbox_ssh/restart'),
|
||||
// 设置 SSH 端口
|
||||
updatePort: (port: number): any => http.Post('/toolbox_ssh/port', { port }),
|
||||
// 设置密码认证
|
||||
|
||||
@@ -4,6 +4,7 @@ defineOptions({
|
||||
})
|
||||
|
||||
import toolboxSSH from '@/api/panel/toolbox-ssh'
|
||||
import ServiceStatus from '@/components/common/ServiceStatus.vue'
|
||||
import TheIcon from '@/components/custom/TheIcon.vue'
|
||||
import { generateRandomString } from '@/utils'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
@@ -11,13 +12,13 @@ import { useGettext } from 'vue3-gettext'
|
||||
const { $gettext } = useGettext()
|
||||
|
||||
// SSH 基础设置
|
||||
const sshStatus = ref(false)
|
||||
const service = ref('')
|
||||
const sshPort = ref(22)
|
||||
const passwordAuth = ref(false)
|
||||
const pubkeyAuth = ref(true)
|
||||
|
||||
// Root 设置
|
||||
const rootLogin = ref('without-password')
|
||||
const rootLogin = ref('yes')
|
||||
const rootPassword = ref('')
|
||||
const rootKey = ref('')
|
||||
|
||||
@@ -33,7 +34,7 @@ const keyLoading = ref(false)
|
||||
// Root 登录选项
|
||||
const rootLoginOptions = [
|
||||
{ label: 'yes - ' + $gettext('Allow password and key login'), value: 'yes' },
|
||||
{ label: 'no - ' + $gettext('Disable root login'), value: 'no' },
|
||||
{ label: 'no - ' + $gettext('Disable login'), value: 'no' },
|
||||
{
|
||||
label: 'prohibit-password - ' + $gettext('Only allow key login (recommended)'),
|
||||
value: 'prohibit-password'
|
||||
@@ -49,7 +50,7 @@ const loadData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const info = await toolboxSSH.info()
|
||||
sshStatus.value = info.status
|
||||
service.value = info.service
|
||||
sshPort.value = info.port
|
||||
passwordAuth.value = info.password_auth
|
||||
pubkeyAuth.value = info.pubkey_auth
|
||||
@@ -63,34 +64,6 @@ const loadData = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 切换 SSH 服务状态
|
||||
const handleToggleSSH = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
if (sshStatus.value) {
|
||||
await toolboxSSH.stop()
|
||||
window.$message.success($gettext('SSH service stopped'))
|
||||
} else {
|
||||
await toolboxSSH.start()
|
||||
window.$message.success($gettext('SSH service started'))
|
||||
}
|
||||
sshStatus.value = !sshStatus.value
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 重启 SSH 服务
|
||||
const handleRestartSSH = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
await toolboxSSH.restart()
|
||||
window.$message.success($gettext('SSH service restarted'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 更新端口
|
||||
const handleUpdatePort = async () => {
|
||||
portLoading.value = true
|
||||
@@ -224,16 +197,10 @@ onMounted(() => {
|
||||
<template>
|
||||
<n-spin :show="loading">
|
||||
<n-flex vertical :size="24">
|
||||
<service-status v-if="service != ''" :service="service" />
|
||||
<!-- SSH 服务 -->
|
||||
<n-card :title="$gettext('SSH Service')">
|
||||
<n-card :title="$gettext('SSH Settings')">
|
||||
<n-flex vertical :size="16">
|
||||
<n-flex align="center" :size="12">
|
||||
<n-text strong>{{ $gettext('SSH Service Status') }}</n-text>
|
||||
<n-switch :value="sshStatus" :loading="loading" @update:value="handleToggleSSH" />
|
||||
<n-button :loading="loading" @click="handleRestartSSH">
|
||||
{{ $gettext('Restart') }}
|
||||
</n-button>
|
||||
</n-flex>
|
||||
<!-- SSH 密码登录 -->
|
||||
<n-flex vertical :size="4">
|
||||
<n-flex align="center" :size="12">
|
||||
@@ -256,9 +223,7 @@ onMounted(() => {
|
||||
@update:value="handleTogglePubkeyAuth"
|
||||
/>
|
||||
</n-flex>
|
||||
<n-text depth="3">{{
|
||||
$gettext('Allow key authentication for SSH login')
|
||||
}}</n-text>
|
||||
<n-text depth="3">{{ $gettext('Allow key authentication for SSH login') }}</n-text>
|
||||
</n-flex>
|
||||
<!-- SSH 端口 -->
|
||||
<n-flex vertical :size="4">
|
||||
|
||||
@@ -38,7 +38,7 @@ const columns: any = [
|
||||
{
|
||||
title: 'Key',
|
||||
key: 'key',
|
||||
minWidth: 200,
|
||||
width: 300,
|
||||
resizable: true,
|
||||
ellipsis: { tooltip: true },
|
||||
render(row: any) {
|
||||
@@ -298,7 +298,7 @@ onMounted(() => {
|
||||
<n-data-table
|
||||
striped
|
||||
remote
|
||||
:scroll-x="1400"
|
||||
:scroll-x="1500"
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
|
||||
Reference in New Issue
Block a user