Questo tutorial spiega come eseguire Jetty sulla porta 80, senza che debba operare con privilegi di root.
Il codice di esempio è inteso per un primo test delle potenzialità di Jetty, e certo non può definirsi "production ready": utilizza una distribuzione pulita di Jetty, non prevede alcuna verifica di sicurezza e utilizza script bash eseguiti come cgi.
Prerequisiti:
- Jetty installato
- Maven installato
Nello specifico sono usate le versioni jetty-6.1.14 e maven-2.0.9
Per installare Jetty basta semplicemente:
wget 'http://dist.codehaus.org/jetty/jetty-6.1.14/jetty-6.1.14.zip' unzip jetty-6.1.14.zip
Per Maven:
wget 'http://apache.panu.it/maven/binaries/apache-maven-2.0.9-bin.zip' unzip apache-maven-2.0.9-bin.zip
Poi modifichiamo .bashrc aggiungendo le variabili d'ambiente M2_HOME e M2.
Quest'ultima deve anche essere aggiunta al PATH.
cat ~/.bashrc dovrebbe quindi restituire qualcosa di simile:
#[...]
M2_HOME=/path/to/apache-maven-2.0.9
export M2_HOME
M2=${M2_HOME}/bin
export M2
export PATH=$M2:$PATH
#[...]Per verificare che Maven sia installato correttamente:
mvn --version
A questo punto possiamo iniziare
$ cd jetty-6.1.14/extras/setuid/
$ mvn install
$ mkdir -p modules/native/target/generated
$ cp modules/native/src/main/native/org_mortbay_setuid_SetUID.c modules/native/target/generated
$ javah -d modules/native/target/generated \
-classpath modules/java/target/jetty-setuid-java-6.1.14.jar org.mortbay.setuid.SetUID
$ gcc -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/ \
-shared modules/native/target/generated/org_mortbay_setuid_SetUID.c \
-o ../../lib/ext/libsetuid.soDi questi comandi l'ultimo potrebbe dare un messaggio di errore, per esempio:
$ gcc -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/ \
-shared modules/native/target/generated/org_mortbay_setuid_SetUID.c \
-o ../../lib/ext/libsetuid.so
/usr/bin/ld: /tmp/cc43Xhvp.o: relocation R_X86_64_32 against `a local symbol' can not be used when
making a shared object; recompile with -fPIC
/tmp/cc43Xhvp.o: could not read symbols: Bad value
collect2: ld returned 1 exit statusIn questo caso riproviamo con
$ gcc -fPIC -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/
-shared modules/native/target/generated/org_mortbay_setuid_SetUID.c
-o ../../lib/ext/libsetuid.soQuesta volta dovrebbe andare; a questo punto abbiamo tutto quanto serve per far partire jetty sulla porta 80 senza essere root, manca solo qualche settaggio di configurazione.
Intanto, fermiamo Apache se sta girando sulla porta 80
sudo /etc/init.d/apache2 stop
Il settaggio dell'utenza con la quale gira Jetty si trova in $jetty_home/etc/jetty-setuid.xml
cd ../.. cat etc/jetty-setuid.xml
Creiamo l'utente col quale vogliamo che Jetty operi
$ sudo useradd jetty $ id jetty uid=3002(jetty) gid=3002(jetty) groups=3002(jetty)
e modifichiamo il file etc/jetty-setuid.xml in modo da avere qualcosa di simile:
$ cat etc/jetty-setuid.xml <?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"> <!-- =============================================================== --> <!-- Configure the Jetty SetUIDServer --> <!-- this configuration file should be used in combination with --> <!-- other configuration files. e.g. --> <!-- java -jar start.jar etc/jetty-setuid.xml etc/jetty.xml --> <!-- =============================================================== --> <Configure id="Server" class="org.mortbay.setuid.SetUIDServer"> <Set name="startServerAsPrivileged">false</Set> <Set name="umask">2</Set> <Set name="uid">3002</Set> <Set name="gid">3002</Set> </Configure>
Poi andiamo a configurare Jetty per bindarsi alla porta 80, scrivendo su etc/jetty.xml
<Set name="port"><SystemProperty name="jetty.port" default="80"/></Set>
Se serve legare Jetty a uno specifico IP, basta aggiungere alla configurazione di default la proprietà "Host":
<Set name="port"><SystemProperty name="jetty.port" default="80"/></Set>
<Set name="Host">111.111.111.111</Set>Per finire, facciamo in modo da verificare con quale utente Jetty stia effettivamente girando.
Per farlo sfruttiamo la possibilità di far eseguire a Jetty script cgi.
Modifichiamo quindi il file webapps/test/cgi-bin/hello.sh aggiungendo un echo per qualche variabile che ci interessa
$ cat webapps/test/cgi-bin/hello.sh #!/bin/sh echo "Content-Type: text/html" echo echo "<H1>Hello World</H1>" ID=$(whoami); echo "<pre>"; echo "whoami: $ID"; echo "" echo "user: $USER"; echo "" echo "uid: $UID"; echo "" touch '/root/test.txt' echo $?
Verifichiamo il path della libsetuid che dovrà essere passato a Jetty come parametro d'avvio:
$ find . -name libsetuid.so ./lib/ext/libsetuid.so ./extras/setuid/target/libsetuid.so ./extras/setuid/modules/native/target/libsetuid.so
Cediamo a Jetty la proprietà della directory nella quale opererà:
(attenzione al fatto che Jetty deve poter raggiungere questa directory, quindi verificare l'intero path)
$ sudo chown -R jetty:jetty .
Finalmente possiamo lanciare Jetty:
$ sudo java -Djetty.libsetuid.path=/home/atoito/jetty-6.1.14/lib/ext/libsetuid.so
-jar start.jar etc/jetty-setuid.xml etc/jetty.xmlPossiamo verificare che tutto sia andato come previsto raggiungendo l'indirizzo http://111.111.111.111/cgi-bin/hello.sh
(L'IP è ovviamente quello inserito in etc/jetty.xml)
Buon Jetty a tutti!