前言

用于记录Linux使用的时候遇到的一些特殊场景, 以及对应的解决方案

多用户同时使用图形界面

机房有一台很好配置的服务器, 但是同学们不太会直接使用命令行界面, 都需要图形化的使用, 这个时候我们就需要多个用户同时使用, 就不用等某个同学的使用了

解决方案: vnc+内网穿透 或者 vnc+向日葵 (这个可能有点问题, 我尝试没成功)

要在CentOS服务器上设置VNC以便远程多用户访问,您可以按照以下步骤进行:

VNC安装

1. 安装VNC Server和桌面环境

首先,您需要安装一个VNC服务器和一个桌面环境。这里以TigerVNC和GNOME桌面环境为例:

1
2
3
sudo yum install epel-release -y
sudo yum install tigervnc-server -y
sudo yum groupinstall "GNOME Desktop" -y

2. 设置VNC Server

创建VNC Server的配置文件:

1
sudo cp /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@:1.service

编辑该文件:

1
sudo vim /etc/systemd/system/vncserver@:1.service

找到以下行并修改<USER>为您的实际用户名:

1
2
3
4
5
6
[Service]
Type=forking
# Clean any existing files in /tmp/.X11-unix environment
ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :'
ExecStart=/usr/bin/vncserver %i
ExecStop=/usr/bin/vncserver -kill %i

保存并关闭文件。

3. 设置VNC密码

切换到您的用户,然后设置VNC密码:

1
2
su - <USER>
vncpasswd

4. 启动VNC服务

重新加载systemd服务,并启动VNC服务:

1
2
3
sudo systemctl daemon-reload
sudo systemctl enable vncserver@:1.service
sudo systemctl start vncserver@:1.service

5. 配置防火墙

打开VNC服务所需的端口:

1
2
sudo firewall-cmd --permanent --add-port=5901/tcp
sudo firewall-cmd --reload

6. 连接到VNC服务器

在本地计算机上,使用VNC客户端连接到服务器的IP地址和端口。例如,如果服务器的IP地址是192.168.1.100,您可以使用192.168.1.100:5901进行连接。

7. 其他配置

可以编辑每个用户的VNC启动脚本以自定义启动环境:

1
vim ~/.vnc/xstartup

添加以下内容以启动GNOME桌面:

1
2
3
4
#!/bin/sh
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
exec /etc/X11/xinit/xinitrc

保存并关闭文件,给脚本添加执行权限:

1
chmod +x ~/.vnc/xstartup

8. 多用户配置

如果需要多个用户访问,可以为每个用户配置一个不同的VNC实例。重复上述步骤2和3,修改配置文件和服务端口号。例如,为第二个用户创建一个新的服务:

1
sudo cp /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@:2.service

编辑该文件并将<USER>替换为新用户的用户名,同时将所有端口号从1改为2

启动新的VNC服务:

1
2
sudo systemctl enable vncserver@:2.service
sudo systemctl start vncserver@:2.service

为新用户设置VNC密码:

1
2
su - <NEW_USER>
vncpasswd

9. 关闭服务

1
2
3
4
5
sudo systemctl stop vncserver@:1.service
sudo systemctl disable vncserver@:1.service
# 多用户
sudo systemctl stop vncserver@:2.service
sudo systemctl disable vncserver@:2.service

10. 同一用户不同桌面

首先按照第8步把服务再配置一份即可

为每个实例设置不同密码

如果需要为每个实例设置独立的密码,可以在不同实例的配置中指定单独的密码文件:

  1. 生成密码文件:

    切换到那个用户 su DJM

    1
    2
    3
    mkdir -p ~/.vnc
    vncpasswd ~/.vnc/passwd1
    vncpasswd ~/.vnc/passwd2
    • ~/.vnc/passwd1 将用于显示号 :1
    • ~/.vnc/passwd2 将用于显示号 :2
  2. 修改服务文件: 在您的 vncserver_wrapper 或直接的 ExecStart 参数中,添加 -rfbauth 选项,指定不同的密码文件:

    1
    ExecStart=/usr/bin/vncserver_wrapper DJM %i -rfbauth /home/DJM/.vnc/passwd%i

    这样,显示号为 :1 的实例会使用 /home/DJM/.vnc/passwd1,显示号为 :2 的实例会使用 /home/DJM/.vnc/passwd2

内网穿透工具

选择其中一个工具,按照使用方法做好端口映射就行

VNC工具

桌面卡死, 项目更换父进程

我在跑我的项目, 但是桌面卡死了, 我又要需要查看当前项目的情况, 这个时候我就需要这个项目的父进程交给其他进程(一定要是这个用户的进程), 不然重启桌面会导致这个项目被杀死

使用ssh登陆进入(如果这个做不到, 就自求多福希望这个跑的项目不重要)

1
2
3
4
5
6
7
8
9
sudo yum install screen

screen -S my_session #

ps -axu | grep 项目信息 # 找到pid

reptyr pid # 使用上面找到的pid

systemctl restart gdm # 这里对应自己的桌面管理程序

这个是事后补救了, 如果是很重要的项目在跑或者很费时间的项目, 建议提前使用 screen这类工具, 这样就不怕什么终端关闭, 桌面卡死了, 但是如果断电还是怕的

获取服务器ip地址

由于服务器是在本地局域网里面, 但是我们又无法给他设定固定ip地址, 省的每次跑去机房看ip地址是多少, 所以我就写了一个程序, 然后程序每次检测当前ip和上一次ip是否相同, 不相同就发送ip给邮箱

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
import smtplib
import subprocess
import re
import time
import os
from email.mime.text import MIMEText

# 配置项
SENDER = '' # 发件邮箱
PASSWORD = '' # 邮箱授权码(需替换)
RECEIVER = '' # 收件邮箱
IP_FILE = '/home/DJM/previous_ip.txt' # IP存储文件
NETWORK_INTERFACE = 'eno1' # 要监控的网卡名称

def get_current_ip():
"""获取eno1网卡的IPv4地址"""
try:
output = subprocess.check_output(['ip', 'addr', 'show', NETWORK_INTERFACE]).decode()
match = re.search(r'inet (\d+\.\d+\.\d+\.\d+)/', output)
return match.group(1) if match else None
except Exception as e:
print(f"获取IP失败: {e}")
return None

def read_previous_ip():
"""读取存储的IP"""
try:
with open(IP_FILE, 'r') as f:
return f.read().strip() or None
except FileNotFoundError:
return None

def write_current_ip(ip):
"""写入当前IP到文件"""
os.makedirs(os.path.dirname(IP_FILE), exist_ok=True)
with open(IP_FILE, 'w') as f:
f.write(ip if ip else '')

def send_email(ip):
"""发送邮件通知"""
msg = MIMEText(f'当前IP地址已变更为:{ip}' if ip else '网卡IP地址丢失!')
msg['Subject'] = 'IP变更通知' if ip else 'IP丢失警告'
msg['From'] = SENDER
msg['To'] = RECEIVER

try:
with smtplib.SMTP_SSL('smtp.qq.com', 465) as server:
server.login(SENDER, PASSWORD)
server.sendmail(SENDER, [RECEIVER], msg.as_string())
print("邮件发送成功")
except Exception as e:
print(f"邮件发送失败: {e}")

def main():
while True:
current_ip = get_current_ip()
previous_ip = read_previous_ip()

if current_ip != previous_ip:
if current_ip:
print(f"检测到IP变更: {previous_ip} -> {current_ip}")
else:
print("警告:网卡IP丢失!")

send_email(current_ip)
write_current_ip(current_ip)

time.sleep(60)

if __name__ == "__main__":
main()

创建 /etc/systemd/system/ip_checker.service

1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=IP Address Checker Service
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/python3 /path/to/ip_checker.py #需替换
Restart=always
RestartSec=60
User=root

[Install]
WantedBy=multi-user.target

启用并启动服务

1
2
3
4
5
6
7
8
9
10
11
# 重载systemd配置
sudo systemctl daemon-reload

# 设置开机启动
sudo systemctl enable ip_checker

# 立即启动服务
sudo systemctl start ip_checker

# 查看服务状态
sudo systemctl status ip_checker