Ngăn chặn lưu lượng đi trừ khi kết nối OpenVPN đang hoạt động bằng pf.conf trên Mac OS X


19

Tôi đã có thể từ chối tất cả các kết nối với các mạng bên ngoài trừ khi kết nối OpenVPN của tôi đang hoạt động bằng pf.conf. Tuy nhiên, tôi mất kết nối Wi-Fi nếu kết nối bị hỏng bằng cách đóng và mở nắp máy tính xách tay hoặc tắt và bật lại Wi-Fi.

  • Tôi đang dùng Mac OS 10.8.1.
  • Tôi kết nối với Web thông qua Wi-Fi (từ các địa điểm khác nhau, bao gồm cả Wi-Fi công cộng).
  • Kết nối OpenVPN được thiết lập với Độ nhớt.

Tôi có các quy tắc lọc gói sau đây được thiết lập trong /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

Tôi bắt đầu dịch vụ lọc gói sudo pfctl -evà tải các quy tắc mới với sudo pfctl -f /etc/pf.conf.

Tôi cũng đã chỉnh sửa /System/Library/LaunchDaemons/com.apple.pfctl.plistvà thay đổi dòng <string>-f</string>để đọc <string>-ef</string>để bộ lọc gói khởi chạy khi khởi động hệ thống.

Tất cả điều này dường như hoạt động rất tốt lúc đầu: các ứng dụng chỉ có thể kết nối với web nếu kết nối OpenVPN đang hoạt động, vì vậy tôi không bao giờ rò rỉ dữ liệu qua kết nối không an toàn.

Nhưng, nếu tôi đóng và mở lại nắp máy tính xách tay của mình hoặc tắt và bật lại Wi-Fi, kết nối Wi-Fi sẽ bị mất và tôi thấy dấu chấm than trong biểu tượng Wi-Fi trên thanh trạng thái. Nhấp vào biểu tượng Wi-Fi sẽ hiển thị thông báo "Thông báo: Không có kết nối Internet":

Không có tin nhắn kết nối Internet

Để lấy lại kết nối, tôi phải ngắt kết nối và kết nối lại Wi-Fi, đôi khi năm hoặc sáu lần, trước khi thông báo "Thông báo: Không có kết nối Internet" biến mất và tôi có thể mở lại kết nối VPN. Lần khác, cảnh báo Wi-Fi biến mất theo ý mình, dấu chấm than sẽ xóa và tôi có thể kết nối lại. Dù bằng cách nào, có thể mất năm phút hoặc hơn để có được kết nối lại, điều này có thể gây bực bội.

Xóa dòng block allgiải quyết vấn đề (nhưng cho phép kết nối không an toàn), do đó, có vẻ như có một dịch vụ tôi đang chặn mà Apple yêu cầu để lấy lại và xác nhận kết nối Wi-Fi. Tôi đã thử:

  • Kích hoạt icmp bằng cách thêm pass on $wifi proto icmp allvào pf.conf
  • Kích hoạt độ phân giải DNS bằng cách thêm pass on $wifi proto udp from $wifi to any port 53
  • Cố gắng tìm hiểu thêm bằng cách ghi nhật ký các gói bị chặn (bằng cách thay đổi block allthành block log all), nhưng việc ghi nhật ký dường như bị vô hiệu hóa trong OS X, vì thực hiện sudo tcpdump -n -e -ttt -i pflog0để xem kết quả nhật ký trong "tcpdump: pflog0: Không có thiết bị nào như vậy tồn tại".

Không ai trong số này giúp thiết lập lại kết nối Wi-Fi nhanh hơn.

Tôi có thể làm gì khác để xác định dịch vụ nào cần có sẵn để lấy lại kết nối Wi-Fi hoặc tôi nên thêm quy tắc nào vào pf.conf để kết nối lại Wi-Fi đáng tin cậy hơn?


1
điều này có thể phù hợp với những người đến sau: sparklabs.com/support/preventing_network_and_dns_traffic_leaks
ptim

Câu trả lời:


14

Bằng cách giám sát các kết nối mạng bằng Little Snitch, tôi thấy rằng Apple sử dụng ứng dụng mDNSResponder trong nền để kiểm tra xem kết nối Wi-Fi có khả dụng hay không. mDNSResponder gửi các gói UDP đến máy chủ tên để kiểm tra kết nối và phân giải tên máy chủ thành IP.

Thay đổi quy tắc UDP mà trước đây tôi đã cho phép tất cả các gói UDP qua Wi-Fi cho phép mDNSResponder kết nối, có nghĩa là Wi-Fi hiện kết nối lại lần đầu tiên sau khi ngắt kết nối. Trong trường hợp nó giúp người khác trong tương lai, pf.conf cuối cùng của tôi bao gồm các quy tắc mặc định của Apple cho Mountain Lion trông như thế này:

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

Điều này có nghĩa là dữ liệu hiện có thể bị rò rỉ qua Wi-Fi bởi một số lượng nhỏ các ứng dụng sử dụng giao thức UDP, không may, chẳng hạn như ntpd (để đồng bộ hóa thời gian) và mDNSResponder. Nhưng điều này vẫn có vẻ tốt hơn so với việc cho phép dữ liệu di chuyển không được bảo vệ qua TCP, đây là điều mà phần lớn các ứng dụng sử dụng. Nếu bất cứ ai có bất kỳ đề xuất để cải thiện thiết lập này, ý kiến ​​hoặc câu trả lời thêm đều được chào đón.


Đây là điều mà tôi tình cờ quan tâm, thấy kết quả của bạn đã truyền cảm hứng cho tôi về nhà và thử nó! cảm ơn!
jakev

@SixSlayer Có vẻ như hoạt động khá tốt! Tôi có Viscosity được thiết lập để tự động kết nối khi khởi động và trên các kết nối bị mất, điều này làm cho toàn bộ mọi thứ khá liền mạch. Điều chính cần lưu ý là pf.conf và com.apple.pfctl.plist được đặt lại về mặc định sau khi cập nhật hệ điều hành, vì vậy, đáng để giữ một bản sao lưu của cả hai.
Nick

IMHO điều UDP là một loại bummer. Tôi không phải là một anh chàng mạng nhưng điều này giúp tôi học hỏi và tôi có một niềm đam mê với việc kiểm soát các loại chi tiết này. Tôi sẽ dành một chút thời gian để tìm kiếm một công việc xung quanh, nhưng nếu có ai đánh bại tôi với nó, thì cũng vậy.
jakev

Điều này thật tuyệt vời - chính xác là những gì tôi đang tìm kiếm. Cảm ơn bạn!
keo

Bạn có thể quản lý để có nhiều kết nối OpenVPN mở cùng một lúc và định tuyến song song với chúng không? (để tăng và thêm băng thông)
keo

11

Bạn không cần phải cho phép tất cả UDP. 'M' trong mDNS có nghĩa là 'multicast' và nó sử dụng một địa chỉ IP đích phát đa hướng cụ thể được gọi là "địa chỉ multicast liên kết cục bộ" và UDPsố cổng 5353.

Điều này có nghĩa là trong giải pháp của bạn ở trên, bạn không cần thiết phải cho phép lưu lượng truy cập đến tất cả 65535 cổng UDP đến tất cả 3,7 tỷ địa chỉ IP có thể định tuyến trên thế giới để bỏ qua VPN của bạn. Bạn sẽ ngạc nhiên khi có bao nhiêu ứng dụng sử dụng UDP, vì vậy bạn đang đánh bại đáng kể mục đích của ý tưởng ban đầu của mình để ngăn chặn lưu lượng đi khi VPN ngừng hoạt động.

Tại sao không sử dụng quy tắc này thay thế:

pass on $wifi proto udp to 224.0.0.251 port 5353

Một quy tắc rất quan trọng với cấu hình tường lửa - khi tạo ngoại lệ thông qua tường lửa của bạn, luôn cố gắng sử dụng quy tắc cụ thể nhất có thể. Tính đặc hiệu đôi khi phải trả giá bằng sự tiện lợi và dễ sử dụng, tức là sau đó bạn có thể tìm thấy một số giao thức liên kết cục bộ khác cần được thông qua và thêm một quy tắc cụ thể khác.

Nếu bạn trao đổi theo quy tắc trên và thấy rằng sự cố wifi ban đầu trở lại, thì PF của bạn có thể đang chặn DHCP, giao thức được sử dụng để tự động cấu hình địa chỉ IP của thiết bị mạng của bạn. (trong mạng gia đình, thông thường bộ định tuyến băng thông rộng của bạn sẽ là máy chủ DHCP của bạn). Quy tắc bạn cần cho phép DHCP, sẽ là:

pass on $wifi proto udp from 0.0.0.0 port 68 to 255.255.255.255 port 67

* Lưu ý: bạn có thể cần phải thay thế 0.0.0.0cho any. Các DHCPREQUESTgói máy tính của bạn đầu tiên gửi, có một địa chỉ nguồn 0.0.0.0vì ở giai đoạn đó, máy tính của bạn không có một địa chỉ IP được nêu ra.
Thành thật mà nói, tôi sẽ nghiêng về sử dụng nhiều hơn any. Một tùy chọn khác là trích xuất bất kỳ đặc tả nguồn nào, nghĩa là pass on $wifi proto udp to 255.255.255.255 port 67, nhưng điều đó có nghĩa là chúng ta mất phần cổng nguồn của quy tắc và càng cụ thể càng tốt luôn là tùy chọn an toàn nhất.

Mong rằng sẽ giúp. Dưới đây là một số liên kết hữu ích:

mDNS: http://en.wikipedia.org/wiki/Multicast_DNS#Packet_structure

DHSP: http://en.wikipedia.org/wiki/Docate_host_Configuration_Protatio#DHCP_discovery


1

Điều này đã cho tôi thông tin cơ bản đầy đủ để thực hiện bước nhảy vọt lớn và sử dụng pf.conf. Đây là những gì tôi sử dụng vào ngày 10.8 để kết nối lại sau khi kết nối VPN bị rớt:

(Tôi chỉ sử dụng ethernet nhưng bạn có thể thay đổi $ lan cho $ wifi và nó sẽ hoạt động)

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

Với mục đích tạo ra các quy tắc PF theo cách "dễ dàng", xác định các giao diện hoạt động hiện có bao gồm các giao diện (vpn) hiện tại, chương trình killswitch nhỏ này có thể được sử dụng,

Vẫn đang tiến hành nhưng có thể là một khởi đầu tốt để xác định IP bên ngoài và các giao diện hoạt động để tạo đúng quy tắc tường lửa.

ví dụ hoặc đầu ra bằng cách sử dụng -itùy chọn (thông tin):

$ 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

Truyền ip máy chủ -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

Không hoàn hảo nhưng công việc đang được tiến hành, nhiều thông tin / mã có thể được tìm thấy ở đây: https://github.com/vpn-kill-switch/killswitch


0

- Ngoài ra -

Bạn có thể muốn thêm dòng này:

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

để cho phép mDNS hoạt động trên ipv6

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.