回答:
他のほぼすべての改善された答え(@ elmart、@ user26312、myself)が(再)改善されました。スクリプトでの編集は必要ありません。
#!/bin/bash
default_line=$(netstat -rn |grep default)
gateway=$(echo $default_line | awk '{print $2}')
interface=$(echo $default_line | awk '{print $6}')
echo $gateway
echo $interface
scutil <<EOF
d.init
get State:/Network/Service/forticlientsslvpn/IPv4
d.add InterfaceName ppp0
set State:/Network/Service/forticlientsslvpn/IPv4
EOF
route delete default
route delete -ifscope $interface default
route add -ifscope $interface default $gateway
route add -net 0.0.0.0 -interface $interface
これを入れたファイルを実行可能にして、sudoで(VPNに接続した後)実行します。スクリプトは変更を行う前に、現在のデフォルトルートを確認するため、現在のゲートウェイとインターフェースを認識します。
完全なソリューションではありません。各VPN接続のセットアップ後に、次の2つの高レベルの作業を行う必要があります。
ppp0
scutil-forti
たとえば、次の名前のファイルを作成します。
d.init
get State:/Network/Service/forticlientsslvpn/IPv4
d.add InterfaceName ppp0
set State:/Network/Service/forticlientsslvpn/IPv4
ゲートウェイのルートをやり直すため、次のファイルを使用して別のファイルを作成routes-forti
します(ネットワークの特定の設定を含む行に注意してください)。
sudo route delete default
sudo route delete -ifscope en0 default # This line depends on your interface
sudo route add -ifscope en0 default 192.168.2.252 # This depends on your normal local gateway.
sudo route add -net 0.0.0.0 -interface en0
今、実行します、
$ cat scutil-forti |sudo scutil ; bash routes-forti
State:/Network/Service/forticlientsslvpn/IPv4
キーは、VPNトンネルが実行されると最初から存在し、VPNトンネルが削除されると削除されます。ルートは実際には本来あるべきものと変わりません。
@hbogertのソリューションをより扱いやすい単一のスクリプトに作り直しました。
#!/bin/bash
scutil <<EOF
d.init
get State:/Network/Service/forticlientsslvpn/IPv4
d.add InterfaceName ppp0
set State:/Network/Service/forticlientsslvpn/IPv4
EOF
route delete default
route delete -ifscope en0 default
route add -ifscope en0 default 192.168.1.1
route add -net 0.0.0.0 -interface en0
これは、en0インターフェースと192.168.1.1デフォルトゲートウェイを使用していることを前提としています。そうでない場合は、対応する値に置き換えてください。それらを知らない場合は、入力route get www.google.com
して入手してください。次に:
chmod u+x fix-vpn
)。sudo fix-vpn
VPNに接続した直後にsudo()で実行します。私はそれを試しました、そしてそれは働きます。私が言ったように、これは以前の解決策の単なる修正です。コメントに十分なスペースがなかったので、別の回答として投稿しました。
ところで、/etc/ppp/ip-up
接続時に自動的に実行されるように、これをスクリプトに含めることもできると思いました。しかし、何らかの理由で、そのようには機能しません。誰かがそれについて説明/改善できる場合は、どうぞ。
古いバージョンのForticlientを使用することができ、動作することを確認しました。
Dropboxへのリンクは次のとおりです。
https://www.dropbox.com/s/p43ssvp0gusmzeq/forticlientsslvpn_macosx_4.0.2297.dmg?dl=0
更新: Mac OS X用の最新の公式バージョン5.4.1をダウンロードしてインストールすると、Mac OS X El Capitanのすべての問題が修正されます。
フォーティネットフォーラムで説明されているように、最新の(まだ公開されていない)バージョンのFortiClientをダウンロードして、Mac OS X El Capitanの問題を修正する必要があります。
https://www.dropbox.com/sh/cb0j4pxw1f8nq84/AABHzZW1bpx1VjzYAmiK00S9a?dl=0
これは私にとって最も簡単な解決策でした。
@elmartの答えを少し改善する(私は思う)。
#!/bin/bash
scutil <<EOF
d.init
get State:/Network/Service/forticlientsslvpn/IPv4
d.add InterfaceName ppp0
set State:/Network/Service/forticlientsslvpn/IPv4
EOF
ROUTE_OUT=$(route get www.google.com)
GATEWAY=$(echo "${ROUTE_OUT}"|grep gateway|cut -d':' -f2|xargs)
INTERFACE=$(echo "${ROUTE_OUT}"|grep interface|cut -d':' -f2|xargs)
echo "Fixing $INTERFACE with gateway $GATEWAY"
route delete default
route delete -ifscope $INTEFACE default
route add -ifscope $INTERFACE default $GATEWAY
route add -net 0.0.0.0 -interface $INTERFACE
そうすれば、スクリプトを編集する必要がなくなります(インターフェイスの変更は問題になりません)。xargs
空白を取り除くために使用されます。
私も追加しました(これが改善であるかどうかはわかりませんが):
rootcheck () {
if [ $(id -u) != "0" ]
then
echo "We need sudo permissions to run this script"
sudo "$0" "$@" # Modified as suggested below.
exit $?
fi
}
rootcheck "$@"
スクリプトの最初に、sudoを使用することを人々に思い出させます。
route get
コマンドにIPアドレスを使用して、DNSへの依存を排除することをお勧めします。
$ netstat -rn
てゲートウェイとインターフェースを取得するだけです。
私はhbogertのスクリプトを取り、それを自分と他の従業員のためにApplescriptでラップしました。ここから入手できます:https ://www.dropbox.com/s/lh0hsqdesk3i0n7/Execute-Post-VPN-Connection.app.zip?dl=0
VPNに接続し、アプリを実行して管理者パスワードを入力するだけです(sudoに必要)。注:/ Applications /に保存する必要があります
FortiClientが提供するものよりも前にGoogle DNSサーバーを使用するようにDNS設定を再構成することで、問題を解決しました。残念ながら、これは再接続するたびに行う必要があります。
#!/bin/bash
scutil <<EOF
d.init
d.add ServerAddresses 8.8.8.8 8.8.4.4 <IP ADDRESSES FOR DNS FROM FORTICLIENT>
set State:/Network/Service/forticlientsslvpn/DNS
quit
EOF
これに関する詳細はここにあります。
私の現在のOS Xバージョン(Sierra 10.12.6)とFortiClient 5.6.1では、ServerAddressesに3つ以上のアドレスがある場合、 "set"コールは何も保持しません( "get"の場合、何もされません)更新しました)。これを回避するために、最初のFortiClient DNSアドレスのみを保持し、それを私のパブリックDNSアドレス(8.8.8.8)とマージすることにしました。
さらに、FortiClient接続でbashスクリプトを自動的に実行することをお勧めします。これは、FortiClient構成スクリプトをエクスポートしてから再インポートすることで実行できます。
以下の完全なガイド:
1 /次のbashスクリプトを作成し、どこかに保存します(私の場合はに入れました~/bashscripts/update-forticlient-dns.sh
)。FortiClient接続が確立している間<FIRST IP ADDRESS FOR FORTICLIENT DNS>
の結果に置き換えることを忘れないでくださいscutil --dns | grep "nameserver\[0\]"
#!/bin/bash
ROOT_PASSWORD=$1
# Uncomment this if you want to log everything happening during this script execution into a dedicated log file
# exec >/tmp/forticlient-log 2>&1
# Ensuring we did a sudo correctly once
# Because we cannot both use a pipe and an stdin redirection at the same time
# (or at least, my bash knowledge is not wide enough for that :-))
echo "$ROOT_PASSWORD" | sudo -S ls /dev/null
sudo scutil <<EOF
get State:/Network/Service/forticlientsslvpn/DNS
d.add ServerAddresses 8.8.8.8 <FIRST IP ADDRESS FOR FORTICLIENT DNS>
set State:/Network/Service/forticlientsslvpn/DNS
quit
EOF
2 / FortiClientを実行し、[ 設定] > [ 全般 ]に移動して、[ バックアップ ]ボタンをクリックすると、FortiClient構成がファイルにエクスポートされます
3 /このファイルで、/ forticlient_configuration / vpn / sslvpn / connections / connection [name = "YOUR CONNECTION"] / on_connect / script / scriptノードを見つけて編集し、その中のスクリプトを呼び出します。
<on_connect>
<script>
<os>mac</os>
<script>/Users/fcamblor/bashscripts/update-forticlient-dns.sh "your_secret_root_password_here"</script>
</script>
</on_connect>
4 / FortiClientコンソールに戻り、左下隅にあるロックをクリックして、[ 設定] > [ 一般]に移動し、[ 復元]ボタンをクリックします。更新された構成ファイルを見つけると、それだけです。DNS 構成は、オンザフライで毎回更新されますVPNに接続します。