一、极空间 SSH

开启 SSH

极空间终于开放 SSH 权限了,这可真是不容易呀,以前简直像防家贼一样。在“设置-系统设置-远程协助-SSH”处可以开启 SSH 访问权限,同时在默认的 Docker 应用中也可以设置 Privileged Mode 咯。不过它又是限制端口(10000 以上),又限制账户,都开放权限了真不至于,略显矫情。

关于安全方面的提醒:建议禁用密码登录,仅允许使用密钥登录

安装 1Panel 面板

话说回来,各位吴彦祖们,不考虑安装个 1Panel 面板,用以辅助管理系统吗?

curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sudo bash quick_start.sh
  • 使用面板肯定比面对黑乎乎的终端窗口方便,放着好好的 GUI 界面不用,岂不成了墨守成规之人。
  • 像宝塔面板这种广告多、强制绑定手机号的工具,并不适合在家用环境中使用(确信

注意事项:1Panel 的安装脚本在处理 Docker 时,会提示覆盖 daemon.json 文件,并将之前的内容备份在同目录下的 daemon.json.1panel_bak 文件中。从这个备份文件可以看到,极空间将 Docker 的数据目录放在了 /data_n002/data/udata/real/zdocker 下。因此,当 1Panel 覆盖并重启 Docker 后,极空间自身的管理应用将无法看到已部署的容器。解决方案是将备份内容重新覆盖回去,再重启 Docker 引擎即可。

二、使用教程

在获得 SSH 权限后,可以对极空间系统进行一定程度的修改和功能补全。

极空间登录页

极空间登录页存在一个烦人的跳转问题,当使用移动端 UA 访问网页时,会自动跳转到极空间下载页面。我们可以直接去掉这个判断跳转。在 /zspace/applications/services/pcweb/home 目录中,找到 index.html 文件并进行编辑:

删除这个判断函数:
<script>var j = function(url) {
window.stop && window.stop()
document.execCommand && document.execCommand("Stop", false)
window.location = url
}
var ua = navigator.userAgent.toLowerCase()
var isMobile = !!ua.match(/iOS|iPhone|Android|windows Phone|BB\d+/i)
var isIPad = !!ua.match(/ipad/i)
var href = window.location.href
if (isMobile && !isIPad && !/\/home\/share/.test(href) && !/\/home\/player/.test(href) && !/\/home\/mobile/.test(href)) j('https://download.zspace.cn/')
else if(!Object.defineProperty||!Array.prototype.forEach) j("/home/error/browser.html")
else if (/^http:\/\/(\w+\.)?zconnect.cn((?!login\/jump).)*$/.test(href)) j('https' + href.substr(4))</script>

除此之外,我们还可以引入个自定义样式,对登录页面做个小小的修改,合乎自己喜欢。

保存样式文件 custom.min.css 到同目录,在 </title> 后追加引用:

<link href='/home/custom.min.css?v=1' rel='stylesheet'>
.copyright, .loginFooter > .tc, .login > .titleText div:not(:first-child) {display: none;}body.normal #app:has(.login) {background-image: url(https://bu.dusays.com/2024/03/26/660293ff8fe00.jpg);background-size: cover;background-position: 50%;background-attachment: fixed;}body.normal #app:has(.login) .contain {position: relative;display: flex;justify-content: center;align-items: center;background-image: unset;}body.normal #app:has(.login) .contain .login {background: #ffffff1a;box-shadow: 0 25px 45px #0000001a;transition: 0.5s;position: relative;padding: 25px 50px;border-radius: 2px;margin: 0;width: auto;top: 0;left: 0;}body.normal #app:has(.login) .contain .login:hover, body.normal #app:has(.login) .contain .login:has(input:focus) {border-radius: 30px;backdrop-filter: blur(10px);}body.normal #app:has(.login) .contain .login .titleText:hover::before {width: 120px;}body.normal #app:has(.login) .contain .login .titleText::before {content: "";position: relative;display: block;left: 0;bottom: -40px;width: 0px;height: 3px;background: white;transition: 0.5s;border-radius: 2px;}body.normal #app:has(.login) .contain .login .el-button {width: inherit;background-color: #f4d2d280;transition: 0.5s;}body.normal #app:has(.login) .contain .login .el-button:hover {transform: scale(0.98);}body.normal #app:has(.login) .contain .login .loginFooter .el-checkbox {transition: 0.5s;}body.normal #app:has(.login) .contain .login .loginFooter .el-checkbox:hover {transform: scale(1.1);}body.normal #app:has(.login) .contain .login .loginFooter .el-checkbox .el-checkbox__inner {border: 1px solid #feffff59;background-color: #feffff59;}body.normal #app:has(.login) .contain .login .el-input:hover::after, body.normal #app:has(.login) .contain .login .el-input:has(input:focus)::after {width: 450px;}body.normal #app:has(.login) .contain .login .el-input::after {width: 0;transition: 0.5s;}body.normal #app:has(.login) .contain .login .el-input input::placeholder {color: #fbf1f1;}body.normal #app:has(.home) .desktop .widget:hover .actIcon {opacity: 1;}body.normal #app:has(.home) .desktop .widget .actIcon {opacity: 0;}
// SCSS TO CSS: https://www.dute.org/sass-to-css

@charset "UTF-8";

.copyright,
.loginFooter>.tc,
.login>.titleText div:not(:first-child) {
display: none;
}

$input-text: #fbf1f1;
$box-shadow: #0000001a;
$boder-color: #feffff59;
$background-color_0: #ffffff1a;
$background-color_1: #f4d2d280;
$background-color_2: #feffff59;

body.normal {
#app {
&:has(.login) {
background-image: url(https://bu.dusays.com/2024/03/26/660293ff8fe00.jpg);
background-size: cover;
background-position: 50%;
background-attachment: fixed;

.contain {
position: relative;
display: flex;
justify-content: center;
align-items: center;
background-image: unset;

.login {
background: $background-color_0;
box-shadow: 0 25px 45px $box-shadow;
transition: 0.5s;
position: relative;
padding: 25px 50px;
border-radius: 2px;
margin: 0;
width: auto;
top: 0;
left: 0;

&:hover,
&:has(input:focus) {
border-radius: 30px;
backdrop-filter: blur(10px);
}

.titleText {
&:hover {
&::before {
width: 120px;
}
}

&::before {
content: "";
position: relative;
display: block;
left: 0;
bottom: -40px;
width: 0px;
height: 3px;
background: white;
transition: 0.5s;
border-radius: 2px;
}
}

.el-button {
width: inherit;
background-color: $background-color_1;
transition: 0.5s;

&:hover {
transform: scale(0.98);
}
}

.loginFooter {
.el-checkbox {
transition: 0.5s;

&:hover {
transform: scale(1.1);
}

.el-checkbox__inner {
border: 1px solid $boder-color;
background-color: $background-color_2;
}
}
}

.el-input {

&:hover,
&:has(input:focus) {
&::after {
width: 450px;
}
}

&::after {
width: 0;
transition: 0.5s;
}

input {
&::placeholder {
color: $input-text;
}
}
}
}
}
}

&:has(.home) {
.desktop .widget {
&:hover {
.actIcon {
opacity: 1;
}
}

.actIcon {
opacity: 0;
}
}
}
}
}

极空间在系统更新后可能会重置该文件。我们可以编写一个脚本,在 1Panel 面板的计划任务运行:

将脚本拷贝到合适的目录,并添加执行权限,最后添加相应计划任务即可。

chmod +x /opt/credentials/shell/check_index.sh

添加计划任务

此处是将所需文件放置在 /zspace/applications/services/pcweb/szyink/ 目录中。自定义添加的目录不会被极空间重置,额外的还覆盖了 favicon.ico 文件。

#!/bin/bash

file_path="/zspace/applications/services/pcweb/home/index.html"
search_string="<title>极空间 - 私有云</title><script>var j = function(url)"
replace_string="<title>柚子屋</title><link href='/home/custom.min.css?v=1' rel='stylesheet'><script>const j = function(){};var jj= function(url)"

log() {
echo "$(date "+[%Y-%m-%d %H:%M:%S]") $1"
}

check_file_exists() {
if [ ! -f "$file_path" ]; then
log "错误:文件 $file_path 不存在。"
exit 1
fi
log "文件 $file_path 存在。"
}

backup_file() {
cp "$file_path" "$file_path.bak"
if [ $? -ne 0 ]; then
log "错误:无法备份文件 $file_path。"
exit 1
fi
log "文件备份已创建。"
}

replace_content() {
if grep -q "$replace_string" "$file_path"; then
log "文件已被修改"
elif grep -q "$search_string" "$file_path"; then
log "查到目标字符串"
backup_file
sed -i "s|$search_string|$replace_string|" "$file_path"
if [ $? -ne 0 ]; then
log "错误:替换内容时出现问题。"
exit 1
fi
log "已将目标字符串替换为新内容"

cp -f /zspace/applications/services/pcweb/szyink/custom.min.css /zspace/applications/services/pcweb/home/
if [ $? -ne 0 ]; then
log "错误:复制 custom.min.css 时出现问题。"
exit 1
fi

cp -f /zspace/applications/services/pcweb/szyink/favicon.ico /zspace/applications/services/pcweb/home/
if [ $? -ne 0 ]; then
log "错误:复制 favicon.ico 时出现问题。"
exit 1
fi

log "已成功复制并覆盖自定义文件。"
else
log "未查到目标字符串"
fi
}

check_file_exists
replace_content

镜像同步

众所周知,极空间备份中心的存储池之间只能进行增量备份,无法实现镜像同步。全面开放 SSH 后,我们可以编写一个脚本自行解决这个问题。

rsync 脚本
根据个人情况自行替换脚本内容
#!/bin/bash

# 定义需要同步的目录对
declare -a directories=(
"/tmp/zfsv3/nvme12/XXXX/data/相册存储:/tmp/zfsv3/sata1/XXXX/data/备份中心/相册存储"
"/tmp/zfsv3/nvme12/XXXX/data/文档同步/手机备份:/tmp/zfsv3/sata1/XXXX/data/备份中心/手机备份"
# more...
)

# 获取当前时间并格式化
log() {
echo "$(date "+[%Y-%m-%d %H:%M:%S]") $1"
}

# 记录开始时间
log "同步开始"

# 同步函数
sync_directories() {
local source_dir="$1"
local target_dir="$2"

# 检查源目录是否存在
if [ ! -d "$source_dir" ]; then
log "源目录 $source_dir 不存在。"
exit 1
fi

# 检查目标目录是否存在,如果不存在则创建
if [ ! -d "$target_dir" ]; then
log "警告:目标目录 $target_dir 不存在,正在创建..."
mkdir -p "$target_dir"
if [ $? -ne 0 ]; then
log "创建目标目录 $target_dir 失败。"
exit 1
fi
fi

log "同步 $source$target..."
# 使用 rsync 进行同步,并记录详细日志
rsync -av --delete "$source_dir/" "$target_dir/" | while read line; do
log "$line"
done

# 检查 rsync 命令是否成功
if [ $? -eq 0 ]; then
log "同步成功!已将 $source_dir 下的文件同步到 $target_dir。"
else
log "同步失败!请检查问题并重新尝试。"
exit 1
fi
}



# 遍历数组并调用同步函数
for pair in "${directories[@]}"; do
IFS=":" read -r source target <<< "$pair"
sync_directories "$source" "$target"
done

log "同步完成"

云端备份

极空间备份中心虽然自带云备功能,但不知从何时起,OneDrive 备份功能在上传文件时会修改文件的时间属性,导致图片类文件失去文件属性而无法使用。为了解决这个问题,我们可以使用 rclone 程序自行实现到 OneDrive 的备份。

sudo -v ; curl https://rclone.org/install.sh | sudo bash

最后我们编写个脚本,方便在计划任务中调用:

rclone 脚本
根据个人情况自行替换脚本内容
#!/bin/bash

# rclone 密码
export RCLONE_CONFIG_PASS="XXXXXX"

# 定义本地和远程目录数组
declare -A directories=(
["/tmp/zfsv3/sata1/XXXX/data/备份中心/相册存储"]="<远端名称>:/备份/异地云备/相册存储"
["/tmp/zfsv3/sata1/XXXX/data/备份中心/手机备份"]="<远端名称>:/备份/异地云备/手机备份"
# 添加更多的目录对
)

# 获取当前时间并格式化
current_time() {
date "+[%Y-%m-%d %H:%M:%S]"
}

# 记录开始时间
echo "$(current_time) 备份开始"

# 循环同步每个目录对
for local_dir in "${!directories[@]}"; do
remote_dir=${directories[$local_dir]}
echo "$(current_time) 同步 $local_dir$remote_dir..."

# 同步操作,并捕获错误
if rclone sync "$local_dir" "$remote_dir" --progress; then
echo "$(current_time) 完成 $local_dir 同步"
else
echo "$(current_time) 失败 $local_dir 同步"
exit 1
fi
done

# 输出备份完成消息并记录结束时间
echo "$(current_time) 所有备份已完成!"
echo "$(current_time) 备份结束"

# 取消设置环境变量
unset RCLONE_CONFIG_PASS

历史内容:以下为极空间未主动开放 SSH 权限时的操作方法。

SSH 获取

可以参考下面视频完成操作,视频中前半段着墨于 Ubuntu 镜像的制作[1],在制作完后就是关闭极空间,插 U 盘开机启动[2]。在修改文件方面,UP 主采用了修改 /etc/shadow, /etc/passwd 文件的方法,手动添加了一个已知密码的新用户。除此之外,还可以采用对 root 用户添加公钥的方式 /root/.ssh/authorized_keys,两种方法都可行,具体取决于个人喜好。

完成修改并重启后,不出意外,您就可以在终端下登录系统了。

SSH 维护

一般情形下,极空间系统更新时会重置关键目录,无论是后加的新用户还是公钥文件均会被清空,导致失去 SSH 访问权,这里提供一个相对讨巧的方案。

首先,将极空间应用目录软链接到你的存储区:

ln -s /zspace/applications/services /tmp/zfsv3/nvme12/XXXXXXXXXXX/data/应用程序/System-link/
  • /zspace/applications/services:该目录为极空间应用所在目录;
  • /tmp/zfsv3/nvme12/…:该目录为个人硬盘的实际挂载目录,可利用df命令查找挂载地址;

软链的目录在极空间 APP 查看会提示没有权限,但可以利用 SMB 查看到这些文件。接着我们只需要随便找一个能被极空间调用的 Shell 脚本,在脚本中追加一些私货,就能搭个顺风车利用极空间实现我们的目标啦,这里推荐修改 SMB 的启动脚本:

/zspace/applications/services/samba/start.sh

在该文件中追加导入公钥的命令:

mkdir /root/.ssh
touch /root/.ssh/authorized_keys
echo '你的公钥' > /root/.ssh/authorized_keys
chmod 700 /root/.ssh
chmod 600 /root/.ssh/authorized_keys

最后在极空间 设置 - 文件及共享服务 开关一次 Samba 服务就搞定啦~


  1. 个人更推荐给 U 盘刷 Ventoy,把 Ubuntu 镜像放到 U 盘根目录。 ↩︎

  2. 我这里默认就是 U 盘优先启动,如果没进 PE 按照视频提示进 BIOS 修改。 ↩︎

评论