특정 Wi-Fi를 사용하여 특정 앱에 대한 인터넷 액세스를 차단합니다.

특정 Wi-Fi를 사용하여 특정 앱에 대한 인터넷 액세스를 차단합니다.

특정 Wi-Fi 액세스 포인트에 연결되어 있을 때 특정 애플리케이션이 인터넷에 액세스하지 못하도록 하는 솔루션을 찾고 있습니다. 내 구체적인 사용 사례는 셀룰러 테더링을 통해 연결된 경우 Dropbox, Spotify 및 유사한 앱이 내 모든 데이터를 사용하지 못하도록 비활성화하려는 것입니다.

솔루션은 네트워크 자체 외부의 다른 수준에 있을 수 있지만 "애플리케이션 종료" 솔루션은 피하는 것이 좋습니다.

저는 Archlinux를 사용하고 있지만, 다른 배포판에 좋은 솔루션이 있다면 확실히 좋은 방향을 제시해 줄 수 있을 것입니다.

답변1

질문은 두 부분으로 나눌 수 있습니다.

  1. 제한된 액세스 포인트(테더링)를 사용할 때 식별

  2. 제한된 애플리케이션에 속하는 나가는 패킷 식별

두 가지를 결합하면 제한된 액세스 포인트를 사용하여 발행된 제한된 애플리케이션에 속하는 패킷이 식별됩니다(그러한 패킷이 삭제될 수 있음).


준비하다

설명 뒤가 아닌 앞에 붙이기를 하므로 모든 내용을 순서대로 입력하는 것이 좋습니다.

두 개의 iptables 체인을 사용합니다. 하나는 작업을 수행합니다(특정 앱 차단), 또 다른 (테더 활성화) 쉽게 새로 고칠 수 있습니다.

iptables -N tetheractivated
iptables -N blocksomeapps
iptables -I OUTPUT -j tetheractivated

1. 액세스 포인트

이 답변은 다음과 같이 가정합니다.하나액세스 포인트는 언제든지 사용 중이며 알려진 네트워크 인터페이스 이름( wlan0)을 사용하고 있습니다. 또한 wpa_supplicant낮은 수준의 데몬에 의해 처리된다고 가정합니다. 쿼리할 수 있는 한 독립 실행형인지 NetworkManager의 백엔드인지는 중요하지 않습니다.wpa_cli및 그 -a(운영) 옵션.

액션 스크립트 myaction.sh:

#!/bin/sh

TETHERSSID='My Tethering'

case "$2" in
    'CONNECTED')
        ssid="$(wpa_cli -p "$WPA_CTRL_DIR" -i "$1" get_network "$WPA_ID" ssid)"
    # Note: ssid's value already comes with an added pair of double quotes around:
    # adding one as well
        if [ "$ssid" = \""$TETHERSSID"\" ]; then
           iptables -A tetheractivated -j blocksomeapps
        fi
    ;;
    'DISCONNECTED')
        iptables -F tetheractivated
    ;;
esac

그런 다음 프로그램을 계속 실행하여 이 스크립트(실행 가능해야 함)를 이벤트 루프로 사용합니다.

wpa_cli -a myaction.sh

이렇게 하면 iptables 체인이 만들어집니다.특정 앱 차단대상 SSID에 연결되면 패킷 경로에 표시되고 연결이 끊어지면(SSID에서) 패킷 경로에서 제거됩니다.


2. 신청 제한

이것은 다루기가 더 어렵습니다. 특정 프로세스에 속하는 패킷을 식별하는 방법에는 여러 가지가 있으며 어떤 경우에도 추가 준비가 필요합니다. 일부 방법은 다른 방법보다 더 많은 것을 요구합니다.

몇 가지 예:

  • 추가 검사를 위해 패킷을 사용자 공간 애플리케이션의 대기열에 넣을 수 있습니다(프로그램은 C 또는 Python으로 작성해야 함).
  • 제한된 프로세스는 별도의 사용자로 실행될 수 있어 처리가 매우 쉽습니다.
  • 제한된 프로세스는 자체 개인 네트워크 네임스페이스에서 실행될 수 있습니다. 일단 완료되면 처리하기 쉽습니다. 먼저 구성 및 루트 액세스를 포함하고 사용자 액세스를 반환하여 실행하면 문제가 발생할 수 있습니다.

이 Q&A에서 찾을 수 있는 매우 간단한 방법은 다음과 같습니다.프로세스에 대한 네트워크 액세스를 차단하시겠습니까? 같은 쌍네트워크CLS그룹iptables에서 조회할 수 있는 값이 있습니다(주 대상: Traffic Controller 외에 tc).

특정 생성네트워크CLS그룹화하고 특정 분류 ID를 지정합니다.

# mkdir -p /sys/fs/cgroup/net_cls/blocksomeapps
# echo 42 > /sys/fs/cgroup/net_cls/blocksomeapps/net_cls.classid

대상 프로세스(스레드를 포함해야 함)를 식별하고 이를 그룹에 추가합니다( tasks한 번에 하나의 pid(또는 tid)를 작성하여). 프로세스가 많이 변경되면 위험할 수 있으므로 애플리케이션 시작 중에 수행하는 것이 가장 좋습니다. 물론, 일단 완료되면 아이들은 자동으로 같은 그룹에 남게 됩니다.

Firefox를 예로 들어 보겠습니다(여러 프로세스에서 여러 스레드를 사용하므로pgrep모든 스레드 ID를 출력 해야 함 --lightweight):

# for i in $(pgrep --lightweight -f firefox); do echo $i > /sys/fs/cgroup/net_cls/blocksomeapps/tasks; done

(그룹에서 제거할 pid/tid는 상위 그룹에 기록되어야 합니다 /sys/fs/cgroup/net_cls/tasks)

빈 링크 차단 규칙 추가특정 앱 차단이전에 준비한 것:

# iptables -A blocksomeapps -m cgroup --cgroup 42 -j DROP

전달되는 패킷만 차단하려면 wlan0다음을 대신 사용하세요.

# iptables -A blocksomeapps -o wlan0 -m cgroup --cgroup 42 -j DROP

그러나 DNS 캐시 데몬 자체가 차단되지 않기 때문에 이러한 응용 프로그램에서 생성된 간접 활동(예: 로컬 DNS 캐시 데몬에 대한 DNS 쿼리)으로 인해 여전히 일부 데이터 트래픽이 생성될 수 있습니다.


노트:

  • SSID 부분은 어딘가에서 라우팅 확인을 수행하고 여러 동시 액세스 포인트를 처리하여 개선할 수 있지만 매우 빠르게 복잡해집니다. 간단한 myaction.sh스크립트만으로는 충분하지 않습니다(연결의 SSID를 아는 것은 아직 구성되지 않은 네트워크 계층에 대한 정보를 제공하지 않기 때문입니다).
  • 지금,cgroupsystemd 또는 cgmanager를 통해 설치 및 구성되었을 수 있습니다. 사용할 수 없는 경우 구성하는 것은 이 Q&A의 범위를 벗어납니다.
  • cgroupv1이 천천히 교체되고 있습니다.cgroupv2이므로 이 답변은 언젠가 v2에 적용되어야 합니다.
  • 또한 이 접근 방식은 이를 사용하여 생성된 컨테이너 또는 네트워크 네임스페이스와 호환되지 않거나 적어도 사용하기 어려울 수 있습니다. ip netns둘 다 cgroup 사용에 제한을 가하기 때문입니다(예 ip netns: 다시 ip netns exec ...마운트하면 트리를 사용할 수 없게 되고 실제로 사용할 수 없게 됩니다). . 두 번 설치됨)./sys//sys/fs/cgroup
  • 모든 출력 패킷이 통과함그룹성냥. 부하를 줄이기 위해 tetheractivated일반적인 Stateful 규칙 뒤에 삽입할 수 있지만 ESTABLISHED이미 설정된 흐름은 삭제되지 않으므로 애플리케이션에 따라 한동안 작동할 수 있습니다. 이것이 도움이 될 수 있습니다conntrack( -D또는 -F).
  • 교통을 막는 것보다iptables(또는nftables)tc(그리고그룹필터)를 사용하여 엄격한 대역폭 제한을 적용할 수 있습니다. 나가는 트래픽이 완전히 제어되는 동안 들어오는 트래픽의 경우에도 마찬가지입니다. 일단 패킷이 수신되면(그리고 이전의 나가는 트래픽과 동일한 흐름과 연결됨) 삭제되더라도 데이터는 소비됩니다.

답변2

두 가지 상황이 있습니다.

사례 1

특정 애플리케이션에 대한 액세스만 거부하려는 경우

여기에서 iptables 항목을 사용할 수 있습니다. 애플리케이션이 어떤 프로토콜(TCP/UDP)을 사용하는지 알아야 합니다. 그러면 다음과 같이 예방할 수 있습니다.

sudo iptables -A OUTPUT -p tcp --dport 80 -j DROP

이렇게 하면 모든 응용 프로그램이 TCP 포트 80에 액세스하는 것을 방지할 수 있습니다. 불행하게도 애플리케이션에 자체 프로토콜이 없고 HTTP와 같은 프로토콜을 사용하는 경우에는 이 방법이 작동하지 않습니다. 그러면 합법적인 트래픽도 차단하게 됩니다.

사례 2

특정 앱만 인터넷에 액세스할 수 있도록 하려면 다음을 허용 목록에 추가하세요.

sudo iptables -A OUTPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -P OUTPUT DROP

이렇게 하면 TCP 포트 80에만 액세스가 허용됩니다. 물론 포트 80 규칙과 같은 더 많은 규칙을 추가할 수 있습니다. 그러나 다른 모든 나가는 패킷(루프백 트래픽 제외)은 차단됩니다.

이 구성은 재부팅 후에도 유지되지 않습니다. 이 문제를 해결하려면 iptables-persist를 사용해 볼 수 있습니다. 또한 이는 IPv6 트래픽을 차단하지 않으므로 동일한 명령을 입력해야 하지만 IPv6를 필터링하려면 iptables를 ip6tables로 바꿔야 합니다.

관련 정보