Linux – IP forwarding from one interface to another on Debian 7

debianhostapdiptableslinuxnetworking

Background

The Debian 7 that I run has the following interfaces

wlan3 == Internet connection  85.5.48.64/24
wlan2 == act as an AP (hostapd) 192.168.5.1/24

I run the following settings on the terminal

sudo iptables -t nat -A POSTROUTING -o wlan3 -j MASQUERADE
sudo iptables -A FORWARD -i wlan3 -o wlan2 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i wlan2 -o wlan3 -j ACCEPT

Problem

But, wlan2 interface cannot access to the Internet.

root@arm:/etc# ping -I wlan2 google.com
PING google.com (173.194.34.78) from 192.168.5.1 wlan2: 56(84) bytes of data.
From 192.168.5.1 icmp_seq=1 Destination Host Unreachable
From 192.168.5.1 icmp_seq=2 Destination Host Unreachable
From 192.168.5.1 icmp_seq=3 Destination Host Unreachable

Can anyone tell me what is the problem and how I can solve it?

Related settings and outputs

root@arm:/etc# uname -a
Linux arm 3.14.4-armv7-x6 #1 SMP Tue May 20 15:29:16 CEST 2014 armv7l GNU/Linux

root@arm:/etc# sysctl -p
net.ipv4.tcp_syncookies = 1
net.ipv4.ip_forward = 1
net.ipv4.conf.eth0.rp_filter = 0
sysctl: cannot stat /proc/sys/net/ipv4/conf/eth1/rp_filter: No such file or directory
net.ipv4.conf.lo.rp_filter = 0

root@arm:/etc# ip route
default via 85.5.48.1 dev wlan3 
85.5.48.0/24 dev wlan3  proto kernel  scope link  src 85.5.48.110 
192.168.5.0/24 dev wlan2  proto kernel  scope link  src 192.168.5.1 

root@arm:/etc# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         supercore.backb 0.0.0.0         UG    0      0        0 wlan3
85.5.48.0       *               255.255.255.0   U     0      0        0 wlan3
192.168.5.0     *               255.255.255.0   U     0      0        0 wlan2

root@arm:/etc# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination  

 root@arm:/etc# cat /etc/network/interfaces 
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback

auto wlan2
iface wlan2 inet static
    address 192.168.5.1
    network 192.168.5.0
    netmask 255.255.255.0

auto wlan3

root@arm:/etc# iptables-save
# Generated by iptables-save v1.4.14 on Wed Jun  4 08:39:05 2014
*nat
:PREROUTING ACCEPT [2634:425297]
:INPUT ACCEPT [1992:263181]
:OUTPUT ACCEPT [7:488]
:POSTROUTING ACCEPT [1:84]
-A POSTROUTING -o wlan3 -j MASQUERADE
-A POSTROUTING -o wlan3 -j MASQUERADE
-A POSTROUTING -o wlan3 -j MASQUERADE
COMMIT
# Completed on Wed Jun  4 08:39:05 2014
# Generated by iptables-save v1.4.14 on Wed Jun  4 08:39:05 2014
*filter
:INPUT ACCEPT [4705:642335]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [31:4015]
-A FORWARD -i wlan3 -o wlan2 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i wlan2 -o wlan3 -j ACCEPT
-A FORWARD -i wlan2 -o wlan3 -j ACCEPT
-A FORWARD -i wlan3 -o wlan2 -j ACCEPT
-A FORWARD -i wlan2 -o wlan3 -j ACCEPT
-A FORWARD -i wlan3 -o wlan2 -j ACCEPT
-A FORWARD -i wlan2 -o wlan3 -j ACCEPT
-A FORWARD -i wlan3 -o wlan2 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i wlan2 -o wlan3 -j ACCEPT
-A FORWARD -i wlan3 -o wlan2 -m state --state RELATED,ESTABLISHED -j ACCEPT
COMMIT
# Completed on Wed Jun  4 08:39:05 2014

root@arm:/etc# ifconfig 
br0       Link encap:Ethernet  HWaddr 42:42:30:df:a0:d0  
          inet6 addr: fe80::4042:30ff:fedf:86d0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:106 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:31581 (30.8 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:5 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:560 (560.0 B)  TX bytes:560 (560.0 B)

mon.wlan2 Link encap:UNSPEC  HWaddr 64-01-02-18-03-6B-00-00-00-00-00-00-00-00-00-00  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:24415 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:5163458 (4.9 MiB)  TX bytes:0 (0.0 B)

wlan2     Link encap:Ethernet  HWaddr 64:02:47:a8:24:80  
          inet addr:192.168.5.1  Bcast:192.168.5.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3210 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3236 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:166955 (163.0 KiB)  TX bytes:230200 (224.8 KiB)

wlan3     Link encap:Ethernet  HWaddr 64:02:47:14:18:be  
          inet addr:85.5.64.110  Bcast:85.5.64.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:40520 errors:0 dropped:0 overruns:0 frame:0
          TX packets:218 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:5549564 (5.2 MiB)  TX bytes:27413 (26.7 KiB)

root@arm:/etc# cat /etc/hostapd.conf 
interface=wlan2
driver=nl80211
ssid=test_network
hw_mode=g
channel=1
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
macaddr_acl=0
auth_algs=1
wpa=2
wpa_passphrase=mypassword
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP CCMP
rsn_pairwise=CCMP

root@arm:/etc# cat /etc/dhcp/dhcpd.conf 
option domain-name "mydomain.org";
option domain-name-servers 8.8.8.8, 8.8.4.4;
default-lease-time 600;
max-lease-time 7200;
subnet 192.168.5.0 netmask 255.255.255.0 {
  range 192.168.5.10 192.168.5.20;
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.5.255;
option domain-name-servers 192.168.5.1;
  option routers 192.168.5.1;
option domain-name-servers 8.8.4.4;
}

root@arm:/etc# hostapd -v
hostapd v2.2-devel

Wi-Fi devices use AR9271 chipset and ath9k_htc driver

EDIT:

root@arm:~#  tcpdump -i wlan2 -n icmp
[  569.446472] device wlan2 entered promiscuous mode
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlan2, link-type EN10MB (Ethernet), capture size 65535 bytes
16:54:31.260589 IP 192.168.5.10 > 83.5.146.49: ICMP echo request, id 3867, seq 17, length 64
16:55:54.175933 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 1, length 64
16:55:55.185028 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 2, length 64
16:55:56.192626 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 3, length 64
16:55:57.200836 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 4, length 64
16:55:58.208679 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 5, length 64
16:55:59.216827 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 6, length 64
16:56:00.224792 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 7, length 64
16:56:01.232757 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 8, length 64
16:56:02.241485 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 9, length 64
16:56:03.249084 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 10, length 64
16:56:04.256561 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 11, length 64
16:56:05.264404 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 12, length 64
16:56:06.272613 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 13, length 64
16:56:07.281494 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 14, length 64
16:56:08.288482 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 15, length 64
16:56:09.296661 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 16, length 64
16:56:10.304534 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 17, length 64
^C
18 packets captured
18 packets received by filter
0 packets dropped[  687.418762] device wlan2 left promiscuous mode
 by kernel
root@arm:~#  tcpdump -i wlan3 -n icmp
[  699.226867] device wlan3 entered promiscuous mode
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlan3, link-type EN10MB (Ethernet), capture size 65535 bytes
16:56:22.402374 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 29, length 64
16:56:23.408142 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 30, length 64
16:56:24.416259 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 31, length 64
16:56:25.424743 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 32, length 64
16:56:26.435974 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 33, length 64
16:56:27.439971 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 34, length 64
16:56:28.448028 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 35, length 64
16:56:29.456024 IP 192.168.5.10 > 8.8.8.8: ICMP echo request, id 3945, seq 36, length 64
^C
8 packets captured
8 packets received by filter
0 packets dropped [  706.608520] device wlan3 left promiscuous mode
by kernel
root@arm:~# 

Best Answer

Not really an answer but two hints not fit for the comment format:

  • When you ping like this, the packet does not traverse the FORWARD chain and it goes right through the OUTPUT chain, so you're not really testing the firewall setup FWIW.

    Another problem which might occur due to the same reason (though I'm not really sure) is that since the packet is generated on the local host, not forwarded, masquerading won't apply to it and so it will supposedly be killed by the kernel at the moment the stack would send it through wlan3—because for that network the packet having its source address in a private subnet would be "martian", and sending such packets is explicitly prohibited for routers. Anyway, even if this packet would be sent, it would be killed by the 85.5.48.1 gateway for the same reason.

    To prove or disprove this hypothesis, use tcpdump on the outgoing interface:

    1. Run

      # tcpdump -i wlan3 -n icmp
      
    2. Ping as before and see if you'll see any ICMP echo requests on the wire, and if yes, which addresses they contain in their IP headers.

  • Your firewall setup has the policy for its FORWARD chain set to ACCEPT. If this is OK for your setup, there's no sense to add explicit rules to that chain since everything is allowed anyway.

    On the other hand, you might consider setting that policy to DROP. Most setups have policies for INPUT and FORWARD set to DROP and then allow only explicit kinds of traffic.

    But note that in your case having no rules (with ACCEPT policies) is just okay while you're getting your forwarding working. After that, consider tightening the setup.

Related Question