ป้องกันทราฟฟิกขาออกยกเว้นว่าการเชื่อมต่อ OpenVPN ทำงานโดยใช้ pf.conf บน Mac OS X


19

ฉันสามารถปฏิเสธการเชื่อมต่อกับเครือข่ายภายนอกทั้งหมดยกเว้นว่าการเชื่อมต่อ OpenVPN ของฉันใช้งานได้โดยใช้ pf.conf อย่างไรก็ตามฉันสูญเสียการเชื่อมต่อ Wi-Fi หากการเชื่อมต่อถูกทำลายโดยการปิดและเปิดฝาแล็ปท็อปหรือเปิดและปิด Wi-Fi อีกครั้ง

  • ฉันใช้ Mac OS 10.8.1
  • ฉันเชื่อมต่อกับเว็บผ่าน Wi-Fi (จากสถานที่ต่าง ๆ รวมถึง Wi-Fi สาธารณะ)
  • การเชื่อมต่อ OpenVPN ถูกตั้งค่าด้วยความหนืด

ฉันมีกฎการตั้งค่าตัวกรองแพ็กเก็ตต่อไปนี้ /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 -esudo pfctl -f /etc/pf.conf

ฉันได้แก้ไข/System/Library/LaunchDaemons/com.apple.pfctl.plistและเปลี่ยนบรรทัด<string>-f</string>เพื่ออ่าน<string>-ef</string>เพื่อให้ตัวกรองแพ็คเก็ตเปิดตัวเมื่อเริ่มต้นระบบ

ทั้งหมดนี้ดูเหมือนจะใช้งานได้ดีในตอนแรก: แอปพลิเคชันสามารถเชื่อมต่อกับเว็บได้หากการเชื่อมต่อ OpenVPN ทำงานอยู่เท่านั้นดังนั้นฉันไม่เคยรั่วไหลข้อมูลผ่านการเชื่อมต่อที่ไม่ปลอดภัย

แต่ถ้าฉันปิดและเปิดฝาแล็ปท็อปของฉันใหม่หรือปิดและเปิด Wi-Fi อีกครั้งการเชื่อมต่อ Wi-Fi จะหายไปและฉันเห็นเครื่องหมายอัศเจรีย์ในไอคอน Wi-Fi ในแถบสถานะ การคลิกไอคอน Wi-Fi จะแสดงข้อความ "แจ้งเตือน: ไม่มีการเชื่อมต่ออินเทอร์เน็ต":

ไม่มีข้อความการเชื่อมต่ออินเทอร์เน็ต

ในการรับการเชื่อมต่ออีกครั้งฉันต้องยกเลิกการเชื่อมต่อและเชื่อมต่อ Wi-Fi ใหม่อีกครั้งบางครั้งห้าหรือหกครั้งก่อนที่ข้อความ "แจ้งเตือน: ไม่มีการเชื่อมต่ออินเทอร์เน็ต" จะหายไปและฉันสามารถเปิดการเชื่อมต่อ VPN อีกครั้ง ในบางครั้งการแจ้งเตือน Wi-Fi จะหายไปตามข้อตกลงของตัวเองเครื่องหมายอัศเจรีย์ล้างข้อมูลและฉันสามารถเชื่อมต่อได้อีกครั้ง ไม่ว่าจะด้วยวิธีใดก็อาจใช้เวลาห้านาทีหรือนานกว่านั้นในการรับการเชื่อมต่ออีกครั้งซึ่งอาจทำให้หงุดหงิด

การลบบรรทัดblock allเพื่อแก้ไขปัญหา (แต่อนุญาตการเชื่อมต่อที่ไม่ปลอดภัย) ดังนั้นจึงดูเหมือนว่ามีบริการที่ฉันบล็อกที่ Apple ต้องการเพื่อให้ได้รับและยืนยันการเชื่อมต่อ Wi-Fi ฉันเหนื่อย:

  • การเปิดใช้งานpass on $wifi proto icmp allicmp โดยเพิ่มไปที่ pf.conf
  • การเปิดใช้งานการแก้ไข DNS โดยการเพิ่ม pass on $wifi proto udp from $wifi to any port 53
  • พยายามเรียนรู้เพิ่มเติมโดยการบันทึกแพ็กเก็ตที่ถูกบล็อก (โดยเปลี่ยนblock allเป็นblock log all) แต่ดูเหมือนว่าการบันทึกจะถูกปิดการใช้งานใน OS X เนื่องจากการทำsudo tcpdump -n -e -ttt -i pflog0เพื่อดูผลลัพธ์บันทึกใน "tcpdump: pflog0: ไม่มีอุปกรณ์ดังกล่าว"

สิ่งเหล่านี้ไม่ช่วยในการสร้างการเชื่อมต่อ Wi-Fi ได้เร็วขึ้น

ฉันสามารถทำอะไรได้อีกเพื่อกำหนดว่าบริการใดบ้างที่จำเป็นต้องมีเพื่อเชื่อมต่อ Wi-Fi อีกครั้งหรือฉันควรเพิ่มกฎใดใน pf.conf เพื่อให้การเชื่อมต่อ Wi-Fi เชื่อถือได้มากขึ้น


1
สิ่งนี้อาจเกี่ยวข้องกับผู้ที่มาหลังจาก: sparklabs.com/support/preventing_network_and_dns_traffic_leaks
ptim

คำตอบ:


14

จากการตรวจสอบการเชื่อมต่อเครือข่ายโดยใช้ Little Snitch ฉันพบว่า Apple ใช้แอพ mDNSResponder ในพื้นหลังเพื่อตรวจสอบว่ามีการเชื่อมต่อ Wi-Fi หรือไม่ mDNSResponder ส่งแพ็กเก็ต UDP ไปยังเซิร์ฟเวอร์เพื่อตรวจสอบการเชื่อมต่อและแก้ไขชื่อโฮสต์ไปยัง IP

การเปลี่ยนกฎ UDP ที่ฉันเคยอนุญาตให้ใช้แพ็คเก็ต UDP ทั้งหมดผ่าน Wi-Fi ทำให้ mDNSResponder เชื่อมต่อซึ่งหมายความว่า Wi-Fi จะเชื่อมต่อใหม่เป็นครั้งแรกหลังจากการตัดการเชื่อมต่อ ในกรณีที่ช่วยคนอื่นในอนาคต pf.conf สุดท้ายของฉันรวมถึงกฎเริ่มต้นของ Apple สำหรับ Mountain Lion มีลักษณะดังนี้:

#
# 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)

ซึ่งหมายความว่าขณะนี้ข้อมูลสามารถรั่วไหลผ่าน Wi-Fi ด้วยแอปพลิเคชั่นจำนวนน้อยที่ใช้โปรโตคอล UDP แต่น่าเสียดายที่เช่น ntpd (สำหรับการซิงโครไนซ์เวลา) และ mDNSResponder แต่นี่ยังดูเหมือนดีกว่าการอนุญาตให้ข้อมูลเดินทางโดยไม่มีการป้องกันผ่าน TCP ซึ่งเป็นสิ่งที่แอพพลิเคชั่นส่วนใหญ่ใช้ หากใครมีข้อเสนอแนะเพื่อปรับปรุงการตั้งค่านี้ความคิดเห็นหรือคำตอบเพิ่มเติมยินดีต้อนรับ


นี่คือสิ่งที่ฉันสนใจโดยบังเอิญการเห็นผลลัพธ์ของคุณเป็นแรงบันดาลใจให้ฉันกลับบ้านแล้วลอง! ขอบคุณ!
jakev

@SixSlayer ดูเหมือนว่าจะทำงานได้ดี! ฉันตั้งค่าความหนืดให้เชื่อมต่ออัตโนมัติเมื่อเริ่มต้นและเชื่อมต่อที่ลดลงซึ่งทำให้สิ่งต่าง ๆ ทั้งหมดราบรื่น สิ่งสำคัญที่ควรทราบคือ pf.conf และ com.apple.pfctl.plist จะถูกรีเซ็ตเป็นค่าเริ่มต้นหลังจากอัปเดตระบบปฏิบัติการดังนั้นจึงคุ้มค่าที่จะสำรองข้อมูลทั้งสองอย่างไว้
Nick

IMHO สิ่งที่ UDP เป็นคนเกียจคร้าน ฉันไม่ใช่คนเครือข่าย แต่สิ่งนี้ช่วยให้ฉันเรียนรู้และฉันมีความหลงใหลในการควบคุมรายละเอียดเหล่านี้ ฉันจะใช้เวลาในการหางานทำ แต่ถ้าใครชนะฉันก็เช่นกัน
jakev

มันยอดเยี่ยมมาก - สิ่งที่ฉันกำลังมองหา ขอขอบคุณ!
keo

คุณอาจจัดการให้เปิดการเชื่อมต่อ OpenVPN จำนวนมากพร้อมกันและกำหนดเส้นทางผ่านการเชื่อมต่อแบบขนานได้หรือไม่ (ที่จะได้รับและเพิ่มแบนด์วิดธ์)
Keo

11

คุณไม่จำเป็นต้องอนุญาตUDP ทั้งหมด ของม. ใน mDNS หมายถึง 'multicast' และจะใช้อยู่ที่เฉพาะเจาะจงหลายผู้รับ IP ปลายทางที่เรียกว่า "การเชื่อมโยงท้องถิ่นอยู่หลายผู้รับ" และหมายเลขพอร์ต UDP5353

ซึ่งหมายความว่าในโซลูชันของคุณด้านบนคุณอนุญาตการรับส่งข้อมูลไปยังพอร์ต 65535 UDP ทั้งหมดไปยังที่อยู่ IP ที่กำหนดเส้นทางได้ 3.7 พันล้านทั้งหมดในโลกเพื่อหลีกเลี่ยง VPN คุณจะประหลาดใจว่ามีแอปพลิเคชั่นจำนวนมากที่ใช้ 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

* หมายเหตุ: คุณอาจจำเป็นต้องทดแทนสำหรับ0.0.0.0 แพ็คเก็ตคอมพิวเตอร์ของคุณก่อนส่งมีแหล่งที่อยู่เพราะในขั้นตอนที่คอมพิวเตอร์ของคุณไม่ได้มีที่อยู่ IP ๆ พูดตามตรงฉันจะเอนตัวไปใช้มากขึ้น ตัวเลือกอื่นคือการดึงข้อมูลจำเพาะของแหล่งข้อมูลออกมานั่นคือนั่นหมายความว่าเราสูญเสียส่วนของพอร์ตต้นทางของกฎและการมีความเฉพาะเจาะจงที่สุดเท่าที่จะทำได้เป็นตัวเลือกที่ปลอดภัยที่สุดเสมอanyDHCPREQUEST0.0.0.0
anypass 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


1

สิ่งนี้ทำให้ฉันมีข้อมูลพื้นฐานเพียงพอที่จะก้าวกระโดดครั้งใหญ่และใช้ pf.conf นี่คือสิ่งที่ฉันใช้ใน 10.8 ของฉันเพื่อทำให้การเชื่อมต่ออีกครั้งหลังจากการเชื่อมต่อ VPN ลดลง:

(ฉันใช้อีเธอร์เน็ตเพียงอย่างเดียว แต่คุณสามารถเปลี่ยน $ 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

โดยมีจุดประสงค์เพื่อสร้างกฎ 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


0

- นอกจากนี้ -

คุณอาจต้องการเพิ่มบรรทัดนี้:

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

อนุญาตให้ mDNS ทำงานบน ipv6

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.