Wednesday 22 February 2017

Setting up wireless bridge with CentOS 7, IPTables and dhcpd

This is useful in specific situations were you need to connect hardware appliances that do not have any means on connecting to a wireless network.

Yes - you can buy specific 'of the shelf' devices to do this - although I refuse to buy any such device since it's actually pretty easy to peform on a normal computer (in my case an Intel NUC.)

I only had a single port on my NIC - so I ended up using a wireless USB dongle.

So - lets firstly install CentOS 7 (minimal) onto the hardware we're going to use - i'll do this via USB boot - so to write the image to the USB we can do something like:

sudo dd if=CentOS-7-x86_64-Minimal-1611.iso of=/dev/sdc; sync

Once we have installed the base OS we'll configure the WiFi - we'll also ensure the kernel has picked up the WiFi adapter:

dmesg | usb

If detected - we should see it with:

nmcli device show

To check the device radio / check for available wireless networks we can issue:

nmcli device wifi list

Let's say that our SSID is 'WirelessNetwork' - in order to connect to it we will use the 'connection add' switch:

nmcli connection add ifname wlp2s0 type wifi ssid WirelessNetwork

to delete a connection - find out what it's been named with:

nmcli connection show

and delete with:

nmcli connection del wifi-wlp2s0

You can also use the 'con-name' switch if you wish to have connections to different wireless network e.g.:

nmcli connection add con-name WirelessNetwork ifname wlp2s0 type wifi ssid WirelessNetwork

We can then add authentication information (in our case we're using a pre-shared key):

nmcli con modify wifi-wlp2s0 wifi-sec.key-mgmt wpa-psk
nmcli con modify wifi-wlp2s0 wifi-sec.psk <password>

Ensure wifi is turned on with:

nmcli radio wifi

and if needed turn it on with:

nmcli radio wifi on

To review our wifi connection in more detail we can issue:

nmcli connection show wifi-wlp2s0

Finally to activate our configuration we should issue:

nmcli connection up wifi-wlp2s0

Running 'nmcli connection' you will notice that it's now green - indicating that you have successfully connected to the network.

Now let's ensure IPTables is installed - refer to my post here for that:

Now - for this tutorial we'll also assume the client device that needs access to the wireless network can't been manually configured with a static IP and hence will require DHCP.

So - we'll configure a DHCP server to run on our ethernet interface (eno1):

sudo ip addr add dev eno1

sudo yum install dhcp

add add something like the following to dhcpd.conf:

vi /etc/dhcp/dhcpd.conf

# name server(s)
option domain-name-servers;

# default lease time
default-lease-time 600;

# max lease time
max-lease-time 7200;

# this DHCP server to be declared valid

# specify network address and subnet mask
subnet netmask {
    # specify the range of lease IP address
    range dynamic-bootp;
    # specify broadcast address
    option broadcast-address;
    # specify default gateway
    option routers;

Enable and start dhcp with:

sudo systemctl enable dhcpd
sudo systemctl start dhcpd

and check the log to ensure that it is up and running / bound to the correct interface (it should automatically pickup which interface to listen on depending on what's defined in dhcpd.conf)

sudo tail -n 30 /var/log/messages | grep dhcpd

Now plug eno1 into a switch and the device in question into a port on the same VLAN - hopefully the device in question should now have picked up an IP in our new scope we defined on the dhcp server. If it hasn't tcpdump is a very useful tool to diagnose dhcp / bootp related problems.

The last step is to setup NAT'ing rules - so lets firstly enable ip forwarding:

echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf

sudo sysctl -p

Flush the IPTable chains:

Set the policy for the filter table chains:

sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT

Flush all tables:
sudo iptables -F -t filter
sudo iptables -F -t nat
sudo iptables -F -t mangle
sudo iptables -F -t raw

Ensure traffic from eno1 is masqueraded - so it will get back to the interface:
iptables -t nat -A POSTROUTING -o wlp2s0 -j MASQUERADE

Allow eno1 to forward traffic to wlp2s0:
iptables -t filter -A FORWARD -i eno1 -o wlp2s0 -j ACCEPT

and the return traffic from wlp2s0 to eno1:
iptables -t filter -A FORWARD -i wlp2s0 -o eno1 -j ACCEPT

and block any other forwarding traffic:
iptables -t filter -A FORWARD -j DROP

Now try and ping a remote host from the internal device - if all goes to plan you should get a response back. If you encounter problems you might want to setup IPTables to log dropped packets to help you diagnose where exactly you are going wrong.

It goes without saying - but the final task is to tighten up the IPTables rules e.g. the INPUT/OUTPUT chains in the filter table.


Post a Comment