Disons que rmnet_data1
est votre interface de données mobiles (sur les appareils Qualcomm) et wlan0
est l'interface WiFi. Lorsque vous activez les données mobiles, votre fournisseur d'accès attribue rmnet_data1
une adresse IP, éventuellement dynamique et pas nécessairement une IP publique (voir détails dans cette réponse ), mais supposons qu'il s'agisse d'une IP publique statique - disons 1.2.3.10
. Lorsque vous activez le tethering, wlan0
est mis en mode AP et une IP statique est attribuée (elle était autrefois 192.168.43.1
mais il est aléatoire depuis Pie). Un serveur DHCP/DNS ( dnsmasq
) est à l'écoute sur cette interface pour attribuer des adresses IP dynamiques à tous les hôtes qui rejoignent le réseau local.
Maintenant, le téléphone est essentiellement un routeur qui relie deux réseaux (différents sous-réseaux) à des passerelles ( rmnet_data1
pour le réseau externe/public, c'est-à-dire WAN et wlan0
pour le réseau local/privé, c'est-à-dire le WLAN). Étant donné qu'une seule IP est attribuée par le fournisseur d'accès à votre téléphone, ce dernier effectue la NAT (au niveau de la couche 3 de l'OSI) pour rendre Internet accessible à tous les clients locaux. Comme dans votre cas, le seul hôte connecté (routeur) se voit attribuer une adresse, disons.., 192.168.43.10
. Vous devrez effectuer une redirection de port spécifique ou une DMZ pour accéder au routeur depuis Internet.
BRIDGING ON LINUX / Android :
Ce que vous voulez faire, c'est attribuer une adresse 1.2.3.10
au routeur en utilisant le pont Ethernet comme vous l'avez indiqué dans le commentaire :
Je ne veux connecter qu'un seul appareil derrière le téléphone, et je veux que l'IP publique du téléphone lui soit attribuée.
Si vous souhaitez conserver la configuration actuelle du réseau sur l'appareil, le pontage Ethernet, qui est une alternative au NAT pour les applications de gestion de réseau, peut être utilisé. partage de l'internet - ne semble pas être une option du tout, sauf si vous obtenez un sous-réseau entier (par ex. /30
) du FAI au lieu d'une seule adresse IP. Voir Annexe A pour des raisons.
PONTAGE SUR LE MODEM / ROUTEUR :
Cela dit, ce que vous recherchez s'appelle Mode demi-pont une fonction fournie dans de nombreux appareils combinés modem/routeur pour éviter le problème de l'utilisation de l'Internet. double NAT . On l'appelle aussi IP Pass-through , Extension IP , L'usurpation d'identité DHCP o Véritable DMZ par différents fabricants. Les autres modes de fonctionnement des appareils combo fournis par ISP sont les suivants NAT y Pont complet .
Nous pouvons utiliser une solution de contournement pour exposer l'IP publique à l'hôte connecté. Cela implique de modifier les configurations IP et la politique/les tables de routage du noyau, ce qui interrompt la connectivité Internet sur l'appareil Android. Ce n'est pas un problème sur les modems/routeurs, mais sur Android, oui. Nous devons donc utiliser le NAT pour le trafic interne d'Android (cf. Annexe B ).
COMMENT TRANSFORMER Android en MODEM / ROUTEUR HALF-BRIDGED ?
Les FAI qui réalisent des CGNAT créent généralement de petits sous-réseaux pour les clients connectés. Dans le cas d'une IP publique, cela peut même être le cas. /8
. Dans notre cas, disons que l'ID du réseau est 1.2.3.8/30
donc 1.2.3.9
sera l'adresse de la passerelle du FAI. Il y a différentes approches possibles, voir Annexe C .
Le reste des détails est donné dans le script suivant qui peut être exécuté en suivant la procédure suivante dhcp
, static
, arp
o stop
argument :
#!/system/bin/sh
set -e
[ "$(id -u)" = 0 ] || { echo 'Not running as root!' >&2; exit 1; }
# internal filed separator
IFS=$' \t\n'
##########################
# define / get variables #
##########################
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)
PUB_IFACE=rmnet_data # set this according to your device (Qualcomm SoCs use 'rmne_data[N]')
WIFI_IFACE=wlan0 # set this according to your device (check with 'lshw' or 'ip link show')
AP_IFACE=${WIFI_IFACE}-AP # we'll create new WiFi interface for hotspot
DIR=/data/local/tmp/$AP_IFACE # where to put config files
LOCAL_SUBNET=192.168.1 # for public interface
PST_RT_CHN=my_chain # to define source NAT for local packets
DNS1=1.1.1.1
DNS2=1.0.0.1
# read public interface name, IP and mask
read -r PUB_IFACE PUB_IP MASK <<< \
$(ip -4 -o a | tr -s ' ' | awk -F'[ /]' '/'"$PUB_IFACE"'/ {print $2,$4,$5}')
# read ISP's default gateway
GW=$(ip r s t all | awk '/^default/ && /'"$PUB_IFACE"'/ {print $3}')
# ip for WiFi hotspot interface in public subnet
AP_IP=$GW/$MASK
############################
# start / stop bridge mode #
############################
STOP()
(
echo 'Cleaning up...'
# ignore errors
set +e
# don't print error messages
exec >/dev/null 2>&1
# hope there are no other instances of same daemons
pkill -15 hostapd
pkill -15 dnsmasq
# remove local IP from public interface
ip address del ${LOCAL_SUBNET}.1 dev $PUB_IFACE
# remove rule and clear RPDB cache
ip rule del lookup main
ip route flush cache
# flush main table
ip route flush table main
# disable forwarding
printf 0 >/proc/sys/net/ipv4/ip_forward
iptables -D FORWARD -i $AP_IFACE -o $PUB_IFACE -j ACCEPT
iptables -D FORWARD -o $AP_IFACE -i $PUB_IFACE -j ACCEPT
# stop listening on DHCP port
iptables -D INPUT -i $AP_IFACE -p udp -m udp --dport 67 -j ACCEPT
# stop local NAT
iptables -t nat -D POSTROUTING -j $PST_RT_CHN
iptables -t nat -F $PST_RT_CHN
iptables -t nat -X $PST_RT_CHN
# delete AP interface
iw $AP_IFACE del
# delete config directory
rm -rf $DIR
)
if [ "$1" = stop ]
then
STOP
exit
elif [ "$1" != dhcp -a "$1" != static -a "$1" != arp ]
then
echo 'Usage:' >&2
printf '\t%s\n' "$(basename "$0") dhcp|static|arp|stop" >&2
exit 1
fi
################
# basic checks #
################
if [ -z $PUB_IP ]
then
echo 'Turn on Mobile Data first.' >&2
exit 1
fi
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_IFACE link | grep -q '^Not connected'
then
echo 'First disconnect form Wi-Fi.' >&2
exit 1
fi
##########################
# clear previous configs #
##########################
STOP
# clean up if error occurs
trap '[ $? = 0 ] || STOP' EXIT
#####################################
# create virtual wireless interface #
#####################################
if ! iw dev $WIFI_IFACE interface add $AP_IFACE type __ap
then
echo "Couldn't create AP interface." >&2
exit 1
fi
####################################
# configure interfaces and routing #
####################################
echo 'Configuring network...'
# add local IP to public interface and delete public IP
ip address add ${LOCAL_SUBNET}.1/30 dev $PUB_IFACE
ip address del $PUB_IP/$MASK dev $PUB_IFACE
# activate the WLAN interface
ip link set dev $AP_IFACE up
if [ "$1" = dhcp ]
then
# assign ip in public subnet to WiFi hotspot interface
ip address add $AP_IP dev $AP_IFACE
elif [ "$1" = static ]
then
# assign ip in local subnet to WiFi hostspot interface
ip address add ${LOCAL_SUBNET}.2/30 dev $AP_IFACE
else
# start proxying ARP queries both ways
printf 1 >/proc/sys/net/ipv4/conf/$AP_IFACE/proxy_arp
fi
# clear auto added routes and add new
ip route flush table main
ip route add $PUB_IP dev $AP_IFACE
ip route add default via $GW dev $PUB_IFACE
ip route flush cache
# Android doesn't look up into main table by default
ip rule add lookup main
# let packets be forwarded
printf 1 >/proc/sys/net/ipv4/ip_forward
iptables -I FORWARD -i $AP_IFACE -o $PUB_IFACE -j ACCEPT
iptables -I FORWARD -o $AP_IFACE -i $PUB_IFACE -j ACCEPT
# apply source NAT on internally generated packets
iptables -t nat -N $PST_RT_CHN
iptables -t nat -I POSTROUTING -j $PST_RT_CHN
iptables -t nat -I $PST_RT_CHN -o $PUB_IFACE ! -s $PUB_IP -j SNAT --to-source $PUB_IP
#######################
# access point daemon #
#######################
# create configuration file
mkdir -p $DIR
cat <<-HOSTAPD >$DIR/hostapd.conf
# network name
ssid=$SSID
# passphrase to use for protected access
wpa_passphrase=$PASSCODE
# maximum STA clients allowed to connect
max_num_sta=1
# network interface to listen on
interface=$AP_IFACE
# wi-fi driver
driver=nl80211
# set operation mode, 'g' for 2.4GHz band
hw_mode=g
# WLAN frequency channel to use
channel=1
# key management protocol; use pre-share key
wpa_key_mgmt=WPA-PSK
# enforce WPA2
wpa=2
HOSTAPD
echo 'Starting hostapd...'
hostapd -B $DIR/hostapd.conf
##########################################
# IP assignment; manually or dynamically #
##########################################
if [ "$1" = dhcp ]
then
# create configuration file
cat <<-DNSMASQ >$DIR/dnsmasq.conf
# we dont want DNS server, only DHCP
port=0
# network interface to listen on
interface=$AP_IFACE
bind-interfaces
# nameservers to be sent to clients
dhcp-option=6,$DNS1,$DNS2
# range of IPs to make available to wlan devices and when to renew IP
dhcp-range=$PUB_IP,$PUB_IP,24h
# where to save leases
dhcp-leasefile=$DIR/dnsmasq.leases
# respond to requests from a different IP broadcast subnet
dhcp-authoritative
# log extra information about DHCP handshakes
log-dhcp
DNSMASQ
# open listening port for dnsmasq
iptables -I INPUT -i $AP_IFACE -p udp -m udp --dport 67 -j ACCEPT
echo 'Starting DHCP server...'
dnsmasq -C $DIR/dnsmasq.conf </dev/null
else
echo
echo 'On connected host disable DHCP, set DNS and do:'
echo 'ip a f dev <wifi>'
echo "ip a a $PUB_IP dev <wifi>"
echo 'ip r f t main'
if [ "$1" = static ]
then
echo "ip r a ${LOCAL_SUBNET}.2 dev <wifi>"
echo "ip r a default via ${LOCAL_SUBNET}.2 dev <wifi>"
else
echo 'ip r a default dev <wifi>'
echo 'ip n f dev <wifi>'
fi
echo
fi
echo Done.
NOTE :
- Tous les binaires nécessaires (
iw
, ip
, iptables
, hostapd
, dnsmasq
) sont disponibles sur Android mais hostapd
ne fonctionne pas en ligne de commande. J'ai utilisé un fichier statique construit binaire testé sur Pie.
- Sur la base des facteurs discutés aquí votre fournisseur d'accès à Internet peut se rendre compte (et s'en rendre compte) que votre trafic ne provient pas d'un appareil Android.
- Après avoir arrêté le mode demi-pont, vous devez désactiver et réactiver la fonction Données mobiles pour reprendre le travail normal, car les routes sont effacées. De même, au démarrage de l'appareil, vous devrez peut-être activer le WiFi une fois pour que les routes soient effacées.
wlan0
est créée.
-
Les serveurs de noms du FAI - si nécessaire - (et la passerelle par défaut) peuvent également être obtenus par :
~$ dumpsys connectivity | grep CONNECTED | grep -o 'Routes: .* DnsAddresses: [^ ]*'
Routes: [0.0.0.0/0 -> 1.2.3.9 rmnet_data1,1.2.3.8/30 -> 0.0.0.0 rmnet_data1,] DnsAddresses: [1.1.1.1,8.8.8.8,]
VERIFICATION :
Votre configuration devrait ressembler à ceci :
1. Routing
==========
~$ ip rule show
0: from all lookup local
9999: from all lookup main
~$ ip route show table main
default via 1.2.3.9 dev rmnet_data1
1.2.3.10 dev wlan0-AP
2. Forwarding
=============
~$ cat /proc/sys/net/ipv4/ip_forward
1
~# iptables -S
-A FORWARD -i rmnet_data1 -o wlan0-AP -j ACCEPT
-A FORWARD -i wlan0-AP -o rmnet_data1 -j ACCEPT
3. Source NAT
=============
~$ ip -4 -o address
rmnet_data1 inet 192.168.1.1/30
~# iptables -t nat -S
-A POSTROUTING -j my_chain
-A my_chain ! -s 1.2.3.10/32 -o rmnet_data1 -j SNAT --to-source 1.2.3.10
4. Access Point Daemon
======================
~# iw dev
Interface wlan0-AP
ssid MyAP
type AP
5 (a). DHCP Server
==================
~$ ip -4 -o address
wlan0-AP inet 1.2.3.9/30
~# netstat -lup
Proto Local Address Foreign Address PID/Program name
udp 1.2.3.9:67 0.0.0.0:* 23693/dnsmasq
~# iptables -S
-A INPUT -i wlan0-AP -p udp -m udp --dport 67 -j ACCEPT
5 (b). Static IP
================
~$ ip -4 -o address
wlan0-AP inet 192.168.1.2/30
5 (c). Proxy ARP
================
~$ cat /proc/sys/net/ipv4/conf/wlan0-AP/proxy_arp
1
APPENDICE A :
Pourquoi le pontage Ethernet n'est pas une option simple sur Android :
- Il y a au moins deux hôtes sur votre réseau local : le téléphone et le routeur, mais une seule adresse IP est reçue du FAI. Deux hôtes sur le même réseau ne peuvent pas avoir la même adresse IP.
- Si vous établissez un pont transparent
rmnet_data1
y wlan0
les deux peuvent avoir la même adresse IP. 1.2.3.10
mais le routeur doit encore se voir attribuer une autre adresse IP, soit de manière statique, soit par un serveur DHCP du côté du FAI. Si vous n'attribuez pas d'IP au full bridge, la connectivité Internet sera interrompue sur Android qui ne pourra pas fonctionner (voir l'annexe B).
- Le pontage Ethernet (qui fonctionne au niveau OSI L2) ne fonctionne pas pour les interfaces WiFi dans les pays suivants Mode STA sans WDS / 4addr (des deux côtés du WiFi) qui n'est pas supporté par toutes les interfaces physiques. Sur Mode AP Cependant, l'interface WiFi prend en charge le pontage, mais pas les interfaces 3G/4G. A récent patch a
rmnet
ajoute la prise en charge du pontage uniquement pour les interfaces qui peuvent envoyer des données MAP.
- Une alternative au pontage Ethernet est le proxy ARP (au niveau OSI L3) ou quelque chose de similaire wlan_kabel qui peut être appliqué aux deux interfaces. Mais là encore, vous avez besoin de trois ou au moins deux adresses IP ; une pour le téléphone et une pour le routeur.
ANNEXE B :
Pourquoi le NAT est-il nécessaire sur le dispositif ?
Les modems possèdent leurs propres processeurs - appelés bande de base ou processeur de communication (BP ou CP) sur les appareils Android - et ils exécutent leurs propres fonctions minimales. RTOS . Sur les petits appareils comme les téléphones, ils sont intégrés dans des SoC. La communication avec le modem se fait à l'aide d'un ensemble de protocoles de contrôle standard. Les commandes AT sont traditionnellement utilisées avec PPP. ( 1 , 2 ) mais les fabricants ont développé nouvelles méthodes (par exemple, QMI ( 3 , 4 , 5 ) / RmNet ( 6 , 7 ) sur les appareils Qualcomm).
Les protocoles de modem de contrôle/données spécifiques au fournisseur et à source fermée utilisés sur les appareils Android ne sont pas (ou du moins pas bien) documentés. Les vendeurs fournissent le démon RIL natif sous la forme d'un blob binaire qui communique avec le modem par le biais de RILJ
et de téléphonie dans la pile Java. Lorsque nous activons les données mobiles, ces composants travaillent ensemble pour s'authentifier auprès du MNO (en lisant les données SIM, les paramètres APN, etc.), puis configurent la pile réseau (IP, DNS, route, etc.) pour rendre possible la connectivité Internet. Ainsi, le modem est disponible pour le système d'exploitation Android en mode pont complet (pas de NAT sur l'appareil).
En utilisant les méthodes expliquées ci-dessus, nous attribuons une IP publique à l'hôte connecté, de sorte que l'appareil Android lui-même perd la connexion Internet. Dès que nous modifions la configuration IP, la pile téléphonique d'Android détecte les déconnexions et envoie une commande de réinitialisation au modem (par le biais de RILD). L'ensemble de la pile réseau est actualisée avec les nouveaux (ou les mêmes) paramètres IP reçus du MNO.
Ainsi, pour configurer un appareil Android en mode Half Bridge, une approche plus fiable consiste à prendre le contrôle total de la communication avec le modem en modifiant le cadre de téléphonie (ce qui n'est pas une tâche simple). Comme solution de contournement, nous faisons du NATing à la source pour les paquets générés en interne sur l'appareil Android afin qu'il ne soit pas déconnecté d'Internet. Alors que l'IP publique est acheminée sans NAT vers le seul hôte connecté à l'appareil Android. wlan0
pour qu'il soit accessible depuis l'internet.
APPENDICE C :
Méthodes de routage pour le mode demi-pont sur Android :
-
DHCP :
Affecter 1.2.3.10
à votre routeur en utilisant un serveur DHCP, 1.2.3.9
a wlan0
y 192.168.1.1/30
(ou toute autre IP privée) vers rmnet_data1
. Il est également possible de créer une hypothétique 1.2.3.0/X
et assigne une IP aléatoire de ce réseau hypothétique à l'utilisateur. wlan0
. Mais l'adresse IP publique ne doit pas entrer en conflit avec l'ID du sous-réseau ou l'adresse de diffusion dans le sous-réseau truqué. Cela devient difficile à réaliser si l'IP est attribué dynamiquement, en particulier si la classe d'IP et le masque de sous-réseau changent constamment de fournisseur d'accès.
De cette façon, l'interface AP et le routeur apparaissent sur le même réseau local, et wlan0
L'IP est définie comme passerelle par défaut (prochain saut) pour le routeur. Ici, nous simulons une adresse IP (au niveau OSI L3).
-
Route statique :
La configuration manuelle de l'IP/DNS sur le routeur vous permet d'attribuer une adresse IP locale à l'interface AP au lieu d'utiliser une pseudo-adresse IP. Ajoutez l'adresse IP de l'AP comme passerelle par défaut sur le routeur. Cependant, le routeur peut avoir des difficultés à utiliser la passerelle par défaut sur un sous-réseau différent.
-
ProxyARP :
Une autre option pour ne pas utiliser le DHCP est ProxyARP. ( 8 , 9 , 10 ) . Si wlan0
n'a pas d'adresse IP, nous devons ajouter une route statique sans adresse IP comme passerelle par défaut. Ainsi, le routeur ne peut pas demander l'adresse MAC de la passerelle et continue donc à demander wlan0
(dans les diffusions globales) où se trouve une adresse internet (next hop). C'est parce que la cible des requêtes ARP est toujours l'adresse IP, soit d'un hôte local, soit de la passerelle par défaut (si l'IP de destination est sur un autre réseau).
En raison de ProxyARP, wlan0
fournit sa propre adresse MAC pour chaque requête ARP reçue d'un hôte connecté. Les requêtes ARP provenant de rmnet_data1
(pour 1.2.3.10
) sont transmis/réceptionnés par wlan0
vers/depuis l'hôte connecté. rmnet_data1
n'a pas d'adresse MAC (comme le PPP). Un effet secondaire de cette approche est que le routeur connecté va polluer son cache ARP en associant chaque adresse Internet visitée à l'adresse MAC de l'AP. Ici, nous simulons une adresse MAC (au niveau OSI L2).
CREDITS :