Dev/Host/NetworkSharing

From Embeded Linux (and more) Wiki by Nathael
< Dev‎ | Host
Jump to navigation Jump to search

When developing on embedded systems, you do not always have the ability to connect your target system directly to the Internet. It may be due to a lack of Wifi on the target, while the target is connected by Ethernet to your computer, od because the target is connected to your computer using USB and you are using IP over USB to connect to the board, or maybe just because you do not want to let it connect to the Internet without some safeguards.

Anyway, it's not a problem, you can share your Host system's access with your development target.

We will only focus on IPv4 here.
Some parts will apply for IPv6 with little modifications, and some will not be required, but I've never done it yet so it is out of the scope of this page right now (maybe I'll test and update the page with IPv6 later).

On the host

Add a subnet

If you want your target to be on a specific subnet (and not connected to your gateway) you need to configure your host so it can send trafic on this subnet.
This may already be the case, especially if you can connect to your target using SSH or if your target is using your host as a NFS server, or if you used TFTP to boot your target using images from your host.

If it's not the case, you can add an IPv4 address to your host either on a specific interface (direct connection like USB or cross Ethernet cable), or using an alias on an existing interface. Of course, this interface must be connected to the target, either directly or through a hub, switch, or router. In case of Wifi connection, the interface must be connected to the same ESSID (or be used as access point).
Pick the right command depending on your configuration

ifconfig eth0:0 192.168.SSS.III  # eth0:0 will be an alias of eth0 interface
ifconfig eth1 192.168.SSS.III    # example of direct Ethernet cable connection
ifconfig usb0 192.168.SSS.III    # example of direct USB cable connection
ifconfig wlan0:0 192.168.SSS.III # wlan0:0 will be an alias of wlan0

Note : SSS and III are numbers between 1 and 254. SSS is the subnet number, "shared" by all devices on the subnet and III is specific to each device on the subnet (no two devices can/must have the same on one subnet). Most people use 0 or 1 for the subnet number (SSS) but anything between 0 and 254 will be OK.

You can use "ifconfig" to display all the interfaces configurations (or "ifconfig eth0:0" to display only the configuration of one interface).

Once your host and your target are connected on the same subnet, you can check connectivity between them using "ping".
For example, with subnet number 42, and addresses 11 and 16, you can do :

ping 192.168.42.11

Which should give :

PING 192.168.42.11 (192.168.42.11) 56(84) bytes of data.
64 bytes from 192.168.42.11: icmp_seq=1 ttl=64 time=0.186 ms
64 bytes from 192.168.42.11: icmp_seq=2 ttl=64 time=0.226 ms
64 bytes from 192.168.42.11: icmp_seq=3 ttl=64 time=0.213 ms

Hit "Ctrl+c" to stop it :)

Once your host and target can exchange ping requests and replies, you can move to the next step.
Otherwise, double check your configuration, your cables, or ... well hard to tell you what went wrong from my point of view ...

Note that in order to make this configuration persistent you add your static interface configuration to "/etc/network/interfaces" (example with eth0:0 alias) :

auto eth0:0
iface eth0:0 inet static
   address 192.168.42.16
   netmask 255.255.255.0
   network 192.168.42.0
   broadcast 192.168.42.255

Forwarding activation

You can now activate forwarding on the host.

The easy way is to run the following three commands.

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -P FORWARD ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

This will allow you to test that it's working, but this is "one shot", which means that on next boot of your host, it won't be activated.

In order to make it automatic across reboots (if you want to) you have three solutions.

  • Easy one : Add these lines to "/etc/rc.local" (before the "exit 0") and make sure that "/etc/rc.local" is executable.
  • Second solution : Add these lines to an init script, possibly one with iptables rules which you use to setup your firewall during the boot process. (Refer to your init system documentation if required, or to this page for an iptables script for sysvinit).
  • The third solution uses a part of the second one for the iptables rules, but uses sysctl configuration for the first line :
Open the file "/etc/sysctl.conf" and uncomment the line "net.ipv4.ip_forward=1"
You will also notice the next comment block which is about IPv6 forwarding :)

Note : As you may have noticed, all this implies that "iptables" is installed, but also that your Host kernel has both iptables and IP forwarding (NAT) activated in it's configuration.
This is out of the scope of this page right now, but I'll add a link to a page with some information on how to do it someday, with also a solution to do it using the new "nftables" alternative, as Debian has decided to force it upon it's users, as they did for systemd ....

On the target

Start by giving an address to your target on the same subnet

ifconfig eth0 192.168.SSS.III   # for example 192.168.42.11

Next, select a DNS server. This is done through the "/etc/resolv.conf" file.
Note that some stupid tools spend their time playing with this file, overriding your modifications, so it may be a good idea to set it read-only to everyone.

echo "nameserver 208.67.222.222" > /etc/resolv.conf
chmod 444 /etc/resolv.conf

Of course, you should be able to use the DNS servers of your choice (this is one of OpenDNS ones).
If it's not the case, consider using another access provider as yours has the power to lie to you, giving you false banking website in order to steal your pin code ...

And finally set the gateway for internet access :

route add default gw 192.168.SSS.III

The IP address here must be the one you chose for your host (192.168.42.16 in our example).

You can check that the route has been accepted, and is the only one for outbound trafic directed to unknown networks by issuing the following command :

netstat -rn

The reply should show only one line starting with "0.0.0.0" and with the "G" flag :

Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         192.168.42.16   0.0.0.0         UG        0 0          0 eth0
192.168.42.0    0.0.0.0         255.255.255.0   U         0 0          0 eth0

OK, once again, you can test (ping nathael.net should both give you nathael.net IP but also the ping replies) but this is not persistent.

And once again, you've got many options :

  • Add these lines to "/etc/rc.local"
  • Add your static interface configuration to "/etc/network/interfaces" :
auto eth0
iface eth0 inet static
   address 192.168.42.11
   netmask 255.255.255.0
   network 192.168.42.0
   broadcast 192.168.42.255
   gateway 192.168.42.16
  • Or configure a DHCP server on your Host and run dhclient during startup or add your interface to "/etc/network/interfaces" but with dhcp configuration :
auto eth0
iface eth0 inet dhcp

And you are done !