阻止 Cisco VPN AnyConnect 在 Linux 下检测注销

阻止 Cisco VPN AnyConnect 在 Linux 下检测注销

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

相关内容