Created
April 28, 2023 12:15
-
-
Save adonistseriotis/798a14557fd38399bfb26ffffff907ef to your computer and use it in GitHub Desktop.
Setup your Raspberry Pi as a Wi-Fi access point
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Helper log function | |
log () { | |
local COLOR='\033[0;32m' # Blue color code | |
case "${2}" in | |
error) COLOR='\033[0;31m';; | |
warning) COLOR='\033[1;33m';; | |
esac | |
local NC='\033[0m' # No color code | |
echo -e "${COLOR}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}" | |
} | |
if ! [ $(cat /etc/os-release 2>/dev/null | grep "Raspbian") ]; then | |
log "Your device is not running Raspbian :(" error | |
exit 1 | |
fi | |
if ! [ $(iw list 2>/dev/null | grep "Supported interface modes" -A 8 | grep AP) ]; then | |
log "Your device does not support being used as an access point :(" error | |
exit 1 | |
fi | |
# Check if the script is being run as root | |
if [ $(id -u) -ne 0 ]; then | |
echo "This script must be run as root. Use sudo." | |
exit 1 | |
fi | |
if [ "$1" = "" ]; then | |
echo "Invalid arguments." | |
echo "Give SSID as 1st parameter" | |
exit 1 | |
fi | |
if [ "$2" = "" ]; then | |
echo "Invalid arguments." | |
echo "Give password as 2nd parameter" | |
exit 1 | |
fi | |
# Install required apt packages | |
installRequiredPackages() { | |
log "Installing required packages..." | |
# Allow non interactive installation of iptables-persistent | |
echo iptables-persistent iptables-persistent/autosave_v4 boolean true | sudo debconf-set-selections | |
echo iptables-persistent iptables-persistent/autosave_v6 boolean true | sudo debconf-set-selections | |
# Install required packages | |
apt install -y dnsmasq hostapd netfilter-persistent iptables-persistent | |
log "Installed!" | |
} | |
uninstallRequiredPackages() { | |
log "Uninstalling required packages..." | |
# Install required packages | |
apt purge -y dnsmasq hostapd netfilter-persistent iptables-persistent | |
log "Uninstalled!" | |
} | |
# hostapd configuration | |
configureHostapd() { | |
log "Configuring hostapd..." | |
test -f /etc/hostapd/hostapd.conf || (touch /etc/hostapd/hostapd.conf && log "Touched /etc/hostapd/hostapd.conf") | |
# tee /etc/hostapd/hostapd.conf > /etc/hostapd/hostapd.conf <<\EOF | |
echo "ctrl_interface=/var/run/hostapd" | tee /etc/hostapd/hostapd.conf > /dev/null | |
echo "driver=nl80211" | tee -a /etc/hostapd/hostapd.conf > /dev/null | |
echo "country_code=IT # Use your country code" | tee -a /etc/hostapd/hostapd.conf > /dev/null | |
echo "ssid=$1" | tee -a /etc/hostapd/hostapd.conf > /dev/null | |
echo "hw_mode=g" | tee -a /etc/hostapd/hostapd.conf > /dev/null | |
echo "channel=7" | tee -a /etc/hostapd/hostapd.conf > /dev/null | |
echo "auth_algs=1" | tee -a /etc/hostapd/hostapd.conf > /dev/null | |
echo "wpa=2" | tee -a /etc/hostapd/hostapd.conf > /dev/null | |
echo "wpa_passphrase=$2" | tee -a /etc/hostapd/hostapd.conf > /dev/null | |
echo "wpa_key_mgmt=WPA-PSK" | tee -a /etc/hostapd/hostapd.conf > /dev/null | |
echo "wpa_pairwise=TKIP" | tee -a /etc/hostapd/hostapd.conf > /dev/null | |
echo "rsn_pairwise=CCMP" | tee -a /etc/hostapd/hostapd.conf > /dev/null | |
echo "ignore_broadcast_ssid=1" | tee -a /etc/hostapd/hostapd.conf > /dev/null | |
# Change conf file permissions | |
chmod 600 /etc/hostapd/hostapd.conf | |
log "Configured hostapd!" | |
} | |
deconfigureHostapd() { | |
log "Deleting conf file /etc/hostapd/hostapd.conf..." | |
test -f /etc/hostapd/hostapd.conf && rm /etc/hostapd/hostapd.conf | |
log "Configured hostapd!" | |
} | |
# Creates the uap service required to host the access point | |
createUAPService() { | |
log "Creating uap service..." | |
test -f /etc/systemd/system/[email protected] || (touch /etc/systemd/system/[email protected] && log "Touched /etc/systemd/system/[email protected] file") | |
# tee /etc/systemd/system/[email protected] > /dev/null <<\EOF | |
echo "[Unit]" | tee /etc/systemd/system/[email protected] > /dev/null | |
echo "Description=IEEE 802.11 %p%i AP on wlan%i with hostapd" | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo "After=network.target" | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo $'\n' | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo "[Service]" | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo "Type=forking" | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo "PIDFile=/run/hostapd.pid" | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo "Restart=on-failure" | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo "RestartSec=2" | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo "Environment=DAEMON_CONF=/etc/hostapd/hostapd.conf" | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo "EnvironmentFile=-/etc/default/hostapd" | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo "ExecStartPre=/sbin/iw dev wlan%i interface add %p%i type __ap" | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo "ExecStart=/usr/sbin/hostapd -i %p%i -P /run/hostapd.pid -B \$DAEMON_OPTS \${DAEMON_CONF}" | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo "ExecStopPost=-/sbin/iw dev %p0 del" | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo $'\n' | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo "[Install]" | tee -a /etc/systemd/system/[email protected] > /dev/null | |
echo "WantedBy=multi-user.target" | tee -a /etc/systemd/system/[email protected] > /dev/null | |
log "Stopping hostapd..." | |
systemctl stop hostapd # if the default hostapd service was active before | |
log "Disabling hostapd..." | |
systemctl disable hostapd # if the default hostapd service was enabled before | |
log "Enabling [email protected]..." | |
systemctl enable [email protected] | |
log "Unblocking wlan..." | |
rfkill unblock wlan | |
log "Created!" | |
} | |
removeUAPService() { | |
log "Stopping [email protected]..." | |
systemctl stop [email protected] | |
log "Disabling [email protected]..." | |
systemctl disable [email protected] | |
log "Removing files..." | |
test -f /etc/systemd/system/[email protected] && rm /etc/systemd/system/[email protected] && log $'\t/etc/systemd/system/[email protected]' | |
test -f /usr/lib/systemd/system/[email protected] && rm /usr/lib/systemd/system/[email protected] && log $'\t/usr/lib/systemd/system/[email protected]' | |
log "Daemon-reloading..." | |
systemctl daemon-reload | |
} | |
setupDhcpcd() { | |
log "Setting up DHCPCD..." | |
# tee -a /etc/dhcpcd.conf > /dev/null <<\EOF | |
# these two lines are not strictly needed, as wlan0 uses the default configuration | |
echo "interface wlan0" | tee -a /etc/dhcpcd.conf > /dev/null | |
echo " dhcp" | tee -a /etc/dhcpcd.conf > /dev/null | |
echo $'\n' | tee -a /etc/dhcpcd.conf > /dev/null | |
# this defines static addressing to uap0 and disables wpa_supplicant for this interface | |
echo "interface uap0 " | tee -a /etc/dhcpcd.conf > /dev/null | |
echo " static ip_address=192.168.50.1/24" | tee -a /etc/dhcpcd.conf > /dev/null | |
echo " ipv4only" | tee -a /etc/dhcpcd.conf > /dev/null | |
echo " nohook wpa_supplicant" | tee -a /etc/dhcpcd.conf > /dev/null | |
log "Set up DHCPCD successful!" | |
} | |
removeDhcpcd() { | |
log "Removing conf lines from /etc/dhcpcd.conf..." | |
test -f /etc/dhcpcd.conf && sed -i '/interface wlan0/,+2d; /interface uap0/,+4d' /etc/dhcpcd.conf | |
log "Removed DHCPCD!" | |
} | |
setupRouting() { | |
log "Setting up routing..." | |
test -f /etc/sysctl.d/routed-ap.conf || (touch /etc/sysctl.d/routed-ap.conf && log "Touched /etc/sysctl.d/routed-ap.conf") | |
# tee /etc/sysctl.d/routed-ap.conf > /dev/null <<\EOF | |
echo "# https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md" | tee /etc/sysctl.d/routed-ap.conf > /dev/null | |
echo "# Enable IPv4 routing" | tee -a /etc/sysctl.d/routed-ap.conf > /dev/null | |
echo "net.ipv4.ip_forward=1" | tee -a /etc/sysctl.d/routed-ap.conf > /dev/null | |
log "Updating firewall rules..." | |
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE | |
sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE | |
sudo iptables -A FORWARD -i wlan0 -o uap0 -m state --state RELATED,ESTABLISHED -j ACCEPT | |
sudo iptables -A FORWARD -i uap0 -o wlan0 -j ACCEPT | |
sudo netfilter-persistent save | |
log "Updated and persisted!" | |
log "Appending to dnsmasq configuration..." | |
# tee -a /etc/dnsmasq.conf >/dev/null <<\EOF | |
echo "# disables dnsmasq reading any other files like /etc/resolv.conf for nameservers" | tee -a /etc/dnsmasq.conf > /dev/null | |
echo "no-resolv" | tee -a /etc/dnsmasq.conf > /dev/null | |
echo $'\n' | tee -a /etc/dnsmasq.conf > /dev/null | |
echo "interface=uap0" | tee -a /etc/dnsmasq.conf > /dev/null | |
echo "no-dhcp-interface=lo,wlan0" | tee -a /etc/dnsmasq.conf > /dev/null | |
echo "domain-needed" | tee -a /etc/dnsmasq.conf > /dev/null | |
echo "bogus-priv" | tee -a /etc/dnsmasq.conf > /dev/null | |
echo "server=8.8.8.8" | tee -a /etc/dnsmasq.conf > /dev/null | |
echo "dhcp-range=192.168.50.50,192.168.50.199,12h" | tee -a /etc/dnsmasq.conf > /dev/null | |
echo "dhcp-option=3,192.168.50.1" | tee -a /etc/dnsmasq.conf > /dev/null | |
log "Set up routing successful!" | |
} | |
removeRouting() { | |
log "Deleting /etc/sysctl.d/routed-ap.conf..." | |
test -f /etc/sysctl.d/routed-ap.conf || rm /etc/sysctl.d/routed-ap.conf | |
log "Deleting forwarding rules..." | |
sudo iptables -D FORWARD -i wlan0 -o uap0 -m state --state RELATED,ESTABLISHED -j ACCEPT || log "Rule 1 non-existent" | |
sudo iptables -D FORWARD -i uap0 -o wlan0 -j ACCEPT || log "Rule 2 non-existent" | |
sudo iptables -t nat -D POSTROUTING -o wlan0 -j MASQUERADE || log "Rule 3 non-existent" | |
sudo iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE || log "Rule 4 non-existent" | |
log "Removing lines added on /etc/dnsmasq.conf..." | |
sed -i '/no-resolv\|interface=uap0\|no-dhcp-interface=lo,wlan0\|domain-needed\|bogus-priv\|server=8.8.8.8\|dhcp-range=192.168.50.50,192.168.50.199,12h\|dhcp-option=3,192.168.50.1/d' /etc/dnsmasq.conf | |
log "Removed routing!" | |
} | |
set -e # Exit if an error occurs | |
while getopts u flag | |
do | |
case "${flag}" in | |
u) uninstall=1;; | |
esac | |
done | |
if [ -z $uninstall ]; then | |
installRequiredPackages | |
configureHostapd | |
createUAPService | |
setupDhcpcd | |
setupRouting | |
else | |
removeRouting | |
removeDhcpcd | |
removeUAPService | |
deconfigureHostapd | |
uninstallRequiredPackages | |
fi | |
log "WARNING:: YOU HAVE TO REBOOT TO SEE THESE ACTIONS TAKE EFFECT" warning |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment