IT办公室的故事 2023-04
[图像源自:https://www.pexels.com/]
NoMachine就像远端桌面Remote Desktop是一款远程桌面软件。它允许用户从自己的电脑上连接到另一个Linux服务器上面,并在本地使用远程服务器的桌面环境和应用程序。
对使用Linux系统的人来说,这时候可能会问为什么不用SSH链接?还要劳什子地使用桌面?
这是因为电子工程系不想花钱买微软多人连线的授权;所以迫使所有的学生不得不使用一个根本不熟悉的操作系统,要是在逼迫他们使用命令行界面那就抓瞎了。当然啦,有些他们使用的软件也需要GUI。
NoMachine本身是一个挺好用的软件,可以管理用户登录的session,自动踢出短线的账号等等。
但是电子工程系往往要使用一些一运行就需要一个多星期的程序;导致我们不能处理断线的终端。再加上学生们会在不同的电脑短程登录,我们时常会收到学生的投诉说自己又连接不上系统了。
因此教授们总是会抱怨IT不能给与自己的学生最方便的服务。但是我们也不能时时地盯着一个系统吧?再说我们也不知道断线的学生是不是登录不了了。
原本这种需要手动操作的工作是由去年愤怒辞职的前同事管理的;我不会处理这种事情。不过新同事来了之后,我也或多或少开始客服工作。
随着越来越多的人使用这个系统。手动操作就比较烦了。于是,我和同事商量何必登录服务器手动做这些事情?
人都是懒的,为了懒所以努力推动科技发展以便让自己更懒。完全可以做一个监视系统,起码可以先检查是不是因为断线造成用户登录不了。要知道NoMachine的指令运行起来不是很快,每次手动操作也恨废时间。
好嘞,开始写程序……
手动操作时,查询用户的登录状况会打出上面的信息。完全可以用Python抓取下来。
import subprocess
import json
# Run the "nxserver --list" command and capture its output
output = subprocess.check_output(["/usr/NX/bin/nxserver", "--list"])
#print(output)
# Convert the output to a string
output_str = output.decode("utf-8")
# Split the output into lines
lines = output_str.split("\n")
# create a list to hold the session information
sessions = []
# Loop through the lines and print the information for each server
for line in lines:
if line.startswith("NX>"): # Skip any informational lines that start with "NX>"
continue
if line.startswith("Display") :
continue
if line.startswith("---") :
continue
#print(line)
cols = line.split()
#if len(cols) > 4 and cols[2] == "-" : # Check that the line has the expected number of columns
if len(cols) > 4 : # Check that the line has the expected number of columns
sessions.append({"session": cols[0], "user": cols[1], "ip": cols[2]})
# save sessions into a JSON file
with open("/user/nxserver-cleanup/sessions.json", "w") as f :
json.dump(sessions, f)
Python的subprocess库可以直接收录系统指令的输出。
剩下的就是通过阵列Array收录自己想要的用户信息,IP地址,以及进程ID了。
上面的程序里把Python抓取的数据放到了一个JSON文件中。这是因为每次调取系统指令都需要一定的时间。监控系统调用这些数据的时候未免需要很长的时间,导致读取中断。
放在一个文件中,用Cronjob一定时间更新就能解决这个问题。
下面就是找一个有web服务的服务器调取信息了。我们有一个PHP 8.0的系统主要存储着各种inventory信息;正好可以用这个网络应用。
public function List($val) {
if ($this->err["errno"] === 1) {
if ($this->session->AdminAuthed($val["admin"])) {
// Remote file path
$json_file = $this->config["nx"]["sessions"];
// Open SFTP subsystem
$sftp = ssh2_sftp($this->connection);
// Open remote file on SFTP subsystem
$remote_file = fopen("ssh2.sftp://$sftp$json_file", "r");
// Read from remote file into a string variable
$content = stream_get_contents($remote_file);
// close file handle
fclose($remote_file);
// Decode the JSON string into an array
$data = json_decode($content, true);
$this->err = [
"count" => count($data),
"errmsg" => $data,
"errno" => 1,
"status" => "success"
];
}
else {
$this->err = [
"errno" => 3,
"note" => "review NX server"
];
}
}
if ($this->err["errno"] === 1 && !empty($this->err["count"]) && (int)$this->err["count"] > 0) {
$search = [];
foreach ($this->err["errmsg"] as $users) {
array_push($search, $users["user"]);
}
$result = $this->ldap->FetchUsersById($search);
$UserCount = count($result);
if ((int)$UserCount > 0) {
$this->err["users"] = [
"count" => $UserCount,
"errno" => 1,
"errmsg" => $result
];
}
}
return $this->err;
}
PHP有一个ssh2.sftp方程,可以通过SSH进入到另一个系统中读取上面的数据。
登录的用户都是Active Directory下面的用户,用LDAP可以调用户信息。那就顺便弄些信息出来,前端监控的时候可以看到除了用户ID之外更多的信息。
就这样,将数据从PHP传到前端;我们的学生工也能在没有sudo权限的情况下看到远程连接的用户信息了。
因为是读取服务器上面的JSON文件,所以可以在前端设置定期更新。
要学生工能够踢出断线的用户则需要PHP能够真正拥有远程操控的权限。这里就不贴程序了。
需要一个sudo不使用密码的账户,ansible
就是利用这种方式安装、删除远程系统软件。设置id_ed25519
密钥,然后在远程系统中更新authorized_key
。
这么一来,学生工可以直接点击黄色的用户就可以删除断线用户的连接中断了。
因为这个操作不需要定期更新,所以远程调用系统指令的延时并不是我们需要考虑的问题。
新程序上线。同事笑着说:“为了让自己懒,指派学生工干活,花了一天的时间,值得!!我们可以继续懒了……”
真棒,酷哥可以把这套程序推广全美高校👍
哈哈,不是所有的学校都是那么抠,不用Windows CAL的。只有我们这种州立分校。
@tipu curate
Upvoted 👌 (Mana: 40/50) Liquid rewards.