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)
#
# http://agentoss.wordpress.com / fredo696@gmail.com
#
# thanks to : http://www.aerospacesoftware.com/howtos/Laptop-NAT-Howto.html
#
# 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
About these ads

7 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)

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