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

関連情報