Find the answer to your Linux question:
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 11
I am in the process of setting up my own Linux gateway/firewall using two nics eth0(external network) and eth1(internal network). The Linux gateway hands out ip addresses using dhcp3-server, and ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jul 2009
    Location
    Nebraska
    Posts
    24

    Can't access websites from internal network...


    I am in the process of setting up my own Linux gateway/firewall using two nics eth0(external network) and eth1(internal network). The Linux gateway hands out ip addresses using dhcp3-server, and uses iptables to route the traffic correctly. Clients are able to connect and access the internet...everything is working great, HOWEVER I can't access my apache virtual hosts websites from the internal network? They work just fine if i access them from the outside network...

    I can type ip of the web server, 192.168.0.201 and it shows the first virtual host listed in my /sites-enables/000-default folder,but none of my NameServers work. I don't have any internal DNS servers running. This doesn't makes sense, because if i replace the linux firewall/router with my normal linksys wrt54G router it works just fine.

    Here is my IPTABLES script:
    NOTE: my web server is running on 8080

    Code:
    #!/bin/bash
    
    IPT=/sbin/iptables
    
    #flush rules
    $IPT -F
    $IPT -X
    $IPT -F -t nat
    
    #default policies and define chains
    $IPT -P OUTPUT ACCEPT
    $IPT -P INPUT DROP
    $IPT -P FORWARD DROP
    
    #allow established connections
    $IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    
    #accept all connections on lo and Lan
    $IPT -A INPUT -i lo -j ACCEPT
    $IPT -A INPUT -i eth1 -j ACCEPT
    
    #external access
    #$IPT -A INPUT -p tcp --dport 22 -j ACCEPT
    
    #squid
    #$IPT -t nat -A POSTROUTING -i eth1 -p tcp -d ! 192.168.0.0/24 --dport 80 -j DNA                                                                             T --to 192.168.0.1:3128
    
    #allow only certain icmp
    
    #0 => echo reply
    $IPT -A INPUT -p icmp --icmp-type 0 -j ACCEPT
    
    #3 => Destination Unreachable
    $IPT -A INPUT -p icmp --icmp-type 3 -j ACCEPT
    
    #11 => Time Exceeded
    $IPT -A INPUT -p icmp --icmp-type 11 -j ACCEPT
    
    #8 => Echo
    #avoid ping flood
    $IPT -A INPUT -p icmp --icmp-type 8 -m limit --limit 1/second -j ACCEPT
    
    #port forwards
    $IPT -A PREROUTING -t nat -i eth0 -p tcp --dport 2020 -j DNAT --to 192.168.0.201                                                                             :2020
    $IPT -A FORWARD -p tcp -d 192.168.0.201 --dport 2020 -j ACCEPT
    $IPT -A PREROUTING -t nat -i eth0 -p tcp --dport 8080 -j DNAT --to 192.168.0.201                                                                             :8080
    $IPT -A FORWARD -p tcp -d 192.168.0.201 --dport 8080 -j ACCEPT
    
    
    #masquerade internal address as extenal IP, drop invailid connections, allow unr                                                                             estriced outbout access
    $IPT -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    $IPT -A FORWARD -i eth1 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
    $IPT -A FORWARD -i eth0 -o eth1 -m state --state NEW,ESTABLISHED,RELATED -j ACCE                                                                             PT
    $IPT -A FORWARD -i eth0 -m state --state NEW,INVALID -j DROP
    
    exit 0

  2. #2
    Linux Engineer Kloschüssel's Avatar
    Join Date
    Oct 2005
    Location
    Italy
    Posts
    773
    without looking at your iptable rules, this scenario is a common routing problem. If you want to access a linux box / router using an external IP address it will most likely be automatically accepted by the lan interface while "moving outwards" and not routed outside and then accepted by the wan interface. This way it will circumvent the linux box / router firewall rules as you probably have them only on the inbound (wan) interface and not on the outbound (lan).

    I, for instance, was always too lazy to set these things up in the firewall as I know how to access my devices in the internal network (local hostname and not the public hostname; i.e. if a servers name is "fuh" within the network "lan", I can access it using "http://fuh" or "http://fuh.lan" locally, but from remote I may access it through dyndns "http://this-is-fuh.ath.cx"). Specially for dynamic things you cannot configure this thing properly cause your ip address changes and thus you would have to refresh the firewall rules from time to time.

    The most easy thing to settle this is to configure the dns server / router to be the authorative dns server that resolves the dns request for your remote hostname (i.e. "http://this-is-fuh.ath.cx" in the above example) to a local ip instead of the public ip. Thus it will never be routed and you don't run into firewall problems.

    BUT on the backside of the coin you'll never know if your public hostname really resolves to your IP and you'll never be able to test service functionality, neither if all firewall rules like port forwarding work properly. So you'll just have to rely that everything is fine for the rest of the world unless you have a device outside that you can access and from which you can run tests.
    Last edited by Kloschüssel; 08-30-2010 at 07:27 AM.

  3. #3
    Just Joined!
    Join Date
    Jul 2009
    Location
    Nebraska
    Posts
    24
    Quote Originally Posted by Kloschüssel View Post
    without looking at your iptable rules, this scenario is a common routing problem. If you want to access a linux box / router using an external IP address it will most likely be automatically accepted by the lan interface while "moving outwards" and not routed outside and then accepted by the wan interface. This way it will circumvent the linux box / router firewall rules as you probably have them only on the inbound (wan) interface and not on the outbound (lan).

    I, for instance, was always too lazy to set these things up in the firewall as I know how to access my devices in the internal network (local hostname and not the public hostname; i.e. if a servers name is "fuh" within the network "lan", I can access it using "http://fuh" or "http://fuh.lan" locally, but from remote I may access it through dyndns "http://this-is-fuh.ath.cx"). Specially for dynamic things you cannot configure this thing properly cause your ip address changes and thus you would have to refresh the firewall rules from time to time.

    The most easy thing to settle this is to configure the dns server / router to be the authorative dns server that resolves the dns request for your remote hostname (i.e. "http://this-is-fuh.ath.cx" in the above example) to a local ip instead of the public ip. Thus it will never be routed and you don't run into firewall problems.

    BUT on the backside of the coin you'll never know if your public hostname really resolves to your IP and you'll never be able to test service functionality, neither if all firewall rules like port forwarding work properly. So you'll just have to rely that everything is fine for the rest of the world unless you have a device outside that you can access and from which you can run tests.
    Thanks for the reply. I finally got things working with a couple IPTABLES rules. The only downside is (like you said), that if my dynamic ip changes I will have to manually change that. However, this isn't a big deal since it only affects the traffic within my LAN. Here is what I did:

    Code:
    #Hairpin NAT for http and ssh (will have to change this if ISP IP address changes)
    $IPT -A PREROUTING -t nat -d ip.of.eth0.here -p tcp --dport 8080 -j DNAT --to 192.168.0.201:8080
    $IPT -t nat -A POSTROUTING -s 192.168.0.0/24 -p tcp --dport 8080 -d 192.168.0.201 -j MASQUERADE
    $IPT -A PREROUTING -t nat -d ip.of.eth0.here -p tcp --dport 2020 -j DNAT --to 192.168.0.201:2020
    $IPT -t nat -A POSTROUTING -s 192.168.0.0/24 -p tcp --dport 2020 -d 192.168.0.201 -j MASQUERADE
    Thanks again!

  4. $spacer_open
    $spacer_close
  5. #4
    Linux Newbie
    Join Date
    Apr 2007
    Posts
    119
    Quote Originally Posted by dschuett View Post
    ...that if my dynamic ip changes I will have to manually change that. ...
    I had this issue also and all I did was to add a portion into the script to pull the ipaddress from the interface information and then use that address for the firewall rules.

  6. #5
    Just Joined!
    Join Date
    Jul 2009
    Location
    Nebraska
    Posts
    24
    Quote Originally Posted by markcole View Post
    I had this issue also and all I did was to add a portion into the script to pull the ipaddress from the interface information and then use that address for the firewall rules.
    That had crossed my mind, but I wouldn't even know where to start. I'm not much of a scripting guy outside of the basics. That would be sweet if you could share your script...if you're ok with that. Either way, I appreciate your help!

  7. #6
    Linux Newbie
    Join Date
    Apr 2007
    Posts
    119
    Quote Originally Posted by dschuett View Post
    That had crossed my mind, but I wouldn't even know where to start. I'm not much of a scripting guy outside of the basics. That would be sweet if you could share your script...if you're ok with that. Either way, I appreciate your help!
    It has been a while, let me see if I can dig it up.

  8. #7
    Just Joined!
    Join Date
    Jul 2009
    Location
    Nebraska
    Posts
    24
    Quote Originally Posted by markcole View Post
    It has been a while, let me see if I can dig it up.
    Hey, just trying to help you out, I found this perl script that works great. I can run it manually and it prints my ip in the terminal. My question now is how would i use a cron job to inject that into my iptables script.

    here is the script:

    Code:
    #!/usr/bin/perl
    
    $net = `/sbin/ifconfig | grep 'eth0'`;
    if (length($net))
    {
    	$net = `/sbin/ifconfig eth0 | grep 'inet addr'`;
    	if (!length($net))
    	{
    	   $net = `/sbin/ifconfig eth0 | grep 'inet end.'`;
    	}
    	if (length($net))
    	{
    	   chop($net);
    	   @netip = split/:/,$net;
    	   $netip[1] =~ /(\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3})/;
    	   $ip = $1 .".". $2 .".". $3 .".". $4;
    	   print "". $ip ."\n";
    	}
    	else
    	{
    	   print "Not Found\n";
    	}
    }
    else
    {
       print "Error\n";
    }
    And once again here is the iptable rules that are needing the dynamic IP:

    Code:
    #Hairpin NAT for http and ssh (will have to change this if ISP IP address changes)
    $IPT -A PREROUTING -t nat -d ip.of.eth0.here -p tcp --dport 8080 -j DNAT --to 192.168.0.201:8080
    $IPT -t nat -A POSTROUTING -s 192.168.0.0/24 -p tcp --dport 8080 -d 192.168.0.201 -j MASQUERADE
    $IPT -A PREROUTING -t nat -d ip.of.eth0.here -p tcp --dport 2020 -j DNAT --to 192.168.0.201:2020
    $IPT -t nat -A POSTROUTING -s 192.168.0.0/24 -p tcp --dport 2020 -d 192.168.0.201 -j MASQUERADE
    Thanks again!

  9. #8
    Just Joined!
    Join Date
    Jul 2009
    Location
    Nebraska
    Posts
    24
    i found that this shell script works as well to output the ip, but still not sure how to get it into my iptables :P

    Code:
    #!/bin/bash
    
    /sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'

  10. #9
    Linux Engineer Kloschüssel's Avatar
    Join Date
    Oct 2005
    Location
    Italy
    Posts
    773
    You have two options:

    1] reload the complete iptables (easier ==> /etc/init.d/iptables reload)
    2] remove the old rules and add the new ones with the correct ip

    downsides:
    1.1] downtimes (even small, but there are downtimes)
    1.2] you loose all statistics stored in iptables (i.e. packet counts)
    1.3] regular calculation overhead (cpu time) for nothing (but can be ignored)

    2.1] complicated to achieve
    2.2] even here calculation overhead (cpu time) for nothing

    x.y] in both cases you have a estimated downtime window between one check and the other. i.e. if you check every 15 minutes if the ip changed, then it possibly changes right after a check at 15min + t (t => 0) and you only check again in 15 minutes. Thus during these 15 minutes your service is down.

    This is why I would recommend a DNS solution. I for instance run a whiterussian router that provides dhcp leases to the network and thus publishes himself as dns server. Hence he is the authority to decide dns name resolution and as such he can surrogate all network clients that a hostname may be on different IPs. One point to configure, all time works, no need to maintain until you change the domain name.

  11. #10
    Just Joined!
    Join Date
    Jul 2009
    Location
    Nebraska
    Posts
    24
    Thanks again for all your suggestions. I know I really need to get DNS running. I have never set up DNS before...but I know there is a lot of tutorials out there. Here is what i have working right now. It will ONLY restart the firewall IF the ip address changes.

    IPTABLE RULES:

    WANIF="eth0"
    WANIP="`/sbin/ifconfig $WANIF | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`"

    #Hairpin NAT for http and ssh (auto updated with /root/jobs/CheckIP.sh)
    $IPT -A PREROUTING -t nat -d $WANIP -p tcp --dport 8080 -j DNAT --to 192.168.0.201:8080
    $IPT -t nat -A POSTROUTING -s 192.168.0.0/24 -p tcp --dport 8080 -d 192.168.0.201 -j MASQUERADE
    $IPT -A PREROUTING -t nat -d $WANIP -p tcp --dport 2020 -j DNAT --to 192.168.0.201:2020
    $IPT -t nat -A POSTROUTING -s 192.168.0.0/24 -p tcp --dport 2020 -d 192.168.0.201 -j MASQUERADE

    CRON JOB THAT RUNS THIS SCRIPT at 4:00 AM EVERY DAY (its not necessary to run more frequent than that, because all this is doing is making the site available within the LAN, it will ALWAYS work outside the LAN as I use ddclient to keep DynDns.com updated):

    #!/bin/bash

    IPFILE=/root/jobs/ipaddress

    CURRENT_IP=$(wget -q -O - http://www.whatismyip.com/automation/n09230945.asp)


    if [ -f $IPFILE ]; then
    KNOWN_IP=$(cat $IPFILE)
    else
    KNOWN_IP=
    fi

    if [ "$CURRENT_IP" != "$KNOWN_IP" ]; then
    echo $CURRENT_IP > $IPFILE

    /etc/init.d/firewall restart >/dev/null 2>&1

    echo "Your IP Address has been changed FROM $KNOWN_IP TO $CURRENT_IP. Firewall has also been succesffully updated." | ssmtp -f myemail@domain.com -F Gateway myemail@domain.com
    fi

Page 1 of 2 1 2 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •