web-dev-qa-db-ja.com

Mac OS Xでpf.confを使用してOpenVPN接続がアクティブでない限り、発信トラフィックを防止します

私のOpenVPN接続がpf.confを使用してアクティブでない限り、外部ネットワークへのすべての接続を拒否できました。ただし、ラップトップの蓋を閉じて開いたり、Wi-Fiのオンとオフを切り替えて接続が切断された場合、Wi-Fi接続が失われます。

  • Mac OS 10.8.1を使用しています。
  • (公共のWi-Fiを含むさまざまな場所から)Wi-Fi経由でWebに接続します。
  • OpenVPN接続はViscosityで設定されています。

次のパケットフィルタルールを/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アイコンをクリックすると、「アラート:インターネット接続がありません」というメッセージが表示されます。

No Internet connection message

接続を回復するには、「アラート:インターネット接続がありません」というメッセージが消えてVPN接続を再び開くことができるようになる前に、Wi-Fiを切断して再接続する必要があります。また、Wi-Fiアラートが自然に消えて感嘆符が消え、再び接続できる場合もあります。どちらの方法でも、接続を再確立するのに5分以上かかることがあり、イライラすることがあります。

block allを削除すると問題が解決します(ただし、安全でない接続は許可されます)。そのため、AppleがWi-Fiを回復して確認するために必要なサービスをブロックしているようです)接続。私が試した:

  • Pf.confにpass on $wifi proto icmp allを追加してicmpを有効にする
  • pass on $wifi proto udp from $wifi to any port 53を追加してDNS解決を有効にする
  • ブロックされたパケットをログに記録して(block allblock log allに変更して)詳細を調べようとしましたが、Sudo tcpdump -n -e -ttt -i pflog0を実行して「tcpdump: pflog0:そのようなデバイスは存在しません。」.

これは、Wi-Fi接続をより速く再確立するのに役立ちません。

Wi-Fi接続を回復するために利用可能なサービスを決定するために他に何ができますか、またはWi-Fi再接続をより信頼できるものにするためにpf.confにどのルールを追加する必要がありますか?

19
Nick

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を介して保護されずに移動することを許可するよりも優れているように見えます。これは、大部分のアプリケーションが使用するものです。誰かがこの設定を改善するための提案を持っている場合は、コメントまたはさらなる回答を歓迎します。

14
Nick

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

*注意:any0.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

11
smashingly

「簡単な」方法で 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

1
nbari

これにより、大きな飛躍を遂げ、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
1
Cedric

-追加として-

次の行を追加することをお勧めします。

pass on $wifi inet6 proto udp from any to FF02:0000:0000:0000:0000:0000:0000:00FB port 5353

mDNSがipv6で動作できるようにする

0
user263367