사용자별로 VPN을 별도로 사용하는 방법:

사용자별로 VPN을 별도로 사용하는 방법:

다중 사용자 설정(Ubuntu)이 있습니다(다른 TTY에 동시에 로그인된 사용자).

계정을 사용하여 NordVPN에 연결하면 nordvpn connect이제 모든 사용자가 해당 VPN을 통해 인터넷에 연결됩니다.

어떻게 하면 사용자의 네트워크를 분리할 수 있습니까? 즉, VPN에 연결할 때 현재 사용자만 영향을 받고 해당 사용자에 대한 모든 연결은 VPN을 사용해야 한다는 의미입니까?


  • nordvpnopenvpn직접 연결과 함께 작동하는 래퍼이므로 openvpn순수한 openvpn솔루션도 도움이 될 것입니다.
  • .root 를 통한 사용자 액세스 sudo.
  • 스크립트 솔루션에 만족합니다.

답변1

사용자별로 VPN을 별도로 사용하는 방법:

사용자가 다른 사용자 공간을 사용하는 상황:

기본적으로 사용자 공간은 네트워크를 분리합니다(회로망), 따라서 nordvpn connect다른 사용자 공간에는 영향을 미치지 않지만 이는 Linux에서 사용자 시스템의 기본 기능이 아니므로 각 사용자의 네트워크를 격리하려면 다른 사용자 공간을 설정해야 합니다. 또한 네트워크 인터페이스는 단일 네임스페이스에만 존재할 수 있습니다. 인터페이스의 브리지 또는 veth는 사용자 공간 간에 트래픽을 전달하는 데 사용됩니다.

사용자가 동일한 사용자 공간을 사용하는 경우:

Linux 사용자 시스템은 동일한 네트워크 시스템에 남아 있습니다. 한 사용자가 Wi-Fi에 연결하면 네트워크 카드가 루트 수준에 설정되어 기본 설정으로 네트워크를 사용하는 모든 사람과 공유되므로 다른 사용자가 해당 연결의 이점을 누릴 수 있습니다.

VPN 연결은 새로운 가상 인터페이스(tun 또는 tap)를 통해 이루어지며 기본 네트워크 인터페이스(wifi 또는 eth0)에 연결됩니다... VPN 연결이 초기화되면 tun/tap 인터페이스가 생성되고, 이 인터페이스가 VPN 서버를 설치하고 터널을 생성하지만 이것이 모든 연결이 VPN 인터페이스를 통해 터널링된다는 의미는 아닙니다. 일반적인 VPN 연결이 작동하려면 먼저 가상 인터페이스를 사용하여 연결을 초기화한 다음노선VPN 인터페이스를 통해 모든 연결을 강제하기 위해 추가되었으며 이를 호출합니다.라우팅.

이 정보를 알고 나면 VPN 연결을 시작하지 않고 솔루션이 시작됩니다.라우팅그런 다음 각 사용자에 대해 개별적으로 라우팅을 설정합니다. VPN이 필요하지 않은 사용자는 변경할 필요가 없으며, VPN을 사용해야 하는 사용자의 경우 iptables/ip-route를 통해 특별한 경로를 추가해야 합니다. 즉, VPN 인터페이스가 설정되지만 기본 인터페이스가 되지 않습니다(기본 VPN 라우팅 규칙이 푸시되지 않기 때문).

VPN 기본값:[Connect Command] > [Create-Tun/Tap] > [Tun/Tap 연결] > [Tun/Tap을 기본 인터페이스의 경로로 설정]

무라우팅 VPN:[Connect Command] > [Create-Tun/Tap] > [Connect Tun/Tap]

사용자 정의 라우팅이 포함된 VPN:[Connect Command] > [Create-Tun/Tap] > [Connect Tun/Tap]그 다음에[사용자 지정 경로]를 수동 또는 자동으로 추가

"라우팅" 단계를 사용하지 않고 VPN에 연결한 다음 사용자 지정 경로를 푸시/설정하세요. 이 작업은 iptables/ip-route 또는 VPN conf 설정 파일을 사용하여 수행할 수 있습니다.

기본 게이트웨이/경로를 푸시하지 않고 openvpn을 구성하는 방법:

VPN 구성 파일을 편집하고 route-nopull지시어를 추가하세요. ( nordvpn명령을 사용하여 openvpn conf 파일에 액세스할 수 있는 경우 필요에 따라 편집할 수 있습니다. 그렇지 않으면 openvpn 또는 네트워크 관리자를 사용하여 VPN에 연결해야 합니다)

특정 Linux 사용자를 위해 특정 인터페이스를 사용하십시오.

이 가이드당신이 달성하고 싶은 것과 똑같은 것을 달성하고 있습니다. 그렇지 않으면그 대답자세한 대안을 제시하세요.

답변2

부분 답변(자세한 내용이 필요함):

"일반" 인터넷 연결과 NordVPN 인터넷 연결을 구별하는 한 가지 방법은 네트워크 네임스페이스를 만들고 nordvpn이 네임스페이스에서 시작한 다음 이 네임스페이스에서 이 VPN을 사용해야 하는 모든 프로세스를 시작하는 것입니다.

세부 사항은 사용 방법에 따라 다릅니다.

  • 항상 NordVPN을 시작하는 사용자가 있는 경우 로그인할 때 해당 네트워크 네임스페이스를 생성하고 해당 네트워크 네임스페이스에서 해당 사용자에 대한 모든 프로세스를 시작할 수 있습니다. 따라서 사용자는 "정상적인" 인터넷 연결을 사용할 수 없습니다.

  • 모두가 "일반" 인터넷 연결과 NordVPN 연결을 사용하려는 여러 사용자가 있는 경우 해당 네임스페이스를 생성하고 여기에서 NordVPN을 실행하며 사용자에게 다른 애플리케이션을 실행할 수 있는 터미널을 제공하는 스크립트를 작성할 수 있습니다. 또는 웹 브라우저와 같은 애플리케이션도 이 네임스페이스에서 실행되었을 수 있습니다. 이 스크립트는 명령을 대체합니다 connect.

요구 사항에 따라 이 작업을 수행하는 방법이 더 있을 수 있습니다. 따라서 질문을 편집하고 요구 사항/상황을 설명하십시오.

네임스페이스를 생성하려면 루트 권한이 필요합니다. 즉, 스크립트를 setuid-root로 설정해야 하며(스크립트에 버그가 있는 경우 보안 문제가 될 수 있음), 사용자 sudo액세스 권한을 부여해야 할 수도 있습니다.

답변3

이 문제는 기존의 전반적인 설정, 공급자의 자체 구성 변경 가능성, 지원되는 실제 VPN 유형, 다소 복잡한 설정을 원하는지 여부에 따라 여러 가지 방법으로 해결될 수 있다고 생각합니다. .

또한 NordVPN 서비스 관련 솔루션의 경우 지원을 요청할 수도 있습니다. 해당 nordvpn 명령이 반드시 OpenVPN을 사용하는 것은 아니며 IPSec 또는 PPTP/L2TP를 사용하는 것을 선호할 수도 있기 때문입니다.

그러나 NordVPN 서비스와 완벽하게 호환되는 범용 OpenVPN 솔루션이라고 부르는 것에 대해 아마도 가장 좋은 접근 방식은 정책 라우팅을 약간 변형하여 사용하는 것일 것입니다.

하지만 먼저 네임스페이스에 대한 귀하의 관심을 보고 이러한 네임스페이스를 사용할 수 있는 가능한 방법에 대한 제 생각을 공유하고 싶습니다.

물론 네임스페이스를 사용하면 사용자 간의 네트워크를 실제로 격리할 수 있으며, 그 주요 장점은 OpenVPN뿐만 아니라 모든 유형의 VPN에 대한 범용 솔루션이 된다는 것입니다.

그러나 많은 Linux 배포판에서는 이를 설정하는 데 필요한 도구를 설치하지 않는 경우가 많습니다. 문제의 문제는 단순히 unshareor ip netns exec 명령을 사용하여 해결되지 않는 것 같습니다. 이러한 명령을 사용하면 해당 프로세스만 해당 프로세스에서 새 네임스페이스를 볼 수 있기 때문입니다. 명령은 사용자의 전체 기존 세션에서 실행되는 대신 세션에서 실행됩니다.

또한 필요한 도구를 설치하여 설정한 대로 시스템을 설정하더라도 동일한 물리적 네트워크 장치를 사용하고 UNIX의 경우 공유하면서 각 사용자를 자신의 네트워크 네임스페이스로 분리하도록 시스템을 신중하게 설정해야 합니다. localhost에서 실행되는 도메인 소켓 및 서비스. 브리지(또는 macvlan), 서브넷 설정, 주소 할당, NAT 및 기타 복잡한 작업. 이것은 가능할 수도 있지만 간단하지는 않을 것이며 원래 문제보다 훨씬 더 복잡하다고 생각합니다.


따라서 라우팅 전략 접근 방식으로 돌아가서 제가 알 수 있는 한 가장 간단한 실행 가능한 솔루션인 기본 솔루션은 아마도 가장 일반적인 사용 사례에 충분하거나 더 복잡한 변형을 시도하기 전의 시작점으로 충분할 것입니다. 별도의 UID를 사용하여 각 사용자 터널의 라우팅 테이블을 사용자의 UID 기반 라우팅 정책을 통해 조회합니다.

다음과 같은 주요 기능을 갖습니다:

  • (상당히) 표준 버전의 OpenVPN이 필요합니다(즉, 공급자가 크게 맞춤화하지 않음).
  • iptables 사용자의 UID 번호를 기반으로 관련 트래픽에 태그를 지정하려면 컴패니언 규칙이 필요합니다 .
  • 기존 방화벽 또는 라우팅 규칙과 함께 사용하는 경우 신중한 통합이 필요할 수 있습니다.
  • 그러나 sudoUID 0으로 실행되기 때문에 사용자가 실행하는 프로세스나 setuid 명령 또는 루트로 실행되는 응용 프로그램은 인식되지 않습니다. 이러한 상황의 대부분은 일반적인 데스크톱 시나리오에는 해당되지 않지만 발생할 가능성이 높으며 예상대로 처리되지 않습니다(즉, 트래픽의 해당 부분이 VPN에 들어 가지 않습니다).

두 개의 도우미 스크립트를 통해 모든 것을 처리할 수 있습니다. 사용할 하나통과OpenVPN, 기타 사용달리기 openvpn그 자체.

표준 OpenVPN은 이 ip명령을 사용하여 tun/tap 장치를 설정하고 VPN 공급자가 푸시한 경로를 설치합니다. 문제는 기본적으로 ip명령이 전체 시스템에서 사용되므로 모든 사용자를 포함하는 기본 라우팅 테이블에서 실행된다는 것입니다.

그러나 OpenVPN에서는 적용해야 하는 설정에 대해 서로 다른 명령을 지정할 수 있으므로 ip 단순히 서로 다른 경로 테이블에서 작동하는 래퍼를 제공할 수 있습니다.

이러한(가칭 myip.sh) 래퍼 스크립트는 다음과 같습니다.

#!/bin/bash -

my_session="$(ps -p $$ -o sid --no-header)" || exit 1
real_uid="$(ps -p $$ -o ouid --no-header || ps -p $my_session -o ruid --no-header || echo 0)"

real_ip_cmd=/sbin/ip

if [ $real_uid -ne 0 ] && [[ "$1" = ro* ]] ; then
    ! [ $2 ] && exec $real_ip_cmd "$1" list table $real_uid
    [[ "$2" =~ ^([adcfls]|rep).*$ ]] && exec $real_ip_cmd "$1" "$2" table $real_uid "${@:3}"
fi
exec $real_ip_cmd "$@"

처음 두 줄은 OpenVPN이 실행되는 실제 UID를 검색하는 데 사용됩니다. 이 UID를 테이블 ID로 사용합니다. 이렇게 하면 각 사용자는 VPN을 시작할 때 자신만의 라우팅 테이블을 갖게 됩니다.

if-then-fi블록은 route설정에 대한 호출을 캡처하고( ip단축되었지만 명확한 키워드를 허용하는 명령 기능을 모방) openvpn에 전달된 모든 명령 앞에 table사용자의 실제 UID와 동일한 ID를 전달하는 옵션을 추가합니다. 다른 모든 ip명령(예: 명령이 아닌 명령 route)은 영향을 받지 않고 전달됩니다.

또 다른 스크립트는 openvpn사용자 생성 트래픽이 다른 테이블에 따라 라우팅되도록 설정과 함께 명령을 래핑합니다. 이 래퍼 스크립트의 요지는 공급자의 자체 구성 파일에 포함될 수 있으므로 보다 원활한 통합이 가능합니다. 이는 비대화형(예: 시작 시)으로 VPN을 설정하려는 경우에 도움이 됩니다. 그러나 이 래퍼 스크립트를 사용하면 구성 파일을 조작할 필요가 없으므로 이 버전을 표시하기로 결정했습니다.

따라서 단일 래퍼 스크립트는 다음과 같습니다.

#!/bin/bash

my_session="$(ps -p $$ -o sid --no-header)" || exit 1
real_uid="$(ps -p $$ -o ouid --no-header || ps -p $my_session -o ruid --no-header || echo 0)"
[ $real_uid -eq 0 ] && { echo "will not run for UID 0" >&2 ; exit 1; }

remove_tagging() {
        iptables -t mangle -D OUTPUT -m owner --uid $real_uid -j MARK --set-mark $real_uid
        ip rule del fwmark $real_uid
        ip route flush table $real_uid
} 2>/dev/null

trap 'remove_tagging' EXIT

source <(ip route | sed "s/^/ip route add table ${real_uid} /")

(
ip -o monitor | grep -qm 1 '^[0-9]\+: tun[0-9]\+[[:blank:]]\+inet '
ip rule add fwmark $real_uid lookup $real_uid
iptables -t mangle -A OUTPUT -m owner --uid $real_uid -j MARK --set-mark $real_uid
) &

openvpn --iproute myip.sh --config tunnel-config.ovpn

처음 세 줄은 사용자의 실제 UID를 검색하려고 다시 시도하고, 얻을 수 없으면 계속하지 마세요.

그런 다음 스크립트가 종료될 때 실행되는 함수가 있습니다. 이 함수는 다음 서브쉘에 의해 이루어진 설정을 제거합니다.

하지만 먼저 현재 기본 라우팅 테이블 전체를 사용자를 위한 다른 테이블에 복사합니다.

그런 다음 서브셸을 실행하고 tunXOpenVPN이 장치를 설정할 때까지 기다린 다음 라우팅 규칙과 iptables동반 규칙을 추가하여 해당 시점부터 사용자가 생성한 트래픽을 표시합니다. 사용자 이름과 비밀번호를 요청해야 하는 경우 포그라운드에서 실행하려면 OpenVPN이 필요하기 때문에 백그라운드에서 실행합니다.

명령 source, 서브쉘(파이프 없음 ip -o monitor ) 및 기능은 remove_taggingVPN 구성 파일에 (각각) 및 옵션으로 포함될 수 있는 부분입니다. 이렇게 하면 이 래퍼 스크립트가 완전히 제거됩니다.uproute-uproute-pre-down

마지막으로 실제 명령을 실행 하고 네트워크를 설정하는 명령으로 openvpn 자체 스크립트를 사용하도록 지시합니다 .myip.sh


ip약간의 변형이 가능한 방법은 대신 라우팅 규칙에서 선택적으로 사용할 수 있는 iproute2 패키지(명령 제공)의 최신 버전을 사용하는 것입니다 uidrange.fwmark

따라서 이 변형은 iptables 명령을 제거하고 명령을 명령 ip rule fwmark ..으로 대체합니다 ip rule uidrange ${real_uid}-${real_uid} lookup $real_uid(해당 명령도 마찬가지임 ip rule del ..).


특정 명령 실행을 지원하는 또 다른 변형은 sudoUID 대신 사용자 그룹(GID)에 대한 정책 라우팅을 기반으로 하는 것입니다. 여기에는 추가적인 기본 요구 사항이 있습니다.

  • Ubuntu를 포함한 많은 Linux 배포판에서 일반적으로 사용되는 사용자 존재에 대한 고유 GID
  • sudo원래 GID 번호를 보존하려면 추가 옵션( -g <user> -u root또는 의 동등한 구성 )을 사용하여 실행하세요.sudoers

그러나 이 클래스 외부에서 실행되는 사용자의 UID 0 프로세스는 여전히 인식되지 않습니다 sudo.


"UID 0 프로세스" 문제를 실제로 해결하려면 cgroup을 사용할 수 있지만 물론 여기에는 다른 요구 사항이 있습니다.

  • iptables Ubuntu 14.04와 같은 시스템에서는 아직 사용할 수 없는 iptables의 고유한 특정 "cgroup" 모듈을 사용하여 관련 트래픽을 표시하기 위한 동반 규칙
  • 이미 존재하는 기존 cgroup 설정과 충돌할 수 있음

cgroup을 사용하면 간단한 스크립트로 net-class-id 설정을 훌륭하게 처리할 수 있습니다.pam_exec.so

#!/bin/bash -e

uid=$(id -ru "${PAM_USER}")
mkdir -p /sys/fs/cgroup/net_cls/user/${uid} && echo $uid > /sys/fs/cgroup/net_cls/user/${uid}/net_cls.classid
echo $$ > /sys/fs/cgroup/net_cls/user/${uid}/cgroup.procs

그런 다음 원하는 구성 파일에 다음 줄을 추가합니다 /etc/pam.d.

session optional    pam_exec.so /root/set-net-cls-id.sh

위의 줄은 대화형 서비스(예: 콘솔 로그인, 데스크톱 환경 등)를 통해 시작된 모든 세션을 /etc/pam.d/common-session 다루기 위해 기존 파일에 포함될 수 있습니다 .ssh

이 설정을 사용하면 iptables 래퍼 스크립트에 사용되는 명령은 다음과 같습니다.

iptables -t mangle -A OUTPUT -m cgroup --cgroup $real_uid -j MARK --set-mark $real_uid

해당 삭제 명령은 로 -D대체 됩니다 -A.

cgroup 솔루션의 가능한 변형은 를 사용하지 않고 cgroup을 직접 처리하는 기능을 systemd사용할 수 있도록 이를 통합하는 것일 수 있습니다 .systemdpam_exec

노트그러나 이 cgroup 설정은 Ubuntu 14.04에서 제대로 작동하지 않습니다. 해당 버전은 사용자 세션당 cgroup을 설정하는 데 사용되므로 이 솔루션에서 설정한 설정을 재정의하기 때문입니다. 오히려 cat /proc/self/cgroup출력을 구문 분석하여 이름을 쉽게 얻을 수 있는 각 세션에 대해 동적으로 생성된 cgroup의 classid 값을 설정해야 합니다 .

관련 정보