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


15

실제 네트워크를 중단하지 않고 오프라인 모드에서 테스트하고 싶은 프로그램이 있습니다. 이 프로그램은 여전히 ​​유닉스 도메인 소켓과 루프백을 포함한 로컬 소켓에 연결해야합니다. 또한 루프백 을 듣고 다른 앱에서 볼 수 있어야합니다.

그러나 원격 시스템에 연결하려는 시도는 실패해야합니다.

strace/ unshare/ 처럼 작동 sudo하고 인터넷 (및 LAN)이 숨겨져 있고 다른 모든 기능이 여전히 작동하는 명령을 실행 하는 유틸리티를 갖고 싶습니다 .

$ offline my-program-to-test

이 질문에는 다음과 같은 힌트 가 있습니다. 프로세스의 네트워크 액세스를 차단 하시겠습니까?

다른 사용자로 실행 한 다음 iptables를 조작하는 등의 몇 가지 제안이 unshare -n있습니다. 그러나 두 경우 모두 유닉스 도메인 소켓과 루프백을 기본 시스템과 공유 할 수있는 명령을 알지 못합니다.이 질문에 대한 답변은 전체 네트워크 를 공유 해제하는 방법 만 알려줍니다 .

테스트중인 프로그램은 여전히 ​​내 X 서버 및 dbus에 연결해야하며 시스템의 다른 앱에서 연결하기 위해 루프백을 청취 할 수도 있습니다.

이상적으로는 네트워크 케이블을 분리하는 것만 큼 성가신 chroots 또는 사용자 또는 VM 등을 만드는 것을 피하고 싶습니다. 즉, 질문의 요점은 어떻게 이것을 간단하게 만들 수 있습니까 sudo?

로컬이 아닌 주소를 지정하는 네트워크 호출이 실패한다는 점을 제외하고는 프로세스를 100 % 정상적으로 실행하고 싶습니다. 동일한 uid, homedir, pwd, 오프라인을 제외한 모든 것을 동일하게 유지하는 것이 이상적입니다.

Fedora 18을 사용하고 있기 때문에 이식 불가능한 Linux 답변은 괜찮습니다 (예상조차도).

C 프로그램을 작성 하여이 문제를 해결하게되어 기쁩니다 .C 프로그램을 작성하면 C 작성과 관련된 답변이 좋습니다. 로컬 네트워크를 유지하면서 외부 네트워크 액세스를 취소하기 위해 C 프로그램이 어떤 syscall을 호출해야하는지 모르겠습니다.

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

답변:


9

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

네임 스페이스를 사용하면 네트워크 공유를 해제 한 다음 제한된 네트워크 액세스가 필요한 경우 가상 네트워크 링크를 만듭니다.

유닉스 도메인 소켓을 공유하려면 이 2010 패치 이후 2.6.36 이상 (RHEL / CentOS를 제외한 모든 현재 배포판의 경우) 이후에 커널 충분해야합니다 .

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

(가) 아래의 코드에서, 내가 사용 ns_exec은 IS 주변이 래퍼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원하는 경우 트래픽을 리디렉션 할 수 있습니다 .


좋은 추가 정보, 감사합니다. veth는 네임 스페이스 "외부"에 대한 링크를 제공하지만 새 네임 스페이스는 여전히 동일한 네트워크 노드에서 로컬이 아닌 인터페이스를 제외한 별도의 네트워크 노드에 해당한다고 생각합니다. 시사점은 (?) : 유닉스 도메인 / 추상 소켓은 여전히 ​​실패하고 iptables를 통해 루프백을 전달할 수는 있지만 전달은 공유를 달성 할 수 없습니다. 즉, 원래 네임 스페이스와 제한된 네임 스페이스가 루프백과 -변경) 포트는 두 네임 스페이스 모두에서 볼 수 있어야합니다. 여기서 내가 원하는 것을 추측하기 시작합니다 :-/
Havoc P

1

iptables 규칙 일치 cgroup을 사용하여이 작업을 수행 할 수도 있습니다. 나는 단계를 추상화하는 도구를 작성했습니다. 초기 설정에는 루트 권한이 필요하지만 setuid 바이너리이지만 질문의 문제를 처리하는 매우 간단한 방법을 제공한다고 생각합니다. 최신의 iptables 버전이 필요하며 적절한 넷 필터 모듈을 사용할 수 있어야합니다.

https://github.com/quitesimpleorg/qsni


0

/ !! \ 이것은 하나의 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.