Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Ok, i'm still working on creating a dmz'd http server

So now I have an ethernet tunnel using ssh -w 0:0 and I have interfaces on each end which can talk to each other:

previous question


So now I'm grappling with getting this http server to be visible to the outside net. Here is the complete setup

So I create a new ec2 instance and I run the setup:

source ./HOST

scp -i green.pem server/* root@$HOST:
ssh -i green.pem root@$HOST ./setup

it in turns runs the setup on the remote machine:

apt-get update
apt-get install telnet

echo 1 | tee /proc/sys/net/ipv4/ip_forward
echo "PermitTunnel yes" >> /etc/ssh/sshd_config
/etc/init.d/ssh restart

then I initiate the ssh connection:

sudo ./runserver $HOST:

HOST=$1
ssh -i green.pem root@$HOST -w 0:0 -o Tunnel=ethernet -o ServerAliveInterval=60

then inside of that ssh term I start routing the iptables forwarding:

#####
# server routing
# bring up the tap
ifconfig tap0 up
# route all traffic for 192.168.2.* through it
ip route add 192.168.2.0/24 dev tap0

#####
# server iptables
REMOTE_INTERNAL_IP=$1

iptables -F
iptables -t nat -F

### end init firewall .. Start DMZ stuff ####
# forward traffic between DMZ and LAN
iptables -A FORWARD -i eth0 -o tap0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i tap0 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

# Route incoming port to DMZ server 192.168.2.1
iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 8000 -j DNAT --to-destination 192.168.2.1:8000
iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to $REMOTE_INTERNAL_IP
### End DMZ .. Add other rules ###

finally on the client i add the routes and port forwarding


##########
# client
HOST=$1

# bring up the tap
ifconfig tap0 up
# put an ip on it so we can listen
ifconfig tap0 192.168.2.1
# add an explicit route for our ssh
ip route add $HOST via 192.168.1.1 dev eth0

# make the tap the default routing
ip route replace default dev tap0
# remove the default link
#ip route del 192.168.2.0/24 dev tap0  proto kernel scope link src 192.168.2.1

and I start the web server

python -m SimpleHTTPServer

when I do a telnet 192.168.2.1 from either server it passes through fine. but if I do a telnet to $THE_REAL_IP it does not work.

if I put a MASQUERADE iptables rule, then it functions fine, but I'm doing to this to avoid MASQUERADE. I want to have the origin IP stay on the packet.


Any ideas what I'm doing wrong?

-----


more information

-----


Ok so now I have tried a whole lot more sets of attempts. And still nothing works.

The one I thought might work would be adding this to the client:

# these should route packets back to tap0
ip rule add from 192.168.2.0/24 table 42
ip route add default dev tap0 table 42

Because this should put a forced rule for everything that is written for 192.168.2.1 should go back through that tap0 interface. But it doesn't work unfortunately.

Also I tried associating an ip with the tap0 on the remote side.

ifconfig tap0 192.168.2.5

And this seems interesting because now I don't need to set up routing, the system seems to do it almost automatically:

#####
# server routing
# bring up the tap
ifconfig tap0 192.168.2.5
ifconfig tap0 up
# route all traffic for 192.168.2.* through it
ip route add 192.168.2.0/24 dev tap0


#####
# server iptables

iptables -F
iptables -t nat -F

# forward traffic between DMZ and LAN
iptables -A FORWARD -i eth0 -o tap0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i tap0 -o eth0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

# Route incoming port to DMZ server 192.168.2.1
iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 8000 -j DNAT --to-destination 192.168.2.1:8000
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

### End Server ####

#############################
#############################

##########
# client
echo 1 | tee /proc/sys/net/ipv4/ip_forward

# bring up the tap
ifconfig tap0 up
# put an ip on it so we can listen
ifconfig tap0 192.168.2.1

# these should route packets back to tap0
# but they actually don't make any difference
#ip rule add from 192.168.2.0/24 table 42
#ip route add default dev tap0 table 42

share|improve this question
    
I am super stuck. If anyone has any clues I would be grateful. Basically I think the packs are getting across, but not coming back. But they should because I have that "ip route replace default" which should send the packets over, and then they should be picked up and forwarded to out eth0 on the remote... no? –  iamacomputer Mar 23 '13 at 21:09
    
Ok I've been researching and researching and I think somehow this: policy based routing is going to com into place.. of course they left out enough information that I will need to research for another hour to even know if it is what I should do.. :-( –  iamacomputer Mar 23 '13 at 21:20
    
ok, so. I've installed this rule set on the local side: ip rule add from 192.168.2.0/24 table 42 and ip route add default dev tap0 table 42 ... they appear to function ... but still the 8000 webserver is not visible from the outside.. which makes me think now that the problem is on the remote end. not the client side. –  iamacomputer Mar 23 '13 at 22:19
add comment

2 Answers

If you use DNAT rather than MASQUERADE then you should keep the source IP address as-is on the incoming packets.

Of course with DNAT, as the source address is not altered, you need to tbe careful to make sure the other end knows to send response packets back the same way - in your case back down the tunnel instead of over the public interface which will be the default gateway.

share|improve this answer
    
yah, I'm doing DNAT.. the problem is the packets aren't coming back :-).. If I stick the MASQUERADE on then the packets come back, but they lose IP information. –  iamacomputer Mar 23 '13 at 21:19
    
I would just like to clarify that I have no idea whether the packets are coming back or not. I'm completely stumped actually. –  iamacomputer Mar 24 '13 at 0:07
add comment

I realise you stated that you want to keep the original IP address hitting your Python server, but you might be taking the wrong approach here. It's standard practice to pass through the original IP address via HTTP in the X-Forwarded-For header. Most web frameworks will pick up this header and use in place of the original IP address if it's specified.

If you wanted to go down that road, all you'd need is a front end web server. It's a good idea to have a front end, anyway: it's more secure because no-one has direct access to your app server, and you can easily implement services like HTTPS and caching without taking more CPU cycles on the app server. Something like Nginx would do the trick beautifully.

share|improve this answer
    
Interesting. I wish I knew about this earlier actually. Although some of what I'm doing is raw tcp (not webserver) I might be able to change this over to websockets. –  iamacomputer Mar 24 '13 at 1:11
    
it turns out I can't convert a key component to webserver/websocket. –  iamacomputer Mar 26 '13 at 10:29
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.