Wifi repeater/range extender script


Updated September 17, 2014 : updated, improved and should be working! (Use at your own risk!). Thanks to AL for pointing errors!

#!/bin/bash
#
# Wireless Repeater/Range extender script
#
# Last changes:
#   - 20/Apr/2014 : added ad filtering (uses an additional hosts file)
#   - 12/Apr/2013 : adapted for Debian (tested under 7.0 Wheezy)
#
# https://agentoss.wordpress.com
#
# thanks to : http://www.aerospacesoftware.com/howtos/Laptop-NAT-Howto.html (link dead now)
#
# hardware requirements : 2 wireless NICs
# software requirements : iptables, wpa_supplicant, hostapd, dnsmasq, dhcpcd (or dhclient)
#
# This is a standalone script, it will not use your existing configuration files
# (wpa_supplicant/hostapd)
#
# Both wireless interfaces will use WPA/WPA2 encryption.
#
# BEFORE STARTING THIS SCRIPT :
# - you must have root rights
# - stop your wireless connection manager (networkmanager, wicd, etc...)
# - disable your firewall
# - disable power management (prevent the computer to go into suspend mode when unused)
#
# This script has been tested on OpenSUSE 12.2, Debian 7.0
# but should work on other Linux systems with minor adaptations.
#
# USE AT YOUR OWN RISK!
#
# TODO : repeater with 1 wireless NIC + 1 ethernet NIC

# this is the wireless interface we use to connect to our existing Access Point
WLAN_STA="wlan0"

# enter here your existing SSID and WPA passphrase
WLAN_STA_SSID="YOUR_EXISTING_SSID"
WLAN_STA_PASSPHRASE="your$existing$passphrase"

# this is the wireless interface we use to create our new AP (the "repeater" AP)
WLAN_AP="wlan1"

# your new AP's SSID (change the name eventually)
WLAN_AP_SSID="REPEAT_$WLAN_STA_SSID"
# Be sure to use different channels for the 2 AP's for best performance
WLAN_AP_CHANNEL=3
WLAN_AP_IP="192.168.9.1"
WLAN_AP_DHCP_RANGE="192.168.9.10,192.168.9.20"
# we can use the same passphrase (or not)
WLAN_AP_PASSPHRASE=$WLAN_STA_PASSPHRASE

# temp files (will contain passphrases in clear text, so make sure they are not world readable)
HOSTAP_TEMP_CONF="/root/hostap_temp.conf"
WPASUPPLICANT_TEMP_CONF="/root/wpasupplicant_temp.conf"

# URL and filename to download for the ad filter hosts file
# Thanks to winhelp2002.mvps.org
# just comment the two variables if you don't want to use ad filtering
HOSTS_FILE="hosts.zip"
HOSTS_URL="http://winhelp2002.mvps.org/$HOSTS_FILE"

# log file for dnsmasq
DNSMASQ_LOG="/root/dnsmasq.log"

# Path for used commands (adapt to your system)
#DHCPCD="/sbin/dhcpcd"
#for Debian we use dhclient (installed by default)
DHCPCD=$(which dhclient)
HOSTAPD=$(which hostapd)
WPASUPPLICANT=$(which wpa_supplicant)
DNSMASQ=$(which dnsmasq)
IPTABLES=$(which iptables)

PIDFILE="/var/run/repeater.pid"
IPTABLES_SAVE_FILE="/root/iptables.save"

USAGE="Usage : `basename $0` \
\n\nWireless repeater/extender script."

MSG_STOP="Repeater has been stopped."

# sub-routines
show_notification()
{
 xmessage -center -timeout $2 "$1"
}

# Main program
if [[ "$#" -ne 1 || "$1" == "help" ]]; then
 # show program help
 echo -e "$USAGE"
 exit 0
fi

# check if we are root
if [ $EUID -ne 0 ]; then
   echo `basename $0` ": this script must be run as root!" 1>&2
   exit 1
fi
# check for software we need
if [ ! -x $DHCPCD ]; then
 echo "FATAL: $DHCPCD not found!"; exit 1
fi
if [ ! -x $HOSTAPD ]; then
 echo "FATAL: $HOSTAPD not found!"; exit 1
fi
if [ ! -x $WPASUPPLICANT ]; then
 echo "FATAL: $WPASUPPLICANT not found!"; exit 1
fi
if [ ! -x $DNSMASQ ]; then
 echo "FATAL: $DNSMASQ not found!"; exit 1
fi
if [ ! -x $IPTABLES ]; then
 echo "FATAL: $IPTABLES not found!"; exit 1
fi
# check for wireless interfaces
ifconfig $WLAN_STA 1>&2>/dev/null
if [[ $? -ne 0 ]]; then
 echo "FATAL: Wireless interface $WLAN_STA unavailable!"; exit 1
fi
ifconfig $WLAN_AP 1>&2>/dev/null
if [[ $? -ne 0 ]]; then
 echo "FATAL: Wireless interface $WLAN_AP unavailable!"; exit 1
fi


# stop the repeater?
if [ "$1" == "stop" ]; then
 # be sure the repeater is already running
 if [ -f "$PIDFILE" ]; then
 # kill existing wireless connections from previous execution of this script
 echo -n -e "Stopping... "
 $DHCPCD -x $WLAN_STA 2>/dev/null
 $DHCPCD -x $WLAN_AP 2>/dev/null
 killall wpa_supplicant 2>/dev/null

 # kill running hostapd daemon if it exists
 killall hostapd 2>/dev/null

 # kill dnsmasq dhcp
 killall dnsmasq 2>/dev/null

 # empty existing temp.conf files, for security
 >$HOSTAP_TEMP_CONF
 >$WPASUPPLICANT_TEMP_CONF

 echo "OK"

 # restore firewall rules
 echo -n -e "Restoring firewall... "
 iptables-restore /dev/null
service wicd stop 2>/dev/null

# create temp wpa_supplicant.conf file for our STA interface
cat >$WPASUPPLICANT_TEMP_CONF <$HOSTAP_TEMP_CONF <"$IPTABLES_SAVE_FILE" && echo "OK"

# enable packet forwarding and add firewall rules to allow forwarding packets
# between our 2 network interfaces.
IF_IN=$WLAN_STA
IF_OUT=$WLAN_AP

sysctl -w net.ipv4.ip_forward=1
$IPTABLES -F
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -t nat -A POSTROUTING -o $IF_IN -j MASQUERADE
$IPTABLES -A FORWARD -i $IF_IN -o $IF_OUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPTABLES -A FORWARD -i $IF_OUT -o $IF_IN -j ACCEPT

# create pid file
echo $$ >"$PIDFILE"

echo -e "\nWireless repeater access point \"$WLAN_AP_SSID\" is *up* and running!\n"
echo -e "To stop it : `basename $0` stop"
show_notification "Wireless repeater access point \"$WLAN_AP_SSID\" is *up* and running!" 3

# optional : open a new xterm which displays the DNS log in realtime
xterm -e "tail -f $DNSMASQ_LOG" &

exit 0
fi

# unknown command, show usage
echo -e "$USAGE"
exit 1

18 thoughts on “Wifi repeater/range extender script

  1. Copy/paste the script into your favorite text editor, adjust some settings (the WLAN_xxx variables), save it as “wifi_extender.sh” and make it executable (chmod +x). Finally run it (as root) :)

  2. How would I adjust the script for Ubuntu? I am trying to use an older PC with two WIFI cards. One with a long range antenna for connecting to a distant WIFI AP. The other WIFI card I would like to use as a Local WIFI AP. This script seems to be what I need but I am unfamiliar with Linux.

    • Hi, did you try to run it already?
      It may need some adjustments for Ubuntu but I’ll have to install a virtual machine to test it on. In the meantime you can try it, just adapt your variables (WLAN_* values at the beginning), stop yout network manager, and start the script as root (sudo su)

  3. Pingback: Wifi repeater/range extender script | Sao Nut

  4. Dang it. Even my reply got mangled. Please disregard my previous posting and hopefully this one (wrapped around some HTML tags) will work better.

    Thank you for the article and instructions, AgentOss.

    I have a few questions:

    1. I think the lines that set up the wpa_supplicant.conf and starts up the wpa_supplicant process got cut out that ended up with the line

    ”cat >$WPASUPPLICANT_TEMP_CONF <$HOSTAP_TEMP_CONF <<EOF"

    , i.e., there must have been something between

    "cat >$WPASUPPLICANT_TEMP_CONF"

    and

    "<$HOSTAP_TEMP_CONF <<EOF"

    ? If so, it’d be great if you can update this article with the complete code.

    2. I worked around it by modifying that line to just become “cat > $HOSTAP_TEMP_CONF <<EOF” and then starting wpa_supplicant manually to have the “wlan0” connect to the AP that I’m trying to repeat. After doing that, I was able to connect to the repeater’s SSID (“REPEAT_MySSID”). From there, I was able to point the browser to the IP of that AP and see the router’s administration page (through its built-in HTTP server). However, the speed is much slower compared to when I connect to that AP’s IP directly (by more than a factor of 10). Any suggestion on what could be the reason?

    3. I found instructions from other sites bridging the network interfaces in hostapd.conf. Is it doing the same thing underneath that the iptables lines towards the end of your script?

    My “wlan0” device is a Ralink RT3070 USB dongle. My “wlan1” device (that becomes the repeater AP) is a Ralink RT5370. The script was run on Debian Wheezy (7.6).

    • Hi AL,

      Thank you for your useful input, yes the script was missing some parts!! (stupid me and ‘code’ tags, now using ‘pre’ tags for better support in wordpress).

      Now fixed & improved (with ad filtering). Just tested it on my Debian 7 laptop with 2 WLAN interfaces. (Sure could still be improved)

      • Just keep your p00p out of my root…

        also

        HOSTAP_TEMP_CONF=”/root/hostap_temp.conf”
        WPASUPPLICANT_TEMP_CONF=”/root/wpasupplicant_temp.conf”

        should go in
        “/etc/hostap/hostap_temp.conf” ???
        /etc/wpa_supplicant/wpasupplicant_temp.conf ???

  5. This is a WirelessWireless AP….. not really a repeater, it’s not repeating anything.

    modemwireless router dhcp1wireless SSID1access point dhcp2wireless SSID2Client/s

    ====

    Repeater would….repeat the hostAP ssid to client/s with host router and repeater point on different subnets, 2 dhcp servers …

    modemwireless router dhcp1wireless SSID1repeater point dhcp2wireless SSID1Client/s

    ====

    Repeater Bridge would….repeat the hostAP ssid to client/s with host router and repeater point on same subnets, hostAP dhcp server…

    modemwireless router dhcp1wireless SSID1repeater Bridge point dhcp1wireless SSID1Client/s

    So you might have noticed, the depictions above are not readily seen on the Internet, thus the mass confusion for most.

    Wouldn’t it be nice to have a script to do all three… using subroutines..!!

    Also (This is a quick & dirty script) >>>> (This is a quick & not so dirty script)

    hth

  6. In the above post of mine a lot of formatting was dissolved from the original writing….wow… makes it hard to read

  7. Hopefully this works…

    This is a WirelessWireless AP….. not really a repeater, it’s not repeating anything.

    modem > wireless router dhcp1 > wireless SSID1 > access point dhcp2 > wireless SSID2 > Client/s
    ====
    Repeater would….repeat the hostAP ssid to client/s with host router and repeater point on different subnets, 2 dhcp servers …

    modem > wireless router dhcp1 > wireless SSID1 > repeater point dhcp2 > wireless SSID1 > Client/s
    ====
    Repeater Bridge would….repeat the hostAP ssid to client/s with host router and repeater point on same subnets, hostAP dhcp server…

    modem > wireless router dhcp1 > wireless SSID1 > repeater Bridge point dhcp1 > wireless SSID1 > Client/s

    So you might have noticed, the depictions above are not readily seen on the Internet, thus the mass confusion for most.

    Wouldn’t it be nice to have a script to do all three… using subroutines..!!

    Also (This is a quick & dirty script) > > > > (This is a quick & not so dirty script)

    hth

    • That’s a good question!

      (I don’t remember if I experienced a “loss of bandwidth” using it. And I don’t use it often right now…)

      It seems that a repeater using 2 different wireless radio devices will be better than only 1 radio (as in cheap repeaters).

      Also, make sure that you use different channels.

      If you have the possibility to test speeds, and compare with a cheap wifi repeater, please let me know!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s