#!/bin/bash -e AP=false DISABLE=false SSID= PASS= CHANNEL=7 REBOOT=false WLAN0_CFG=/etc/network/interfaces.d/wlan0 HOSTAPD_CFG=/etc/hostapd/hostapd.conf DNSMASQ_CFG=/etc/dnsmasq.conf DHCPCD_CFG=/etc/dhcpcd.conf WPA_CFG=/etc/wpa_supplicant/wpa_supplicant.conf function query_config() { if [ -e $WLAN0_CFG ]; then SSID=$(grep wpa-ssid $WLAN0_CFG | sed 's/^[[:space:]]*wpa-ssid "\([^"]*\)"/\1/') echo "{\"ssid\": \"$SSID\", \"mode\": \"client\"}" else if [ -e $HOSTAPD_CFG -a -e /etc/default/hostapd ]; then SSID=$(grep ^ssid= $HOSTAPD_CFG | sed 's/^ssid=\(.*\)$/\1/') CHANNEL=$(grep ^channel= $HOSTAPD_CFG | sed 's/^channel=\(.*\)$/\1/') echo -n "{\"ssid\": \"$SSID\", " echo "\"channel\": $CHANNEL, \"mode\": \"ap\"}" else echo "{\"mode\": \"disabled\"}" fi fi } function disable_wifi() { rm -f $WLAN0_CFG $HOSTAPD_CFG /etc/default/hostapd } function configure_wlan0() { echo "auto wlan0" echo "allow-hotplug wlan0" echo "iface wlan0 inet dhcp" echo " wpa-scan-ssid 1" echo " wpa-ap-scan 1" echo " wpa-key-mgmt WPA-PSK" echo " wpa-proto RSN WPA" echo " wpa-pairwise CCMP TKIP" echo " wpa-group CCMP TKIP" echo " wpa-ssid \"$SSID\"" if [ ${#PASS} -ne 0 ]; then echo " wpa-psk \"$PASS\"" fi } function configure_wpa() { echo "country=US" echo "ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev" echo "update_config=1" if [ ${#PASS} -eq 0 ]; then echo "network={" echo " ssid=\"$SSID\"" echo " key_mgmt=NONE" echo "}" fi } function configure_dhcpcd() { echo "hostname" echo "clientid" echo "persistent" echo "option rapid_commit" echo "option domain_name_servers, domain_name, domain_search, host_name" echo "option classless_static_routes" echo "option ntp_servers" echo "option interface_mtu" echo "require dhcp_server_identifier" echo "slaac private" if $AP; then echo echo "interface wlan0" echo " static ip_address=192.168.43.1/24" fi } function configure_wifi() { disable_wifi echo "source-directory /etc/network/interfaces.d" > /etc/network/interfaces configure_wlan0 > $WLAN0_CFG configure_wpa > $WPA_CFG configure_dhcpcd > $DHCPCD_CFG } function configure_dnsmasq() { echo "interface=wlan0" echo "domain-needed" echo "bogus-priv" echo "dhcp-range=192.168.43.2,192.168.43.20,255.255.255.0,12h" } function configure_hostapd() { echo "interface=wlan0" echo "driver=nl80211" echo "ssid=$SSID" echo "hw_mode=g" echo "channel=$CHANNEL" echo "wmm_enabled=0" echo "macaddr_acl=0" echo "auth_algs=1" echo "ignore_broadcast_ssid=0" echo "wpa=2" echo "wpa_passphrase=$PASS" echo "wpa_key_mgmt=WPA-PSK" echo "wpa_pairwise=TKIP" echo "rsn_pairwise=CCMP" } function is_installed() { dpkg-query -W --showformat='${Status}' $1 | grep "install ok installed" >/dev/null if [ $? -eq 0 ]; then echo true; else echo false; fi } function configure_ap() { disable_wifi # Install packages ( $(is_installed dnsmasq) && $(is_installed hostapd) && $(is_installed iptables-persistent) ) || ( export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install -yq dnsmasq hostapd iptables-persistent ) configure_dhcpcd > $DHCPCD_CFG configure_dnsmasq > $DNSMASQ_CFG configure_hostapd > $HOSTAPD_CFG echo "DAEMON_CONF=\"/etc/hostapd/hostapd.conf\"" > /etc/default/hostapd # Enable IP forwarding sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf echo 1 > /proc/sys/net/ipv4/ip_forward # Enable IP masquerading iptables -t nat -F iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables-save > /etc/iptables/rules.v4 } function usage() { echo "Usage: config-wifi [OPTIONS]" echo echo "Configure wifi as either a client or access point." echo echo "OPTIONS:" echo echo " -a Configure access point." echo " -d Disable wifi." echo " -r Reboot when done." echo " -s Set SSID." echo " -p Set password." echo " -c Set wifi channel." echo " -j Report wifi config as JSON data." echo } # Parse args while [ $# -ne 0 ]; do case "$1" in -a) AP=true ;; -d) DISABLE=true ;; -r) REBOOT=true; ;; -s) SSID="$2"; shift ;; -p) PASS="$2"; shift ;; -c) CHANNEL="$2"; shift ;; -j) query_config; exit 0 ;; -h) usage exit 0 ;; *) usage echo "Unknown argument '$1'" exit 1 esac shift done if $DISABLE; then disable_wifi else # Check args function clean_str() { echo "$1" | tr -d '\n\r"' } SSID=$(clean_str "$SSID") PASS=$(clean_str "$PASS") LANG=C LC_ALL=C # For correct string byte length if [ ${#SSID} -eq 0 -o 32 -lt ${#SSID} ]; then echo "Invalid or missing SSID '$SSID'" exit 1 fi if [ ${#PASS} -ne 0 ]; then if [ ${#PASS} -lt 8 -o 128 -lt ${#PASS} ]; then echo "Invalid passsword" exit 1 fi fi echo "$CHANNEL" | grep '^[0-9]\{1,2\}' > /dev/null if [ $? -ne 0 ]; then echo "Invalid channel '$CHANNEL'" exit 1 fi # Execute if $AP; then echo "Configuring Wifi access point" configure_ap else echo "Configuring Wifi" configure_wifi fi fi if $REBOOT; then nohup reboot & fi