私のOpenVPN接続がpf.confを使用してアクティブでない限り、外部ネットワークへのすべての接続を拒否できました。ただし、ラップトップの蓋を閉じて開いたり、Wi-Fiのオンとオフを切り替えて接続が切断された場合、Wi-Fi接続が失われます。
次のパケットフィルタルールを/etc/pf.conf
で設定しています
# Deny all packets unless they pass through the OpenVPN connection
wifi=en1
vpn=tun0
block all
set skip on lo
pass on $wifi proto udp to [OpenVPN server IP address] port 443
pass on $vpn
Sudo pfctl -e
でパケットフィルターサービスを開始し、Sudo pfctl -f /etc/pf.conf
で新しいルールをロードします。
また、/System/Library/LaunchDaemons/com.Apple.pfctl.plist
を編集し、<string>-f</string>
の行を<string>-ef</string>
に変更して、システムの起動時にパケットフィルターが起動するようにしました。
これはすべて最初はうまく機能しているように見えます。OpenVPN接続がアクティブな場合にのみアプリケーションがWebに接続できるため、安全でない接続を介してデータをリークすることはありません。
しかし、ラップトップの蓋を閉じて再度開くか、Wi-Fiをオフにしてから再びオンにすると、Wi-Fi接続が失われ、ステータスバーのWi-Fiアイコンに感嘆符が表示されます。 Wi-Fiアイコンをクリックすると、「アラート:インターネット接続がありません」というメッセージが表示されます。
接続を回復するには、「アラート:インターネット接続がありません」というメッセージが消えてVPN接続を再び開くことができるようになる前に、Wi-Fiを切断して再接続する必要があります。また、Wi-Fiアラートが自然に消えて感嘆符が消え、再び接続できる場合もあります。どちらの方法でも、接続を再確立するのに5分以上かかることがあり、イライラすることがあります。
行block all
を削除すると問題が解決します(ただし、安全でない接続は許可されます)。そのため、AppleがWi-Fiを回復して確認するために必要なサービスをブロックしているようです)接続。私が試した:
pass on $wifi proto icmp all
を追加してicmpを有効にするpass on $wifi proto udp from $wifi to any port 53
を追加してDNS解決を有効にするblock all
をblock log all
に変更して)詳細を調べようとしましたが、Sudo tcpdump -n -e -ttt -i pflog0
を実行して「tcpdump: pflog0:そのようなデバイスは存在しません。」.これは、Wi-Fi接続をより速く再確立するのに役立ちません。
Wi-Fi接続を回復するために利用可能なサービスを決定するために他に何ができますか、またはWi-Fi再接続をより信頼できるものにするためにpf.confにどのルールを追加する必要がありますか?
Little Snitchを使用してネットワーク接続を監視したところ、AppleがバックグラウンドでmDNSResponderアプリを使用してWi-Fi接続が利用可能かどうかを確認しています。mDNSResponderがUDPサーバーをネームサーバーに送信して接続を確認しています。ホスト名をIPに解決します。
以前許可していたUDPルールの変更all Wi-Fi経由のUDPパケットはmDNSResponderの接続を許可します。つまり、切断後にWi-Fiが初めて再接続するようになります。それが将来他の人を助ける場合に備えて、マウンテンライオンに対するAppleのデフォルトルールを含む私の最終的なpf.confは次のようになります。
#
# com.Apple anchor point
#
scrub-anchor "com.Apple/*"
nat-anchor "com.Apple/*"
rdr-anchor "com.Apple/*"as
dummynet-anchor "com.Apple/*"
anchor "com.Apple/*"
load anchor "com.Apple" from "/etc/pf.anchors/com.Apple"
#
# Allow connection via Viscosity only
#
wifi=en1 #change this to en0 on MacBook Airs and other Macs without ethernet ports
vpn=tun0
vpn2=tap0
block all
set skip on lo # allow local traffic
pass on p2p0 #allow AirDrop
pass on p2p1 #allow AirDrop
pass on p2p2 #allow AirDrop
pass quick proto tcp to any port 631 #allow AirPrint
pass on $wifi proto udp # allow only UDP packets over unprotected Wi-Fi
pass on $vpn # allow everything else through the VPN (tun interface)
pass on $vpn2 # allow everything else through the VPN (tap interface)
これは、残念ながらntpd(時刻同期用)やmDNSResponderなど、UDPプロトコルを使用する少数のアプリケーションによってWi-Fi経由でデータが漏洩する可能性があることを意味します。しかし、これはデータがTCPを介して保護されずに移動することを許可するよりも優れているように見えます。これは、大部分のアプリケーションが使用するものです。誰かがこの設定を改善するための提案を持っている場合は、コメントまたはさらなる回答を歓迎します。
allUDPを許可する必要はありません。 mDNSの「m」は「マルチキャスト」を意味し、「リンクローカルマルチキャストアドレス」と呼ばれる特定のマルチキャスト宛先IPアドレスとUDP
ポート番号5353
を使用します。
これは、上記のソリューションでは、VPNをバイパスするために、世界中の37億のすべてのルーティング可能なIPアドレスへの65535個のUDPポートすべてへのトラフィックを不必要に許可していることを意味します。 UDPを使用するアプリケーションの数に驚かれるので、VPNがダウンしているときに発信トラフィックを防止するという元のアイデアの目的を大幅に破っています。
代わりにこのルールを使用しないのはなぜですか。
pass on $wifi proto udp to 224.0.0.251 port 5353
ファイアウォールの設定に関する非常に重要な経験則-ファイアウォールを介して例外を作成する場合は、常に可能な限り最も具体的なルールを使用するようにしてください。特異性は、利便性と使いやすさを犠牲にして得られる場合があります。つまり、通過させる必要のある他のリンクローカルプロトコルがいくつかあり、さらに別の特定のルールを追加する場合があります。
上記のルールを入れ替えて、元のwifiの問題が再発する場合は、PFがDHCP(ネットワークデバイスのIPアドレスの自動構成に使用されるプロトコル)をブロックしている可能性があります。 (ホームネットワークでは、通常、ブロードバンドルーターがDHCPサーバーになります)。 DHCPを許可するために必要なルールは次のとおりです。
pass on $wifi proto udp from 0.0.0.0 port 68 to 255.255.255.255 port 67
*注意:any
を0.0.0.0
に置き換える必要がある場合があります。コンピューターが最初に送信するDHCPREQUEST
パケットには、送信元アドレス0.0.0.0
があります。その段階では、コンピューターにはまだIPアドレスがないためです。
正直に言うと、私はany
の使用にもっと傾倒します。別のオプションは、任意のソース仕様、つまりpass on $wifi proto udp to 255.255.255.255 port 67
を取り除くことですが、これは、ルールのソースポート部分を失うことを意味し、できるだけ具体的にすることが常に最も安全なオプションです。
お役に立てば幸いです。ここにいくつかの便利なリンクがあります:
mDNS: http://en.wikipedia.org/wiki/Multicast_DNS#Packet_structure
DHSP: http://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol#DHCP_discovery
「簡単な」方法で PFルール を作成する目的で、現在の(vpn)インターフェースを含む既存のアクティブなインターフェースを特定するこの小さな killswitch プログラムを使用できます。
まだ進行中ですが、ファイアウォールルールを適切に作成するために、外部IPとアクティブなインターフェースを識別するための良い出発点になる可能性があります。
-i
(情報)オプションを使用した例または出力:
$ killswitch -i
Interface MAC address IP
en1 bc:57:36:d1:82:ba 192.168.1.7
ppp0 10.10.1.3
public IP address: 93.117.82.123
サーバーのIPを渡す-ip
:
# --------------------------------------------------------------
# Sat, 19 Nov 2016 12:37:24 +0100
# Sudo pfctl -Fa -f ~/.killswitch.pf.conf -e
# --------------------------------------------------------------
int_en1 = "en1"
vpn_ppp0 = "ppp0"
vpn_ip = "93.117.82.123"
set block-policy drop
set ruleset-optimization basic
set skip on lo0
block all
pass on $int_en1 proto udp to 224.0.0.251 port 5353
pass on $int_en1 proto udp from any port 67 to any port 68
pass on $int_en1 inet proto icmp all icmp-type 8 code 0
pass on $int_en1 proto {tcp, udp} from any to $vpn_ip
pass on $vpn_ppp0 all
完璧とはほど遠いですが、作業は進行中ですより多くの情報/コードがここにあります: https://github.com/vpn-kill-switch/killswitch
これにより、大きな飛躍を遂げ、pf.confを使用するための十分な背景情報が得られました。 VPN接続が切断された後に10.8で再接続するために使用するものは次のとおりです。
(私はイーサネットのみを使用していますが、$ lanを$ wifiに変更することができ、それは動作するはずです)
lan=en0
wifi=en1
vpn=tun0
block all
set skip on lo
pass on $lan proto { udp,tcp } to 8.8.8.8
pass on $lan proto tcp to vpn.btguard.com port 1194
pass on $vpn
-追加として-
次の行を追加することをお勧めします。
pass on $wifi inet6 proto udp from any to FF02:0000:0000:0000:0000:0000:0000:00FB port 5353
mDNSがipv6で動作できるようにする