iptables --set-mark-다른 인터페이스를 통해 다른 포트를 라우팅


15

짧은 이야기,
3 개의 인터페이스, eth0 (LAN), eth1 (ADSL), eth2 (4G).
eth0-> eth1 : 작동
(포트 80, 443, 4070) eth0-> eth2 : 발생하지 않음


이것은 아이디어를 그래픽으로 표현한 것입니다.

eth2를 통한 포트 80 & 443
개미 eth1을 통한 나머지
여기에 이미지 설명을 입력하십시오

Netscheme :

eth0: -ip 10.0.0.1 -net 10.0.0.0/8 -gw 10.0.0.1 (the servers own intf) 
eth1: -ip 192.168.1.74 -net 192.168.1.0/24 -gw 192.168.1.254 
eth2: -ip 192.168.1.91 -net 192.168.0.0/24 -gw 192.168.0.1 






이 새로운 스크립트는 22와 4070을 적절한 테이블로 다시 라우팅한다고 생각합니다.
그러나 해당 테이블에 도달 한 후에는 eth2로 다시 라우팅되지 않습니다.




이 스크립트는 22와 4070을 제외하고 작동합니다!

(포트 80은 주석 처리되어 있지 않으며 작동하지만 eth1을 통해 작동합니다.)

modprobe iptable_nat
modprobe ip_conntrack

echo "1" > /proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -F PREROUTING
iptables -t nat -F
iptables -t mangle -F
iptables -F
# This next line restores any issues trying to connect to something
# if you get weird ACK packets when trying to connect (at least i did)!
iptables -t mangle -A PREROUTING -p tcp -j CONNMARK --restore-mark
ip route flush table main

iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 22 -j MARK --set-mark 1
###  iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 80 -j MARK --set-mark 1
iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 4070 -j MARK --set-mark 1

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
## -- Does the same as ip route below? route add default gw 192.168.1.254


echo "201 eth2.out" >> /etc/iproute2/rt_tables

ip rule add fwmark 1 table eth2.out
ip route add default via 192.168.0.1 dev eth2 table eth2.out
ip route add default via 192.168.1.254 dev eth1



## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE









이전 스크립트 :


  Ignore everything below unless you're interested in retracing my steps!!




내가 나쁜 일을 할 수 있도록 환경을 설정하기 위해 router.sh 스크립트를 만들었습니다. 4G 연결로 보내고 자하는 3 개의 포트가 있고 나머지는 유선 ADSL 연결을 통해 있습니다. 이를 위해 iptables가 기본 경로에서 패키지를 맹 글링하고 --dport == 443 | 80 | 4070

그러나 이것은 작동하지 않습니다. 나는 어쨌든 여전히 내 유선을 통해 라우팅되고 있습니다.

이것은 내 스크립트 모양입니다 :

#!/bin/bash

## routing tables
# wireless = 4G via eth2
# adsl = adsl via eth1

modprobe iptable_nat
modprobe ip_conntrack

echo "1" > /proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -t nat -F
ip route flush table main
ip route flush table wireless
ip route flush table adsl

## Setup routing tables
# ADSL
ip route add table adsl to 192.168.1.0/24 dev eth1
# 4G
ip route add table wireless to 192.168.0.0 dev eth2
ip rule add fwmark 0x1 table wireless

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
route add default gw 192.168.1.254


## Forward ports into the LAN
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.0.3:80


## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -j LOG
#iptables --table nat --append POSTROUTING --out-interface eth2 --jump SNAT --to-source "192.168.1.74"
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

또한이 3을 스크립트의 맨 아래에 추가하려고했습니다.

iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 80 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 443 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 4070 -j SNAT --to "192.168.0.91"

또한 성공하지 않고 시도했습니다.

iptables -A PREROUTING -t mangle -i eth0 -p tcp --dport 80 -j MARK --set-mark 1

마지막으로 시도한 것 :

## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

라우팅이 작동하고 웹을 탐색하고 음악을 듣고 무엇을들을 수는 있지만 잘못된 인터페이스를 통해하고 있습니다. 나는 오랫동안 구글 검색을 해 왔으며 내가하고있는 일과 내가하는 일을 이해하기 위해 약간의 조각과 조각을 발견했습니다. 나는 tc를 통해 트래픽 쉐이핑을 할 수 있지만 iptables에 패키지를 표시하여 가능하다면 먼 길을 도울 것입니다.

내 생각에 다른 규칙, 주로 MASQUERADE 부분 에서 순서를 잘못하고 있습니까? 아니면 거기에 있어야합니까?

누군가 외부 인터페이스 (하나 또는 둘 다 프로토콜)에서 내부 10.0.0.0 주소 공간으로 tcp : 80 으로 DNAT 포트를 말하는 방법을 설명 할 수 있습니까 ?



출력 :

root@Netbridge:~# route -n Kernel IP routing table Destination    

Gateway         Genmask         Flags Metric Ref    Use Iface<br>
0.0.0.0         192.168.1.254   0.0.0.0         UG    0      0        0 eth1<br>
10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 eth0<br>
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 eth2<br>
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth1


root@Netbridge:~# ifconfig

eth0      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:4e  
          inet addr:10.0.0.1  Bcast:10.255.255.255  Mask:255.0.0.0

eth1      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:58  
          inet addr:192.168.1.74  Bcast:192.168.1.255  Mask:255.255.255.0

eth2      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:62  
          inet addr:192.168.0.91  Bcast:192.168.0.255  Mask:255.255.255.0

다음 지침을 따르십시오.
출력 트래픽에 다른 인터페이스 기반의 대상에 대한
iptables- 앞으로 특정 포트에서 특정 NIC까지
몇 가지 다른 관련 스레드 중에서.


죄송하지만 아파치 localhosteth2인터페이스 주소와 주소 에만 바인딩하지 않는 이유가 있습니까?
Jan Marek

@ JanMarek : 여기에는 아파치에 대한 언급이 없습니다. 그리고 귀하의 정보를 위해, ethXIP 주소의 소켓을 바인딩 하면 ethXLAN의 호스트가 IP 주소 를 사용하여 로컬 서버에 액세스하는 ethY것을 막을 수 있으며 호스트가 IP 주소를 ethY사용하여 서버에 액세스하는 것을 막을 수 없습니다 ethX. Linux는 약한 호스트 모델을 사용합니다.
BatchyX 2016

좋아, 아파치 서버뿐만 아니라 더 많은 웹 서버가있을 수 있습니다 ...하지만 인터페이스 eth2의 웹 서버를 바인딩하는 간단한 솔루션이 될 수 있습니다. 그러나 나는 틀릴 수있다.
Jan Marek

답변:


6

BatchyX는 이미 iptables와 라우팅에 대해 아주 좋은 설명을 제공하므로 게으름을 피우고 스크립트로 직접 이동합니다.

포트 80,443,22,4070에서 192.168.0.91까지의 모든 트래픽을 NAT해야합니다. 나머지는 모두 192.168.1.254를 통해 NAT됩니다.

테스트를 다시하고이 안내서를 따라 갑니다. 이 안내서에서 빠진 것은 스크립트의 마지막 3 줄입니다. 다른 포트에서 발견했지만 해당 링크를 잃어 버렸습니다.

테스트 된 작업 스크립트입니다.

기본 경로 필요

스크립트에 넣지 않은 한 가지는 기본 경로를 설정하는 것입니다. 그것은해야한다

route add default gw 192.168.1.254

당신이 할 때 route -n, 그것은 유일한 기본 경로 (Dest : 0.0.0.0)이어야합니다

0.0.0.0    192.168.1.254    0.0.0.0    UG    0    0    0    eth1

fw-router.sh

# iptables 재설정 / 세척
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P 입력 수락
iptables -P 포워드 수락
iptables -P 출력 수락

# 재설정 / 세척 / 설정 IP 경로 (표 4)
IP 경로 플러시 테이블 4
IP 경로 쇼 테이블 메인 | grep -Ev ^ default | ROUTE를 읽는 동안; ip route add table 4를 수행하십시오 $ ROUTE; 끝난
192.168.0.1을 통한 ip route add table 4 기본값

D.Port와 일치하는 #Mark 패킷
iptables -t mangle -A PREROUTING -p tcp --dport 22 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 80 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 443 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 4070 -s 10.0.0.0/24 -j MARK --set-mark 4

#SNAT 규칙
iptables -t nat -A POSTROUTING -o eth1 -j SNAT-소스 192.168.1.74
iptables -t nat -A POSTROUTING -o eth2 -j SNAT-소스로 192.168.0.91

#IP 경로
ip 규칙 추가 fwmark 4 표 4
IP 경로 플러시 캐시

#IP 스택
#이 가이드에서 빠진 부분입니다
에코 1> / proc / sys / net / ipv4 / ip_forward
/ proc / sys / net / ipv4 / conf / * / rp_filter의 f; echo 0> $ f; 끝난
에코 0> / proc / sys / net / ipv4 / route / flush

PS1 : 요컨대, MASQUERADE어떤 종류의로드 밸런싱이 필요하거나 들어오는 트래픽을 처리하기 위해 DNAT가 필요한 여러 외부 IP가있는 NAT의 경우 (대부분의 경우, 그리고 분명히 당신의 경우에는) 작동하지 않습니다. SNAT방향 제어 가 필요 합니다.

PS2 : 순수한 iptable로는 충분하지 않습니다.


우선, 스크립트에 직접 갈 것을 응원합니다 :) 나는 이것이 실행될 환경으로 돌아갈 때 오늘 밤 이것을 시도 할 것입니다!
Torxed

흠, 무거운 수정이 필요할 수 있습니다. 결과를 알려주세요.
John Siu

수정, 지금 작동해야합니다.
John Siu

단, 짧은 시간에 다시 연락 드리겠습니다 : D
Torxed

나는 너를 너무나 사랑해 두통을 해결했다! 감사합니다!
Torxed

6

참고 : 나는 이전 스크립트를 무시하고 첫 번째 스크립트 만 고려했습니다.

  • 현재 iptables를 사용하여 수동으로 netfilter 모듈을 수정하지 않아도됩니다. 이것은 사용자 지정 연결 추적기에만 필요합니다.
  • 최대 혼합하지 마십시오 routeip route. 이것은 순수한 악입니다. 그냥 사용하는 ip모든 곳에서 약 잊어 ifconfigroute
  • /etc/iproute2/rt_tables재부팅해도 재설정되지 않습니다. 동일한 항목을 반복해서 추가하는 것은 좋은 생각이 아니며 한 번만 수행하면됩니다. 기억 rt_tables단지 숫자 값에 이름 별칭을 정의, 어떤 구성을 변경하지 않습니다.

  • 이제 iptables: FORWARD체인에서 LAN에서 4G로 오는 패킷을 삭제합니다. 이것은 나쁘다. FORWARD후크가 완료 라우팅 후 사용됩니다. 이 시점에서 모든 정책 라우팅이 완료되었으며 패킷을 4G 또는 ADSL로 전송할지 여부는 이미 알려져 있습니다. 내부 FORWARD또는 이후에 경로 재 지정이 없습니다 FORWARD(기술적으로는 경로 재 지정이 POSTROUTING심각한 경우에 수행 될 수 있지만 그 시점으로 돌아갈 수 있음).

이제 라우팅 : 우분투는 기본적으로 역방향 경로 필터링을 활성화합니다. 리버스 경로 필터링은 다음과 같이 작동합니다. 커널이 인터페이스 A로부터 패킷을 수신하면 (전달 될 수도 있고 안될 수도 있음) 소스 주소와 대상 주소를 반전시키고 결과 패킷이 인터페이스 A를 통해 라우팅되어야하는지 확인합니다. 그렇지 않으면 주소 스푸핑 시도로 패킷이 삭제됩니다.

에서받은 패킷의 eth0경우 문제가되지 않습니다. eth1소스 IP 주소와 대상 IP 주소를 되돌릴 때 커널이 기본 경로를 table의 경로로 지정하기 때문에 로부터 수신 한 패킷의 경우 에도 문제가되지 않습니다 main. 에서 수신 한 패킷 ( eth2표시하지 않음)의 경우 커널이 table의 기본 경로에 도달 main하고이 패킷이에서 수신 된 것으로 간주 되므로 문제 가됩니다 eth1. 가장 쉬운 해결책은 eth1에서 역방향 경로 필터링을 비활성화하는 것입니다.

sysctl -w net.ipv4.conf.eth1.rp_filter=0

모든 훌륭한 의견과 예, 예를 들어 매번 rt_tables에 추가하고 특히 특정 테이블을 지우지 않지만 나는 거기에 도착할 것입니다 :) 나는 모든 것을 줄 것입니다. 그것이 효과가 있다면, 당신에게 +50이되며 가장 중요하게는 사람을 조금이라도 평화롭게 잘게 자르지 못하도록 막아 냈습니다! :)
초에 Torxed

1
아래 스크립트는 작동하지만 모든 감사를받을 자격이 있습니다. 저에게 생각할 것이 하나 또는 두 개 주어졌고 rp_filter = 0이 먼 길을 도왔습니다! : D
Torxed

@BatchyX는 매우 유익한 정보입니다.
John Siu

@Torxed 내가 언급 한 게시물은 모든 인터페이스에 대해 rp_filter를 비활성화해야합니다. 다른 방식으로 작동하는지 확실하지 않습니다.
John Siu

@ JohnSiu : 문제가있는 인터페이스에서 rp 필터를 비활성화해야합니다. 이 경우 마크가 설정되지 않은 경우 해당 인터페이스로가는 경로가 없기 때문에 eth1입니다. eth2는 기본 경로가 해당 인터페이스로 들어가는 것과 같은 문제가 없습니다. eth0의 경우 실제로 rp 필터를 활성화하는 것이 유용합니다. 그렇지 않으면 LAN의 누군가가 인터넷에있는 소스 주소와 LAN의 대상 주소를 가진 IP 패킷을 위조 할 수 있으며 라우터는이를 행복하게 받아들이고 전달합니다. 그것은 다시 eth0으로 돌아갑니다.
BatchyX
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.