Rustdesk远程桌面搭建,TeamViewer平替(API+Web)

Rustdesk远程桌面搭建,TeamViewer平替

以最新版本1.2.3为例,不要安装nightly,会存在很多问题

搭建私人中转服务器

防火墙放开21115-21119,8000,21116端口

1
2
3
wget https://github.com/rustdesk/rustdesk-server/releases/download/1.1.8-2/rustdesk-server-linux-amd64.zip
tar -xvzf rustdesk-server-linux-amd64.zip
cd amd64

使用screen,或者pm2运行

1
2
./hbbs -r <relay-server-ip[:port]>
./hbbr

or

1
2
pm2 start hbbs -- -r <relay-server-ip[:port]>
pm2 start hbbr

公钥在当前目录下的.pub文件

API服务

  1. 新建mysql数据库
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
 
--
-- 表的结构 `rustdesk_peers`
--

CREATE TABLE `rustdesk_peers` (
`deviceid` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
`uid` int UNSIGNED NOT NULL COMMENT '用户ID',
`id` char(16) NOT NULL DEFAULT '' COMMENT '设备ID',
`username` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '操作系统用户名',
`hostname` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '操作系统名',
`alias` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '别名',
`platform` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '平台',
`tags` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '标签',
PRIMARY KEY (`deviceid`),
UNIQUE KEY `uuid` (`id`,`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 COMMENT='远程设备表';




--
-- 表的结构 `rustdesk_tags`
--
CREATE TABLE `rustdesk_tags` (
`id` smallint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'tagID',
`uid` int UNSIGNED NOT NULL COMMENT '用户ID',
`tag` char(20) NOT NULL DEFAULT '' COMMENT 'tag名称',
PRIMARY KEY (`id`),
UNIQUE KEY `tag` (`tag`,`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 COMMENT='tags表';



--
-- 表的结构 `rustdesk_token`
--

CREATE TABLE `rustdesk_token` (
`username` char(16) NOT NULL COMMENT '用户名',
`uid` int UNSIGNED NOT NULL COMMENT '用户ID',
`id` char(16) NOT NULL COMMENT '设备码',
`uuid` char(64) NOT NULL COMMENT '设备ID',
`access_token` varchar(128) NOT NULL DEFAULT '' COMMENT '登录token',
`login_time` int UNSIGNED NOT NULL DEFAULT '0' COMMENT '登录时间',
`expire_time` int DEFAULT NULL COMMENT '过期时间',
PRIMARY KEY (`access_token`),
UNIQUE KEY `login_token` (`username`,`id`,`uuid`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 COMMENT='登录Token表';


--
-- 表的结构 `rustdesk_users`
--

CREATE TABLE `rustdesk_users` (
`id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`username` char(16) NOT NULL COMMENT '用户名',
`password` char(32) NOT NULL COMMENT '密码',
`create_time` int UNSIGNED NOT NULL DEFAULT '0' COMMENT '添加时间',
`delete_time` int UNSIGNED NOT NULL DEFAULT '0' COMMENT '删除时间',
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 COMMENT='用户表';

--
-- 转存表中的数据 `rustdesk_users`
--

INSERT INTO `rustdesk_users` (`id`, `username`, `password`, `create_time`, `delete_time`) VALUES
(1, 'admin', 'd3541a8746eb583a010c1157438a7ba1', 0, 0);

  1. 新建php网站
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
<?php 
header("Content-type:text/html;charset=utf-8");//字符编码设置
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Headers:X-Requested-With,Content-Type,Authorization');
header('Access-Control-Allow-Methods:POST');
//原生的php操作mysql,
// mysqli_connect(host,username,password,dbname,port,socket);
//连接数据库,host为数据库服务器IP或域名,username为数据库用户名,password为数据库密码为数据库名,port数据库连接端口,默认3306,socket忽略即可
//下面这行必须改为自己的服务器上对应的信息,否则,你懂的。。。
$conn=mysqli_connect("localhost","rustdesk","RMkARpSxnr6A732L","rustdesk",3306);
if(!$conn){
  die("数据库连接出错了: " . mysqli_connect_error());//如果连接失败输出一条消息,并退出当前脚本
}
//获取访问的啥方法
$action = $_GET['s'];
$raw_post_data = file_get_contents('php://input');//这个就是提交过来的数据集合
$auth_token = $_SERVER['HTTP_AUTHORIZATION'] ;//这个访问时需要验证的token
if($auth_token){
$_auth = explode(' ',$auth_token);
$auth_token = $_auth[1];
}

#登录
if($action =='/api/login'){
//获取提交过来数据
$data = json_decode($raw_post_data,true);
//计算密码
$pwd = md5($data['password'].'rustdesk');
//sql语句
$sql = "select * from rustdesk_users where `username` ='".$data['username']."' and `password` = '".$pwd."' and `delete_time`=0";
//执行sql语句并取得记录集
$result=mysqli_query($conn,$sql);
//获取一条记录
$info = mysqli_fetch_assoc($result);
//有记录就是密码用户名是对的,反之不正确
//定义返回信息
$res = array();
//判断是否有记录,有则正确,否则无记录
if($info){
$time = time();
//加密因子
$key = 'rustdesk'.strtotime('now');
//这是通讯验证串
$token = md5($key);
$res = array(
'type' => 'access_token',//这行就是区别
'access_token' => $token,
'user' => array('name'=> $info['username'])
);
$sql = "insert into `rustdesk_token` (`username`, `uid`,`id`, `uuid`, `access_token`, `login_time`) VALUES ('".$info['username']."', ".$info['id'].",'".$data['id']."','".$data['uuid']."', '".$token."', ".$time.") ON DUPLICATE KEY UPDATE `access_token` = values(`access_token`)";
mysqli_query($conn,$sql);
}else {
//数据库里查不到数据
$res = array('error'=>'用户名或密码错误');
}

//返回json数据
// $json_string = json_encode($res);
//出现中文乱码是用下面这行
$json_string = json_encode($res,JSON_UNESCAPED_UNICODE);
//输出结果json字符串
echo $json_string;
}

#获取当前登录用户的所有信息
if($action =='/api/currentUser'){
//获取提交过来数据
$data = json_decode($raw_post_data,true);
//去数据库查此用户的sql语句
$sql = "select * from `rustdesk_token` where `id` = '".$data['id']."' and `uuid` = '".$data['uuid']."' and `access_token` = '".$auth_token."'";
//print_r($sql);exit();
//执行sql语句并取得记录集
$result=mysqli_query($conn,$sql);
//获取一条记录
$info = mysqli_fetch_assoc($result);
//有记录就是等成功的用户
//定义返回信息
$res = array();
//判断是否有记录,有则正确,否则无记录
if($info){
$res = array('name'=> $info['username']);
}else {
//数据库里查不到数据
$res = array('error'=>'查无此人或登录超时了');
}
//返回json数据
$json_string = json_encode($res);
//出现中文乱码是用下面这行
//$json_string = json_encode($res,JSON_UNESCAPED_UNICODE);
//输出结果json字符串
echo $json_string;
}
//更新地址簿,一下子更新所有的信息,包括标签、地址簿等
if($action =='/api/ab'){
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
//更新逻辑
// 处理POST请求的逻辑
// 可以通过 $_POST 获取POST请求的数据
// 例如:$data = $_POST['data'];
//获取提交过来数据
$p_data =json_decode($raw_post_data)->data;
//解析json里的字段
$tp_data = json_decode($p_data);
//解析出标签json
$tags = $tp_data->tags;
//解析出设备列表json
$peers = $tp_data->peers;
//根据用户登录的token去数据库Rustdesk_Token查询登录的用户相关信息的SQL语句
$sql ="select * from `rustdesk_token` where `access_token` = '".$auth_token."'";
//执行sql语句
$result=mysqli_query($conn,$sql);
//获取一条记录
$info = mysqli_fetch_assoc($result);
//标签集合(因为是原生的,只能拼接字符串了,大家凑合着用吧)
$tags_data = [];
foreach ($tags as $k => $v) {
$item = [];
$item['uid'] = $info['uid'];
$item['tag'] = $v;
$tags_data[] = $item ;
}
//设备集合(地址簿)
$peers_data = [];
foreach ($peers as $k => $v) {
$item = [];
$item['uid'] = $info['uid'];
$item['id'] = $v->id;
$item['username'] = $v->username ;
$item['hostname'] = $v->hostname ;
$item['alias'] = $v->alias ;
$item['platform'] = $v->platform ;
if($v->tags){
$item['tags'] = implode(',',$v->tags);
}else{
$item['tags'] = '';
}
$peers_data[] = $item;
}
//如果tag集合不为空,则删除原来现有的记录
if($tags_data){
//删除数据sql
$del_tag_sql = "delete from rustdesk_tags where `uid` = ".$info['uid'];
//执行删除
mysqli_query($conn,$del_tag_sql);
//插入新的数据集合,拼接批量插入sql语句
$insert_tag_sql = "insert into `rustdesk_tags` (`uid`,`tag`) VALUES ";
foreach($tags_data as $item) {
$itemStr = '( ';
$itemStr .= sprintf("%d, '%s'",(int)$item['uid'],$item['tag']);
$itemStr .= '),';
$insert_tag_sql .= $itemStr;
}
// 去除最后一个逗号,并且加上结束分号
$insert_tag_sql = rtrim($insert_tag_sql, ',');
$insert_tag_sql .= ';';
//print_r($insert_tag_sql);exit();
//执行插入数据
mysqli_query($conn,$insert_tag_sql);
}
//如果peers集合不为空,则删除原来现有的记录
if($peers_data){
//删除数据sql
$del_peers_sql = "delete from `rustdesk_peers` where `uid` = ".$info['uid'];
//执行删除
mysqli_query($conn,$del_peers_sql);
//插入新的数据集合,拼接批量插入sql语句
$insert_peers_sql = "insert into `rustdesk_peers` (`uid`, `id`, `username`, `hostname`, `alias`, `platform`, `tags`) VALUES ";
foreach($peers_data as $item) {
$itemStr = '( ';
$itemStr .= sprintf("%d, '%s','%s','%s','%s','%s','%s'",(int)$item['uid'],$item['id'],$item['username'],$item['hostname'],$item['alias'],$item['platform'],$item['tags']);
$itemStr .= '),';
$insert_peers_sql .= $itemStr;
}
// 去除最后一个逗号,并且加上结束分号
$insert_peers_sql = rtrim($insert_peers_sql, ',');
$insert_peers_sql .= ';';
//执行插入数据
$_info = mysqli_query($conn,$insert_peers_sql);
// echo json_encode(mysqli_error($conn));
}
} elseif ($_SERVER['REQUEST_METHOD'] == 'GET') {
// 获取列表
// 处理GET请求的逻辑
// 可以通过 $_GET 获取GET请求的数据
// 例如:$data = $_GET['data'];
//获取提交过来数据
$data = json_decode($raw_post_data,true);
//获取已登录的用户信息
//去数据库查此用户的sql语句,主要是获取用户ID
$sql = "select * from `rustdesk_token` where `access_token` = '".$auth_token."'";
// echo $sql;
//执行sql语句并取得记录集
$result=mysqli_query($conn,$sql);
//获取一条登录的记录
$info = mysqli_fetch_assoc($result);
//print_r($info);exit();
//分别去`rustdesk_tags`和`rustdesk_peers`表里取当前用户的所有信息,全部一次性返回到客户端就完事了
//定义一个临时数组来存放这里两个表取出来的数据
$_address_book = array();
if($info){
//开始获取rustdesk_tags数据
$sql = "select `tag` from `rustdesk_tags` where `uid` = ".$info['uid'];
// echo $sql;
//执行sql语句并取得记录集
$o_tag=mysqli_query($conn,$sql);
$_tags = [];
while($row = mysqli_fetch_array($o_tag)){
$_tags[] = $row['tag'];
}
//开始获取rustdesk_peers数据
$sql = "select id,username,hostname,alias,platform,tags from `rustdesk_peers` where `uid` = ".$info['uid'];
// echo $sql;
//执行sql语句并取得记录集
$o_peer=mysqli_query($conn,$sql);
$_peers =[];
while($row = mysqli_fetch_array($o_peer)){
$item=[];
$item['id'] = $row['id'];
$item['username'] = $row['username'];
$item['hostname'] = $row['hostname'];
$item['alias'] = $row['alias'];
$item['platform'] = $row['platform'];
$item['tags'] = explode(',',$row['tags']);
$_peers[] = $item;
// echo json_encode($item);
}
$_address_book = array(
'error'=> false,
'updated_at' => date('Y-m-d H:i:s', time()),
'data' => json_encode(array("tags"=>$_tags,"peers"=>$_peers))
);
// echo json_encode($_address_book);
}else{
$_address_book = array("error" => "获取地址簿有误");
}
//转成json数据
// $address_book = json_encode($_address_book);
//输出结果json字符串
echo json_encode(array('data' => json_encode(array("tags"=>$_tags,"peers"=>$_peers))));
echo $address_book;
}


}
//获取地址簿
if($action =='/api/ab/get'){
//获取提交过来数据
$data = json_decode($raw_post_data,true);
//获取已登录的用户信息
//去数据库查此用户的sql语句,主要是获取用户ID
$sql = "select * from `rustdesk_token` where `access_token` = '".$auth_token."'";
// echo $sql;
//执行sql语句并取得记录集
$result=mysqli_query($conn,$sql);
//获取一条登录的记录
$info = mysqli_fetch_assoc($result);
//print_r($info);exit();
//分别去`rustdesk_tags`和`rustdesk_peers`表里取当前用户的所有信息,全部一次性返回到客户端就完事了
//定义一个临时数组来存放这里两个表取出来的数据
$_address_book = array();
if($info){
//开始获取rustdesk_tags数据
$sql = "select `tag` from `rustdesk_tags` where `uid` = ".$info['uid'];
// echo $sql;
//执行sql语句并取得记录集
$o_tag=mysqli_query($conn,$sql);
$_tags = [];
while($row = mysqli_fetch_array($o_tag)){
$_tags[] = $row['tag'];
}
//开始获取rustdesk_peers数据
$sql = "select id,username,hostname,alias,platform,tags from `rustdesk_peers` where `uid` = ".$info['uid'];
// echo $sql;
//执行sql语句并取得记录集
$o_peer=mysqli_query($conn,$sql);
$_peers =[];
while($row = mysqli_fetch_array($o_peer)){
$item=[];
$item['id'] = $row['id'];
$item['username'] = $row['username'];
$item['hostname'] = $row['hostname'];
$item['alias'] = $row['alias'];
$item['platform'] = $row['platform'];
$item['tags'] = explode(',',$row['tags']);
$_peers[] = $item;
// echo json_encode($item);
}
$_address_book = array(
'error'=> false,
'updated_at' => date('Y-m-d H:i:s', time()),
'data' => json_encode(array("tags"=>$_tags,"peers"=>$_peers))
);
// echo json_encode($_address_book);
}else{
$_address_book = array("error" => "获取地址簿有误");
}
//转成json数据
$address_book = json_encode($_address_book);
//输出结果json字符串
// echo json_encode(array('data' => json_encode(array("tags"=>$_tags,"peers"=>$_peers))));
echo $address_book;
}
//心跳检测,基本用不到,不用关注
if($action =='/api/audit'){

$_res = array(
'data' =>'在线!!!'
);
$result = json_encode($_res);
echo $result;
}
//退出登录,删除rustdesk_token数据库信息
if($action =='/api/logout'){
//获取提交过来数据
$data = json_decode($raw_post_data,true);
//删除rustdesk_token表中记录
$sql = "delete from `rustdesk_token` where `id` = '".$data['id']."' and `uuid` = '".$data['uuid']."' and `access_token` = '".$auth_token."'";
//执行sql语句
$result=mysqli_query($conn,$sql);
//返回退出消息,反正客户端看不见,返回啥是啥
$_logout = array(
'data' =>date('Y-m-d H:i', time())
);
$logout = json_encode($_logout);
echo $logout;
}
//关闭数据库连接
mysqli_close($conn);
?>

由【3】修改得到,感谢原版大佬,1.2.3该用/api/ab的get方法获取设备列表,且返回内容略有改动,使用到老源码代码会报错,如果使用1.1.9版本的则接着使用原版代码

客户端配置

ID服务写入服务端ip地址,API服务器写入新建立网站域名或ip地址/index.php?s=

image-20231202180847851

搭建WEB控制界面

新建网站,把web-client文件夹解压放入即可

修改api网址

image-20231202181258019

资源

链接:https://pan.baidu.com/s/1NIvbNmtAbqf6s_BEaYULyw?pwd=c4xh 提取码:c4xh

参考

  1. rustdesk-github
  2. rustdesk-server
  3. rustdesk服务端安装文档
  4. API服务器教程,适用于1.1.9
  5. rustdesk-api-server