Skip to main content
fix: Added missing context
Source Link

Then you just start a web server in the IP 192.168.43.1 and you're done!

python -m http.server 8080 --bind 192.168.43.1

Note that this doesn't do any authentication. The script above only does the traffic redirection. You'll have to implement authentication yourself, probably through nginx, PHP and iptables.

Then you just start a web server in the IP 192.168.43.1 and you're done!

python -m http.server 8080 --bind 192.168.43.1

Note that this doesn't do any authentication. The script above only does the traffic redirection. You'll have to implement authentication yourself, probably through nginx, PHP and iptables.

Source Link

I've made a script that works alongside Irfan Latif's CLI-based AP. I've made some minor modifications to their script, so here's the final result which works in Android 12 (LineageOS 19)(SELinux: Enforcing):

#!/system/bin/sh

# SCRIPT SOURCE: https://android.stackexchange.com/a/215514
# SEE ALSO: https://android.stackexchange.com/a/202335

set -e
#set -x

# this scripts creates a hotspot network

[ "$(id -u)" = 0 ] || { echo 'Not running as root!' >&2; exit 1; }

# Add /vendor/bin/hw to path. That’s where hostapd is in LineageOS 19.0
export PATH=$PATH:/vendor/bin/hw

# check required binaries are on PATH
for bin in iw ip iptables hostapd dnsmasq
do
    ! which $bin >/dev/null || continue
    echo "$bin not found." >&2
    exit 1
done

####################
# define variables #
####################
source /data/data/com.termux/files/home/customAP/config.sh

##########################
# start / stop tethering #
##########################
STOP()
(
    echo 'Cleaning up. Feel free to ignore any errors in this stage..'

    # don't print error messages
    #exec >/dev/null 2>&1

    # hope there are no other instances of same daemons
    pkill -15 hostapd
    # Do not kill wpa_supplicant to avoid WifiSelfRecovery from disabling wifi
    #pkill -15 wpa_supplicant
    pkill -15 dnsmasq
    # remove RPDB rule and iptables rule
    ip rule del lookup main
    iptables -D INPUT -i $AP_INTERFACE -p udp -m udp --dport 67 -j ACCEPT
    # delete AP interface
    #ip link show
    iw dev $AP_INTERFACE del
    #ip link show
    rm -rf $DIR
    echo "Cleanup done."
)

if [ "$1" = stop ]
then
    STOP || true
    exit
elif [ "$1" != start ]
then
    echo 'Usage:' >&2
    printf '\t%s\n' "$(basename "$0") start|stop" >&2
    exit 1
fi

################
# basic checks #
################
if ! iw phy | grep -A10 'Supported interface modes:' | grep -q '\*[ ]*AP'
then
    echo 'AP mode not supported.' >&2
    exit 1
fi

if ! iw dev $WIFI_INTERFACE link | grep -q '^Not connected'
then
    echo 'First disconnect form Wi-Fi.' >&2
    exit 1
fi

##########################
# stop running instances #
##########################
STOP || true

#####################################
# create virtual wireless interface #
#####################################
if ! iw dev $WIFI_INTERFACE interface add $AP_INTERFACE type __ap
then
    echo "Couldn't create AP interface." >&2
    exit 1
fi

#####################################
# configure newly created interface #
#####################################
echo 'Configuring network...'

# activate the interface and add IP
ip link set up dev $AP_INTERFACE
ip addr add ${IP}/24 broadcast ${SUBNET}.255 dev $AP_INTERFACE

# Android doesn't look up into main table by default
ip rule add lookup main

#######################
# access point daemon #
#######################
# create configuration file
mkdir -p "$DIR"
cat <<-EOF >$DIR/hostapd.conf

logger_syslog=1
logger_syslog_level=0

logger_stdout=-1
logger_stdout_level=0

country_code=AR

# network name
ssid=$SSID
# passphrase to use for protected access
wpa_passphrase=$PASSCODE

# network interface to listen on
interface=$AP_INTERFACE
# wi-fi driver
driver=nl80211

# set operation mode, 'g' for 2.4GHz band
hw_mode=g
# WLAN frequency channel to use
channel=9

#Win10 compatibility stuff
ieee8021x=0
eap_server=0
ignore_broadcast_ssid=0

# Security
wpa=2
# key management protocol; use pre-share key
wpa_key_mgmt=WPA-PSK

#Win10 compatibility stuff
wpa_pairwise=TKIP
rsn_pairwise=CCMP

EOF

#Show condiguration
#echo '========================================='
#echo 'Using this hostapd.conf configuration file:'
#cat $DIR/hostapd.conf
#echo '========================================='

echo 'Starting hostapd...'
hostapd -B $DIR/hostapd.conf

################################################
# run a dhcp server to assign IP's dynamically #
################################################
# create configuration file
cat <<-EOF >$DIR/dnsmasq.conf
    # we dont want DNS server, only DHCP
    port=0

    # nameservers to be sent to clients
    dhcp-option=6,1.1.1.1,1.0.0.1

    # range of IPs to make available to wlan devices and when to renew IP
    dhcp-range=$IP,${SUBNET}.254,24h
    # where to save leases
    dhcp-leasefile=$DIR/dnsmasq.leases

    # respond to requests from a different IP broadcast subnet
    dhcp-authoritative
    # don't look for any hosts file and resolv file
    no-hosts
    no-resolv

EOF

# open listening port
iptables -I INPUT -i $AP_INTERFACE -p udp -m udp --dport 67 -j ACCEPT

#echo "dnsmasq config:"
#cat $DIR/dnsmasq.conf

echo 'Starting DHCP server...'
dnsmasq --pid-file -C $DIR/dnsmasq.conf </dev/null

echo "All Done!"

If you're having issues with the AP starting up feel free to uncomment some of my left-over debugging commands.

Also note that most times it takes a couple of minutes (2mins) until Windows 10 actually detects the AP and allows you to connect to it.

For more information about that script, checkout the links at the beginning.

The contents of config.sh:

SSID=MyAP                           # set this to your desired string (avoid spaces and non-ascii characters)
PASSCODE=foobarfoobar               # set this to your desired string (8 to 63 characters)
WIFI_INTERFACE=wlan0                # set this according to your device (check with 'lshw' or 'ip link show')
AP_INTERFACE=${WIFI_INTERFACE}-AP
#AP_INTERFACE=p2p0
DIR=/data/local/tmp/$AP_INTERFACE
SUBNET=192.168.43
IP=${SUBNET}.1

Now, this is the script I made. Run it as root to enable the traffic redirection. Note that running it with "sudo" doesn't work.

# ./captive_portal.sh start
#!/system/bin/sh

source /data/data/com.termux/files/home/customAP/config.sh

# IP the traffic will be redirected to
REDIRECT_IP=192.168.43.1

STOP()(
echo "Stopping dnsmasq..."
pkill -15 dnsmasq

echo "Restoring previous dnsmasq config..."
mv $DIR/dnsmasq.conf.bak $DIR/dnsmasq.conf

echo "Removing phishing redirect iptables rules..."
iptables -t nat -D PREROUTING -i wlan0-AP -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -D PREROUTING -i wlan0-AP -p udp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -D PREROUTING -i wlan0-AP -p tcp -j DNAT --to-destination $REDIRECT_IP

echo "Starting dnsmasq..."
dnsmasq --pid-file -C $DIR/dnsmasq.conf </dev/null

echo "Done."
)

if [ "$1" = "stop" ]
then
    STOP || true
    exit
elif [ "$1" != "start" ]
then
    echo 'Usage:' >&2
    printf '\t%s\n' "$(basename "$0") start|stop" >&2
    exit 1
fi

echo "Stopping dnsmasq..."
pkill -15 dnsmasq

echo "Setting up iptables rules..."
iptables -t nat -A PREROUTING -i wlan0-AP -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A PREROUTING -i wlan0-AP -p udp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A PREROUTING -i wlan0-AP -p tcp -j DNAT --to-destination $REDIRECT_IP

# Backup the dnsmasq config
cp $DIR/dnsmasq.conf $DIR/dnsmasq.conf.bak

# Overwrite the config
rm  $DIR/dnsmasq.conf
cat <<-EOF >$DIR/dnsmasq.conf

    # nameservers to be sent to clients
    dhcp-option=6,$IP,$IP

    # range of IPs to make available to wlan devices and when to renew IP
    dhcp-range=$IP,${SUBNET}.254,24h
    # where to save leases
    dhcp-leasefile=$DIR/dnsmasq.leases

    # respond to requests from a different IP broadcast subnet
    dhcp-authoritative
    # don't look for any hosts file and resolv file
    no-hosts
    no-resolv

    # Reply to all queries with my IP
    address=/#/$REDIRECT_IP

EOF

echo "Starting dnsmasq..."
dnsmasq --pid-file -C $DIR/dnsmasq.conf </dev/null

echo "Done."