Λίστα ελέγχου για το Deployment

Το Internet είναι ένα εχθρικό περιβάλλον. Πριν ανεβάσετε το Django project σας για το ευρύ κοινό, θα πρέπει να αφιερώσετε λίγο χρόνο να ξανακοιτάξετε τις ρυθμίσεις σας σχετικά με την ασφάλεια, την απόδοση και την λειτουργικότητα.

Το Django περιέχει πολλά χαρακτηριστικά ασφαλείας. Κάποια είναι προεγκατεστημένα και πάντα ενεργοποιημένα. Κάποια άλλα είναι προαιρετικά επειδή δεν είναι πάντα κατάλληλα ή είναι μη βολικά για το development. Για παράδειγμα, ο εξαναγκασμός για χρήση HTTPS ίσως όχι μόνο να μην είναι κατάλληλο για όλα τα websites αλλά, επίσης, και μη πρακτικό όταν κάνετε development τοπικά στον υπολογιστή σας.

Ένα άλλο trade-off είναι μεταξύ των βελτιστοποιήσεων της απόδοσης (performance optimizations) και της ευκολίας. Για παράδειγμα, το caching είναι χρήσιμο στην παραγωγή, αλλά όχι τόσο για τοπικό development (στον υπολογιστή σας). Οι ανάγκες για αναφορά σφαλμάτων είναι, επίσης, διαφορετικές μεταξύ τοπικού (local) και παραγωγικού (production) περιβάλλοντος.

Η ακόλουθη λίστα ελέγχου περιλαμβάνει ρυθμίσεις που:

  • πρέπει να ρυθμιστούν κατάλληλα για το Django για την παροχή του αναμενόμενου επιπέδου ασφαλείας,
  • αναμένονται να είναι διαφορετικές για κάθε περιβάλλον,
  • ενεργοποιούν προαιρετικά χαρακτηριστικά ασφαλείας,
  • ενεργοποιούν βελτιστοποιήσεις της απόδοσης και
  • παρέχουν αναφορές σφαλμάτων.

Πολλές από αυτές τις ρυθμίσεις είναι ευαίσθητες και θα πρέπει να αντιμετωπιστούν ως απόρρητες. Αν πρόκειται να διανείμετε τον πηγαίο κώδικα του project σας, μια κοινή πρακτική είναι να δημοσιοποιήσετε τις κατάλληλες ρυθμίσεις για το αναπτυξιακό περιβάλλον και να χρησιμοποιήσετε ένα προσωπικό module ρυθμίσεων για την παραγωγή. Αντί, λοιπόν, να έχετε ένα μόνο αρχείο settings.py μπορείτε να έχετε ένα Python package με το όνομα settings και μέσα διάφορα settings αρχεία, καθένα διαφορετικό για κάθε περιβάλλον.

Τρέξτε την εντολή manage.py check --deploy

Μερικοί από τους ελέγχους που περιγράφονται παρακάτω μπορούν να αυτοματοποιηθούν χρησιμοποιώντας την επιλογή check --deploy. Σιγουρευτείτε ότι τρέχετε αυτή την εντολή σύμφωνα με το αρχείο ρυθμίσεων που αφορά στο παραγωγικό σας περιβάλλον, όπως περιγράφεται στο εγχειρίδιο της επιλογής αυτής.

Σημαντικές ρυθμίσεις

SECRET_KEY

Το μυστικό κλειδί (secret key) πρέπει να είναι μια μεγάλου μήκους τυχαία τιμή και πρέπει να κρατηθεί μυστική.

Σιγουρευτείτε ότι το κλειδί που χρησιμοποιείτε σε παραγωγικό περιβάλλον δεν χρησιμοποιείται πουθενά αλλού και αποφύγετε να το κάνετε commit σε κάποιο source control (πχ git, mercurial κλπ). Αυτό ελαχιστοποιεί τις πιθανότητες όπου κάποιος κακόβουλος τρίτος θα μπορούσε να αποκτήσει πρόσβαση στο κλειδί σας.

Αντί να υπάρχει γραμμένο, ως έχει, το κλειδί στο module των ρυθμίσεων σας, σκεφτείτε να το φορτώνετε από μια environment variable:

import os
SECRET_KEY = os.environ['SECRET_KEY']

ή από ένα αρχείο:

with open('/etc/secret_key.txt') as f:
    SECRET_KEY = f.read().strip()

DEBUG

**Δεν πρέπει ποτέ να έχετε ενεργοποιημένο το debug στην παραγωγή.

Εννοείται πως αναπτύσσετε το project σας με το DEBUG = True, αφού αυτό παρέχει μερικά χρήσιμα χαρακτηριστικά όπως full tracebacks μέσα στον browser σας.

Ωστόσο, για ένα παραγωγικό περιβάλλον, αυτό είναι μια εντελώς κακή ιδέα, επειδή διαρρέει πολλές πληροφορίες για το project σας: αποσπάσματα από τον πηγαίο κώδικα σας, τοπικές μεταβλητές, ρυθμίσεις, βιβλιοθήκες που χρησιμοποιείτε κλπ.

Ρυθμίσεις ανάλογα το περιβάλλον

ALLOWED_HOSTS

Όταν το DEBUG = False, το Django δεν μπορεί να δουλέψει χωρίς μια κατάλληλη τιμή για την ρύθμιση ALLOWED_HOSTS.

Αυτή η ρύθμιση είναι απαραίτητη για να προστατέψει το site σας από τυχόν CSRF επιθέσεις. Αν χρησιμοποιήσετε ένα wildcard (πχ *), θα πρέπει να φτιάξετε το δικό σας validation για τον HTTP header με το όνομα Host ή αλλιώς σιγουρευτείτε ότι δεν είστε ευάλωτοι από τέτοιου είδους επιθέσεις.

Θα πρέπει επίσης να ρυθμίσετε τον Web server, που βρίσκεται μπροστά από το Django, για να κάνει validate τον host. Θα πρέπει να ανταποκριθεί (respond) με μια στατική σελίδα σφάλματος ή να αγνοήσει τα requests για λανθασμένους hosts αντί να τα προωθεί στο Django. Με αυτό τον τρόπο θα αποφύγετε ψεύτικα σφάλματα μέσα στα Django logs σας (ή στα emails αν έχετε ρυθμίσει κατ’ αυτό τον τρόπο την αναφορά σφαλμάτων). Για παράδειγμα, θα μπορούσατε να ρυθμίσετε τον Web server nginx να επιστρέφει ένα σφάλμα «444 No Response» σε κάθε μη αναγνωρίσιμο host:

server {
    listen 80 default_server;
    return 444;
}

CACHES

Αν χρησιμοποιείτε μια cache, οι ρυθμίσεις της σύνδεσης ενδέχεται να είναι διαφορετικές μεταξύ του development και του production περιβάλλοντος. Η προεπιλογή του Django είναι η per-process local-memory caching που ίσως να μην είναι η επιθυμητή ρύθμιση.

Οι cache servers δεν έχουν συνήθως δυνατό σύστημα πιστοποίησης (authentication). Σιγουρευτείτε ότι δέχονται συνδέσεις μόνο από τους application servers σας.

Αν χρησιμοποιείτε την Memcached, σκεφτείτε μήπως χρησιμοποιήσετε τα cached sessions για να βελτιώσετε την απόδοση της εφαρμογής σας.

DATABASES

Οι παράμετροι σύνδεσης με την βάση δεδομένων είναι πιθανώς διαφορετικές μεταξύ development και production.

Οι κωδικοί της βάσης δεδομένων είναι πολύ ευαίσθητοι. Άλλωστε πρόκειται για κωδικούς που αν γνωστοποιηθούν, τα πραγματικά δεδομένα σας θα είναι εκτεθειμένα. Θα πρέπει να τους προστατέψετε ακριβώς όπως το SECRET_KEY.

Για μέγιστη ασφάλεια, σιγουρευτείτε ότι οι database servers δέχονται μόνο συνδέσεις από τους δικούς σας application servers.

Αν δεν έχετε κάνει κάποιο backup για τη βάση δεδομένων σας, κάντε το τώρα! Σκεφτείτε επίσης να κάνετε συχνά backup (πχ τα ξημερώματα κάθε μέρα) μέσω ενός cron job.

STATIC_ROOT και STATIC_URL

Τα static files (στατικά αρχεία – css, fonts, js, εικόνες κλπ) εξυπηρετούνται αυτόματα από τον development server. Στην παραγωγή, όμως, θα πρέπει να ορίσετε έναν φάκελο STATIC_ROOT όπου η εντολή collectstatic θα τα αντιγράψει.

Δείτε το άρθρο See Διαχειρίζοντας τα static files (πχ εικόνες, JavaScript, CSS) για περισσότερες πληροφορίες.

MEDIA_ROOT και MEDIA_URL

Τα media files τα ανεβάζουν οι χρήστες σας. Χρήστης θεωρείται και ο Django admin που έχει πρόσβαση στο Django admin και μέσα από κει ανεβάζει σε κάποιον server φωτογραφίες, αρχεία κλπ. Αυτού του είδους τα αρχεία είναι μη έμπιστα! Σιγουρευτείτε ότι ο Web server σας δεν θα πρέπει ποτέ να προσπαθήσει να τα εκτελέσει-τρέξει. Για παράδειγμα, αν ένας χρήστης ανεβάσει ένα αρχείο .php, ο Web server δεν θα πρέπει να το εκτελέσει.

Τώρα είναι μια καλή στιγμή να ελέγξετε την στρατηγική σας σχετικά με αυτού του είδους τα αρχεία.

HTTPS

Κάθε website το οποίο επιτρέπει σε χρήστες να κάνουν log in, θα πρέπει να χρησιμοποιούν HTTPS πρόσβαση για την αποφυγή της εκπομπής των διακριτικών πρόσβασης χωρίς κρυπτογράφηση. Στο Django, τα διακριτικά πρόσβασης περιλαμβάνουν τα login/password, το session cookie και τα password reset tokens. (Δεν μπορείτε να κάνετε και πολλά για να προστατέψετε τα password reset tokens αν τα στέλνετε με email.)

Η προστασία των ευαίσθητων τομέων όπως ο λογαριασμός του χρήστη ή του admin δεν είναι αρκετή, επειδή το ίδιο το session cookie χρησιμοποιείται για το HTTP και το HTTPS. Ο Web server σας θα πρέπει αν ανακατευθύνει όλη την HTTP κίνηση στην HTTPS και να εκπέμπει μόνο HTTPS requests στο Django.

Όταν ρυθμίσετε το HTTPS, ενεργοποιήστε τις ακόλουθες ρυθμίσεις.

Βελτιστοποιήσεις απόδοσης

Θέτοντας το DEBUG = False απενεργοποιεί πολλά χαρακτηριστικά τα οποία είναι χρήσιμα μόνο στο development. Επιπροσθέτως, μπορείτε να φέρετε στα μέτρα σας τις ακόλουθες ρυθμίσεις.

CONN_MAX_AGE

Ενεργοποιώντας τις μόνιμες συνδέσεις στη βάση δεδομένων θα έχετε, ως αποτέλεσμα, περισσότερη ταχύτητα όταν συνδέεστε στη βάση δεδομένων σας για πολλαπλά request. Με άλλα λόγια, δεν θέλετε να περιλαμβάνεται το ovehead για την εγκαθίδρυση νέας σύνδεσης στη βάση για κάθε νέο request.

Αυτό βοηθάει πολύ σε virtualized hosts με περιορισμένη απόδοση του δικτύου.

TEMPLATES

Ενεργοποιώντας τον cached template loader, συχνά βελτιώνει δραστικά την απόδοση, αφού αποφεύγει το compiling κάθε template κάθε φορά που χρειάζεται να γίνει rendered. Δείτε στο άρθρο template loaders για περισσότερες πληροφορίες.

Αναφορά σφαλμάτων

Όταν ανεβάσετε το site σας για το ευρύ κοινό, θα είναι πιθανόν σταθερό και πλήρως λειτουργικό, αλλά αυτό δε σημαίνει ότι έχετε υπολογίσει κάθε σφάλμα που μπορεί να προκύψει. Ευτυχώς, το Django μπορεί να αιχμαλωτίσει τα σφάλματα και να σας ειδοποιήσει καταλλήλως.

LOGGING

Επανεξετάστε τις ρυθμίσεις του logging σας πριν ανεβάσετε το website σας και ελέγξτε ότι δουλεύει πλήρως, μόλις αποκτήσετε κάποια κίνηση.

Δείτε στο άρθρο Logging για περισσότερες πληροφορίες σχετικά με το logging.

ADMINS και MANAGERS

Οι ADMINS θα ειδοποιηθούν για σφάλματα τύπου 500 μέσω email.

Οι MANAGERS θα ειδοποιηθούν για σφάλματα τύπου 404. Η ρύθμιση IGNORABLE_404_URLS μπορεί να σας βοηθήσει να φιλτράρετε τυχόν ψεύτικες αναφορές. Δείτε στο άρθρο αναφορές σφαλμάτων για λεπτομέρειες σχετικά με αναφορές σφαλμάτων μέσω email.

Δείτε στο άρθρο Αναφορά σφαλμάτων για λεπτομέρειες σχετικά με αναφορές σφαλμάτων μέσω email.

Οι αναφορές σφαλμάτων μέσω email δεν κλιμακώνονται πολύ καλά

Σκεφτείτε να χρησιμοποιήσετε ένα σύστημα παρακολούθησης όπως το Sentry πριν τα εισερχόμενα σας ξεχειλίσουν από αναφορές. Το Sentry μπορεί επίσης να ομαδοποιήσει τα logs.

Παραμετροποιώντας τα προεπιλεγμένα views σφαλμάτων

Το Django περιλαμβάνει μερικά προεπιλεγμένα views και templates για διάφορους HTTP κωδικούς σφαλμάτων. Αυτά τα templates ίσως να μην αντιπροσωπεύουν πλήρως την αίσθηση και την εμφάνιση με το υπόλοιπο site σας, οπότε ίσως να θέλετε να τα αλλάξετε. Μπορείτε, βεβαίως, παρακάμπτοντας τα προεπιλεγμένα templates και δημιουργώντας δικά σας μέσα στον πηγαίο φάκελο που κρατάτε τα templates σας: 404.html, 500.html, 403.html και 400.html. Τα προεπιλεγμένα views αρκούν για το 99% των Web εφαρμογών, αλλά αν θέλετε να τα παραμετροποιήσετε, δείτε αυτές τις οδηγίες οι οποίες περιλαμβάνουν, επίσης, λεπτομέρειες σχετικά με τα προεπιλεγμένα templates:

Επιλογές Python

Προτείνεται να ενεργοποιείτε την Python process η οποία τρέχει την Django εφαρμογή σας, χρησιμοποιώντας την επιλογή -R ή με την environment variable PYTHONHASHSEED της οποίας η τιμή θα είναι random. Αυτή η επιλογή είναι ενεργοποιημένη, από προεπιλογή, στην Python 3.3.

Αυτές οι επιλογές, σας βοηθούν να προστατέψετε το site σας από denial-of-service (DoS) επιθέσεις οι οποίες ενεργοποιούνται από προσεκτικά δημιουργημένα inputs. Αυτού του είδους η επίθεση μπορεί να αυξήσει σημαντικά την χρήση της CPU προκαλώντας πτώση της απόδοσης όταν δημιουργείτε dict instances. Δείτε στο oCERT advisory #2011-003 για περισσότερες πληροφορίες.

Back to Top