Cisco VPN AnyConnect가 Linux에서 로그아웃을 감지하지 못하도록 방지

Cisco VPN AnyConnect가 Linux에서 로그아웃을 감지하지 못하도록 방지

Cisco VPN AnyConnect는 VPN 세션을 시작한 사용자가 로그아웃하고 VPN 연결을 끊는 시기를 자동으로 감지합니다. 이런 일이 발생하지 않도록 하고 싶습니다. 로그아웃 후에도 지속되는 스크린 세션을 사용해 보았지만 여전히 VPN 연결이 끊깁니다.

문제는 다음과 같습니다

  • VPN 클라이언트가 로그아웃을 감지하는 데 사용할 수 있는 메커니즘은 무엇입니까?
  • VPN 클라이언트 연결 끊김을 방지하는 방법(Cisco 연결 프로필 XML을 수정할 수 없습니다.)

시스템에 대한 루트 액세스 권한이 있습니다.

답변1

VPN 클라이언트의 동작을 더욱 심층적으로 분석한 결과, 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

관련 정보