Florian Amrhein

Das Apple iPhone als Modem unter Linux nutzen

Diese Anleitung ist hoffnungslos veraltet. Seit etlicher Zeit bietet sogar das iPhone eine relativ normale "Tethering"-Funktionalität.


Jedes andere auch nur ansatzweise moderne Mobiltelephon lässt sich leicht als Modem für einen Laptop nutzen: Einfach per USB oder Bluetooth verbinden, und per PPP eine Verbindung aufbauen. Der Rechner bekommt seine eigene IP-Adresse, und alles funktioniert.

Das iPhone kann dies leider nicht. Derartiges ist zwar für Firmware 3.0 versprochen, aber wir werden sehen, ob das auch wirklich funktionieren wird, und welche weiteren Widrigkeiten sich Apple dabei wieder ausgedacht hat.

Dieser Text beschreibt nun ein Verfahren um über Umwege das iPhone eben doch als Modem zu benutzen, wenn auch mit einigen Nachteilen. Einige dieser Nachteile werde ich jedoch weiter hinten im Text auch noch lösen, so daß man eine fast gleichwertige Lösung im Vergleich zu einer echten PPP-Einwahl erhalten kann.

Zielsetzung


Zwei Ziele sollen erreicht werden:
  1. Das Iphone über USB an den Rechner anschliessen, und einen Socks-Proxy laufen lassen, so daß alle Programme, die socks unterstützen, Zugriff aufs Internet erhalten
  2. Zusätzlich stelle ich eine Methode ("transparentes socks") vor, wie man dafür sorgen kann, daß die einzelnen Programme nicht mehr für Socks konfiguriert werden müssen, und auch an den Rechner angeschlossene weitere Computer diesen als Router nutzen können.

Ziel 1: Online per Socks-Server


Schritt 1: Grundlegendes


Dieses solltest Du bereits schon selbstständig erledigt haben, dabei werde ich Dir nicht helfen. Solltest Du daran schon scheitern, bist Du eh ein hoffnungsloser Fall und kannst gleich hier aufgeben. ;-)

  • Das iPhone muss gejailbreaked worden sein.
  • SSH-Server muss laufen
  • Du solltest Ahnung von der Shell (sowohl im iPhone als auch unter Linux) haben, und Programme (unter Linux) kompilieren können.

Schritt 1: Vorbereitung des Telephons


Wir werden im nächsten Schritt darauf angewiesen sein, dass das Telephon selbstständig eine Verbindung ins Internet aufbaut (es ist nicht immer online, sondern geht lediglich bei Bedarf online, was man als Nutzer aber meist garnicht mitbekommt) und diese auch hält. Dazu muss auf dem Gerät selbst ein kleines Shellscript namens /var/mobile/usbconnect.sh installiert werden:

#!/bin/bash
openURL http://wapedia.mobi # safari oeffnen, erzwingt Verbindung ins netz
killall -KILL socks # alten socks-proxy abschiessen
socks -p8081 -i127.0.0.1 & # neuen socks-proxy starten
while true; do
	ping -c 1 -i 10 -n 193.99.144.85 | grep time=  # verbindung offen halten
sleep 3 
done


Auf dem Telephon mußt Du per cydia oder apt-get folgende Pakete installieren:
  • 3proxy (socks-Server)
  • bash

Schritt 2: Computer mit Telephon über USB verbinden


Ich habe mich dazu entschieden, das Telephon per USB zu verbinden. Theoretisch ist auch WLAN möglich, aber dies ist recht kompliziert da der Computer dann einen WLAN Access Point bereit stellen muß, und dies sehr viel Strom verbraucht.

Ein Linux-Programm namens "itunnel" kann die Verbindung mit dem Telephon per USB aufbauen. Download!

Kompiliere Dieses Programm und kopiere es nach /usr/local/bin/

Protokoll zur Kommunikation mit dem Telephon über USB ist eine Art "TCP über USB", man kann damit direkt Programme auf dem Gerät erreichen die auf einem TCP-Port lauschen - wie z.B. dem SSH-Server.

Schritt 3: socks tunneln


In diesem Schritt bauen wir die beiden zuvor genannten Komponenten zusammen: Wir werden über USB auf den auf dem Telephon laufenden socks-Server zugreifen. Folgendes Shellscript für Linux namens iphone-usb.sh automatisiert dies mehr oder weniger:

#!/bin/sh

# alten itunnel abschiessen
killall -TERM itunnel
sleep 1
killall -KILL itunnel

# neuen itunnel starten
/usr/local/bin/itunnel &

ssh -p 3023 -L8081:127.0.0.1:8081 \
	  -L3025:127.0.0.1:22 root@localhost \
	  /var/mobile/usbconnect.sh


Der SSH-Client baut damit über das USB-Kabel eine Verbindung zu dem auf dem iPhone laufenden SSH-Server auf und leitet einige Ports weiter:

  • 8081: der Socks-Port
  • 3025: SSH-Port, so dass man sich selbst noch auf dem iPhone einloggen kann

Programme, die nun Zugriff aufs Internet bekommen sollen, müssen nur umkonfiguriert werden so daß sie einen Socks-Proxy verwenden. Dessen Adresse ist:

  • Socks-Server: 127.0.0.1
  • Socks-Port: 8081

Ferner darf das Programm keine eigenen DNS-Server-Abfragen machen, sondern muss dies dem Socks-Server überlassen.

Das Erste der beiden zu Beginn gesteckten Ziele ist damit nun erreicht, der Computer ist online!

Ziel 2: "transparentes socks"


Dass alle Programme auf dem Computer nun per Socks online gehen können ist schön und gut, hat aber diverse Nachteile:

  • jedes Programm muss einzeln umkonfiguriert werden
  • Das Programm darf keine DNS-Abfragen machen
  • Nicht jedes Programm unterstützt Socks

Wenn der Computer als Router eingesetzt werden soll muss zudem jedes Programm auf jedem einzelnen angeschlossenen Computer umkonfiguriert werden - ein erheblicher Aufwand.

Im folgenden Beschreibe ich, wie man socks vor den Programmen verstecken kann.

Schritt 1: transocks_ev


transocks_ev ist ein fabelhaftes Programm: Zusammen mit iptables fängt es ausgehende TCP-Verbindungen des Rechners ab, und wandelt diese in socks-Aufrufe um.

  1. Herunterladen!
  2. kompilieren!
  3. installieren!

Folgendes Shellcript bitte unter /usr/local/bin/transocks.sh Abspeichern. Es sorgt für die passenden iptables-Einträge um die Datenpakete tatsächlich an transocks_ev umzuleiten und damit an den socks-Server zu übergeben:

#!/bin/sh   
 
IPTABLES="/sbin/iptables"
 
TRANSOCKS_PORT="8082"
SOCKS_HOST="127.0.0.1"
SOCKS_PORT="8081"

# clear
iptables -F -v
iptables -F -t nat -v
iptables -X

echo 1 > /proc/sys/net/ipv4/ip_forward

# Create our own chain
$IPTABLES -t nat -N TRANSOCKS
 
# Do not try to redirect local traffic
$IPTABLES -t nat -I TRANSOCKS -o lo -j RETURN
 
# Do not redirect LAN traffic and some other reserved addresses.
$IPTABLES -t nat -A TRANSOCKS -d 0.0.0.0/8 -j RETURN
$IPTABLES -t nat -A TRANSOCKS -d 10.0.0.0/8 -j RETURN
$IPTABLES -t nat -A TRANSOCKS -d 127.0.0.0/8 -j RETURN
$IPTABLES -t nat -A TRANSOCKS -d 169.254.0.0/16 -j RETURN
$IPTABLES -t nat -A TRANSOCKS -d 172.16.0.0/12 -j RETURN
$IPTABLES -t nat -A TRANSOCKS -d 192.168.0.0/16 -j RETURN
$IPTABLES -t nat -A TRANSOCKS -d 224.0.0.0/4 -j RETURN  
$IPTABLES -t nat -A TRANSOCKS -d 240.0.0.0/4 -j RETURN

# Do not redirect traffic for the SOCKS server (not needed if server is 
# already excluded by above rules)
$IPTABLES -t nat -I TRANSOCKS -p tcp -d $SOCKS_HOST --dport $SOCKS_PORT -j RETURN
	
# Redirect all traffic that gets to the end of our chain
$IPTABLES -t nat -A TRANSOCKS -p tcp -j REDIRECT --to-port $TRANSOCKS_PORT
 
# Filter  all traffic that is routed over this host
# (für den Betrieb dieses Rechners als Router)
$IPTABLES -t nat -A PREROUTING -p tcp -j TRANSOCKS
#$IPTABLES -t nat -A PREROUTING -p tcp -s 172.19.42.0/24 --syn -j TRANSOCKS
 
## Filter all traffic from the own host 
# (damit Programme auf diesem Rechner aufs Internet zugreifen können)
$IPTABLES -t nat -A OUTPUT -p tcp -j TRANSOCKS


(dieses Skript habe ich von einer Webseite, deren Adresse ich leider nicht mehr finde...)

Schritt 2: Routen und Umleiten


Es werden hier von iptables nur solche Pakete erfasst und damit an socks umgeleitet, die an einen externen Router geschickt werden. Da unterwegs selten ein externer Router zur Verfügung steht, muss man einen vortäuschen.

Folgende Befehle sollten alles nötige erledigen:
# ethernet-Karte mit IP versehen,
ifconfig eth0 172.19.42.1 netmask 255.255.255.0 up

# Alle Datenpakete auf einen nicht existierenden Router leiten
route add default gateway 172.19.42.254

# transocks_ev starten
# (socks-tunnel-endpunkt ist 127.0.0.1 mit Port 8081,
# 8082 ist der Kontrollport von transocks_ev
transocks_ev -s 8081 -S 127.0.0.1 -H 0.0.0.0 -p 8082

# iptables konfigurieren
/usr/local/bin/transocks.sh


Schritt 3: DNS-Probleme lösen


Der über SSH getunnelte Socks-Server ermöglicht uns ausschliesslich TCP, UDP oder gar ICMP sind nicht möglich! Das ist im Normalfall zu verschmerzen, lediglich für DNS müssen wir uns nun etwas anderes ausdenken.

Wenn die Programme manuell auf socks konfiguriert werden sind DNS-Abfragen nicht nötig, da diese dem socks-Server einfach den Hostnamen mitteilen, und dieser dann alles nötige erledigen. Mit unserem "transparenten socks" wissen die Programme jedoch nichts von socks und machen die DNS-Abfragen selbst - und diese gehen dann schief.

Zum Glück gehen DNS-Abfragen auch über TCP. Das einzige was wir also brauchen ist ein DNS-Server der seinerseits DNS-Abfragen über UDP annehmen kann, diese aber per TCP weiterleitet. pdnsd kann dies:

  1. Download!
  2. Konfigurieren: ./configure --with-query-method=tcpudp --sysconfdir=/etc/
  3. Kompilieren
  4. Installieren

Folgende Konfigurationsdatei /etc/pdnsd.conf verwende ich:

global {
 perm_cache=1024;
 cache_dir="/var/cache/pdnsd";
 pid_file = /var/run/pdnsd.pid;
 run_as="nobody";
 server_ip = eth0;  # Use eth0 here if you want to allow other
	                            # machines on your network to query pdnsd.
 status_ctl = on;
#       paranoid=on;       # This option reduces the chance of cache poisoning
	                         # but may make pdnsd less efficient, unfortunately.
 query_method=tcp_only;
 min_ttl=15m;       # Retain cached entries at least 15 minutes.
 max_ttl=1w;        # One week.
 timeout=10;        # Global timeout option (10 seconds).
}

server {
 label = "opendns";
 ip = 208.67.222.222, 208.67.220.220;
 reject = 67.215.65.132/32;  # You may need to add additional address ranges
 proxy_only=on;
 reject_policy = fail;     # If you do not provide any alternative server
	                           # sections, like the following root-server
	                           # example, "negate" may be more appropriate here.
 timeout = 4;
}

rr {
 name=localhost;
 reverse=on;
 a=127.0.0.1;
 owner=localhost;
 soa=localhost,root.localhost,42,86400,900,86400,86400;
}


Es werden die Nameserver von opendns.org verwendet. Ausserdem wird hier wieder angenommen, dass einem ganzen Netz von Rechnern die über eth0 erreichbar sind Zugang zum Internet vermittelt werden soll.

Nun in die eigene /etc/resolv.conf als Nameserver die IP-Adresse von eth0 (z.B. 172.19.42.1) eintragen und pdnsd starten.

Schritt 4: Alles zusamensetzen


Eine vollständige iphone-usb.sh könnte nun so aussehen:

#!/bin/sh
# alten itunnel abschiessen
killall -TERM itunnel
sleep 3
killall -KILL itunnel
sleep 1

# neuen itunnel starten
/usr/local/bin/itunnel &
sleep 1

# aufraeumen
killall -KILL transocks_ev
killall -KILL pdnsd
iptables -F -v ; iptables -F -t nat -v ; iptables -X

# ethernet-interface konfigurieren
ifconfig eth0 172.19.42.1 netmask 255.255.255.0 up
route add default gateway 172.19.42.254

# socks transparent machen
/usr/local/sbin/transocks_ev -s 8081 -S 127.0.0.1 -H 0.0.0.0 -p 8082
/usr/local/sbin/transocks.sh

# anderes
/usr/local/sbin/pdnsd -d
echo "nameserver 172.19.42.1" > /etc/resolv.conf

# ssh-tunnel (mit oeffentlich erreichbarem socks-tunnel)
ssh -p 3023 -L0.0.0.0:8081:127.0.0.1:8081 \
	  -L3025:127.0.0.1:22 root@localhost \
	  /var/mobile/usbconnect.sh


Zusammenfassung


Was wurde erreicht?

  • Das iPhone kann bequem per USB angeschlossen werden, und wird dabei geladen
  • ein Rechner kann über das Telephon ins Internet gehen, und Router für andere Rechner spielen
  • kein Computer muss speziell für socks konfiguriert werden, dies geschieht transparent

Was geht nicht?
  • UDP und ICMP gehen nicht, lediglich TCP wird unterstützt
  • Ich empfehle einen DHCP-Server zu installieren, um beim Betrieb als Router die Konfiguriation der anderen Rechner zu erleichtern

Probleme:
  • gelegentlich startet sich das iPhone neu nachdem man das USB-Kabel abgezogen hat
  • Ich habe bisher nicht getestet wie sich das iPhone bei Funklöchern verhält, ob es selbstständig die Verbindung zum Internet wieder herstellt, oder ob man dies manuell (z.B. im Safari die Seite neu laden) erledigen muss.

Der socks-Proxy ist im Übrigen auch weiterhin nutzbar, trotz "transparentem socks", man kann ihn in einigen Programmen also auch weiterhin noch manuell verwenden. Im Firefox habe ich kein Unterschiede zwischen konfiguriertem und transparentem socks feststellen können, aber ich kann mir vorstellen, dass Programm die lange eine Verbindung offen halten müssen mit konfiguriertem socks besser funktionieren.