[wifi-ap] Packets aren't being sent to shared interface

Bug #1854391 reported by Li The G No Lie
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
snappy-hwe-snaps
New
Undecided
Unassigned

Bug Description

I'm trying to use a left-behind wifi-card to create an access point that shares the internet with my router.

# Problem

Wifi doesn't share internet.

# Setup

    router 192.168.178.1 <---provides dhcp
        |
        |
        |---enp24s0 192.168.178.115 (ethnernet interface)
    server
        |---wlp29s0 10.0.60.1 (wlan interface)
        |
        | WiFi: YouAreTooLoud
        |
    client 10.0.60.63

The server is running **Ubuntu 18.04** and is using the [`wifi-ap` snap](https://docs.ubuntu.com/core/en/stacks/network/wifi-ap/docs/) which creates a `hostapd` and `dnsmasq` config.

## Config

**wifi-ap config**

    $ wifi.ap.config get
    debug: false
    dhcp.lease-time: 12h
    dhcp.range-start: 10.0.60.2
    dhcp.range-stop: 10.0.60.199
    disabled: false
    share.disabled: false <----- this should work
    share.network-interface: enp24s0
    wifi.address: 10.0.60.1
    wifi.channel: 6
    wifi.country-code:
    wifi.hostapd-driver: nl80211
    wifi.interface: wlp29s0
    wifi.interface-mode: direct
    wifi.netmask: 255.255.255.0
    wifi.operation-mode: g
    wifi.security: wpa2
    wifi.security-passphrase: TheWallsAreTooThin:(
    wifi.ssid: YouAreTooLoud

## Result

`wifi-ap` uses a script (https://git.launchpad.net/~snappy-hwe-team/snappy-hwe-snaps/+git/wifi-ap/tree/bin/ap.sh#n161) to generate the `hostapd.conf` and create `iptables` rules

**wifi-ap** snippet

    if [ "$SHARE_DISABLED" = "false" ] ; then
            # Enable NAT to forward our network connection
            iptables --table nat --append POSTROUTING --out-interface "$SHARE_NETWORK_INTERFACE" -j MASQUERADE
            iptables --append FORWARD --in-interface $iface -j ACCEPT
            sysctl -w net.ipv4.ip_forward=1
    fi

**generated ip tables rules**

    $ iptables -S
    #....
    -A FORWARD -i wlp29s0 -j ACCEPT
    $ iptables -S -t nat
    # ...
    -A POSTROUTING -o enp24s0 -j MASQUERADE

**routes**

    $ route
    Kernel IP routing table
    Destination Gateway Genmask Flags Metric Ref Use Iface
    default _gateway 0.0.0.0 UG 0 0 0 enp24s0
    10.0.60.0 0.0.0.0 255.255.255.0 U 0 0 0 wlp29s0
    link-local 0.0.0.0 255.255.0.0 U 1000 0 0 enp24s0
    172.16.200.0 0.0.0.0 255.255.255.0 U 0 0 0 br-c9e2758dee42
    172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
    192.168.178.0 0.0.0.0 255.255.255.0 U 0 0 0 enp24s0

Revision history for this message
Li The G No Lie (helpunclejackoff) wrote :
Revision history for this message
Li The G No Lie (helpunclejackoff) wrote :

This patch adds iptables rules to forward packets between the wlan interface and the shared interface. The rules are also removed in the cleanup phase.

It's running on my system right now and works. Clients connecting to the hotspot/access point now have the internet through the shared interface.

Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

@helpunclejackoff thanks for the patch. wifi-ap is able to share a connection with its clients, which is a widely used feature. So I am a bit surprised that it is not working for you, is there anything special about your setup? It looks pretty standard at first sight. Do you want just to share internet connectivity or also to access hosts in the 192.168.178.0 network?

Also, could you explain a bit more why your changes fix the problem?

Revision history for this message
Li The G No Lie (helpunclejackoff) wrote :

@alfonsosanchezbeato

I just want to share internet connectivity.

Maybe the existence of multiple network interfaces makes it necessary to specify which interface the packets have to be forwarded to from the wlan interface.
You could try and reproduce the issue by installing docker which will add its own interfaces.

My patch specifies exactly which interface the packets should be forwarded to e.g
wifi interface: wlan0
shared interface: eth0

--> any connections being forwarded out of wlan0 have to go to eth0
--> any established connections / responses for wlan0 entering eth0 have to go to wlan0

The current rules might be too ambiguous due to the additional interfaces.

Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

@helpunclejackoff I have performed some testing on Ubuntu 18.04, but I did not come into any issues (and I do have lots of interfaces on that machine :-). Also, I have found no evidence of the need for the additional rules you added. Enabling masquerade and making sure packages from the wifi are forwarded should be enough if the default route uses the shared interface, I think.

Is there any other networking configuration that you have in your server? maybe a firewall?

Also, could you share the full output of the 'iptables -S' and 'iptables -S -t nat' when using the old and the new rules?

Revision history for this message
Li The G No Lie (helpunclejackoff) wrote :
Download full text (5.7 KiB)

@alfonsosanchezbeato

> Enabling masquerade and making sure packages from the wifi are forwarded should be enough if the default route uses the shared interface, I think.

I don't know why they aren't enough for me, but the iptables rules I added do actually make sure that the packages are forwarded. As you can see above in the `route` output I posted, my routes should be properly configured.

> Is there any other networking configuration that you have in your server? maybe a firewall?

Not that I'm aware of. UFW is inactive and I got rid of NetworkManager.

/etc/network/interface only has

    # Loopback
    auto lo
    iface lo inet loopback

    # ethernet interface
    auto enp24s0
    iface enp24s0 inet dhcp

Here are the outputs of the other commands you requested

    $ iptables -S
    -P INPUT ACCEPT
    -P FORWARD DROP
    -P OUTPUT ACCEPT
    -N DOCKER
    -N DOCKER-ISOLATION-STAGE-1
    -N DOCKER-ISOLATION-STAGE-2
    -N DOCKER-USER
    -A FORWARD -j DOCKER-USER
    -A FORWARD -j DOCKER-ISOLATION-STAGE-1
    -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    -A FORWARD -o docker0 -j DOCKER
    -A FORWARD -i docker0 ! -o docker0 -j ACCEPT
    -A FORWARD -i docker0 -o docker0 -j ACCEPT
    -A FORWARD -o br-c9e2758dee42 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    -A FORWARD -o br-c9e2758dee42 -j DOCKER
    -A FORWARD -i br-c9e2758dee42 ! -o br-c9e2758dee42 -j ACCEPT
    -A FORWARD -i br-c9e2758dee42 -o br-c9e2758dee42 -j ACCEPT
    -A FORWARD -i wlp29s0 -o enp24s0 -j ACCEPT
    -A FORWARD -i enp24s0 -o wlp29s0 -m state --state RELATED,ESTABLISHED -j ACCEPT
    -A FORWARD -i wlp29s0 -j ACCEPT
    -A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 5800 -j ACCEPT
    -A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
    -A DOCKER-ISOLATION-STAGE-1 -i br-c9e2758dee42 ! -o br-c9e2758dee42 -j DOCKER-ISOLATION-STAGE-2
    -A DOCKER-ISOLATION-STAGE-1 -j RETURN
    -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
    -A DOCKER-ISOLATION-STAGE-2 -o br-c9e2758dee42 -j DROP
    -A DOCKER-ISOLATION-STAGE-2 -j RETURN
    -A DOCKER-USER -j RETURN

    $ iptables -S -t nat
    -P PREROUTING ACCEPT
    -P INPUT ACCEPT
    -P OUTPUT ACCEPT
    -P POSTROUTING ACCEPT
    -N DOCKER
    -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
    -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
    -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
    -A POSTROUTING -s 172.16.200.0/24 ! -o br-c9e2758dee42 -j MASQUERADE
    -A POSTROUTING -o enp24s0 -j MASQUERADE
    -A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 5800 -j MASQUERADE
    -A DOCKER -i docker0 -j RETURN
    -A DOCKER -i br-c9e2758dee42 -j RETURN
    -A DOCKER -d 127.0.0.1/32 ! -i docker0 -p tcp -m tcp --dport 5800 -j DNAT --to-destination 172.17.0.2:5800

    $ ifconfig
    br-c9e2758dee42: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
            inet 172.16.200.1 netmask 255.255.255.0 broadcast 172.16.200.255
            ether 02:42:a8:57:eb:16 txqueuelen 0 (Ethernet)
            RX packets 0 bytes 0 (0.0 B)
            RX errors 0 dropped 0 overrun...

Read more...

Revision history for this message
Li The G No Lie (helpunclejackoff) wrote :

I experienced this issue once again on my raspberry-pi and this patch fixed it once again.

It would be great to have it included so I don't have to enter the iptables rules myself and take care of saving and restoring them.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.