Linux에서 하위 프로세스를 "오프라인"(외부 네트워크 없음)으로 실행하는 명령

Linux에서 하위 프로세스를 "오프라인"(외부 네트워크 없음)으로 실행하는 명령

실제 네트워크를 종료하지 않고 오프라인 모드에서 테스트하고 싶은 프로그램이 있습니다. 프로그램은 여전히 ​​Unix 도메인 소켓 및 루프백을 포함하여 로컬 소켓에 연결해야 합니다. 그것은 또한 필요하다듣다루프백 및 다른 애플리케이션에 표시됩니다.

그러나 원격 컴퓨터에 연결하려는 시도는 실패합니다.

strace나는 //와 같이 작동하고 다른 모든 것은 여전히 ​​잘 작동하는 동안 인터넷(및 LAN)을 숨기는 명령을 실행하는 유틸리티를 원합니다 unshare.sudo

$ offline my-program-to-test

이 질문은 이미 답을 암시하고 있습니다.프로세스에 대한 네트워크 액세스를 차단하시겠습니까?

다른 사용자로 실행한 다음 iptables를 조작하거나 unshare -n. 공유를 취소하는 방법을 알려주세요.모두회로망.

내가 테스트하고 있는 프로그램은 여전히 ​​내 X 서버와 dbus에 연결해야 하며 시스템의 다른 응용 프로그램에서 루프백 연결을 수신할 수도 있습니다.

이상적으로는 chroot, 사용자, VM 등을 생성하는 것이 네트워크 케이블을 뽑는 것만큼 귀찮기 때문에 피하고 싶습니다. 즉, 질문의 요점은 어떻게 하면 처럼 만들 수 있느냐는 것입니다 sudo.

로컬이 아닌 주소를 지정하는 네트워크 호출이 실패한다는 점을 제외하고는 프로세스가 100% 작동하고 실행되기를 원합니다. 이상적으로는 동일한 uid, 동일한 homedir, 동일한 비밀번호, 오프라인을 제외한 모든 항목을 동일하게 유지하세요.

저는 Fedora 18을 사용하고 있으므로 이식성이 없는 Linux 답변은 괜찮습니다(예상하기도 함).

나는 C 프로그램을 작성함으로써 이 문제를 기꺼이 해결할 것입니다. 그것이 C 프로그램 작성과 관련된 답이라면 말이죠. 로컬 네트워크를 유지하면서 외부 네트워크 액세스를 취소하기 위해 C 프로그램이 어떤 시스템 호출을 해야 하는지 모르겠습니다.

"오프라인 모드"를 지원하려는 개발자라면 누구나 이 유틸리티를 높이 평가할 것입니다!

답변1

전통적인 대답은 다른 사용자로 프로그램을 실행하고 이를 사용하는 것입니다 iptables -m owner. 이렇게 하면 네트워크 구성을 공유할 수 있습니다. 그러나 네임스페이스의 출현으로 더 쉬운 방법이 있습니다.

네임스페이스를 사용하면 네트워크 공유를 제거한 다음 제한된 네트워크 액세스가 필요할 때 가상 네트워크 링크를 만들 수 있습니다.

유닉스 도메인 소켓을 공유하기 위해 필요한 것은 충분히 새로운 커널뿐입니다.이번 2010 패치, 따라서 2.6.36 이상입니다(이 글을 쓰는 시점에서는 RHEL/CentOS를 제외한 모든 현재 배포판에 해당됩니다).

자체 IP 네임스페이스에서 프로그램을 실행합니다. 프로그램을 시작하기 전에 가상 이더넷 인터페이스를 생성하십시오. 문서가 많지 않은 것 같습니다. 일부 블로그에서 올바른 진언을 찾았습니다.

아래 코드 조각 ns_exec에서는이 포장지setns제한된 네임스페이스에서 실행되는 프로세스에서 네트워크 링크의 호스트 측 시작은 매뉴얼 페이지에 나열되어 있습니다. 실제로는 이것이 필요하지 않습니다. 제한된 네임스페이스 외부에서 링크의 호스트 측을 설정할 수 있습니다. 내부에서 이 작업을 수행하면 흐름 제어가 용이해집니다. 그렇지 않으면 링크가 설정된 후 프로그램을 시작하기 전에 링크를 설정하기 위해 일부 동기화가 필요합니다.

unshare -n -- sh -c '
  # Create a virtual ethernet interface called "confined",
  # with the other end called "global" in the namespace of PID 1
  ip link add confined type veth peer name global netns 1

  # Bring up the confined end of the network link
  ip addr add 172.16.0.2/30 dev confined
  ip link set confined up

  # Bring up the global end of the network link
  ns_exec /proc/1/ns/net ifconfig global 172.16.0.1 netmask 255.255.255.252 up

  # Execute the test program
  exec sudo -E -u "$TARGET_USER" "$0" "$@"
' /path/to/program --argument

이 모든 작업을 수행하려면 루트 권한이 있어야 합니다. 이것커널 3.8에 도입된 사용자 네임스페이스이를 수행하기 위해 네트워크 링크의 전역 끝을 설정하는 것 외에는 특별한 권한이 필요하지 않습니다.

두 네임스페이스 간에 localhost를 공유하는 방법을 모르겠습니다. 가상 이더넷 인터페이스는 지점 간 브리지를 생성합니다. 필요한 경우 iptables전달 규칙을 사용하여 트래픽을 리디렉션 할 수 있습니다 lo.

답변2

이는 cgroup과 일치하는 iptables 규칙을 통해서도 달성할 수 있습니다. 나는 이러한 단계를 추상화하는 도구를 작성했습니다. 초기 설정을 위해 루트 권한이 필요하고 setuid 바이너리이지만 문제의 문제를 처리하는 상당히 간단한 방법을 제공한다고 생각합니다. 이를 위해서는 충분히 최신 버전의 iptables와 적절한 netfilter 모듈이 필요합니다.

https://github.com/quitesimpleorg/qsni

답변3

최근에 이 문제가 발생했습니다. usergroup을 사용하여 이 문제를 해결했습니다.

  1. "no-external-internet" 그룹을 추가하고 여기에 사용자를 추가하세요.

    sudo addgroup no-external-internet
    sudo adduser $USER no-external-internet
    
  2. 나가는 트래픽을 iptables허용 하고 다른 모든 아웃바운드 연결을 거부하는 규칙을 추가합니다 .{HOST}{PORT}

    sudo iptables -A OUTPUT -m owner --gid-owner no-external-internet -s {HOST} -p tcp --sport {PORT} -j ACCEPT; 
    sudo iptables  -A OUTPUT -m owner --gid-owner no-external-internet -j REJECT; 
    sudo ip6tables -A OUTPUT -m owner --gid-owner no-external-internet -j REJECT; 
    
  3. 사용자 그룹을 사용하여 하위 프로세스를 실행합니다.

    sg no-external-internet "your command to run child process"
    

답변4

/!!\ 이는 단일 PID뿐만 아니라 모든 트래픽을 다운시키기 때문에 아마도 유효한 대답이 아닐 것입니다.

나는 그것을 사용하지 않았지만 Comcast를 사용할 수도 있다고 생각합니다.

https://github.com/tylertreat/comcast

100% 패킷 손실로 설정

이번에도 테스트하지는 않았지만 이론적으로는 Readme를 수정하여 다음을 수행할 수 있습니다.


리눅스

Linux에서는 이 기능을 사용하여 iptables들어오고 나가는 패킷을 삭제할 수 있습니다.

$ iptables -A INPUT -m statistic --mode random --probability 1 -j DROP
$ iptables -A OUTPUT -m statistic --mode random --probability 1 -j DROP

또는 tc이를 사용하여 몇 가지 추가 옵션을 지원할 수도 있습니다.

$ tc qdisc change dev eth0 root netem reorder 0 duplicate 0 corrupt 1

초기화:

$ tc qdisc del dev eth0 root netem

관련 정보