Apache Web Server with WebDav and SSL Encryption
Διάβασα αρκετά Tutorials & How Tos πριν γράψω αυτό το mini tutorial. Βρήκα αρκετά που περιγράφουν την υλοποίηση μέσω apache, αρκετά που εξηγούν την υλοποίηση του webdav, αρκετά για ssl (και μερικά για ldap), μα δεν βρήκα κάποιο επεξηγηματικό. Όσα βρήκα ήταν πολύ focus μόνο σε ένα αντικείμενο κι απλά είχαν και τον αντίστοιχο κώδικα.
Contents
Ο σκοπός αυτού του mini tutorial είναι η δημιουργία ενός VirtualHost στον Apache Web Server, που θα ακούει σε μία διαφορετική (non default) high TCP Port και θα υποστηρίζει το WebDav πρωτόκολλο με user authentication πάνω από SSL για κρυπτογράφηση των αρχείων μας.
Έχω χωρίσει αυτό το mini tutorial σε 4 κύρια μέρη:
- Apache Web Server – Virtual Host
- WebDav Support
- Authentication – Authorization
- SSL Support
Apache Web Server – Virtual Host
O apache είναι ο δημοφιλέστερος web server. Κατέχει το 60% της παγκόσμιας αγοράς, σύμφωνα με τα τελευταία στατιστικά της netcraft.
Τι είναι αυτό που τον κάνει τόσο δημοφιλή; Μερικά από τα προτερήματά του είναι τα εξής:
- Διανέμεται δωρεάν μαζί με τον πηγαίο κώδικα,
- Τρέχει σε πολλά και διαφορετικά λειτουργικά συστήματα,
- Υποστηρίζει πολλαπλά domains,
- Είναι αρθρωτός – modular,
- Έχουν γραφτεί χιλιάδες modules κι
- υπάρχει εκτενής τεκμηρίωση
Δεν θα εξηγήσουμε τον δομή του, μα ούτε και τα πιο βασικά σημεία του αρχείου ρυθμίσεων. Αυτό σε κάποιο άλλο tutorial.
Θα αναφερθούμε μόνο τα βασικά σημεία που αφορούν την δική μας υλοποίηση.
Virtual Host
Μέσω της directive <VirtualHost></~VirtualHost> μπορούμε να παραμετροποιήσουμε τον apache ώστε να έχει διαφορετική συμπεριφορά για κάθε domain που φιλοξενούμε. Μπορούμε ακόμα να ρυθμίσουμε διαφορετικά πράγματα ακόμα και για το ίδιο domain, εάν ορίσουμε μια διαφορετική TCP port.
Για τις ανάγκες του mini tutorial, έστω ότι το domain μας είναι το εξής: mydomain.gr
Εάν γνωρίζουμε την IP στην οποία "ακούει" ο apache μας, τότε το VirtualHost μπορεί να είναι ως εξής:
<VirtualHost IP:PORT> ServerName mydomain.gr </VirtualHost>
Εάν θέλουμε να "ακούει" σε όλες τις IPs του server μας, τότε αντικαθιστούμε την IP με το *
Εάν επιλέξουμε την πόρτα: 9999 τότε το conf μας γίνεται ως εξής:
<VirtualHost *:9999> # Name of our domain ServerName mydomain.gr # FileSystem Path of our webdav directory DocumentRoot /opt/webdav/ # Alias Alias /webdav /opt/webdav/ # Logs CustomLog logs/mydomain.webdav.access.log combined ErrorLog logs/mydomain.webdav.error.log </VirtualHost>
Εμπλουτίσαμε με μερικά χρήσιμα στοιχεία το VirtualHost, είναι πολύ απλά και δεν χρειάζονται περαιτέρω εξήγηση.
Permissions
Θα πρέπει σε αυτό το σημείο να κάνουμε μια αναφορά για τα απαραίτητα δικαιώματα που χρειάζονται.
Η εξής δήλωση:
DocumentRoot /opt/webdav/
δηλώνει ότι ο κατάλογος στον οποίο θα βρίσκονται τα αρχεία μας, θα είναι ο /opt/webdav/
Για να έχουμε πρόσβαση στον συγκεκριμένο κατάλογο και για να μπορούμε να διαχειριζόμαστε τα αρχεία που βρίσκονται μέσα σε αυτόν,
θα πρέπει ο κατάλογος να ανήκει στον χρήστη που τρέχει ο apache ή να δημιουργήσουμε έναν νέο χρήστη στον οποία θα μεταβιβάσουμε τα δικαιώματα σε αυτόν.
οι δηλώσεις στο αρχείο ρυθμίσεων του apache είναι οι εξής:
User nobody Group nobody
Οπότε θα πρέπει να τρέξουμε την εξής εντολή:
chown -R nobody.nobody /opt/webdav/
Οι παραπάνω δηλώσεις (User/~Group) μπορούν να μπουν κι εντός του VirtualHost
ώστε να μπορούμε να μεταβιβάσουμε τα δικαιώματα σε έναν διαφορετικό χρήστη.
Εάν πχ ο χρήστης μας είναι ο: webdavuser
τότε το conf μας θα πρέπει να γίνει ως εξής:
User webdavuser Group webdavuser
και δεν πρέπει να ξεχάσουμε να αλλάξουμε τα δικαιώματα στον κατάλογο:
chown -R webdavuser.webdavuser /opt/webdav/
LISTEN
Σε αυτό το σημείο, να πούμε δυο λόγια για την δήλωση LISTEN στο αρχείο ρυθμίσεων του apache μας.
Για να μπορεί ο web server μας, να ακούει στην παραπάνω TCP Port (9999), πρέπει να έχει την εξής δήλωση:
LISTEN IP:9999
εάν έχει κάτι σαν κι αυτό:
LISTEN *:9999
τότε είμαστε και πάλι εντάξει.
NameVirtualHost
Στην προκαθορισμένη εγκατάσταση του apache web server, η δήλωση: NameVirtualHost είναι πάντα σχολιασμένη.
Δηλώνει εάν θέλουμε ο apache να "ακούει" VirtualHost με βάση το όνομα ή την ip ή και τα δύο.
Προτείνω απλά να την σχολιάσετε, εάν δεν είναι ήδη. Στο δικό μου παράδειγμα είναι ως εξής:
#NameVirtualHost *:80
WebDav
Web-based Distributed Authoring and Versioning
Διαβάστε καλύτερα εδώ: WebDav on wikipedia για να ενημερωθείτε πλήρως.
Θα προσπαθήσω να εξηγήσω τι είναι όσο πιο απλά γίνεται, όπως δλδ το καταλαβαίνω κι εγώ.
Όσοι γνωρίζεται το συγκεκριμένο αντικείμενο, ΠΑΡΑΚΑΛΩ να με διορθώσετε, όπου πρέπει.
Το WebDav είναι ένα πρωτόκολλο που επιτρέπει μέσω μεθόδων την προσπέλαση αρχείων πάνω από το Http.
Κι όταν λέμε http methods, αναφερόμαστε σε κάτι τέτοιο:
- GET
- PUT
- OPTIONS
- DELETE
- POST
- PROPFIND
- PROPPATCH
- MKCOL
- COPY
- MOVE
- LOCK
- UNLOCK
Διαβάστε όμως καλύτερα εδώ: rfc 2518 που τα εξηγεί πολύ ωραία.
Με λίγα λόγια μέσω του WebDav, μπορούμε να έχουμε αρχεία σε έναν Web Server και να τα επεξεργαζόμαστε από τον browser μας.
Υποστηρίζει Locking μηχανισμούς για να μην γράφουν ταυτόχρονα δύο χρήστες, μα και μπορείς να δημιουργήσεις groups και να έχεις διαβάθμιση στην πρόσβαση των χρηστών.
Άλλοι μόνο διαβάζουν, άλλοι γράφουν σε ένα συγκεκριμένο κατάλογο ενώ κάποιοι άλλοι σε κάποιον άλλο. Κάποιοι είναι admins σε όλα κλπ κλπ.
Πολύ ενδιαφέρον είναι και ο versioning μηχανισμός των αρχείων, κάτι όμως που προστέθηκε αργότερα.
Χρησιμοποιείται αρκετά σε calendars και distribute document managements συστήματα, μιας και τα CalDAV & GroupDAV παίζουν μέσω του WebDav.
Αξίζει να ρίξετε μια ματιά στα παραπάνω δύο links που έχω καταγράψει.
WebDav on Apache
Για να χρησιμοποιήσουμε το WebDav σε κάποιο VirtualHost στον Apache, θα πρέπει το αντίστοιχο module να έχει εγκατασταθεί.
Κι αυτό γίνεται εάν το ενεργοποιήσουμε κατά την μεταγλώττιση του πηγαίου κώδικα:
./configure \ --enable-dav \ --enable-dav-fs
Στις περισσότερες εγκαταστάσεις είναι by default ενεργοποιημένο.
Για να δούμε εάν είναι όντως:
apachectl -l | grep -i dav mod_dav.c mod_dav_fs.c
Τι μπορούμε να ορίσουμε λοιπόν:
apachectl -L | grep -i ^dav DAV (mod_dav.c) DAVMinTimeout (mod_dav.c) DAVDepthInfinity (mod_dav.c) DAVLockDB (mod_dav_fs.c)
η παραπάνω εντολή:
apachectl -L | less
είναι πάρα πολύ χρήσιμη. Μας ενημερώνει για τις διαθέσιμες ρυθμίσεις στον apache μας και σε ποια directive ορίζονται.
Το παραπάνω VirtualHost γίνεται ως εξής:
<VirtualHost *:9999> # Name of our domain ServerName mydomain.gr # FileSystem Path of our webdav directory DocumentRoot /opt/webdav/ # Alias Alias /webdav /opt/webdav/ # Logs CustomLog logs/mydomain.webdav.access.log combined ErrorLog logs/mydomain.webdav.error.log # File for DAV locks DAVLockDB /var/tmp/webdav.DAVLock <Location /webdav > DAV On </Location> </VirtualHost>
Μετά από κάθε αλλαγή, ελέγχουμε το configuration του apache web server:
apachectl -S
Από αυτή την στιγμή, είμαστε έτοιμοι και μπορούμε να χρησιμοποιήσουμε τα αρχεία του καταλόγου: /opt/webdav/
μέσω ενός browser μας !!!
Simple As That
LimitExcept
Μπορεί στο παράδειγμά μας να μην χρειάζεται, αλλά είναι καλό να εξηγήσουμε τι είναι το LimitExcept.
Μπορούμε να ορίσουμε τις μεθόδους που επιτρέπουμε να χρησιμοποιηθούν στο WebDav VirtualHost μας.
Ένα παράδειγμα είναι το εξής:
<LimitExcept GET PUT> Require valid-user </LimitExcept>
ενώ ένα πιο πλήρες παράδειγμα:
<LimitExcept GET PUT POST DELETE PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK OPTIONS> Require valid-user </LimitExcept>
Authentication – Authorization
Κι εάν νομίζεται ότι μέχρι εδώ είμαστε καλά, σας ενημερώνω ότι είμαστε περίπου στην μέση!
Με το παραπάνω configuration ΔΕΝ έχουμε ορίσει ποιοι χρήστες μπορούν να διαχειριστούν τα αρχεία μας.
Υπάρχουν δύο(2) κύριοι τρόποι για να δημιουργήσουμε χρήστες και συνθηματικά στον apache:
- Basic
- Digest
Σχεδόν σε όλα τα tutorials ο Basic αναφέρεται ως μη-ασφαλής και πρέπει να αποφεύγεται.
Εμείς όμως αυτόν θα χρησιμοποιήσουμε! Γιατί ?
Μα γιατί παρακάτω θα περιγράψουμε πως θα περάσουμε την κίνησή μας πάνω από SSL.
Και ας μην γελιόμαστε, είναι πολύ πιο εύκολο και παίζει πάντα χωρίς προβλήματα!
AuthUserFile
Πρώτα πρέπει να δημιουργήσουμε το αρχείο στο οποίο θα προσθέσουμε τους χρήστες.
htpasswd -bc /var/tmp/webdav.user.file webdavuser webdavpassword
Δημιουργήσαμε ένα νέο αρχείο: /var/tmp/webdav.user.file
στο οποίο καταχωρήσαμε τον χρήστη: webdavuser
και το MD5 αποτέλεσμα του συνθηματικού: webdavpassword
Εσείς καλύτερα να βάλετε το αρχείο κάπου αλλού, σε πιο ασφαλή κατάλογο
και φυσικά να δημιουργήσετε πιο δύσκολα συνθηματικά για τους χρήστες που θέλετε.
VirtualHost – Auth Support
Το παραπάνω VirtualHost γίνεται ως εξής :
<VirtualHost *:9999> # Name of our domain ServerName mydomain.gr # FileSystem Path of our webdav directory DocumentRoot /opt/webdav/ # Alias Alias /webdav /opt/webdav/ # Logs CustomLog logs/mydomain.webdav.access.log combined ErrorLog logs/mydomain.webdav.error.log # File for DAV locks DAVLockDB /var/tmp/webdav.DAVLock <Location /webdav > DAV On # Auth Support AuthType Basic AuthName WebDav AuthUserFile /var/tmp/webdav.user.file Require valid-user </Location> </VirtualHost>
Πλέον για να αποκτήσει πρόσβαση κάποιος, στα αρχεία μας μέσω webdav θα χρειάζεται να δίνει Username/~Password
SSL Encryption
Και πως προστατεύουμε τα αρχεία μας και τα στοιχεία πρόσβασης από διάφορες υποκλοπές;
Ενεργοποιώντας: Secure Sockets Layer over HyperText Transfer Protocol
Ρίξτε μια ματιά στην εξής σελίδα: Apache SSL
Περιγράφω πως μπορούμε να παράγουμε κλειδιά και πως να τα υπογράψουμε με την χρήση ενός Self Signed Certificate Authority
Εναλλακτικά κι ο προτιμώμενος τρόπος είναι να παράγεται πιστοποιητικά και να τα υπογράψετε μέσω του Cacert
ως Trusted Third Party.
Δυστυχώς όμως by-default ο firefox δεν αποδέχεται το cacert γιατί δεν έχει περάσει ακόμα το CA audit
(για περισσότερα επί του θέματος, διαβάστε εδώ: 215243
ενώ πολλές διανομές έχουν ήδη περάσει το CaCert στο αντίστοιχο: ca-certificates πακέτο τους.
Apache – mod_ssl
Όπως και με το WebDav, για να χρησιμοποιήσουμε το SSL στον apache, χρειάζεται να το έχουμε ενεργοποιημένο.
Έτσι κατά την μεταγλώττιση του apache, θα πρέπει να έχουμε πληκτρολογήσει το εξής:
./configure \ --enable-dav \ --enable-dav-fs \ --enable-ssl
Για να δούμε εάν είναι ήδη ενεργοποιημένο στον apache μας:
apachectl -l | grep -i ssl
ενώ για να δούμε όλες τις διαθέσιμες SSL ρυθμίσεις:
apachectl -L | grep -i ^ssl
VirtualHost – SSL Support
Αφού λοιπόν έχουμε παράγει ή προμηθευτεί τα πιστοποιητικά μας και είναι υπογεγραμμένα κι έγκυρα,
μπορούμε να τα περάσουμε στο VirtualHost μας. Έτσι το παραπάνω VirtualHost γίνεται ως εξής:
<VirtualHost *:9999> # Name of our domain ServerName mydomain.gr # FileSystem Path of our webdav directory DocumentRoot /opt/webdav/ # Alias Alias /webdav /opt/webdav/ # Logs CustomLog logs/mydomain.webdav.access.log combined ErrorLog logs/mydomain.webdav.error.log # File for DAV locks DAVLockDB /var/tmp/webdav.DAVLock <Location /webdav > DAV On # Auth Support AuthType Basic AuthName WebDav AuthUserFile /var/tmp/webdav.user.file Require valid-user </Location> # SSL Support SSLEngine On SSLProtocol SSLv3 SSLCertificateFile /www/certs/mydomain.webdav.pem SSLCertificateKeyFile /www/certs/mydomain.webdav.key SSLCertificateChainFile /usr/share/ca-certificates/cacert.org/cacert.org.crt </VirtualHost>
Η δήλωση: SSLCertificateChainFile περιγράφει το αρχείο με τα: PEM-encoded Server CA Certificates (όπως γράφει στο mod_ssl).
cadaver
cadaver είναι ένας WebDav client με τον οποίο μπορούμε να δοκιμάσουμε το παραπάνω configuration μας.
[ebal@mylaptop ~]€ cadaver dav:!> help Available commands: ls cd pwd put get mget mput edit less mkcol cat delete rmcol copy move lock unlock discover steal showlocks version checkin checkout uncheckout history label propnames chexec propget propdel propset search set open close echo quit unset lcd lls lpwd logout help describe about Aliases: rm=delete, mkdir=mkcol, mv=move, cp=copy, more=less, quit=exit=bye dav:!> open https://mydomain.gr:9999/webdav Authentication required for WebDav on server `mydomain.gr': Username: webdavuser Password: dav:/webdav/> ls Listing collection `/webdav/': succeeded. bookmark.json 229803 Μάρ 19 15:31 password.json 178712 Μάρ 18 10:26 dav:/webdav/> quit Connection to `mydomain.gr' closed.