L’objectiu serà aprendre a instal.lar i configurar el nostre web server, i començar a crear llocs virtuals. Concretament, crearàs el site que doni suport a l’assignatura d’aquest mòdul: http://localhost/M9.
Instal·lar Apache en una màquina virtual de nova creació¶
Em basaré en una màquina amb una instal·lació minimalista de CentOS 7 amb adreça IP 192.168.56.200.
Per a instal·lar Apache hem d’instal·lar el paquet httpd, disponible des dels repositoris base de CentOS:
yum install httpd -y
Per tal d’evitar problemes i simplificar la solució, desactivaré el SELinux i deshabilitaré el Firewall del sistema amb les comandes:
Una vegada instal·lat el programa, el podem engegar i habilitar perquè arrenqui automàticament amb el sistema amb:
systemctl enable httpd
systemctl start httpd
Per a comprovar-ho, podem obrir el navegador des de l’ordinador client (la màquina física) i demanar per http://192.168.56.200. Si tot ha anat bé i Apache està funcionant, ens sortirà la pàgina principal que s’activa per defecte a l’instal·lar-lo:
Simplificaré la creació d’aquest directori posant l’arrel del site al directori /var/www/html/M9 de manera que, la configuració per defecte d’Apache servirà el contingut d’aquest directori sense necessitat de fer-hi canvis.
Crearé el directori amb
mkdir /var/www/html/M9
i li donaré permisos al servidor web per tal que pugui llegir el contingut i servir-lo
chown apache.apache /var/www/html/M9
Una vegada creat el subdirectori, crearem un arxiu index.html que serà el que servirà el web server per defecte quan naveguem cap a http://192.168.56.200/M9.
nano /var/www/html/M9/index.html
i hi afegirem un contingut HTML bàsic com ara:
<h1>Web Guillem</h1>
desarem l’arxiu i obrirem el navegador i demanarem per http://192.168.56.200/M9. Ens sortirà el contingut de l’arxiu HTML que hem creat abans:
Utilitza un port diferent del 80 per accedir a la web¶
Per a poder canviar el port d’escolta del servidor web haurem de modificar l’arxiu de configuració del dimoni del servidor. En CentOS 7 (i versions equivalents de Fedora i Red Hat Enterprise Linux) es troba a /etc/httpd/conf/httpd.conf. Editarem l’arxiu amb nano, per exemple, i buscarem la línia on es defineix la directiva Listen:
(...)# Listen: Allows you to bind Apache to specific IP addresses and/or# ports, instead of the default. See also the <VirtualHost># directive.## Change this to Listen on specific IP addresses as shown below to# prevent Apache from glomming onto all bound IP addresses.##Listen 12.34.56.78:80Listen80(...)
Una vegada haguem localitzat aquesta línia, podem canviar el valor per defecte pel nou port que volguem configurar. Podem fer que deixi d’escoltar pel 80 i escolti pel 8080 o bé podríem optar per afegir una nova directiva Listen i fer que el servidor web escoltés en múltiples ports; sempre i quan no estiguin en ús per a altres serveis.
Jo opto per a deixar d’escoltar pel 80 i escoltar només les peticions pel 1996; de manera que la línia remarcada anteriorment es converteix en:
(...)# Listen: Allows you to bind Apache to specific IP addresses and/or# ports, instead of the default. See also the <VirtualHost># directive.## Change this to Listen on specific IP addresses as shown below to# prevent Apache from glomming onto all bound IP addresses.##Listen 12.34.56.78:80Listen1996(...)
A continuació hem de parar i tornar a engegar el servidor web per tal que recarregui la configuració nova i passi a escoltar peticions pel port 1996:
..code :: bash
systemctl restart httpd
Una vegada aplicada la nova configuració, podem accedir a la web pel port triat, definint-lo a la URL tal que http://192.168.56.200:1996/M9 i obtindrem el mateix resultat que abans:
Nota
Es pot veure que la directiva Listen permet un número com a argument per a referir-se al port a través del que volem que escolti el servidor, però també podem definir una combinació adreça IP+port en el format x.y.z.t:pppp. Això pot ser útil per a servidors on tenim més d’una targeta de xarxa i volem restringir l’accés a través de només una d’elles. Si el meu servidor estigués accessible en 2 xarxes diferents com ara 192.168.56.0/24 i 172.20.20.0/24, podria decidir que només els usuaris des de la xarxa 192.168.56.0/24 tinguessin accés si definís la directiva com:
Listen192.168.56.200:1996
D’aquesta manera, li estic dient a Apache que només escolti les peticions HTTP que li provinguin per la targeta de xarxa que té IP=192.168.56.200 i que no escolti per la 172.20.20.X.
La directiva per a permetre que Apache llegeixi i tingui en compte arxius addicionals .htaccess l’afegirem al directori d’arxius de configuració creant un arxiu nou:
De manera que estem definint directives per a un directori concret; en aquest cas, per al directori on hem posat la web de prova. La directiva AllowOverrideall és la que permet que els arxius .htaccess de dins d’aquest directori, en cas d’existir, siguin parsejats per l’Apache i apliqui les directives que s’hi hagin descrit.
Per a protegir el directori de M9 d’usuaris no autoritzats afegirem doncs, un arxiu .htaccess al directori des d’on se serveix la web: /var/www/html/M9 amb el nom amb el següent contingut:
La línia important és la que defineix una ruta a un arxiu anomenat .htpasswd. És important perquè en aquest arxiu és on definirem una relació entre usuaris i passwords de manera que Apache consulti aquest arxiu per a saber si un usuari pot accedir a aquell directori o no. Per a crear aquest arxiu de claus, usarem la comanda htpasswd:
htpasswd -c /var/www/html/.htpasswd guillem
Aquesta comanda crea un arxiu .htpasswd a la ruta desitjada i ens demanarà la contrasenya que volem definir per a l’usuari que li passem com a últim paràmetre de manera que, una vegada «registrat» aquell usuari amb la seva contrasenya, podem veure que l’arxiu .htpasswd que s’ha creat té el següent contingut:
guillem:$apr1$9CRXnHWv$s4M.oat2SCzHMdKfz4Mhp0
on s’hi relaciona un usuari guillem amb un hash de la contrasenya que li hem definit. Si volem afegir més usuaris podem repetir la mateixa ordre que abans i afegir, per exemple, l’usuari xavi. Aleshores, el contingut serà:
Segons la configuració actual, la directiva Requirevalid-user permetria l’accés a qualsevol dels usuaris definits en l’arxiu .htpasswd:
Si accedim autenticant-nos com a «xavi»:
Però podem modificar aquest comportament si en comptes de posar la directiva Requirevalid-user la modifiquem per Requireuserguillem: ara estem restringint l’accés a només un usuari concret, encara que al fitxer .htpasswd també hi existeixi un tal «xavi», de manera que podem accedir si som «guillem» però no ens permet l’accés si som «xavi»:
Nota
Al fer modificacions a l’arxiu de configuració hem de fer un restart de l’Apache perquè recarregui la directiva nova que haguem modificat, per exemple quan limitem l’accés a un sol usuari o a qualsevol usuari present a l’arxiu de passwords.
M’he connectat a la web de’n Joan López des del meu navegador escrivint la seva IP i definint el subdirectori M9 per tal de veure el contingut de la seva plana. Ell ha hagut de modificar la configuració de l’Apache per a aquest directori amb una directiva Allow172.16.19.3 per tal que la meva màquina pogués accedir, mantenint la resta de la xarxa sense accés a la seva web.
Aquesta part l’haurem de fer amb un certificat autosignat. Això ens permetrà xifrar el trànsit HTTP entre el servidor i el client però no tindrem el candau verd de confiança perquè aquest certificat SSL l’hem firmat nosaltres mateixos i no hi ha cap entitat certificadora que pugui corroborar que el nostre site és nostre. Tot i això, per a realitzar la pràctica, no serà problema; tant sols haurem de saltar l’advertència de seguretat però podrem veure’n el funcionament.
El procediment per a crear aquest certificat és més o menys llarg però es pot documentar de manera simple. Els passos a seguir són els següents:
Crearem una clau privada al servidor lligada al nom de domini del web
És important que el nom de domini que escrivim coincideixi amb el nom de domini sota el qual tenim la web penjada; però com que aquesta pràctica la fem en local, no és crucial ja que no sortirà a Internet). Podem introduir una paraula de pas per a aquesta clau privada, que ens permetrà una capa de seguretat per a autenticar-nos a nosaltres mateixos com a propietaris d’aquesta clau; però tampoc és obligatòria.
openssl genrsa -des3 -out practicam09.local.key 2048
Generating RSA private key, 2048 bit long modulus
...............................+++
....................................................................................+++
e is 65537(0x10001)
Enter pass phrase for practicam09.local.key:
Verifying - Enter pass phrase for practicam09.local.key:
Crearem un Certificate Signing Request per a obtenir el certificat a partir de la clau privada generada al punt anterior
openssl req -new -key practicam09.local.key -out practicam09.local.csr
Enter pass phrase for practicam09.local.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [XX]:.
State or Province Name (full name) []:.
Locality Name (eg, city) [Default City]:.
Organization Name (eg, company) [Default Company Ltd]:Guillem Sola Boeck
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:practicam09.local
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
El que ens demana primer és la paraula de pas de la clau privada per a poder-ne saber el contingut. Llavors ens va demanant diverses dades que s’inclouran en el certificat que podrem extreure a partir d’aquest CSR com ara el codi de país, l’estat, ciutat, nom d’organització, secció, nom comú (que hauria de coincidir amb el nom de domini que volem protegir), i una adreça de correu de contacte. Aquestes dades seran públiques per a tothom que pugui accedir al nostre certificat, per exemple, qualsevol client que accedís a la nostra web xifrada amb el certificat que extreiem amb aquest CSR de manera que podem evitar dades que no volguem publicar (adreça de correu personal, potser).
Crear el certificat a partir del CSR i la clau privada
openssl x509 -req -days 365 -in practicam09.local.csr -signkey practicam09.local.key -out practicam09.local.crt
Signature ok
subject=/O=Guillem Sola Boeck/CN=practicam09.local
Getting Private key
Enter pass phrase for practicam09.local.key:
En aquest pas hem de definir un temps de caducitat del certificat (expiració). En aquest cas, aquest certificat deixarà de ser vàlid d’aquí un any.
Una vegada generat el certificat, mourem els 2 arxius necessaris (Private Key i certificat) al directori per defecte on l’Apache els pot llegir: /etc/pki/tls/ i els col·locarem al subdirectori on correspongui: certs o bé private per al certificat i la clau privada, respectivament.
Apache és un software molt modular que permet un funcionament bàsic amb la instal·lació de sèrie però es pot extendre amb mòduls addicionals. Per tal de poder oferir suport per a HTTPS amb el mòdul SSL corresponent que instal·larem
yum install mod_ssl
Amb la instal·lació d’aquest mòdul se’ns crearà un arxiu de configuració nou al directori de configuració de l’Apache que és el que s’encarrega de les directives per al default site que se servirà per HTTPS.
Aplicar el certificat al servidor Apache
L’últim pas és dir a Apache que pel port 443 (defecte per a HTTPS) xifri les comunicacions mitjançant aquest certificat que hem creat. Per no complicar-nos massa, modificaré l’arxiu de configuració per defecte que defineix les directives del meu web server pel que fa a HTTPS: /etc/httpd/conf.d/ssl.conf.
Buscarem la secció corresponent al certificat i editarem per tal de definir-hi la ruta al certificat creat.
(...)# Server Certificate:# Point SSLCertificateFile at a PEM encoded certificate. If# the certificate is encrypted, then you will be prompted for a# pass phrase. Note that a kill -HUP will prompt again. A new# certificate can be generated using the genkey(1) command.SSLCertificateFile/etc/pki/tls/certs/practicam09.local.crt(...)
(...)# Server Private Key:# If the key is not combined with the certificate, use this# directive to point at the key file. Keep in mind that if# you've both a RSA and a DSA private key you can configure# both in parallel (to also allow the use of DSA ciphers, etc.)SSLCertificateKeyFile/etc/pki/tls/private/practicam09.local.key(...)
Reiniciar servidor Apache per aplicar els canvis
Farem un systemctlrestarthttpd de manera que Apache recarregui la nova configuració amb el certificat triat. Em demana la contrasenya de la clau privada.
systemctl restart httpd
Enter SSL pass phrase for fe80::1ffe:b3b3:fb1b:5476:443 (RSA) : *********
Prova
Entrarem amb el navegador a la URL https://192.168.56.5/M9 i veurem que ens surt un avís de seguretat perquè el certificat és autosignat:
Fem un by-pass de l’advertència i mirem el contingut del certificat:
Una vegada dins la pàgina, veiem que se serveix de la mateixa manera que per HTTP pla però tenim el candau que ens avisa que la connexió amb el servidor s’ha xifrat:
Instal·lar PHP
Configura el teu web server per a que pugui processar PHP.
Necessitem instal·lar els paquets necessaris de MySQL i PHP.
yum install php
Nota
En el cas de CentOS 7 s’instal·larà PHP 5 tot i que les últimes versions són les 7; però al nivell nostre serà pràcticament transparent. De totes maneres, podem activar els repositoris Remi per poder instal·lar PHP 7 en el nostre CentOS.
Un cop instal·lat PHP, instal·larem un servidor SQL de codi obert i compatible amb MySQL que s’anomena MariaDB:
yum install mariadb mariadb-server
Nota
Tot i existir la versió 10.x com a més nova i estable d’aquest servei SQL, els repositoris oficials de CentOS instal·len la versió estable anterior (5.x). De la mateixa manera que PHP, podem utilitzar repositoris de tercers per a poder instal·lar MariaDB 10 si fos molt necessari. També hi ha una part de posada a punt del servidor MySQL que no contemplo en aquesta pràctica però que correspon a la configuració de la contrasenya de l’usuari root del servidor de MariaDB i l’habilitació (enable) i engegada (start`)delserveiensímitjançant``systemctl.
Podem comprovar la instal·lació correcta dels paquets des de la consola:
php --v
PHP 5.4.16 (cli)(built: Apr 12201819:02:01)
Copyright (c)1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c)1998-2013 Zend Technologies
mysql --version
mysql Ver 15.1 Distrib 5.5.60-MariaDB, for Linux (x86_64) using readline 5.1
Fes la teva primera pàgina PHP
Crea una pàgina PHP que mostri el teu nom i cognoms en pantalla per comprovar que tota la instal·lació anterior ha estat correcta.
Crearé un fitxer nou dins de /var/www/html/M9 que es digui index.php. El contingut d’aquest fitxer serà un simple script PHP amb una comanda echo amb el meu nom i cognoms, com es demana:
3.1. Escriu el programa que mostri en php el teu nom i cognoms, i el teu email en línies diferents¶
<?php$nom="Guillem Solà i Boeck";$mail="guillem_solaboeck@iescarlesvallbona.cat";echo"<p>El meu nom és ".$nom."</p>";echo"<p>El meu correu electrònic és ".$mail."</p>";?>
3.2. Escriu un programa que donades tres variables amb un valor diferent cadascuna les mostri per pantalla i digui el tipus¶
<?php$var1="Guillem Solà i Boeck";$var2=50;$var3=10.6;$typ1=gettype($var1);$typ2=gettype($var2);$typ3=gettype($var3);echo"<p>La variable 1 (".$var1.") és del tipus ".$typ1."</p>";echo"<p>La variable 2 (".$var2.") és del tipus ".$typ2."</p>";echo"<p>La variable 3 (".$var3.") és del tipus ".$typ3."</p>";?>
3.3. Sabent que la funció RAND ens retorna un valor aleatori entre un rang de dos enters: Genera 3 números i mostra per pantalla el tres números i la frase «El més gran és » + número més gran¶
<?php$random1=rand(3,729);#Random entre 3 i 729$random2=rand(7,987);#Random entre 7 i 987$random3=rand(0,1024);#Random entre 0 i 1024echo"<p> El primer número aleatori és el ".$random1."</p>";echo"<p> El segon número aleatori és el ".$random2."</p>";echo"<p> El tercer número aleatori és el ".$random3."</p>";$major=$random1;if($random2>$major){$major=$random2;}if($random3>$major){$major=$random3;}echo"<p> El número més gran és el ".$major."</p>";?>
3.4. Obté quin dia és avui amb date(«D») i mostra si és dilluns, dimarts, dimecres, dijous…¶
3.8. Donat una array mostra en una taula els índex i els valors¶
<?php// Array donada$matriz[0]="cougar";$matriz[1]="ford";$matriz[2]=null;$matriz[3]="2.500";$matriz[4]="V6";$matriz[5]=182;// Mostrar índexs i valorsecho"<table>";echo"<th>Índex</th><th>Valor</th>";for($i=1;$i<sizeof($matriz);$i++){echo"<tr><td>$i</td><td>$matriz[$i]</td></tr>";}echo"</table>";?>
3.9. Donat una array mostra en una taula amb noms i edats i una frase indicant qui és el més gran i el més jove¶
<?php$noms=array("Xavier"=>"40","Lluís"=>"35","Julian"=>"45");echo"<table>";echo"<th>Nom</th><th>Edat</th>";foreach($nomsas$nom=>$edat){echo"<tr><td>$nom</td><td>$edat</td></tr>";}echo"</table>";$gran=array_search(max($noms),$noms);$jove=array_search(min($noms),$noms);echo"<p>El més gran és $gran</p>";echo"<p>El més jove és $jove</p>";?>
3.10. Crea un formulari amb dues entrades de text i un botó. Introdueix dos números i realitza la suma, resta, divisió i la multiplicació dels dos números¶
3.11. Amb el mateix formulari d’abans fes que després de demanar els dos números te’ls mostri en pantalla concatenats¶
<!DOCTYPE html><html><body> <form method="GET" action="exercici11.php"> <p>Número 1: <input type="text" name="num1" value="" required/></p> <p>Número 2: <input type="text" name="num2" required/></p> <p><button type="submit">Concatena</button></p> </form><?php$num1=$_GET["num1"];$num2=$_GET["num2"];if($num1!==NULL&&$num2!==NULL){$suma=$num1+$num2;$resta=$num1-$num2;$multiplicacio=$num1*$num2;$divisio=$num1/$num2;echo"<p>".$num1.$num2."</p>";}else{echo"<p>Introdueix dos números per a concatenar.</p>";}?></body></html>
3.12. Escriu un programa PHP que mostri la següent figura¶
*********************************************
<?php$espai=" ";#Espai buit$asterisc=$espai."*";#El caràcter que formarà la piràmide$numFiles=20;#Número de files que vull generar#Executo el bucle tantes vegades com $numFiles, però inversfor($filaActual=$numFiles;$filaActual>0;$filaActual--){$caracterActual=1;#Variable per saber la posició actual dins la fila#Executo el bucle tantes vegades com caràcters calguin en aquella $filaActualfor($caracterActual;$caracterActual<=$numFiles;$caracterActual++){if($caracterActual>=$filaActual){#Si la posició actual és igual o major al número invers de la#fila actual vol dir que estem en posició de posar asteriscosecho$asterisc;}else{#Mentre la posició sigui anterior a la dels asteriscos posarem caràcters d'espai en blancecho$espai;}}echo"<br>";}?>
Crearem un formulari per a realitzar l’alta com a client a una empresa de serveis. Heu de fer un formulari d’alta d’usuari amb aquest contingut:
Tipus de document (desplegable)
NIF
NIE
Passaport
Número de document
Nom
Cognoms
Sexe (desplegable)
Home
Dona
Data de naixement
Correu electrònic
Confirmació correu electrònic
Telèfon mòbil
Població (desplegable amb 5 poblacions)
Codi Postal
Adreça
Periodicitat de cobrament (radiobutton) només es pot marcar un
Anual 100 €
Semestral 55 €
Mensual 10 €
He llegit i accepto les condicions (checkbutton)
Accepto rebre comunicacions de las empreses del grup XXX (checkbutton)
Password
Confirmació Password
Observacions (camp de text de múltiples files)
Camp per pujar un arxiu
Hi haurà el botó d’esborrar que deixarà el formulari en blanc se tenim dades introduïdes i el botó d’enviar, on mostrareu a una altre pàgina “validat.php” un text conforme s’ha enviat correctament, sempe que no hi hagi errors de validació, les dades similar a:
"Sr/a Noms i Cognoms, les seves dades s’han enregistrat correctament a les XX hores del dd/mm/aaaa"
Nota
En cas d’errors de validació s’hauran de mantenir les dades introduïdes al formulari per a no tornar a introduir-les. Investigueu la forma de fer-ho.
Restriccions/validacions
Totes les dades (camps) són obligatoris
DNI: obligatori i s’ha de validar (buscar funció validació DNI + lletra)
Data de naixement: posarem una data per defecte 01/01/2000. S’ha de validar que sigui major d’edat
Correu electrònic: obligatoris i han de ser iguals amb el camp Correu electrònic
Telèfon mòbil: s’ha de validar (9 dígits)
Password i confirmació Password: els dos són obligatoris i han de ser iguals
L’arxiu que pujarem només podrà ser en format PDF
Tots els camps de tipus INPUT han de tenir PLACEHOLDER