• 1、使用 Cassandra:3.0.9 镜像

  • 2、cd /opt/cassandra/bin/

目录

  • 3、全量备份,执行:nodetool snapshot

备份

程序会自动在每张表下生成备份时间戳的文件夹,里面有备份文件。
备份单个keyspace执行:nodetool snapshot yourkeyspace

  • 4、启用增量备份
    启用:nodetool enablebackup
    查看状态:nodetool statusbackup

增量备份

  • 5、删除快照
    命令:nodetool clearsnapshot

删除

  • 6、备份恢复
    将备份目录下的文件复制到 表目录下:
    cp /var/lib/cassandra/data/thingsboard/ts_kv_latest_cf-49f924507df811eeaf8a3b94212b0656/snapshots/1699939125001/* /var/lib/cassandra/data/thingsboard/ts_kv_latest_cf-49f924507df811eeaf8a3b94212b0656/

备份

备份2

再执行恢复命令:
nodetool refresh -- yourkeyspace yourtable

恢复

当我们部署了 headscale 以及 headscale UI等程序,需要对 headscale 及UI 进行代理。本文使用nginx进行代理。

headscale ui相关的开源程序,推荐使用 headscale-admin,界面美观,功能较丰富,使用较简单,只要启动容器即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
user  root;
worker_processes auto;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/nginx-access.log;
error_log /var/log/nginx/nginx-error.log;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';


sendfile on;

keepalive_timeout 65;

gzip on;
gzip_static on;

proxy_buffer_size 128k;
proxy_buffers 32 128k;
proxy_busy_buffers_size 128k;

fastcgi_buffers 8 128k;
send_timeout 60;

server {
listen 8088 ssl;
server_name xxx.ownding.xyz;
ssl_certificate /home/headscale/cert/xxx.ownding.xyz.crt;
ssl_certificate_key /home/headscale/cert/xxx.ownding.xyz.key;
ssl_session_cache shared:le_nginx_SSL:1m;
ssl_session_timeout 1440m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;

# add_header X-Frame-Options "SAMEORIGIN";
# add_header X-XSS-Protection "1; mode=block";
# add_header X-Content-Type-Options "nosniff";

location / {
proxy_pass http://172.26.0.93:8080; # Headscale的HTTP端口
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_redirect http:// https://;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;

# CORS-Handling
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, User-Agent' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range' always;
add_header 'Content-Length' 0 always;
add_header 'Content-Type' 'text/plain; charset=utf-8' always;
return 204;
}

# CORS-Header
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, User-Agent' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range' always;
}

location /admin {
proxy_pass http://172.26.0.93:8443; # Headscale admin的HTTP端口
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_redirect http:// https://;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;

# CORS-Handling
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, User-Agent' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range' always;
add_header 'Content-Length' 0 always;
add_header 'Content-Type' 'text/plain; charset=utf-8' always;
return 204;
}

# CORS-Header
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, User-Agent' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range' always;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

以上配置中需要注意 add_header 'Access-Control-Allow-Origin' '*' always; , 将 * 替换为你自己服务器的域名。

如果你想部署 headscale-admin,以及不希望api暴露,可以在 nginx 中删除 /admin 的配置,以及 /cros 配置即可。

目的

为了加快Bing搜索引擎对网站的索引,可通过 IndexNow 主动提交网址链接。

  • 1、在 https://www.bing.com/indexnow/getstarted 获得 API key
  • 2、将 keytxt 文件放到网站根目录下,方便访问
  • 3、将网站的所有链接生成一个 txt 文档,使用脚本提交
  • 4、到 Bing Webmaster Tools 网站查看提交情况

脚本

以下是用于批量提交链接到 Bing IndexNow 的 shell 脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/bin/bash

# === 配置参数(请根据实际情况修改) ===
HOST="www.ownding.com" # 你的域名
KEY="878777754f5740419ae123455c77d8ca" # 你的API密钥
KEY_LOCATION="http://www.ownding.com/878777754f5740419ae123455c77d8ca.txt" # 密钥验证文件URL
URL_FILE="/xxx/baidu_urls.txt" # URL文件路径

# === 检查文件是否存在 ===
if [ ! -f "$URL_FILE" ]; then
echo "错误:文件 $URL_FILE 不存在"
exit 1
fi

# === 读取并处理URL列表 ===
# 过滤空行,添加双引号,转换为JSON数组格式
URLS=$(grep -v '^$' "$URL_FILE" | sed 's/.*/"&"/' | paste -sd ',' -)

echo "-------"
echo "-------"
echo $URLS
echo "-------"
echo "-------"

# === 构建JSON请求体 ===
JSON_BODY=$(cat <<EOF
{
"host": "$HOST",
"key": "$KEY",
"keyLocation": "$KEY_LOCATION",
"urlList": [$URLS]
}
EOF
)

echo ""
echo "-------"
echo "-------"
echo $JSON_BODY
echo "-------"
echo "-------"


# === 发送POST请求 ===
echo "正在提交 $HOST 的链接..."
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "https://www.bing.com/indexnow" \
-H "Content-Type: application/json; charset=utf-8" \
-d "$JSON_BODY")

# === 解析响应 ===
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
RESPONSE_BODY=$(echo "$RESPONSE" | sed '$d')

if [ "$HTTP_CODE" -eq 200 ]; then
echo "提交成功!Bing返回:$RESPONSE_BODY"
else
echo "提交失败!HTTP状态码:$HTTP_CODE"
echo "响应内容:$RESPONSE_BODY"
exit 1
fi

baidu_urls.txt 文件中 URL格式:

1
2
3
4
5
6
7
http://www.ownding.com/2025/06/12/%E5%9C%A8%E6%9C%89%E5%85%AC%E7%BD%91IP%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%E5%A6%82%E4%BD%95%E5%AE%89%E5%85%A8%E5%9C%B0%E8%BF%9B%E8%A1%8C%E8%BF%9C%E7%A8%8B%E6%A1%8C%E9%9D%A2%E8%BF%9E%E6%8E%A5/
http://www.ownding.com/2025/06/12/%E5%9C%A8%E4%BA%91%E7%AB%AF%E9%81%A8%E6%B8%B8%EF%BC%8C%E4%BB%A3%E7%A0%81%E5%A6%82%E9%A3%9E%EF%BC%81%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%BF%9C%E7%A8%8B%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/
http://www.ownding.com/2025/06/11/zlmediakit%E9%87%8D%E5%90%AF%E6%8B%89%E6%B5%81%E9%85%8D%E7%BD%AE%E4%B8%A2%E5%A4%B1%E4%B8%80%E7%A7%8D%E7%AE%80%E5%8D%95%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95/
http://www.ownding.com/2025/06/11/%E7%B3%BB%E7%BB%9F%E9%98%B2%E6%AD%A2%E8%BF%9C%E7%A8%8B%E6%9A%B4%E5%8A%9B%E7%A0%B4%E8%A7%A3%E6%96%B9%E6%B3%95/
http://www.ownding.com/2025/06/10/nginx%E9%85%8D%E7%BD%AEmap%E5%A4%9A%E4%B8%AA%E5%9F%9F%E5%90%8D%E8%BD%AC%E5%8F%91%E5%88%B0%E4%B8%8D%E5%90%8C%E5%90%8E%E7%AB%AF/
http://www.ownding.com/2025/06/10/ubuntu%E6%9B%B4%E6%96%B0%E6%A0%B9%E8%AF%81%E4%B9%A6/

使用说明:

  1. 将脚本保存为 submit_to_bing.sh
  2. 修改配置参数:
    • HOST: 你的网站域名
    • KEY: 你的 Bing IndexNow API 密钥
    • KEY_LOCATION: 验证密钥文件的 URL
    • URL_FILE: 你的 URL 文件路径
  3. 赋予执行权限:
    1
    chmod +x submit_to_bing.sh
  4. 运行脚本:
    1
    ./submit_to_bing.sh

在有公网 IP 的情况下如何安全地进行远程桌面连接?

Author: OwnDing

Date: 2023-12-23

我从22年3月开始到现在一直在iPad使用微软远程桌面登入云电脑进行办公,刚开始也为网络安全绞尽脑汁,还好最后总算被我找到了解决方案,而且都是免费的,不用花一分钱。

话不多说,下面介绍下我使用远程桌面的一些安全措施,请重点关注两项增强措施


基本措施

1、修改RDP的默认端口;限制administrator账号登入(我偷懒没有禁止admin账号,不过强烈建议使用其它用户名登入);使用强密码。


增强措施:

2、安装IPBan。由于远端连接的相关端口暴露在互联网会导致别人暴力破解,安装IPBan后,可以将多次登入失败的IP地址自动加入防火墙禁用。网址:GitHub - DigitalRuby/IPBan: Since 2011, IPBan is the worlds most trusted, free security software to block hackers and botnets. With both Windows and Linux support, IPBan has your dedicated or cloud server protected. Upgrade to IPBan Pro today and get a discount. Learn more at ↓

超过三次失败限制登入几分钟

3、使用Duo Security进行二次验证

Multi-Factor Authentication & Single Sign-On | Duo Security

当你输入正确的用户名、密码登入后,会出现Duo验证界面,需要你在手机上确认是否登入。

手机二次验证

手机Duo界面

Duo RDP设置界面

以上安全措施我在另一篇文章中也提过:

告别电脑,完全使用iPad(平板)进行办公、学习、娱乐的最佳方案

在云端遨游,代码如飞!服务器远程开发指南

Author: OwnDing

Date: 2024-02-25

还在为本地电脑的低配置而烦恼吗?还在为繁重的编译和运行时间而抓狂吗?快来看看服务器远程开发的解决方案吧!

服务器化开发,释放本地电脑的潜能

服务器远程开发,顾名思义,就是把开发环境搬到服务器上,本地电脑只需要负责轻量级的编辑和控制。这种方式可以大大降低本地电脑的配置要求,让即使是老掉牙的电脑也能流畅运行开发环境。

前端使用 Visual Studio Code Remote 方案,纵享云端开发的自由

Visual Studio Code Remote 是一款强大的扩展,可以将 Visual Studio Code 的开发环境扩展到远程服务器。有了它,你可以在本地电脑上编辑代码,而编译、运行和调试都在服务器上进行。

后端使用 JetBrains Gateway 方案,体验专业工具的魅力

如果你需要一个更专业的开发环境,那么 JetBrains Gateway 绝对是你的不二之选。它是一款免费的软件,不过它提供了无与伦比的功能和稳定性。有了它,你可以使用最新版本的 IntelliJ IDEAPyCharm 和其他 JetBrains 工具,在服务器上进行开发。

Gateway支持的IDE

Gateway 最大优点是可以使用VPN远程到服务器内网,也可以稳定运行调试编写代码,让你在任意地方随心所欲的编程。

缺点是需要付费IDEA使用。

我使用JetBrains Gateway有数个月时间了,代码及后端计算均在服务器上完成,本地电脑上主要就是一个显示、编辑操作,对电脑性能要求低。此外,现阶段的Gateway稳定性较之前版本有很大的提升,此外你无需将代码下载到本地电脑,这样也保证了代码的安全性。

Gateway界面

如果你想了解更多关于服务器远程开发的信息,可以访问以下链接:

好了,以上就是关于服务器远程开发的全部内容了。希望对你有帮助!

ZLMediaKit 重启后拉流配置丢失一种简单解决方法

问题背景

ZLMediaKit 在服务重启后可能会出现已配置的拉流任务丢失的问题。本文提供一种通过 API 自动恢复拉流配置的解决方法。


解决方法概述

  1. 使用 jq 工具解析 JSON 配置文件
  2. 通过 Shell 脚本调用 ZLMediaKit API 批量恢复拉流任务
  3. 配置开机自启动实现自动化恢复

实施步骤

1. 安装 jq 工具

1
2
3
4
5
6
7
8
# Ubuntu/Debian 系统
sudo apt-get install jq

# CentOS/RHEL 系统
sudo yum install jq

# 验证安装
jq --version

2. 创建流配置文件 streams.json

将需要持久化的拉流配置保存为 JSON 格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[
{
"vhost": "192.168.16.10",
"app": "live",
"stream": "xxx225",
"url": "rtsp://admin:admin@192.168.11.225:554/h266/ch1/main/av_stream",
"secret": "CCCOuGTsZG7EZoHtt1l6HUmbBW6xP4ri"
},
{
"vhost": "192.168.16.10",
"app": "live",
"stream": "xxx224",
"url": "rtsp://admin:admin@192.168.11.224:554/h266/ch1/main/av_stream",
"secret": "CCCOuGTsZG7EZoHtt1l6HUmbBW6xP4ri"
},
{
"vhost": "192.168.16.10",
"app": "live",
"stream": "xxx223",
"url": "rtsp://admin:admin@192.168.11.223:554/h266/ch1/main/av_stream",
"secret": "CCCOuGTsZG7EZoHtt1l6HUmbBW6xP4ri"
}
]

⚠️ 注意事项:

  • 确保字段与 ZLMediaKit API 文档要求一致
  • 敏感信息建议设置文件权限:chmod 600 streams.json
  • 建议将文件存储在安全目录(如 /etc/zlmediakit/

3. 创建恢复脚本 restore_zlmediakit.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash

# 检查 jq 是否安装
if ! command -v jq &> /dev/null; then
echo "错误:jq 未安装,请先执行安装步骤"
exit 1
fi

# JSON 文件路径
CONFIG_FILE="/path/to/streams.json"

# API 地址(根据实际环境修改端口)
API_URL="http://127.0.0.1:8080/index/api/addStreamProxy"

# 读取配置并逐条添加
jq -c '.[]' "$CONFIG_FILE" | while read -r item; do
curl -s -X POST "$API_URL" \
-H "Content-Type: application/json" \
-d "$item"
done

echo "拉流配置恢复完成"

📝 使用说明:

  • 修改 CONFIG_FILE 为实际存储路径
  • 确认 API_URL 的端口号与配置文件一致
  • 添加执行权限:chmod +x restore_zlmediakit.sh

4. 配置开机自启动

方法一:通过 crontab

1
2
3
4
5
# 编辑 crontab
crontab -e

# 添加以下内容(注意修改脚本实际路径)
@reboot /absolute/path/to/restore_zlmediakit.sh >> /var/log/zlmediakit_restore.log 2>&1

方法二:创建 systemd 服务

1
2
3
4
5
6
7
8
9
10
11
12
# /etc/systemd/system/zlmediakit-restore.service
[Unit]
Description=ZLMediaKit Pull Stream Restorer
After=network.target

[Service]
ExecStart=/absolute/path/to/restore_zlmediakit.sh
User=your_user
Environment="PATH=/usr/bin:/usr/local/bin"

[Install]
WantedBy=multi-user.target
1
2
# 启用服务
sudo systemctl enable zlmediakit-restore

验证与维护

手动测试脚本

1
2
./restore_zlmediakit.sh
# 检查返回结果或查看 ZLMediaKit 日志

查看运行状态

1
2
3
# 如果使用 systemd
systemctl status zlmediakit-restore
journalctl -u zlmediakit-restore

日志分析

  • 默认日志路径:/var/log/zlmediakit/
  • 关注 API 返回状态码(200 表示成功)

注意事项

必须验证项

  • ✅ ZLMediaKit API 端点地址和端口
  • ✅ 流媒体服务器 IP 地址是否固定
  • ✅ 网络策略是否允许本地回环访问(127.0.0.1)

安全加固(可选)

1
2
3
4
# 设置脚本权限
chmod 700 restore_zlmediakit.sh
# 设置配置文件权限
chmod 600 streams.json

原理:读取系统相关登入、安全日志,调用防火墙禁止频繁登入失败的IP。

目的:

Nginx 配置 SSL,透传到 后端。 根据不同的域名转发到不同的后端。

配置示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
user  root;
worker_processes auto;
events {
worker_connections 1024;
}
stream {
log_format basic '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$ssl_preread_server_name" "$name"';
access_log /var/log/nginx/stream_access.log basic;

map $ssl_server_name $name {
# hostnames;
default app_default_backend;
app.ownding.com.cn app1_backend;
www.ownding.com.cn app2_backend;
}
upstream app1_backend {
server 192.168.0.117:30080 weight=5 max_fails=1 fail_timeout=10s;
}
upstream app2_backend {
server 192.168.0.117:30081 weight=5 max_fails=1 fail_timeout=10s;
}
upstream app_default_backend {
server 192.168.0.117:30081;
}
server {
listen 31180 ssl;
ssl_certificate /home/cert/scs1687747992522__.ownding.com.cn_server.crt;
ssl_certificate_key /home/cert/scs1687747992522__.ownding.com.cn_server.key;
proxy_pass $name;
}
}

遇到的错误:

1
curl: (60) SSL certificate problem: unable to get local issuer certificate

说明 curl 在验证服务器证书时找不到对应的 CA 根证书,也就是说你的系统没有信任该网站所使用的证书签发机构(CA)。


✅ 你有根证书,可以手动添加到 Ubuntu 系统的信任库中,以下是完整解决步骤:


🔧 步骤 1:确认你有 CA 的根证书文件

你可能有一个 .crt.pem 文件,例如:

1
my-ca.crt

如果没有,请从你的证书颁发机构获取。


🔧 步骤 2:将证书复制到系统证书目录

以 root 权限执行以下命令:

1
sudo cp my-ca.crt /usr/local/share/ca-certificates/

注意:

  • 证书文件名必须是 .crt 后缀;
  • 推荐放在 /usr/local/share/ca-certificates/ 目录下。

🔧 步骤 3:更新系统证书信任库

运行以下命令更新系统的 CA 信任列表:

1
sudo update-ca-certificates

输出类似:

1
2
3
4
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.

这表示你的证书已成功加入系统信任链。


✅ 验证是否生效

再次运行你的 curl 命令:

1
curl -v https://vpn.ownding.xyz

如果一切正常,就不会再报 unable to get local issuer certificate 错误了。


📌 补充说明

如果你使用的是自签名证书:

  • 你也需要把服务端使用的 服务器证书本身 添加为信任证书,或者在客户端使用 --cacert 指定它:
1
curl --cacert /path/to/server.crt https://vpn.ownding.xyz

🛡️ 安全提示

  • 不要随意添加不可信的证书到系统信任库,这会带来安全风险。
  • --insecure(即 -k)参数虽然能绕过证书验证,但不建议在生产环境中使用。

✅ 总结

问题 解决方式
curl 报错 unable to get local issuer certificate 将根证书添加到系统信任库
有根证书怎么处理? 复制到 /usr/local/share/ca-certificates/ 并运行 update-ca-certificates

  • 1、在某一个客户端(路由器/网关)端生成 ipv6 子网

使用命令:tailscale debug via 7 192.168.6.0/24

其中 7siteID,可自行填写 0-60000之间的数值。

生产 ipv6 子网后,需要在客户端重新宣告子网。

tailscale set --advertise-routes=ipv6子网

openwrt

  • 2、在 headscale 服务端允许 子网

我使用 docker 部署的 headscale 服务端,使用如下命令开启子网。

docker exec headscale headscale routes enable -r 2

openwrt

  • 3、根据 计算方法获取 下挂设备的 ipv6地址:

比如 192.168.4.146 对应的地址 ipv6 地址是 :fd7a:115c:a1e0:b1a:0:7:c0a8:692

参考链接: http://www.ownding.com/2025/06/05/Tailscale-4via6-%E5%8A%9F%E8%83%BD-IP%E5%9C%B0%E5%9D%80%E8%BD%AC%E6%8D%A2%E8%A7%84%E5%88%99/

  • 4、测试 ipv6 地址访问

ipv6

0%