feat: add preset scripts for synologydsm and fnos on deployment to ssh
This commit is contained in:
@@ -52,6 +52,8 @@ export const initPresetScript = (
|
||||
key: "sh_backup_files" | "ps_backup_files" | "sh_reload_nginx" | "ps_binding_iis" | "ps_binding_netsh" | "ps_binding_rdp",
|
||||
params?: {
|
||||
certPath?: string;
|
||||
certPathForServerOnly?: string;
|
||||
certPathForIntermediaOnly?: string;
|
||||
keyPath?: string;
|
||||
pfxPassword?: string;
|
||||
jksAlias?: string;
|
||||
@@ -77,19 +79,22 @@ if (Test-Path -Path "${params?.keyPath || "<your-key-path>"}" -PathType Leaf) {
|
||||
`.trim();
|
||||
|
||||
case "sh_reload_nginx":
|
||||
return `sudo service nginx reload`;
|
||||
return `# *** 需要 root 权限 ***
|
||||
|
||||
sudo service nginx reload
|
||||
`.trim();
|
||||
|
||||
case "ps_binding_iis":
|
||||
return `# 需要管理员权限
|
||||
return `# *** 需要管理员权限 ***
|
||||
|
||||
# 请将以下变量替换为实际值
|
||||
$pfxPath = "${params?.certPath || "<your-cert-path>"}" # PFX 文件路径
|
||||
$pfxPassword = "${params?.pfxPassword || "<your-pfx-password>"}" # PFX 密码
|
||||
$pfxPath = "${params?.certPath || "<your-cert-path>"}" # PFX 文件路径(与表单中保持一致)
|
||||
$pfxPassword = "${params?.pfxPassword || "<your-pfx-password>"}" # PFX 密码(与表单中保持一致)
|
||||
$siteName = "<your-site-name>" # IIS 网站名称
|
||||
$domain = "<your-domain-name>" # 域名
|
||||
$ipaddr = "<your-binding-ip>" # 绑定 IP,“*”表示所有 IP 绑定
|
||||
$port = "<your-binding-port>" # 绑定端口
|
||||
|
||||
|
||||
# 导入证书到本地计算机的个人存储区
|
||||
$cert = Import-PfxCertificate -FilePath "$pfxPath" -CertStoreLocation Cert:\\LocalMachine\\My -Password (ConvertTo-SecureString -String "$pfxPassword" -AsPlainText -Force) -Exportable
|
||||
# 获取 Thumbprint
|
||||
@@ -111,16 +116,16 @@ Remove-Item -Path "$pfxPath" -Force
|
||||
`.trim();
|
||||
|
||||
case "ps_binding_netsh":
|
||||
return `# 需要管理员权限
|
||||
return `# *** 需要管理员权限 ***
|
||||
|
||||
# 请将以下变量替换为实际值
|
||||
$pfxPath = "${params?.certPath || "<your-cert-path>"}" # PFX 文件路径
|
||||
$pfxPassword = "${params?.pfxPassword || "<your-pfx-password>"}" # PFX 密码
|
||||
$ipaddr = "<your-binding-ip>" # 绑定 IP,“0.0.0.0”表示所有 IP 绑定,可填入域名。
|
||||
$pfxPath = "${params?.certPath || "<your-cert-path>"}" # PFX 文件路径(与表单中保持一致)
|
||||
$pfxPassword = "${params?.pfxPassword || "<your-pfx-password>"}" # PFX 密码(与表单中保持一致)
|
||||
$ipaddr = "<your-binding-ip>" # 绑定 IP,“0.0.0.0”表示所有 IP 绑定,可填入域名
|
||||
$port = "<your-binding-port>" # 绑定端口
|
||||
|
||||
$addr = $ipaddr + ":" + $port
|
||||
|
||||
# 导入证书到本地计算机的个人存储区
|
||||
$addr = $ipaddr + ":" + $port
|
||||
$cert = Import-PfxCertificate -FilePath "$pfxPath" -CertStoreLocation Cert:\\LocalMachine\\My -Password (ConvertTo-SecureString -String "$pfxPassword" -AsPlainText -Force) -Exportable
|
||||
# 获取 Thumbprint
|
||||
$thumbprint = $cert.Thumbprint
|
||||
@@ -134,10 +139,11 @@ Remove-Item -Path "$pfxPath" -Force
|
||||
`.trim();
|
||||
|
||||
case "ps_binding_rdp":
|
||||
return `# 需要管理员权限
|
||||
return `# *** 需要管理员权限 ***
|
||||
|
||||
# 请将以下变量替换为实际值
|
||||
$pfxPath = "${params?.certPath || "<your-cert-path>"}" # PFX 文件路径
|
||||
$pfxPassword = "${params?.pfxPassword || "<your-pfx-password>"}" # PFX 密码
|
||||
$pfxPath = "${params?.certPath || "<your-cert-path>"}" # PFX 文件路径(与表单中保持一致)
|
||||
$pfxPassword = "${params?.pfxPassword || "<your-pfx-password>"}" # PFX 密码(与表单中保持一致)
|
||||
|
||||
# 导入证书到本地计算机的个人存储区
|
||||
$cert = Import-PfxCertificate -FilePath "$pfxPath" -CertStoreLocation Cert:\\LocalMachine\\My -Password (ConvertTo-SecureString -String "$pfxPassword" -AsPlainText -Force) -Exportable
|
||||
|
||||
@@ -8,7 +8,7 @@ import CodeInput from "@/components/CodeInput";
|
||||
import Show from "@/components/Show";
|
||||
import { CERTIFICATE_FORMATS } from "@/domain/certificate";
|
||||
|
||||
import { initPresetScript } from "./DeployNodeConfigFormLocalConfig";
|
||||
import { initPresetScript as _initPresetScript } from "./DeployNodeConfigFormLocalConfig";
|
||||
|
||||
type DeployNodeConfigFormSSHConfigFieldValues = Nullish<{
|
||||
format: string;
|
||||
@@ -45,6 +45,126 @@ const initFormModel = (): DeployNodeConfigFormSSHConfigFieldValues => {
|
||||
};
|
||||
};
|
||||
|
||||
const initPresetScript = (
|
||||
key: Parameters<typeof _initPresetScript>[0] | "sh_replace_synologydsm_ssl" | "sh_replace_fnos_ssl",
|
||||
params?: Parameters<typeof _initPresetScript>[1]
|
||||
) => {
|
||||
switch (key) {
|
||||
case "sh_replace_synologydsm_ssl":
|
||||
return `# *** 需要 root 权限 ***
|
||||
# 脚本参考 https://github.com/catchdave/ssl-certs/blob/main/replace_synology_ssl_certs.sh
|
||||
|
||||
# 请将以下变量替换为实际值
|
||||
$tmpFullchainPath = "${params?.certPath || "<your-fullchain-cert-path>"}" # 证书文件路径(与表单中保持一致)
|
||||
$tmpCertPath = "${params?.certPathForServerOnly || "<your-server-cert-path>"}" # 服务器证书文件路径(与表单中保持一致)
|
||||
$tmpKeyPath = "${params?.keyPath || "<your-key-path>"}" # 私钥文件路径(与表单中保持一致)
|
||||
|
||||
DEBUG=1
|
||||
error_exit() { echo "[ERROR] $1"; exit 1; }
|
||||
warn() { echo "[WARN] $1"; }
|
||||
info() { echo "[INFO] $1"; }
|
||||
debug() { [[ "\${DEBUG}" ]] && echo "[DEBUG] $1"; }
|
||||
|
||||
certs_src_dir="/usr/syno/etc/certificate/system/default"
|
||||
target_cert_dirs=(
|
||||
"/usr/syno/etc/certificate/system/FQDN"
|
||||
"/usr/local/etc/certificate/ScsiTarget/pkg-scsi-plugin-server/"
|
||||
"/usr/local/etc/certificate/SynologyDrive/SynologyDrive/"
|
||||
"/usr/local/etc/certificate/WebDAVServer/webdav/"
|
||||
"/usr/local/etc/certificate/ActiveBackup/ActiveBackup/"
|
||||
"/usr/syno/etc/certificate/smbftpd/ftpd/")
|
||||
|
||||
# 获取证书目录
|
||||
default_dir_name=$(</usr/syno/etc/certificate/_archive/DEFAULT)
|
||||
if [[ -n "$default_dir_name" ]]; then
|
||||
target_cert_dirs+=("/usr/syno/etc/certificate/_archive/\${default_dir_name}")
|
||||
debug "Default cert directory found: '/usr/syno/etc/certificate/_archive/\${default_dir_name}'"
|
||||
else
|
||||
warn "No default directory found. Probably unusual? Check: 'cat /usr/syno/etc/certificate/_archive/DEFAULT'"
|
||||
fi
|
||||
|
||||
# 获取反向代理证书目录
|
||||
for proxy in /usr/syno/etc/certificate/ReverseProxy/*/; do
|
||||
debug "Found proxy dir: \${proxy}"
|
||||
target_cert_dirs+=("\${proxy}")
|
||||
done
|
||||
|
||||
[[ "\${DEBUG}" ]] && set -x
|
||||
|
||||
# 复制文件
|
||||
cp -rf "$tmpFullchainPath" "\${certs_src_dir}/fullchain.pem" || error_exit "Halting because of error moving fullchain file"
|
||||
cp -rf "$tmpCertPath" "\${certs_src_dir}/cert.pem" || error_exit "Halting because of error moving cert file"
|
||||
cp -rf "$tmpKeyPath" "\${certs_src_dir}/privkey.pem" || error_exit "Halting because of error moving privkey file"
|
||||
chown root:root "\${certs_src_dir}/"{privkey,fullchain,cert}.pem || error_exit "Halting because of error chowning files"
|
||||
info "Certs moved from /tmp & chowned."
|
||||
|
||||
# 替换证书
|
||||
for target_dir in "\${target_cert_dirs[@]}"; do
|
||||
if [[ ! -d "$target_dir" ]]; then
|
||||
debug "Target cert directory '$target_dir' not found, skipping..."
|
||||
continue
|
||||
fi
|
||||
info "Copying certificates to '$target_dir'"
|
||||
if ! (cp "\${certs_src_dir}/"{privkey,fullchain,cert}.pem "$target_dir/" && \
|
||||
chown root:root "$target_dir/"{privkey,fullchain,cert}.pem); then
|
||||
warn "Error copying or chowning certs to \${target_dir}"
|
||||
fi
|
||||
done
|
||||
|
||||
# 重启服务
|
||||
info "Rebooting all the things..."
|
||||
/usr/syno/bin/synosystemctl restart nmbd
|
||||
/usr/syno/bin/synosystemctl restart avahi
|
||||
/usr/syno/bin/synosystemctl restart ldap-server
|
||||
/usr/syno/bin/synopkg is_onoff ScsiTarget 1>/dev/null && /usr/syno/bin/synopkg restart ScsiTarget
|
||||
/usr/syno/bin/synopkg is_onoff SynologyDrive 1>/dev/null && /usr/syno/bin/synopkg restart SynologyDrive
|
||||
/usr/syno/bin/synopkg is_onoff WebDAVServer 1>/dev/null && /usr/syno/bin/synopkg restart WebDAVServer
|
||||
/usr/syno/bin/synopkg is_onoff ActiveBackup 1>/dev/null && /usr/syno/bin/synopkg restart ActiveBackup
|
||||
if ! /usr/syno/bin/synow3tool --gen-all && sudo /usr/syno/bin/synosystemctl restart nginx; then
|
||||
warn "nginx failed to restart"
|
||||
fi
|
||||
|
||||
info "Completed"
|
||||
`.trim();
|
||||
|
||||
case "sh_replace_fnos_ssl":
|
||||
return `# *** 需要 root 权限 ***
|
||||
# 脚本参考 https://github.com/lfgyx/fnos_certificate_update/blob/main/src/update_cert.sh
|
||||
|
||||
|
||||
# 请将以下变量替换为实际值
|
||||
# 飞牛证书实际存放路径请在 \`/usr/trim/etc/network_cert_all.conf\` 中查看,注意不要修改文件名
|
||||
$tmpFullchainPath = "${params?.certPath || "<your-fullchain-cert-path>"}" # 证书文件路径(与表单中保持一致)
|
||||
$tmpCertPath = "${params?.certPathForServerOnly || "<your-server-cert-path>"}" # 服务器证书文件路径(与表单中保持一致)
|
||||
$tmpKeyPath = "${params?.keyPath || "<your-key-path>"}" # 私钥文件路径(与表单中保持一致)
|
||||
$fnFullchainPath = "/usr/trim/var/trim_connect/ssls/example.com/1234567890/fullchain.crt" # 飞牛证书文件路径
|
||||
$fnCertPath = "/usr/trim/var/trim_connect/ssls/example.com/1234567890/example.com.crt" # 飞牛服务器证书文件路径
|
||||
$fnKeyPath = "/usr/trim/var/trim_connect/ssls/example.com/1234567890/example.com.key" # 飞牛私钥文件路径
|
||||
$domain = "<your-domain-name>" # 域名
|
||||
|
||||
# 复制文件
|
||||
cp -rf "$tmpFullchainPath" "$fnFullchainPath"
|
||||
cp -rf "$tmpCertPath" "$fnCertPath"
|
||||
cp -rf "$tmpKeyPath" "$fnKeyPath"
|
||||
chmod 755 "$fnCertPath"
|
||||
chmod 755 "$fnKeyPath"
|
||||
chmod 755 "$fnFullchainPath"
|
||||
|
||||
# 更新数据库
|
||||
NEW_EXPIRY_DATE=$(openssl x509 -enddate -noout -in "$fnCertPath" | sed "s/^.*=\\(.*\\)$/\\1/")
|
||||
NEW_EXPIRY_TIMESTAMP=$(date -d "$NEW_EXPIRY_DATE" +%s%3N)
|
||||
psql -U postgres -d trim_connect -c "UPDATE cert SET valid_to=$NEW_EXPIRY_TIMESTAMP WHERE domain='$domain'"
|
||||
|
||||
# 重启服务
|
||||
systemctl restart webdav.service
|
||||
systemctl restart smbftpd.service
|
||||
systemctl restart trim_nginx.service
|
||||
`.trim();
|
||||
}
|
||||
|
||||
return _initPresetScript(key as Parameters<typeof _initPresetScript>[0], params);
|
||||
};
|
||||
|
||||
const DeployNodeConfigFormSSHConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: DeployNodeConfigFormSSHConfigProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -160,6 +280,24 @@ const DeployNodeConfigFormSSHConfig = ({ form: formInst, formName, disabled, ini
|
||||
const handlePresetPostScriptClick = (key: string) => {
|
||||
switch (key) {
|
||||
case "sh_reload_nginx":
|
||||
{
|
||||
formInst.setFieldValue("postCommand", initPresetScript(key));
|
||||
}
|
||||
break;
|
||||
|
||||
case "sh_replace_synologydsm_ssl":
|
||||
case "sh_replace_fnos_ssl":
|
||||
{
|
||||
const presetScriptParams = {
|
||||
certPath: formInst.getFieldValue("certPath"),
|
||||
certPathForServerOnly: formInst.getFieldValue("certPathForServerOnly"),
|
||||
certPathForIntermediaOnly: formInst.getFieldValue("certPathForIntermediaOnly"),
|
||||
keyPath: formInst.getFieldValue("keyPath"),
|
||||
};
|
||||
formInst.setFieldValue("postCommand", initPresetScript(key, presetScriptParams));
|
||||
}
|
||||
break;
|
||||
|
||||
case "ps_binding_iis":
|
||||
case "ps_binding_netsh":
|
||||
case "ps_binding_rdp":
|
||||
@@ -324,11 +462,13 @@ const DeployNodeConfigFormSSHConfig = ({ form: formInst, formName, disabled, ini
|
||||
<div className="text-right">
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: ["sh_reload_nginx", "ps_binding_iis", "ps_binding_netsh", "ps_binding_rdp"].map((key) => ({
|
||||
key,
|
||||
label: t(`workflow_node.deploy.form.ssh_preset_scripts.option.${key}.label`),
|
||||
onClick: () => handlePresetPostScriptClick(key),
|
||||
})),
|
||||
items: ["sh_reload_nginx", "sh_replace_synologydsm_ssl", "sh_replace_fnos_ssl", "ps_binding_iis", "ps_binding_netsh", "ps_binding_rdp"].map(
|
||||
(key) => ({
|
||||
key,
|
||||
label: t(`workflow_node.deploy.form.ssh_preset_scripts.option.${key}.label`),
|
||||
onClick: () => handlePresetPostScriptClick(key),
|
||||
})
|
||||
),
|
||||
}}
|
||||
trigger={["click"]}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user