Con la ayuda de las respuestas de @ Irfan Latif vinculado en el comentario y aquí y examinando la salida de iptables -L
y iptables -t nat -L
en varios escenarios como Hotspot, BT tethering, USB tethering, etc., me las arreglé para escribir un script que me ayuda a compartir mi conexión de datos móviles a la red Wi-Fi local mediante el uso de una IP estática para el teléfono, y establecerlo como puerta de enlace en el router Wi-Fi o en dispositivos individuales.
Aquí está el script que escribí, se debe ejecutar en un shell Root o mediante el prefijo su -c
:
#!/bin/sh
echo "(Re-)creating iptables NAT and Forward rules..."
for i in 0 1 2 3 4 5 6 7 8 9 10 ; do
iptables -t nat -D POSTROUTING -o rmnet_data$i -j MASQUERADE
iptables -t nat -I POSTROUTING -o rmnet_data$i -j MASQUERADE
iptables -D FORWARD -i rmnet_data$i -o wlan0 -m state --state RELATED,ESTABLISHED
iptables -D FORWARD -i rmnet_data$i -o wlan0 -j ACCEPT
iptables -D FORWARD -i wlan0 -o rmnet_data$i -j ACCEPT
#iptables -D FORWARD -i wlan0 -o rmnet_data$i -m state --state INVALID -j DROP
iptables -I FORWARD -i rmnet_data$i -o wlan0 -m state --state RELATED,ESTABLISHED
iptables -I FORWARD -i rmnet_data$i -o wlan0 -j ACCEPT
iptables -I FORWARD -i wlan0 -o rmnet_data$i -j ACCEPT
#iptables -I FORWARD -i wlan0 -o rmnet_data$i -m state --state INVALID -j DROP
done
echo "Enabling forwarding for wlan and rmnet_data interfaces..."
echo 1 >/proc/sys/net/ipv4/conf/wlan0/forwarding
echo 1 >/proc/sys/net/ipv6/conf/wlan0/forwarding
for i in 0 1 2 3 4 5 6 7 8 9 10 ; do
echo 1 >/proc/sys/net/ipv4/conf/rmnet_data$i/forwarding
echo 1 >/proc/sys/net/ipv6/conf/rmnet_data$i/forwarding
done
echo "Emptying the main route table..."
ip route flush table main
echo "Copying rmnet_data interface routes to main table..."
IFS=$'\n'; for i in $(
ip route show table all |
grep "table rmnet_data" |
grep -v "expires" |
sed -Er 's/table rmnet_data[0-9]* /table main /g'
); do
eval "ip route add $i"
done
echo "Copying wifi interface routes to main table (except default)..."
ip route del default table wlan0
IFS=$'\n'; for i in $( ip route show table wlan0 | grep -vE 'expires|default' ); do
eval "ip route add $i table main"
done
echo "Replacing lookup routes for main table..."
while ip rule del from all lookup main ; do "" ; done 2>/dev/null
ip rule add lookup main
echo "Clearing routing cache..."
ip route flush cache
(No suelo escribir shell scripts, así que algunas cosas pueden no ser las mejores aquí )
Algunas notas y suposiciones:
-
Sólo he probado esto en un rooteado Android 10 teléfono que ejecuta MIUI 12, no estoy seguro de si funciona para los demás.
-
En las opciones de Desarrollador del teléfono, tengo el Datos móviles siempre activos activado, para evitar la desactivación de los datos móviles cuando se conecta Wi-Fi.
-
He escrito el guión de tal manera que también soy capaz de continuar acceder a los dispositivos de la red Wi-Fi local mientras actúa como puerta de entrada. El icono en la barra de estado puede indicar erróneamente que se está utilizando Wi-Fi para Internet, sin embargo, se puede verificar en un navegador, que los datos móviles se están utilizando para Internet.
-
Los cambios realizados por este script son no permanente . Cuando el Wi-Fi o los datos móviles se desconectan o si se activa el anclaje USB / Wi-Fi hotspot / BT tethering, algunos de los cambios anteriores son eliminados por Android y el script tiene que ser ejecutado de nuevo. Esto puede automatizarse utilizando aplicaciones como Automatice / Tasker .
-
Interfaces de datos móviles: En la salida de ip addr
Veo que mi teléfono (módem Qualcomm de doble SIM) tiene 11 interfaces denominadas rmnet_data0..10
y 9 interfaces denominadas r_rmnet_data0..8
. No estaba seguro de cuál es el responsable de los datos móviles. Al activar y desactivar el modo avión varias veces, vi que r_rmnet_data
nunca se le asigna una dirección, pero el teléfono elige al azar 2 interfaces de los 11 rmnet_data
interfaces y les asigna una dirección IPv4 y v6 (supongo que SIM 1 usa las 5 primeras y SIM 2 las 5 restantes pero no estoy seguro).
Para simplificar, he decidido activar el reenvío para todas las interfaces. Los nombres de las interfaces pueden variar para diferentes dispositivos, por lo que el for
en el script anterior deberán ajustarse/eliminarse en consecuencia.
-
El nombre del Interfaz Wi-Fi fue wlan0
en mi teléfono. Puede ser diferente para otros, y por lo tanto tendrá que ser ajustado en la secuencia de comandos anterior.
-
Contadores de uso de datos erróneos: Los contadores de uso de datos en los ajustes de Android podrían no mostrar ninguna cuenta de los datos móviles utilizados por los dispositivos Wi-Fi de esta manera, o el contador total de uso de datos podría no coincidir con la suma de los recuentos de uso de datos de todas las aplicaciones. Creo que esto puede solucionarse utilizando la función tetherctrl_FORWARD
en lugar de FORWARD
para que cuente este uso como hotspots móviles, pero aún no lo he probado.
-
Aunque he activado el reenvío para IPv6 en el script anterior, no he sido capaz de encontrar la manera de propagar el prefijo delegado a los dispositivos de la red Wi-Fi local o utilizar el teléfono como una pasarela NAT IPv6 (ni siquiera estoy seguro de si Android soporta esto). Actualmente estoy contento con sólo IPv4, así que puede que no actualice el script para IPv6, a menos que alguien esté interesado (comentarios por favor).
-
Drenaje de la batería: La batería del teléfono se agota considerablemente cuando se utiliza como puerta de enlace con la secuencia de comandos anterior, al igual que cuando se utiliza el punto de acceso Wi-Fi.