PHP sur IPod Touch 1G

Voici un petit article décrivant comment recycler votre vieille IPod Touch 1G en serveur PHP.

Mise à jour d’IOS

Pour mettre à jour son IOS rien de plus facile, on lance itunes, on connecte son IPod Touch 1G et on fait la mise à jour / restauration de l’IOS. Ici on me propose la dernière version disponible à savoir 3.1.3

JailBreak

Le but de la manipulation est de pouvoir utiliser des produits open source sur l’IPod. Dans notre cas nous voulons installer php.
Le JailBreak d’un ancien IOS tel que le 3.1.3 est extrêmement simple. Lancer le safari sur l’IPod et aller sur le site www.jailbreakme.com, ensuite il suffit de demander le jailbreak.

Cydia

Le JailBreak installe Cydia un outil de gestion de package qui va nous permettre d’installer ce que l’on souhaite.
Avant tout une mise à jour de Cydia s’impose, lors du premier démarrage il nous demande le mode de fonctionnement, nous allons prendre développeur.

ssh et aptitude

Grace à Cydia (une fois mis à jour) on installe les packages suivants:

  • openssh (permettant la connexion à votre IPod Touch en ssh)
  • aptitude (un gestionnaire de package plus sympa que apt-get)

ssh et itunnel

Je souhaite pouvoir me connecter à mon IPod Touch via le cable apple. Pour ce faire j’utilise itunnel. Télécharger le produit puis:

scolas@scolas:~/perso/ipod/utils/itunnel-0.0.9$ make
gcc -Wall -g -O0 -I/usr/local/include/   -c -o iphone.o iphone.c
gcc -Wall -g -O0 -I/usr/local/include/   -c -o itunnel.o itunnel.c
gcc -Wall -g -O0 -I/usr/local/include/ -L/usr/local/lib -lpthread -lusb -lrt ./iphone.o ./itunnel.o -o itunnel
./iphone.o: In function `iphone_get_specific_device':
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:184: undefined reference to `usb_init'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:185: undefined reference to `usb_find_busses'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:186: undefined reference to `usb_find_devices'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:187: undefined reference to `usb_get_busses'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:195: undefined reference to `usb_open'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:196: undefined reference to `usb_set_configuration'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:197: undefined reference to `usb_claim_interface'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:209: undefined reference to `usb_bulk_write'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:213: undefined reference to `usb_strerror'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:218: undefined reference to `usb_bulk_read'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:226: undefined reference to `usb_strerror'
./iphone.o: In function `iphone_get_device':
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:275: undefined reference to `usb_init'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:276: undefined reference to `usb_find_busses'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:277: undefined reference to `usb_find_devices'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:279: undefined reference to `usb_get_busses'
./iphone.o: In function `iphone_free_device':
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:304: undefined reference to `usb_release_interface'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:305: undefined reference to `usb_reset'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:306: undefined reference to `usb_close'
./iphone.o: In function `send_to_phone':
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:340: undefined reference to `usb_bulk_write'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:347: undefined reference to `usb_strerror'
./iphone.o: In function `recv_from_phone_timeout':
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:383: undefined reference to `usb_bulk_read'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:393: undefined reference to `usb_strerror'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:395: undefined reference to `usb_strerror'
./iphone.o: In function `iphone_mux_free_client':
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:561: undefined reference to `usb_bulk_write'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:563: undefined reference to `usb_strerror'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:565: undefined reference to `usb_bulk_read'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:567: undefined reference to `usb_strerror'
./iphone.o: In function `iphone_mux_send':
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:610: undefined reference to `clock_gettime'
./iphone.o: In function `iphone_mux_recv_timeout':
/home/scolas/perso/ipod/utils/itunnel-0.0.9/iphone.c:931: undefined reference to `clock_gettime'
./itunnel.o: In function `clientthread':
/home/scolas/perso/ipod/utils/itunnel-0.0.9/itunnel.c:190: undefined reference to `pthread_create'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/itunnel.c:260: undefined reference to `pthread_join'
./itunnel.o: In function `server_loop':
/home/scolas/perso/ipod/utils/itunnel-0.0.9/itunnel.c:317: undefined reference to `pthread_create'
/home/scolas/perso/ipod/utils/itunnel-0.0.9/itunnel.c:340: undefined reference to `pthread_join'
collect2: ld returned 1 exit status
make: *** [itunnel] Error 1

Après quelques recherche il se trouve que ma version de gcc est trop récente. Je corrige donc le Makefile:

TARGET := itunnel
SRCDIR := .
SOURCES := itunnel.c iphone.c 
OBJS := $(patsubst %.c,%.o,$(wildcard $(SRCDIR)/*.c))

CC := gcc
CFLAGS := -Wall -g -O0 -I/usr/local/include/

#LDFLAGS :=  -L/usr/local/lib -lpthread -lusb -lrt -liphone
LDFLAGS :=  -L/usr/local/lib -lpthread -lusb -lrt

all:    $(TARGET)

$(TARGET): $(OBJS)
	$(CC) $(OBJS) -o $@ $(CFLAGS) $(LDFLAGS)

%.o: %.m
	$(CC) -c $(CFLAGS)  $< -o $@


clean:
	rm $(TARGET) $(OBJS)

On relance la compilation

scolas@scolas:~/perso/ipod/utils/itunnel-0.0.9$ make
gcc -Wall -g -O0 -I/usr/local/include/   -c -o iphone.o iphone.c
gcc -Wall -g -O0 -I/usr/local/include/   -c -o itunnel.o itunnel.c
gcc ./iphone.o ./itunnel.o -o itunnel -Wall -g -O0 -I/usr/local/include/ -L/usr/local/lib -lpthread -lusb -lrt

On démarre itunnel (2 fois pour démonter le système fichier ipod)

scolas@scolas:~/perso/ipod/utils/itunnel-0.0.9$ ./itunnel 
- iphone get device error: -5
ERROR: failed to connect to iphone. quitting.
quit ok.
scolas@scolas:~/perso/ipod/utils/itunnel-0.0.9$ ./itunnel 
get_iPhone() success
- successfully got device
server waiting for ssh connection on port 3023

On se connecte et on change le mot de passe (par défaut alpine):

scolas@scolas:~/perso/ipod/utils/itunnel-0.0.9$ ssh -p 3023 localhost -l root
The authenticity of host '[localhost]:3023 ([127.0.0.1]:3023)' can't be established.
RSA key fingerprint is e8:54:de:b3:69:0e:c8:40:9f:f9:0f:4a:8e:d9:d8:f6.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[localhost]:3023' (RSA) to the list of known hosts.
root@localhost's password: 
sebs-iPod:~ root# passwd
Changing password for root.
New password:
Retype new password:
sebs-iPod:~ root# exit
logout
Connection to localhost closed.

Connexion ssh via clef

Pour pouvoir utiliser des scripts nous allons maintenant nous authentifier en ssh via clef. Tout d’abord générons la clef:

scolas@scolas:~/perso/ipod/utils/itunnel-0.0.9$ ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/home/scolas/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again: 
Your identification has been saved in /home/scolas/.ssh/id_rsa.
Your public key has been saved in /home/scolas/id_rsa.pub.

Copions la clef sur l’ipod:

scolas@scolas:~/perso/ipod/utils/itunnel-0.0.9$ scp -P 3023 ~/.ssh/id_rsa.pub root@127.0.0.1:
root@127.0.0.1's password: 
id_rsa.pub                                                                               100%  398     0.4KB/s   00:00    

Autorisons la clef à se connecté sur l’ipod:

scolas@scolas:~/perso/ipod/utils/itunnel-0.0.9$ ssh -p 3023 localhost -l root
root@localhost's password:     
sebs-iPod:~ root# mkdir .ssh         
sebs-iPod:~ root# cat id_rsa.pub >.ssh/authorized_keys     
sebs-iPod:~ root# exit
logout
Connection to localhost closed.
scolas@scolas:~/perso/ipod/utils/itunnel-0.0.9$ ssh -p 3023 localhost -l root
sebs-iPod:~ root# exit
logout
Connection to localhost closed.

Installation de PHP et divers…

Ensuite on installe les packages dont on a besoin (au moins php et lighttpd):

scolas@scolas:~/perso/ipod/utils/itunnel-0.0.9$ ssh -p 3023 localhost -l root
sebs-iPod:~ root# aptitude install php rsync lighttpd vim   

Configuration du serveur web lighttpd

Voici le fichier de configuration que j’utilise

# sebs-iPod:~ root# cat /etc/lighttpd/lighttpd.conf 
server.document-root = "/private/var/htdocs"
server.port = 80

server.tag ="lighttpd"
server.errorlog = "/etc/lighttpd/logs/error.log"
accesslog.filename = "/etc/lighttpd/logs/access.log"

server.modules = ("mod_access","mod_accesslog","mod_fastcgi","mod_rewrite","mod_auth","mod_fastcgi")

index-file.names = ( "index.html", "index.php" )

#Configuration PHP
fastcgi.server = (".php" =>
        ("localhost" =>
                ("bin-path" => "/usr/bin/php-cgi",
                "socket" => "/tmp/php.socket")
        )
)

Il ne faudra pas oublier que créer le répertoire /private/var/htdocs et de mettre le contenu du site web dedans.
On créé un script de démarrage (ne pas oublier de donner les droits en exécution):

sebs-iPod:~ root# ls -l /usr/bin/lighttpd.sh 
-rwxr-xr-x 1 root wheel 50 Oct 11 12:58 /usr/bin/lighttpd.sh
sebs-iPod:~ root# cat /usr/bin/lighttpd.sh 
#!/bin/sh
lighttpd -f /etc/lighttpd/lighttpd.conf

Ensuite on crée un script pour le démarrage automatique:

sebs-iPod:~ root# cat /System/Library/LaunchDaemons/com.lighttpd.startup.plist
<!--?xml version="1.0" encoding="UTF-8"?-->



Label
com.lighttpd.startup
ProgramArguments

/usr/bin/lighttpd.sh

RunAtLoad



Déploiement du site web

Voici un petit script qui permet de déployer automatiquement le site web sur l’ipod:

scolas@scolas:~/bin$ cat ipod_php_deploy.php 
rsync -av --delete --progress --inplace --bwlimit=100 --rsh='ssh -p3023' /var/www root@127.0.0.1:/etc/lighttpd/htdocs

On notera la limitation du débit, sans elle itunnel ne répond plus.