* SSH Port Forwarding with iptables
@ 2009-09-29 15:16 Bill Hendrickson
2009-09-29 16:14 ` Bill Hendrickson
2009-09-29 16:16 ` Gáspár Lajos
0 siblings, 2 replies; 10+ messages in thread
From: Bill Hendrickson @ 2009-09-29 15:16 UTC (permalink / raw)
To: netfilter list
Hey list,
I'm having trouble setting up port forwarding using iptables. This is
my first attempt so I'm not surprised. I want to have a dual-NIC
linux server set up to take incoming SSH requests on a non-standard
port, and forward them to an internal server running SSH on the
standard port. I actually need to have two internal servers set up
this way, and handling HTTP redirects as well, but I'll settle for one
working SSH server.
This is my setup:
EXTERNAL_PC<===>SWITCH<===>GATEWAY_SVR<== x/o ==>INTERNAL_SVR
EXTERNAL_PC
eth0:172.17.17.9
SWITCH:
Linksys SD2008 (no ipaddr)
GATEWAY_SVR
eth0:172.17.17.165
eth1:172.16.0.165
INTERNAL_SVR
eth0:172.16.0.101
I poured thru tutorials and other googled bounty, and this is what I
came up with for my iptables script (hand-typed, not cut-and-paste):
<<<<<<<<<<<<<<>>>>>>>>>>>>
#!/bin/bash
modprobe iptable_nat
echo 1 > /proc/sys/net/ipv4/ip_forward
EXT_IFACE="eth0"
EXT_IP="172.17.17.165"
INT_IFACE="eth1"
SSH_IP="172.16.0.101"
SSH_PORT="2203"
IPT="/sbin/iptables"
$IPT -F
$IPT -F -t nat
$IPT -X
$IPT -A OUTPUT -o $EXT_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -o $INT_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
# wide open, for testing...
$IPT -t nat -P PREROUTING ACCEPT
$IPT -t nat -P POSTROUTING ACCEPT
$IPT -t nat -P OUTPUT ACCEPT
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -i lo -j ACCEPT
$IPT -t nat -A PREROUTING -p tcp -i $EXT_IFACE -d $EXT_IP --dport
$SSH_PORT --sport 1024:65535 -j DNAT --to $SSH_HOST:22
$IPT -A FORWARD -p tcp -i $EXT_IFACE -o $INT_IFACE -d $SSH_HOST
--dport $SSH_PORT --sport 1024:65535 -m state --state NEW -j ACCEPT
$IPT -A FORWARD -j LOG --log-prefix "meh "
<<<<<<<<<<<<<<>>>>>>>>>>>>
All 3 boxes are running Fedora 8. All three boxes are set up for
static IP: there is no default gateway defined for any box, and the
netmask for all three is 255.255.255.0. There is no DNS/internet
involved (at least /etc/resolv.conf is empty). TCP_wrappers are
disabled. I can successfully SSH from GATEWAY_SVR to INTERNAL_SVR no
problem. I can also SSH from EXTERNAL_PC to GATEWAY_SVR no problem.
But when I try to SSH from EXTERNAL_PC directly to INTERNAL_SVR, via
the redirected port, e.g.:
root@EXTERNAL_PC # ssh -p 2203 172.17.17.165
it just hangs, until SSH times out. I have Wireshark running on
INTERNAL_SVR, so I know the packets are getting there. They just seem
to get stuck on the return path, at the GATEWAY_SVR box.
This is what is getting logged on GATEWAY_SVR, in /var/log/messages:
meh IN=eth0 OUT=eth1 SRC=172.17.17.9 DST=172.16.0.101 LEN=60 TOS=0x00
PREC=0x00 TTL=63 ID=53921 DF PROTO=TCP SPT=34718 DPT=22 WINDOW=5840
RES=0x00 SYN URGP=0
meh IN=eth0 OUT=eth1 SRC=172.17.17.9 DST=172.16.0.101 LEN=44 TOS=0x00
PREC=0x00 TTL=45 ID=24728 PROTO=TCP SPT=58967 DPT=22 WINDOW=3072
RES=0x00 SYN URGP=0
meh IN=eth0 OUT=eth1 SRC=172.17.17.9 DST=172.16.0.101 LEN=44 TOS=0x00
PREC=0x00 TTL=46 ID=20175 PROTO=TCP SPT=58968 DPT=22 WINDOW=4096
RES=0x00 SYN URGP=0
If I nmap port 2203 on GATEWAY_SVR from EXTERNAL_PC, it reports the
state as "filtered".
The infuriating thing is, I had it working briefly. Then I tried to
add two more internal SSH servers, but those dogs did not hunt - they
were "filtered", although the first one still worked. Then I dorked
things all up, and can get nothing to work now.
Can anyone help?
-bill
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: SSH Port Forwarding with iptables
2009-09-29 15:16 SSH Port Forwarding with iptables Bill Hendrickson
@ 2009-09-29 16:14 ` Bill Hendrickson
2009-10-01 10:37 ` Pascal Hambourg
2009-09-29 16:16 ` Gáspár Lajos
1 sibling, 1 reply; 10+ messages in thread
From: Bill Hendrickson @ 2009-09-29 16:14 UTC (permalink / raw)
To: netfilter list
okay, i simplified my script, and tried MASQUERADE vs FORWARD, and got
it to work:
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 2022 -j DNAT
--to-destination 172.16.0.101:22
iptables -t nat -A POSTROUTING -j MASQUERADE
why does this way work? what are the ramifications of using
masquerading, i.e., any reason i shouldn't adopt this method?
>
> #!/bin/bash
>
> modprobe iptable_nat
> echo 1 > /proc/sys/net/ipv4/ip_forward
>
> EXT_IFACE="eth0"
> EXT_IP="172.17.17.165"
> INT_IFACE="eth1"
>
> SSH_IP="172.16.0.101"
> SSH_PORT="2203"
>
> IPT="/sbin/iptables"
> $IPT -F
> $IPT -F -t nat
> $IPT -X
>
> $IPT -A OUTPUT -o $EXT_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
> $IPT -A OUTPUT -o $INT_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
>
> # wide open, for testing...
> $IPT -t nat -P PREROUTING ACCEPT
> $IPT -t nat -P POSTROUTING ACCEPT
> $IPT -t nat -P OUTPUT ACCEPT
>
> $IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
> $IPT -A INPUT -i lo -j ACCEPT
>
> $IPT -t nat -A PREROUTING -p tcp -i $EXT_IFACE -d $EXT_IP --dport
> $SSH_PORT --sport 1024:65535 -j DNAT --to $SSH_HOST:22
> $IPT -A FORWARD -p tcp -i $EXT_IFACE -o $INT_IFACE -d $SSH_HOST
> --dport $SSH_PORT --sport 1024:65535 -m state --state NEW -j ACCEPT
>
> $IPT -A FORWARD -j LOG --log-prefix "meh "
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: SSH Port Forwarding with iptables
2009-09-29 15:16 SSH Port Forwarding with iptables Bill Hendrickson
2009-09-29 16:14 ` Bill Hendrickson
@ 2009-09-29 16:16 ` Gáspár Lajos
2009-09-29 16:41 ` Bill Hendrickson
1 sibling, 1 reply; 10+ messages in thread
From: Gáspár Lajos @ 2009-09-29 16:16 UTC (permalink / raw)
To: netfilter; +Cc: Bill Hendrickson
Hi!
You did not told but I assume that the Internal server's default gw is
the firewall.
I think you need the following rule to get it work:
$IPT -t nat -A POSTROUTING -j SNAT -o $EXT_IFACE --to-source $EXT_IP
Swifty
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: SSH Port Forwarding with iptables
2009-09-29 16:16 ` Gáspár Lajos
@ 2009-09-29 16:41 ` Bill Hendrickson
2009-09-29 17:00 ` Gáspár Lajos
0 siblings, 1 reply; 10+ messages in thread
From: Bill Hendrickson @ 2009-09-29 16:41 UTC (permalink / raw)
To: Gáspár Lajos; +Cc: netfilter
> You did not told but I assume that the Internal server's default gw is the
> firewall.
> I think you need the following rule to get it work:
>
> $IPT -t nat -A POSTROUTING -j SNAT -o $EXT_IFACE --to-source $EXT_IP
Swifty,
You nailed it - thanks! I needed to do both things (set the default
gw on internal server and use the rule). Re: my other post, which is
the better way to go, in your opinion - FORWARDing or MASQUERADing?
-bill
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: SSH Port Forwarding with iptables
2009-09-29 16:41 ` Bill Hendrickson
@ 2009-09-29 17:00 ` Gáspár Lajos
2009-09-29 17:12 ` Bill Hendrickson
0 siblings, 1 reply; 10+ messages in thread
From: Gáspár Lajos @ 2009-09-29 17:00 UTC (permalink / raw)
To: Bill Hendrickson; +Cc: netfilter
Bill Hendrickson írta:
> Swifty,
> You nailed it - thanks! I needed to do both things (set the default
> gw on internal server and use the rule). Re: my other post, which is
> the better way to go, in your opinion - FORWARDing or MASQUERADing?
>
Your welcome! :D
FORWARD is the chain...
MASQUERADING is a techique...
But to answer your question:
You are FORWARDing packets to and from your internal/external networks
on the firewall/gateway.
If you have fix external IP then you should SNAT every packet that
leaves your network.
If you have dynamic IP then you should MASQUERADE.
Your first attempt was unsuccessful because the external client expected
the packets from the gateway and not from an "internal" unknown IP.
As of the manual:
MASQUERADE
This target is only valid in the nat table, in the POSTROUTING
chain. It should only be used with dynamically assigned IP (dialup)
connections: if you have a static IP
address, you should use the SNAT target. Masquerading is
equivalent to specifying a mapping to the IP address of the interface
the packet is going out, but also has
the effect that connections are forgotten when the interface goes
down. This is the correct behavior when the next dialup is unlikely
to have the same interface
address (and hence any established connections are lost anyway).
Swifty
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: SSH Port Forwarding with iptables
2009-09-29 17:00 ` Gáspár Lajos
@ 2009-09-29 17:12 ` Bill Hendrickson
0 siblings, 0 replies; 10+ messages in thread
From: Bill Hendrickson @ 2009-09-29 17:12 UTC (permalink / raw)
To: Gáspár Lajos; +Cc: netfilter
>
> Your welcome! :D
>
> FORWARD is the chain...
> MASQUERADING is a techique...
> But to answer your question:
> You are FORWARDing packets to and from your internal/external networks on
> the firewall/gateway.
> If you have fix external IP then you should SNAT every packet that leaves
> your network.
> If you have dynamic IP then you should MASQUERADE.
> Your first attempt was unsuccessful because the external client expected the
> packets from the gateway and not from an "internal" unknown IP.
>
> As of the manual:
>
> MASQUERADE
> This target is only valid in the nat table, in the POSTROUTING chain.
> It should only be used with dynamically assigned IP (dialup) connections:
> if you have a static IP
> address, you should use the SNAT target. Masquerading is equivalent
> to specifying a mapping to the IP address of the interface the packet is
> going out, but also has
> the effect that connections are forgotten when the interface goes down.
> This is the correct behavior when the next dialup is unlikely to have
> the same interface
> address (and hence any established connections are lost anyway).
>
> Swifty
Excellent, I see. You the man, Swifty. Case closed. Points awarded.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: SSH Port Forwarding with iptables
2009-09-29 16:14 ` Bill Hendrickson
@ 2009-10-01 10:37 ` Pascal Hambourg
2009-10-01 15:24 ` Bill Hendrickson
2009-10-01 16:26 ` Gáspár Lajos
0 siblings, 2 replies; 10+ messages in thread
From: Pascal Hambourg @ 2009-10-01 10:37 UTC (permalink / raw)
To: Bill Hendrickson; +Cc: netfilter list
Hello,
Bill Hendrickson a écrit :
> okay, i simplified my script, and tried MASQUERADE vs FORWARD, and got
> it to work:
>
> iptables -t nat -P PREROUTING ACCEPT
> iptables -t nat -P POSTROUTING ACCEPT
> iptables -t nat -P OUTPUT ACCEPT
> iptables -t nat -A PREROUTING -p tcp -m tcp --dport 2022 -j DNAT
> --to-destination 172.16.0.101:22
> iptables -t nat -A POSTROUTING -j MASQUERADE
>
> why does this way work?
Because MASQUERADE replaces the original source address (which the SSH
server cannot reach due to a missing default or subnet route) with the
address of the output interface eth1 (which the SSH server can reach).
The server did not reply to the SYN packets because there is no route in
its routing table for the client address.
> what are the ramifications of using
> masquerading, i.e., any reason i shouldn't adopt this method?
You don't need SNAT nor masquerade. It hides the real source address
from the server. You just need to add a proper route on the server so it
knows how to reach the client address via the router.
Besides, the SNAT rule proposed by Gaspar could not help because it
works on the external interface, while the missing route on the server
requires SNAT/MASQUERADE on the internal interface.
>> $IPT -A OUTPUT -o $EXT_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
>> $IPT -A OUTPUT -o $INT_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
You don't need all the ACCEPT rules when the default policies are ACCEPT
and there are no DROP/REJECT rules.
>> $IPT -t nat -A PREROUTING -p tcp -i $EXT_IFACE -d $EXT_IP --dport
>> $SSH_PORT --sport 1024:65535 -j DNAT --to $SSH_HOST:22
>> $IPT -A FORWARD -p tcp -i $EXT_IFACE -o $INT_IFACE -d $SSH_HOST
>> --dport $SSH_PORT --sport 1024:65535 -m state --state NEW -j ACCEPT
In the FORWARD chain the destination port has already been changed by
the DNAT rule just like the destination address, so this rule must match
on destination port 22, not on the original destination port.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: SSH Port Forwarding with iptables
2009-10-01 10:37 ` Pascal Hambourg
@ 2009-10-01 15:24 ` Bill Hendrickson
2009-10-01 22:07 ` Pascal Hambourg
2009-10-01 16:26 ` Gáspár Lajos
1 sibling, 1 reply; 10+ messages in thread
From: Bill Hendrickson @ 2009-10-01 15:24 UTC (permalink / raw)
To: Pascal Hambourg; +Cc: netfilter list
Hi Pascal,
> Because MASQUERADE replaces the original source address (which the SSH
> server cannot reach due to a missing default or subnet route) with the
> address of the output interface eth1 (which the SSH server can reach).
>
> You don't need SNAT nor masquerade. It hides the real source address
> from the server. You just need to add a proper route on the server so it
> knows how to reach the client address via the router.
Yes, I really should have remembered the default gateway - that's
bitten me before.
> Besides, the SNAT rule proposed by Gaspar could not help because it
> works on the external interface, while the missing route on the server
> requires SNAT/MASQUERADE on the internal interface.
I'll remove that rule and try it out next chance I get - people are
already using the connection.
>>> $IPT -A OUTPUT -o $EXT_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
>>> $IPT -A OUTPUT -o $INT_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
>
> You don't need all the ACCEPT rules when the default policies are ACCEPT
> and there are no DROP/REJECT rules.
yeah, I set those default ACCEPT policies when I was trouble-shooting,
i need to remove them...
>>> $IPT -t nat -A PREROUTING -p tcp -i $EXT_IFACE -d $EXT_IP --dport
>>> $SSH_PORT --sport 1024:65535 -j DNAT --to $SSH_HOST:22
>>> $IPT -A FORWARD -p tcp -i $EXT_IFACE -o $INT_IFACE -d $SSH_HOST
>>> --dport $SSH_PORT --sport 1024:65535 -m state --state NEW -j ACCEPT
>
> In the FORWARD chain the destination port has already been changed by
> the DNAT rule just like the destination address, so this rule must match
> on destination port 22, not on the original destination port.
>
So you're saying it needs to be this?
$IPT -A FORWARD -p tcp -i $EXT_IFACE -o $INT_IFACE -d $SSH_HOST
--dport 22 --sport 1024:65535 -m state --state NEW -j ACCEPT
For now, I've actually got it like this (which is working, but I
should lock it down):
-A FORWARD -p tcp -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
thx,
-bill
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: SSH Port Forwarding with iptables
2009-10-01 10:37 ` Pascal Hambourg
2009-10-01 15:24 ` Bill Hendrickson
@ 2009-10-01 16:26 ` Gáspár Lajos
1 sibling, 0 replies; 10+ messages in thread
From: Gáspár Lajos @ 2009-10-01 16:26 UTC (permalink / raw)
To: Pascal Hambourg; +Cc: Bill Hendrickson, netfilter list
Hi!
Pascal Hambourg írta:
> You don't need SNAT nor masquerade. It hides the real source address
> from the server. You just need to add a proper route on the server so it
> knows how to reach the client address via the router.
>
> Besides, the SNAT rule proposed by Gaspar could not help because it
> works on the external interface, while the missing route on the server
> requires SNAT/MASQUERADE on the internal interface.
>
After reading back the whole conversation I found out that you are right! :D
I just thought that we have here an usual "gateway/firewall" scenario.
So you really only need SNAT/MASQUERADE on any interface (mostly on the
internet side) if your connected network (internet) does NOT knows
anything about the other side of your gateway (your LAN).
Swifty
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: SSH Port Forwarding with iptables
2009-10-01 15:24 ` Bill Hendrickson
@ 2009-10-01 22:07 ` Pascal Hambourg
0 siblings, 0 replies; 10+ messages in thread
From: Pascal Hambourg @ 2009-10-01 22:07 UTC (permalink / raw)
To: Bill Hendrickson; +Cc: netfilter list
Bill Hendrickson a écrit :
>> In the FORWARD chain the destination port has already been changed by
>> the DNAT rule just like the destination address, so this rule must match
>> on destination port 22, not on the original destination port.
>
> So you're saying it needs to be this?
>
> $IPT -A FORWARD -p tcp -i $EXT_IFACE -o $INT_IFACE -d $SSH_HOST
> --dport 22 --sport 1024:65535 -m state --state NEW -j ACCEPT
Correct.
> For now, I've actually got it like this (which is working, but I
> should lock it down):
>
> -A FORWARD -p tcp -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
This is much too permissive, it allows any connection through the router.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2009-10-01 22:07 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-29 15:16 SSH Port Forwarding with iptables Bill Hendrickson
2009-09-29 16:14 ` Bill Hendrickson
2009-10-01 10:37 ` Pascal Hambourg
2009-10-01 15:24 ` Bill Hendrickson
2009-10-01 22:07 ` Pascal Hambourg
2009-10-01 16:26 ` Gáspár Lajos
2009-09-29 16:16 ` Gáspár Lajos
2009-09-29 16:41 ` Bill Hendrickson
2009-09-29 17:00 ` Gáspár Lajos
2009-09-29 17:12 ` Bill Hendrickson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.