iptables-특정 인터페이스로 패킷을 라우팅하는 대상?


25

내 홈 서버에는 두 가지 기본 인터페이스 eth1(표준 인터넷 연결)와 tun0(OpenVPN 터널)이 있습니다. iptablesUID 1002가 소유 한 로컬 프로세스에서 생성 된 모든 패킷을 강제 종료 tun0하고 다른 모든 패킷은 강제 종료하는 데 사용하고 싶습니다 eth1.

일치하는 패킷을 쉽게 표시 할 수 있습니다.

iptables -A OUTPUT -m owner --uid-owner 1002 -j MARK --set-mark 11

이제 POSTROUTING 체인 (아마도 mangle 테이블)에 11로 표시된 패킷을 일치시키고을 보내고 tun0모든 패킷과 일치하고을 보내는 규칙을 규칙에 추가하고 싶습니다 eth1.

ROUTE 대상을 찾았지만 소스 인터페이스를 잘못 작성하지 않는 한 소스 인터페이스 만 다시 작성하는 것 같습니다.

iptables가 가능합니까? 대신 라우팅 테이블을 사용 ip route하거나 레거시 route명령을 통해 엉망으로 만들어야 합니까?

편집 : 더 많은 정보를 제공해야한다고 생각했습니다. 현재 다른 iptables 규칙이 없습니다 (향후 관련없는 작업을 수행하기위한 규칙을 만들 수는 있지만). 또한 출력 ip route은 다음과 같습니다.

default via 192.168.1.254 dev eth1  metric 203
10.32.0.49 dev tun0  proto kernel  scope link  src 10.32.0.50
85.17.27.71 via 192.168.1.254 dev eth1
192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.73  metric 203

나는 라우팅 테이블을 건드리지 않았습니다. 이것은 현재의 상태입니다 (꽤 더러워 보이지만). 죄송하지만 route이 컴퓨터에 레거시 명령이 설치되어 있지 않습니다 .

그리고 ip addreth0과 eth2 의 출력은 무시할 수 있습니다-현재 사용되지 않는 NIC입니다.

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 1c:6f:65:2a:73:3f brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast     state UP qlen 1000
    link/ether 00:1b:21:9d:4e:bb brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.73/24 brd 192.168.1.255 scope global eth1
    inet6 fe80::21b:21ff:fe9d:4ebb/64 scope link
       valid_lft forever preferred_lft forever
4: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 00:1b:21:6a:c0:4b brd ff:ff:ff:ff:ff:ff
5: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc     pfifo_fast state UNKNOWN qlen 100
    link/none
    inet 10.32.0.50 peer 10.32.0.49/32 scope global tun0

편집 : 약간의 효과가 있지만 표시된 패킷을 tun0으로 전달하지 않습니다. 기본적으로 표 (11)을 추가하고 다음을 사용했습니다.

ip route add table 11 via 10.32.0.49 dev tun0
ip rule add priority 10000 fwmark 11 table 11

방금했을 때 sudo -u user1000 wget -qO- whatismyip.org집의 외부 IP 주소를 얻지 만,한다면 sudo -u user1002 wget -qO- whatismyip.org집의 IP 주소도 얻습니다 (그러나 OpenVPN 터널의 다른 쪽 끝에서 IP를 가져와야합니다).

Running iptables -vL은 패킷이 표시 규칙과 일치하는지 확인하지만 라우팅 규칙을 따르지 않는 것으로 보입니다.

편집 : 나는 이것에 오랜 시간을 보냈는데 여전히 작동하지 않지만 조금 더 가깝다고 생각합니다.

iptables 규칙은 mangle테이블의 OUTPUT 체인 에 있어야 합니다. nat소스 주소를 설정하려면 테이블의 POSTROUTING 체인 에 MASQUERADE 규칙이 필요하다고 생각 합니다. 그러나 OUTPUT의 맹글이 발생한 후 발생하는 재 라우팅이 올바르게 작동하지 않습니다.

나는 지금 이것에 5 시간을 보냈으므로 휴식을 취하고 오늘 밤이나 내일 언젠가 다시 돌아올 것입니다.

답변:


26

나는 조금 다른 문제가 있지만 최근에 비슷한 문제를 겪었습니다. 나는 경로에 원하는 경우에만 기본 인터페이스를 통해 (심지어 같은 호스트에 대한) 다른 모든 트래픽을 라우팅하면서,하는 OpenVPN 일단 tap0 인터페이스를 통해 TCP 포트 25 (SMTP).

그렇게하려면 패킷을 표시하고 처리 규칙을 설정해야했습니다. 먼저, 커널 라우팅 패킷이 2through table 로 표시되도록하는 규칙을 추가 하십시오 3(나중에 설명).

ip rule add fwmark 2 table 3

에 기호 이름을 추가 할 수는 /etc/iproute2/rt_tables있었지만 귀찮게하지 않았습니다. 숫자 23무작위로 선택됩니다. 실제로 이것들은 동일 할 수 있지만 명확성을 위해이 예제에서는하지 않았습니다 (내 자신의 설정에서 수행하더라도).

게이트웨이가 10.0.0.1다음 과 같다고 가정하고 다른 인터페이스를 통해 트래픽을 리디렉션하기위한 경로를 추가하십시오 .

ip route add default via 10.0.0.1 table 3

매우 중요! 라우팅 캐시를 비우십시오. 그렇지 않으면 응답을받지 않고 몇 시간 동안 머리에 손을 대고 앉아 있습니다.

ip route flush cache

이제 지정된 패킷을 표시하기위한 방화벽 규칙을 설정하십시오.

iptables -t mangle -A OUTPUT -p tcp --dport 465 -j MARK --set-mark 2

위 규칙은 패킷이 로컬 시스템에서 온 경우에만 적용됩니다. http://inai.de/images/nf-packet-flow.png를 참조하십시오 . 요구 사항에 맞게 조정하십시오. 예를 들어, tap0인터페이스를 통해 나가는 HTTP 트래픽 만 라우팅 하려면 465를 80으로 변경하십시오.

전송 된 패킷이 tap0LAN 주소를 소스 IP로 가져 오는 것을 방지하려면 다음 규칙을 사용하여 인터페이스 주소로 변경하십시오 (인터페이스의 10.0.0.2IP 주소로 가정 tap0).

iptables -t nat -A POSTROUTING -o tap0 -j SNAT --to-source 10.0.0.2

마지막으로 역방향 경로 소스 검증을 완화하십시오. 일부는로 설정하도록 제안 0하지만 https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt2 에 따르면 더 나은 선택으로 보입니다 . 이 단계를 건너 뛰면 패킷을 수신 하지만 (을 사용하여 확인할 수 있음 ) 패킷은 수락되지 않습니다. 패킷을 허용하도록 설정을 변경하는 명령 :tcpdump -i tap0 -n

sysctl -w net.ipv4.conf.tap0.rp_filter=2

MASQUERADE 대신 SNAT를 사용하는 이유는 무엇입니까? MASQUERADE는 IP 주소가 "런타임"인터페이스에서 수집되고 구성 파일에 하드 코딩되지 않은 경우를 제외하고 동일한 작업을 수행하지 않습니까?
Ethan

6
@Ethan From man iptables: 동적으로 할당 된 IP (다이얼 업) 연결에만 사용해야합니다. 고정 IP 주소가있는 경우 SNAT 대상을 사용해야합니다. 마스 쿼 레이 딩은 패킷이 나가는 인터페이스의 IP 주소에 대한 매핑을 지정하는 것과 동일하지만 인터페이스가 다운 될 때 연결을 잊어 버리는 효과도 있습니다. 당신은 옳습니다. 그러나 나의 IP는 절대 변하지 않기 때문에 맨 페이지의 추천에 따라 SNAT를 사용하기로 결정했습니다.
Lekensteyn 2016 년

마지막 단계 (역 경로 소스 유효성 검사)는 필요하지 않다고 생각합니다 (테스트하지는 않았지만). 기본 게이트웨이에 따라 PREROUTING체인에 다른 규칙을 DNAT올바른 소스 주소에 추가하기 만하면 됩니다.
Christian Wolf

7

나는 이것을 해결했다. 문제는 표 11의 라우팅 규칙과 관련이 있습니다. 표 11에 문제 발생했지만 라우팅 규칙으로 인해 작동하지 않습니다. 이 스크립트는 현재 사용하고 있으며 잘 작동하는 것 같습니다 (확실히 설정에 따라 다르지만). 또한 메인 업 링크 (eth1) 전용의 새 테이블 21을 만들었습니다.

# Add relevant iptables entries.
iptables -t mangle -A OUTPUT -m owner --uid-owner 1002 -j MARK --set-mark 11
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

# Flush ALL THE THINGS.
ip route flush table main
ip route flush table 11
ip route flush table 21
ip rule flush

# Restore the basic rules and add our own.
ip rule add lookup default priority 32767
ip rule add lookup main priority 32766
ip rule add fwmark 11 priority 1000 table 11
# This next rule basically sends all other traffic down eth1.
ip rule add priority 2000 table 21

# Restore the main table.  I flushed it because OpenVPN does weird things to it.
ip route add 127.0.0.0/8 via 127.0.0.1 dev lo
ip route add 192.168.1.0/24 dev eth1 src 192.168.1.73
ip route add default via 192.168.1.254

# Set up table 21.  This sends all traffic to eth1.
ip route add 192.168.1.0/24 dev eth1 table 21
ip route add default via 192.168.1.254 dev eth1 table 21

# Set up table 11.  I honestly don't know why 'default' won't work, or
# why the second line here is needed.  But it works this way.
ip route add 10.32.0.49/32 dev tun0 table 11
ip route add 10.32.0.1 via 10.32.0.50 dev tun0 table 11
ip route add 0.0.0.0/1 via 10.32.0.50 dev tun0 table 11

ip route flush cache

## MeanderingCode edit (아직 댓글을 달 수 없기 때문에)

이 답변에 감사드립니다! 여기에 경로 정보를 유지해야 할 수도 있기 때문에 (지저분 할 수도 있고, 경로를 설정하려는 다른 것들을 깨뜨릴 수 있기 때문에) 이것은 지저분해질 수 있습니다.

서버가 경로를 "푸시"하도록 구성되어 모든 트래픽이 "맨손"인터넷이 아닌 VPN 네트워크 인터페이스를 통해 라우팅 될 수 있으므로 OpenVPN의 라우팅 테이블에 "이상한 일"이 발생할 수 있습니다. 또는 OpenVPN 구성 또는 스크립트 / 응용 프로그램이 설정하는 것은 경로를 설정하는 것입니다.

전자의 경우 OpenVPN 구성을 편집하고 "route-nopull"을 포함하는 줄을 넣을 수 있습니다
. 후자의 경우 OpenVPN 또는 모든 래퍼 (예 : 많은 현재 Linux 데스크탑 배포판의 네트워크 관리자 -openvpn) 구성을 확인하십시오
. 이 스크립트를 실행할 때와 시스템이 수행하는 작업에 따라 테이블을 플러시하는 것보다 라우팅 설정을 제거하는 것이 더 깨끗하고 안전합니다.

건배!


2

나는 당신이 원하는 것 같아요 :

/sbin/ip route add default via 10.32.0.49 dev tun0 table 11
/sbin/ip rule add priority 10000 fwmark 11 table 11

http://lartc.org/howto/lartc.netfilter.html

그러나 나는 위의 테스트를하지 않았습니다.


첫 번째 명령은 "오류 :"to "가 중복되었거나"10.32.0.49 "가 가비지입니다."를 반환합니다.
Ethan

기본과 IP 사이의 경유를 잊어 버렸습니다.
mfarver

나는 그것을 시도했다. default키워드 를 그대로 두는 것과 같은 효과가있는 것 같습니다 .
Ethan

옵션을 제거하려면 tun0에서 패킷 캡처를 시도하고 해당 인터페이스에서 패킷이 끝나는 지 확인하십시오. tcpdump -i tun0 .. 또는 사용자 ID를 기준으로해야합니까? 대상 IP 주소 (더 쉬운)를 기반으로 할 수 있습니까? route add <remote host> 통해 10.32.0.49
mfarver

대상 IP 주소를 벗어나면 기반을 둘 수 없습니다. 많은 IP 주소가있을 것입니다. 이론적으로 pid를 기반으로 할 수도 있지만 데몬이 시작될 때까지 pid를 알지 못하기 때문에 훨씬 더 어렵습니다.
Ethan

0

iptables 명령없이 수행 할 수 있습니다. 간단한 ip 명령을 실행하십시오.

uid 1002의 경우 :

ip rule add uidrange 1002-1002 table 502

원하는 인터페이스를 통해 표 502에 대한 기본 경로 추가

eth0 ip rule add default via a.b.c.d dev eth0

그 명령을 테스트했는데 작동하지 않았습니다.Error: argument "uidrange" is wrong: Failed to parse rule type
kasperd

@ kasperd 당신은 그가 잘못하고 있어야합니다, 왜냐하면 그것은 나를 위해 잘 작동합니다.
horseyguy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.