Mac에서 분할 VPN을 강제로 Cisco VPN으로 강제 전송하는 방법


40

누구나 시스코 VPN을 통해 라우팅 테이블을 해킹하여 VPN 라우팅을 강제로 물리 치는 방법을 알고 있습니까? 내가하고 싶은 것은 VPN을 통해 10.121. * 및 10.122. * 주소 만 있고 인터넷에 직접 연결되는 모든 것입니다.

답변:


27

다음은 나를 위해 작동합니다. Cisco VPN에 연결 한 후이를 실행하십시오. (저는 Cisco 브랜드 클라이언트가 아닌 OS X의 내장 Cisco 클라이언트를 사용하고 있습니다.)

sudo route -nv add -net 10 -interface utun0
sudo route change default 192.168.0.1

10첫 번째 명령에서 터널의 다른쪽에있는 네트워크로 바꿉니다 .

192.168.0.1로컬 네트워크의 게이트웨이로 교체하십시오 .

나는 이것을 bash 스크립트에 넣었다.

$ cat vpn.sh 
#!/bin/bash

if [[ $EUID -ne 0 ]]; then
    echo "Run this as root"
    exit 1
fi

route -nv add -net 10 -interface utun0
route change default 192.168.0.1

VPN을 연결할 때 자동으로 실행 하는 방법에 대한 설명을 찾았 지만 금요일에 늦었고 시도하지 않는 것이 좋습니다. :)

편집하다:

그 후 Cisco VPN을 사용하던 직장을 떠났으므로 메모리에서 비롯된 것입니다.

10첫 번째 명령은 VPN을 통해 라우팅 할 네트워크입니다. 10의 짧은 손입니다 10.0.0.0/8. 에서 투안 안 트란의 경우, 네트워크는 것 같습니다 192.168.5.0/24.

두 번째 명령에서 지정할 게이트웨이는 로컬 게이트웨이 여야합니다. 스플릿 터널링을 방지하는 VPN에 로그인하면 모든 패킷이 가상 인터페이스에서 라우팅되도록 라우팅 테이블을 변경하여 해당 정책을 시행합니다. 따라서 기본 경로를 VPN을 사용하기 전의 경로로 다시 변경하려고합니다 .

게이트웨이를 알아내는 가장 쉬운 방법 netstat -rn은 VPN에 로그인하기 전에 실행 하고 "기본"대상의 오른쪽에있는 IP 주소를 보는 것입니다. 예를 들어, 여기 내 상자에 다음과 같은 모양이 있습니다.

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
default            10.0.1.1           UGSc           29        0     en1
10.0.1/24          link#5             UCS             3        0     en1
10.0.1.1           0:1e:52:xx:xx:xx   UHLWIi         55   520896     en1    481
10.0.1.51          7c:c5:37:xx:xx:xx  UHLWIi          0     1083     en1    350
10.0.1.52          127.0.0.1          UHS             0        0     lo0

내 게이트웨이는 10.0.1.1— "기본"대상의 오른쪽에 있습니다.


1
좀 더 설명해 주시겠습니까? 내 ifconfig 가 utun0을 반환합니다 : flags = 8051 <UP, POINTOPOINT, RUNNING, MULTICAST> mtu 1280 inet 192.168.5.102-> 192.168.5.102 netmask 0xffffffff. 또한 위의 숫자 10으로 무엇을 바꿔야하는지 이해하지 못합니다. 감사합니다.
Tuan Anh Tran

@TuanAnhTran : 답변을 업데이트했습니다. 도움이되는지 알려주십시오.
Mark E. Haase

최신 버전의 경우 /Applications/VPNClient.app가 설치되어 있고 ifconfig에 나열된 utun0이 표시되지 않습니다. gif0, stf0 및 fw0 어댑터가 표시됩니다. 올바른 어댑터가 무엇인지 어떻게 알 수 있습니까? VPN 연결 여부에 관계없이 ifconfig 출력에 아무런 차이가 없습니다 (entu의 MTU 값 제외).
haridsv

1
LaunchDaemons에 익숙하지 않은 사람들 을 위해 VPN에 연결할 때마다 스크립트를 호출하는 방법을 설명하는 안내서를 작성했습니다 . (그런데, +1 우수한 답변이지만 요점을 작동시키기 위해 조금 더 필요했습니다).
dr jimbob

1
안타깝게도 Cisco AnyConnect 클라이언트에서는 작동하지 않습니다.
jeremyjjbrown

5

mehaase정보를 사용하여 Mac 에서이 프로세스를 단순화하는 Python 스크립트를 작성했습니다. 스크립트를 실행하면 스크립트가 방화벽 정보를 저장하고 AnyConnect 클라이언트를 시작한 후 로그인을 기다린 다음 경로 및 방화벽을 수정합니다. '터미널'에서 스크립트를 실행하십시오.

#!/usr/bin/python

# The Cisco AnyConnect VPN Client is often configured on the server to block
# all other Internet traffic. So you can be on the VPN <b>OR</b> you can have
# access to Google, etc.
#
# This script will fix that problem by repairing your routing table and
# firewall after you connect.
#
# The script does require admin (super user) access. If you are prompted for
# a password at the start of the script, just enter your normal Mac login
# password.
#
# The only thing you should need to configure is the vpn_ip_network.
# Mine is 10.x.x.x so I just specify '10' but you could be more specific
# and use something like '172.16'
vpn_ip_network = '10'

import sys
import subprocess


def output_of(cmd):
    lines = subprocess.Popen(cmd if isinstance(cmd, list) else cmd.split(' '), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0]
    try:
        lines = lines.decode('utf-8')
    except Exception:
        pass
    return [line.strip() for line in lines.strip().split('\n')]

sys.stdout.write("Mac Account Login ")
good_firewall_ids = set([line.partition(' ')[0] for line in output_of('sudo ipfw -a list')])
sys.stdout.write('Firewall Saved.\n')

gateway = None
for line in output_of('route get default'):
    name, delim, value = line.partition(':')
    if name == 'gateway':
        gateway = value.strip()
        p = subprocess.Popen(['/Applications/Cisco/Cisco AnyConnect VPN Client.app/Contents/MacOS/Cisco AnyConnect VPN Client'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        was_disconnected = False
        while True:
            line = p.stdout.readline()
            if line == '' or p.poll():
                sys.stdout.write("Never connected!\n")
                break
            try:
                line = line.decode('utf-8')
            except Exception:
                pass
            if 'Disconnected' in line:
                sys.stdout.write('Waiting for you to enter your VPN password in the VPN client...\n')
                was_disconnected = True
            if 'Connected' in line:
                if was_disconnected:
                    subprocess.Popen(['sudo','route','-nv','add','-net',vpn_ip_network,'-interface','utun0'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).wait()
                    subprocess.Popen(['sudo','route','change','default',gateway], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).wait()
                    unfriendly_firewall_ids = list(set([line.partition(' ')[0] for line in output_of('sudo ipfw -a list')])-good_firewall_ids)
                    extra = ''
                    if unfriendly_firewall_ids:
                        subprocess.Popen('sudo ipfw delete'.split(' ') + unfriendly_firewall_ids, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).wait()
                        sys.stdout.write("VPN connection established, routing table repaired and %d unfriendly firewall rules removed!\n" % len(unfriendly_firewall_ids))
                    else:
                        sys.stdout.write("VPN connection established and routing table repaired!\n")
                else:
                    try:
                        subprocess.Popen.kill(p)
                        sys.stdout.write('VPN was already connected. Extra VPN client closed automatically.\n')
                    except Exception:
                        sys.stdout.write('VPN was already connected. Please close the extra VPN client.\n')
                break
        break
else:
    sys.stdout.write("Couldn't get gateway. :-(\n")

4

이 이전 답변 의 Python 스크립트 는 도움이되었지만 AnyConnect가 장치의 다른 인터페이스 (예 : VMware 인터페이스)를 인계하는 데 사용 된 경로는 처리하지 않았습니다. 또한 여러 VPN 네트워크를 처리 할 수 ​​없었습니다.

내가 사용하는 스크립트는 다음과 같습니다.

#!/bin/bash

HOME_NETWORK=192.168
HOME_GATEWAY=192.168.210.1
WORK_NETWORKS="X.X.X.X/12 10.0.0.0/8 X.X.X.X/16"

# What should the DNS servers be set to?
DNS_SERVERS="10.192.2.45 10.216.2.51 8.8.8.8"

##
## Do not edit below this line if you do not know what you are doing.
##
function valid_ip()
{
    local  ip=$1
    local  stat=1

    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        OIFS=$IFS
        IFS='.'
        ip=($ip)
        IFS=$OIFS
        [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
            && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
        stat=$?
    fi
    return $stat
}

# Nuke any DENY firewall rules
for RULE in `sudo ipfw list | grep deny | awk '{print $1}' | xargs`; do sudo ipfw delete $RULE; done

# Delete any routes for the home network that Anyconnect might have made
sudo route delete -net ${HOME_NETWORK}
sudo route add -net ${HOME_NETWORK} ${HOME_GATEWAY}

# Get the AnyConnect interface
ANYCONNECT_INTERFACE=`route get 0.0.0.0 | grep interface | awk '{print $2}'`

# Add the work routes
for NETWORK in ${WORK_NETWORKS}; do
    sudo route -nv add -net ${NETWORK} -interface ${ANYCONNECT_INTERFACE}
done

# Set the default gateway
sudo route change default ${HOME_GATEWAY}

# Mass route changes
for NET in `netstat -nr | grep -e ^${HOME_NETWORK} | grep utun1 | awk '{print $1}' | xargs`; do 
    if valid_ip ${NET}; then
        echo "Changing route for network"
        sudo route change ${NET} ${HOME_GATEWAY}
    else
        echo "Changing route for host"
        sudo route change -net ${NET} ${HOME_GATEWAY}
    fi      
done

# Set the nameservers
sudo scutil << EOF
open
d.init
d.add ServerAddresses * ${DNS_SERVERS}
set State:/Network/Service/com.cisco.anyconnect/DNS
quit
EOF

이것은 cisco anyconnect 3.1.0에서 작동합니까? 나는 그렇게 생각하지 않습니다 ... 3.1.0에 대한 업데이트 된 스크립트가 있습니까? 감사!
코스타

2

관리자는 10.121. * 및 10.122. * 서브넷에 대한 로컬 라우팅을 사용하고 원격 (가정용 컴퓨터)이 나머지 모든 요청을 라우팅하도록 VPN 연결을 설정해야 할 것입니다. (대역폭과 책임을 절약합니다)

Cisco의 "VPN Client"를 사용하고 있습니까? OS OS X?

OS X의 VPN (네트워킹 기본 설정 창을 통해 설정)을 사용하는 경우 "고급"을 클릭하고 "요청시 VPN"탭을 선택할 수 있습니다. 그런 다음 VPN이 사용하는 데 필요한 서브넷을 제공하십시오.


4
OS X vpn 클라이언트에는 "VPN on Demand"옵션이없는 별도의 "Cisco"옵션 (PPTP 및 L2TP와 별도)이 있습니다.
Mark E. Haase

2

Locamatic 기능과 비슷한 Split Tunnel 라우팅을 활성화하기 위해 로그온 할 때 실행하고 계속 실행 / 숨길 수있는 기본 '앱'을 원했습니다 . 아마도 나는 Locamatic을 포크하고 그것을 가지고 놀 것이다. 이 AppleScript를 Github에 업로드 할 수도 있습니다. 답변에서 알 수 있듯이 데몬을 망치고 싶지 않았습니다 .

이 스크립트는 VPN에 기본 VPN (Cisco IPSec)이름이 있고 VPN 경로가 10.10.10.1/22> 라고 가정 합니다 10.10.20.10. 이들은 변경 / 추가 경로를 추가해야합니다. netstat -rnVPN이 연결된 경로를 보려면 VPN이 연결되어있을 때 (이 스크립트를 활성화하기 전에) 터미널을 실행하십시오 .

이 스크립트는 알림 센터에서 으르렁 스타일 알림도 생성합니다. :)

여기에 이미지 설명을 입력하십시오

나는 몇 가지 문제로 실행 마크 E. 하세대답은 A로부터 내 시스코 VPN의 수정 기존 게이트웨이 UCScA와 UGScI(EN0 인터페이스 특정) 경로와 같은 VPN 게이트웨이를 추가하는 UCS두 개의 기본 게이트웨이의 삭제를 필요로하고 다시 추가, 경로 원래 UGSc기본 게이트웨이

StackExchange / google에 감사합니다. 이것이 첫 번째 AppleScript이며 몇 시간의 인터넷 검색 없이는 함께 사용할 수 없었습니다.

제안 / 수정 / 최적화 환영합니다!

AppleScript ( GitHubGist ) :

global done
set done to 0

on idle
    set status to do shell script "scutil --nc status "VPN (Cisco IPSec)" | sed -n 1p"
    # do shell script "scutil --nc start "VPN (Cisco IPSec)"
    if status is "Connected" then
        if done is not 1 then
            display notification "VPN Connected, splitting tunnel"
            set gateway to do shell script "( netstat -rn | awk '/default/ {if ( index($6, \"en\") > 0 ){print $2} }' ) # gets non-VPN default gateway"
            do shell script "sudo route delete default" # deletes VPN-assigned global (UCS) default gateway
            do shell script "sudo route delete default -ifscope en0" # deletes en0 interface-specific (UGScI) LOCAL non-vpn gateway that prevents it being re-added as global default gateway
            do shell script "sudo route add default " & gateway # re-adds LOCAL non-vpn gateway (from get command above) as global default gateway
            do shell script "sudo route add 10.10.10.1/22 10.10.20.10" # adds VPN route
            display notification "VPN tunnel has been split"
            set done to 1
        end if
    else
        if done is not 2 then
            display notification "VPN Disconnected"
            set done to 2

        end if
    end if
    return 5
end idle

앱으로 저장 :

분할 터널 앱 저장 설정

마우스 오른쪽 버튼을 클릭하고 패키지 내용을 표시하고 info.plist에 다음을 추가하십시오 (이것은 도크에서 앱 아이콘을 숨겨서 Activity Monitor 또는 터미널을 사용해야 함> pkill -f 'Split Tunnel'앱을 종료해야 함). 독 아이콘을 원하면 생략하십시오.

<key>LSBackgroundOnly</key>
<string>1</string>

routeNOPASSWD다음 코드를 사용하여 새로운 한 줄 파일 (확장자 없음)을 정확하게 생성하십시오 (잘못하면 sudo 액세스를 막을 수 있습니다. visudo더 자세한 정보는 Google) -AppleScript의 sudo 명령을 암호 프롬프트없이 실행할 수 있습니다. 라우팅 테이블을 변경해야 할 경우 암호 프롬프트) :

%admin ALL = (ALL) NOPASSWD: /sbin/route

이 파일을 복사 /etc/sudoers.d

터미널에서 다음 명령을 실행합니다 (두 번째 명령은 암호를 묻습니다-암호를 sudo route묻지 않고 AppleScript 의 명령을 실행할 수 있습니다. 스크립트가 라우팅 테이블을 변경할 때 암호 프롬프트가 필요한 경우 생략)

chmod 440 /private/etc/sudoers.d/routeNOPASSWD
sudo chown root /private/etc/sudoers.d/routeNOPASSWD

마지막으로 앱을 시스템 환경 설정> 사용자 및 그룹> 로그인 항목에 추가하십시오.

분할 터널 로그인 항목


1

연결중인 라우터 관리자에게 분할 터널링을 수행하는 별도의 "그룹"을 설정하고 해당 그룹의 그룹 이름 및 그룹 암호가 포함 된 PCF 파일을 제공하도록 요청할 수 있어야합니다.


2
그것은 일어나지 않을 것입니다 :) 그들은 편집증입니다

1

나는 같은 문제가 있었고 @mehaase 덕분 에이 작업을 수행했습니다.

~/vpn.sh@mehaase의 답변을 작성한 후 다음 단계를 사용하여 실행 가능한 응용 프로그램 자동화 스크립트에 넣을 수 있습니다.

  1. Automator를 사용하여 새 응용 프로그램 만들기
  2. 라이브러리> 유틸리티에서 "AppleScript 실행"을 추가하십시오.
  3. 들어가다: do shell script "sudo ~/vpn.sh" with administrator privileges
  4. 저장하기

chmod 700 ~/vpn.sh스크립트에 실행 권한을 부여하기 위해 터미널 에서 실행해야 할 수도 있습니다 .

VPN에 연결 한 후이 응용 프로그램 스크립트를 실행하면됩니다. 관리자 비밀번호를 입력하고 확인-완료를 클릭하십시오. :)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.