리눅스에서 프로세스의 특정 인터페이스를 통해 트래픽 라우팅


20

프로세스가 사용하는 트래픽을 특정 인터페이스를 통해 라우팅 할 수 있습니까?

예를 들어, 다운로드 응용 프로그램 별 네트워크 트래픽은 항상 인터페이스를 사용해야 wlan0하지만 컴퓨터의 다른 모든 응용 프로그램은을 사용해야 eth0합니다.

리눅스에서 이런 종류의 규칙을 가질 수 있습니까?

답변:


22

Linux 네트워크 네임 스페이스를 사용하여 수행 할 수 있습니다.

방법을 설명하는 기사 가 있습니다. 기본적으로 다른 기본 경로로 네트워크 네임 스페이스를 생성하고 필요한 기본 프로세스를 실행합니다. 새로 만든 네트워크 네임 스페이스를 브리지를 사용하여 실제 어댑터에 연결합니다 (그러나 다른 솔루션도 가능합니다).

업데이트 : 커널 3.14 부터이 기사 에서 설명하는 것처럼 컨트롤 그룹을 사용하는 것이 훨씬 쉽습니다 . 당신은해야합니다 :

1) 주어진 프로세스의 패킷에 classid (또는 프로세스 그룹)로 주석을 달도록 net_cls 제어 그룹을 정의하십시오.

2) iptables cgroup 모듈 (Linux 3.14에 추가)을 사용하여 패킷을 fwmark하십시오

3) 정책 라우팅 (ip rule add fwmark ....)을 사용하여 표시된 패킷에 대한 새 라우팅 테이블을 만듭니다.

장점은 브리징을 할 필요가 없으며 cgroup 덕분에 모든 것이 훨씬 더 역동적이라는 것입니다.


14

나는 sooo가 이것으로 어려움을 겪었으므로 여기에 완전한 해결책이 있습니다. Ubuntu 15 & 16에서 테스트되었습니다. 특히 OpenVPN과 함께 사용하여 특정 앱을 VPN 터널 인터페이스 외부로 라우팅 할 수 있습니다.

완벽한 "cgroup"솔루션

어떻게 작동합니까?

  • 리눅스 커널은 앱을 컨트롤 그룹에 넣을 것이다 . 이 cgroup에있는 앱의 네트워크 트래픽은 네트워크 컨트롤러 수준에서 클래스 ID로 식별됩니다.
  • iptables는이 트래픽을 표시하고 올바른 IP로 강제 종료합니다.
  • ip route는 원하는 게이트웨이 IP에 대한 기본 경로를 사용하여 다른 라우팅 테이블에서 표시된 트래픽을 처리합니다.

자동화 된 스크립트

의존성 설치 및 실행을 자동화하기 위해 novpn.sh 스크립트를 만들었습니다 . 우분투에서 테스트되었습니다.

먼저 VPN을 시작하십시오.

wget https://gist.githubusercontent.com/kriswebdev/a8d291936fe4299fb17d3744497b1170/raw/cf8b37fbe6c3f50a0be825eb77cafa3e0134946f/novpn.sh
# If you don't use eth0, edit the script setting.
sudo chmod +x novpn.sh
./novpn.sh traceroute www.google.com
./novpn.sh --help

수동 사용법

먼저 cgroup 지원 및 도구를 설치하십시오.

sudo apt-get install cgroup-lite cgmanager cgroup-tools

재부팅합니다 (필요하지 않을 수도 있음).

iptables 1.6 .0+ 가 필요합니다 . iptables 1.6.0 release source 를 가져 와서 추출 한 다음 --disable-nftablesiptables source dir 에서이 플래그 를 실행하여 오류를 피하십시오.

sudo apt-get install dh-autoreconf bison flex
./configure --prefix=/usr      \
            --sbindir=/sbin    \
            --disable-nftables \
            --enable-libipq    \
            --with-xtlibdir=/lib/xtables
make
sudo make install
iptables --version

이제 실제 설정입니다. 라는 제어 그룹을 정의하십시오 novpn. 이 cgroup의 프로세스는 0x00110011(11:11) 의 classid를 갖습니다 .

sudo su
mkdir /sys/fs/cgroup/net_cls/novpn
cd /sys/fs/cgroup/net_cls/novpn
echo 0x00110011 > net_cls.classid

이제 특정 앱에 사용하려는 인터페이스 eth0가 게이트웨이 IP 인 것으로 가정 10.0.0.1합니다. 대체 당신이 정말로 (에서 정보를 얻을 원하는 이러한를 ip route). 여전히 루트로 실행하십시오.

# Add mark 11 on packets of classid 0x00110011
iptables -t mangle -A OUTPUT -m cgroup --cgroup 0x00110011 -j MARK --set-mark 11

# Force the packets to exit through eth0 with NAT
iptables -t nat -A POSTROUTING -m cgroup --cgroup 0x00110011 -o eth0 -j MASQUERADE

# Define a new "novpn" routing table
# DO THIS JUST ONCE !
echo 11 novpn >> /etc/iproute2/rt_tables

# Packets with mark 11 will use novpn
ip rule add fwmark 11 table novpn

# Novpn has a default gateway to the interface you want to use
ip route add default via 10.0.0.1 table novpn

# Unset reverse path filtering for all interfaces, or at least for "eth0" and "all"
for i in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $i; done

마지막으로 특정 인터페이스에서 앱을 실행하십시오.

exit
sudo cgcreate -t $USER:$USER -a $USER:$USER -g net_cls:novpn
cgexec -g net_cls:novpn traceroute www.google.com
# Close all Firefox windows first
cgexec -g net_cls:novpn firefox

또는 이미 실행중인 프로세스를 cgroup으로 옮기고 싶다면 할 수 없습니다! NAT (가장 무도회) 기능 때문인 것 같습니다 iptables -nvL -t nat. cgroup이 전환 될 때는 일치하지 않지만 일치합니다 iptables -nvL -t mangle.

# Get PID of the process (we'll then suppose it's 1234)
pidof firefox
# Add to cgroup - THIS DOESN'T WORK! Silently fails to produce the final result.
sudo echo 1234 > /sys/fs/cgroup/net_cls/novpn/tasks
# Remove - but this works...
sudo echo 1234 > /sys/fs/cgroup/net_cls

크레딧 : 없음 대답은 예상대로 작동되지 않았다, 그러나 이들의 혼합 않았다 evolware 글에 답변 chripell 라우팅 cgroup을, iptables에 정책을 사용하여 : 테이크 2 라우팅 프로세스 당 , 내가 특정 프로세스가 사용하는 OpenVPN 연결을 통해하지 않을 수 있을까요 어떻게? , 킬의 iptables에 기초 OpenVPN을위한 스위치


위대한 답변에 감사드립니다. 아파치와 어떻게 작동합니까? 나는 cgexec -g net_cls:novpn apache2변수 정의되지 않은 erros의 전체 목록을 시도 하고 나에게 주었다!
razzak

2
apache2터미널에서 직접 실행하면 동일한 오류가 발생합니다 . 이는 apache2일반적으로와 함께 서비스로 시작 되기 때문 입니다 systemctl start apache2. 그러나는 작동하지 않습니다 cgexec. apache2net_cls cgroup이 전파 되려면 호출 된 프로그램이 원하는 ( ) 프로세스 의 부모 여야합니다 . 따라서 시작 스크립트를 찾아야합니다. 이 경우에는 sudo cgexec -g net_cls:novpn /usr/sbin/apache2ctl start입니다. 로 확인하십시오 ./novpn.sh --list.
KrisWebDev

더 이상 우분투 16.04에서 작동하지 않습니다!
razzak

2
우분투 16.04에서 사용하고 있으며 제대로 작동합니다. Ubuntu 16에서 인터페이스 이름이 변경되었으므로 eth0다음과 같이 바꿔야 할 수도 있습니다 enp7s0. ifconfig명령 에서 정보를 가져옵니다 .
KrisWebDev 2016 년

감사합니다. 그러나 cpmanager로 인해 Ubuntu 18.04에서는 작동하지 않습니다. systemd와의 충돌로 인해 제거되었습니다
skonsoft


3

mariusmatutiae와 KrisWebDev의 탁월한 답변을 결합하여 KrisWebDev의 뛰어난 novpn.sh스크립트를 광범위하게 수정했습니다 . KrisWebDev의 스크립트는보다 구체적인 가려움증 (VPN 내부 / 외부에서 프로세스 실행 및 이동)을 스크래치하도록 설계되었지만 내 버전을 사용하면 지정한 네트워킹 환경에서 기본적으로 모든 명령을 실행할 수 있습니다. 바인딩 할 인터페이스, 기본 경로, 고유 한 iptables 규칙, 정적 경로를 지정하고 "테스트"를 지정하여 명령을 실행하기 전에 원하는대로 모든 것이 작동하는지 확인할 수 있습니다. 내부에서 명령 / 프로세스를 실행할 수있는 특정 네트워킹 환경을 정의 할 수 있도록 여러 구성 파일을 사용할 수 있습니다.

나는 여기에 요점으로 게시했다 : https://gist.github.com/level323/54a921216f0baaa163127d960bfebbf0

나중에 cgroup / iptables / routing 테이블을 정리할 수도 있습니다!

피드백 환영합니다.

PS-데비안 8 (Jessie)을 위해 설계되었습니다


@allnatural 안녕하세요, altnetworking.sh 스크립트를 사용하고 싶지만 구성 파일에 무엇을 넣어야합니까?
Cris70

0

응용 프로그램별로 아닙니다. 포트 또는 IP 주소 등으로 수행하거나 응용 프로그램 자체가 특정 네트워크 카드에 바인딩하여 사용할 수 있습니다.

그래도 규칙을 설정할 수 없습니다.


Java 응용 프로그램을 가지고 있는데 해당 응용 프로그램을 인터페이스에 바인딩 할 수 있습니까?
Suresh

소스 코드를 가지고 있고 내부를 다시 프로그래밍 할 수있는 Java 애플리케이션?
Majenko

Apache http 라이브러리를 사용하는 Java 응용 프로그램 소스 코드가 있습니다.
Suresh

그런 다음 stackoverflow.com으로 가서 프로그래머에게 프로그램 변경 방법을 문의하십시오. Java로 프로그래밍 한 적이 없습니다.
Majenko
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.