Cisco VPN AnyConnect 会自动检测发起 VPN 会话的用户何时注销,然后断开 VPN 连接。我想阻止这种情况发生。我尝试使用注销后持续存在的屏幕会话,但 VPN 仍然断开连接。
问题是:
- VPN 客户端用于检测注销的可能机制是什么
- 如何阻止 VPN 客户端断开连接(我无法修改 Cisco 连接配置文件 XML)
我确实拥有系统的 root 访问权限。
答案1
在更深入地分析 VPN 客户端的行为后,我发现它不会查找进程或其父进程,而只是在建立 VPN 连接时跟踪所有登录会话。
这意味着,如果您在连接 VPN 时打开了 2 个登录会话 A 和 B,并且关闭了其中任何一个,VPN 将断开连接。
我的解决方案是在与客户端连接之前从 utmp 中删除会话(utmp 基本上是运行w
或时显示的内容)。who
为此,我编写了一个名为 的小工具utmpremove
,其源代码如下:
#include <string.h>
#include <stdlib.h>
#include <pwd.h>
#include <unistd.h>
#include <utmp.h>
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
struct utmp *u; // Used to read existing entries
struct utmp newent; // Used for new entry (to delete)
char *my_tty = ttyname(STDIN_FILENO);
printf("Searching utmp for my TTY: %s\n", my_tty);
setutent();
int found_myself = 0;
for (;;) {
u = getutent();
if(!u) break;
if(u->ut_type != USER_PROCESS) continue;
// Get TTY of this utmp entry (taken from source of 'w')
char tty[5 + UT_LINESIZE + 1] = "/dev/";
for (int i = 0; i < UT_LINESIZE; i++) {
/* clean up tty if garbled */
if (isalnum(u->ut_line[i]) || (u->ut_line[i] == '/'))
tty[i + 5] = u->ut_line[i];
else
tty[i + 5] = '\0';
}
// Check if this matches ours
printf("- utmp tty: %s\n", tty);
if(strcmp(my_tty, tty) == 0) {
printf("This is me! Removing...\n");
found_myself = 1;
memcpy(newent.ut_id, u->ut_id, sizeof(u->ut_id));
break;
}
}
// Remove entry if found
if(found_myself) {
newent.ut_type = DEAD_PROCESS;
memset(newent.ut_line, 0, UT_LINESIZE);
newent.ut_time = 0;
memset(newent.ut_user, 0, UT_NAMESIZE);
setutent();
if(pututline(&newent)) {
printf("Removed utmp entry successfully.\n");
endutent();
exit(EXIT_SUCCESS);
} else {
printf("Failed removing utmp entry.\n");
endutent();
exit(EXIT_FAILURE);
}
} else {
printf("No matching utmp entry found.\n");
endutent();
exit(EXIT_FAILURE);
}
}
命令行将如下所示:
(sudo ./utmpremove) && /opt/cisco/anyconnect/bin/vpn -s connect