One place for hosting & domains

      Cara Menginstal Nginx pada Ubuntu 20.04


      Pengantar

      Nginx adalah salah satu server web terpopuler di dunia dan berperan sebagai hos dari sebagian situs terbesar dan situs yang memiliki lalu lintas tertinggi di jagad internet. Ini adalah pilihan ringan yang dapat digunakan baik sebagai server web atau proksi balik.

      Dalam panduan ini, kita akan membahas cara menginstal Nginx pada server Ubuntu 20.04 Anda, menyesuaikan firewall, mengelola proses Nginx, dan menyiapkan blok server untuk menjadi hos dari lebih dari satu domain dari suatu server tunggal.

      Prasyarat

      Sebelum Anda memulai panduan ini, Anda harus memiliki pengguna non-root reguler dengan privilese sudo yang terkonfigurasi di server Anda. Anda dapat mempelajari cara mengonfigurasi akun pengguna reguler dengan mengikuti Panduan penyiapan server awal untuk Ubuntu 20.04 dari kami.

      Ketika Anda sudah memiliki akun, log masuk sebagai pengguna non-root untuk memulai.

      Langkah 1 – Menginstal Nginx

      Karena Nginx tersedia di repositori asali Ubuntu, maka kita dimungkinkan untuk menginstalnya dari repositori ini menggunakan sistem pengemasan apt.

      Karena ini adalah interaksi pertama kita dengan sistem pengemasan apt pada sesi ini, kita akan memperbarui indeks pengemasan lokal agar kita memiliki akses ke daftar paket terbaru. Setelah itu, kita dapat menginstal nginx:

      • sudo apt update
      • sudo apt install nginx

      Setelah menerima prosedur, apt akan menginstal Nginx dan segala dependensi yang diperlukan ke server Anda.

      Langkah 2 – Menyesuaikan Firewall

      Sebelum menguji Nginx, perangkat lunak firewall perlu disesuaikan untuk mengizinkan akses ke layanan. Nginx mendaftarkan dirinya sendiri sebagai sebagai layanan dengan ufw pada saat instalasi, yang mempermudah untuk mengizinkan akses Nginx.

      Buat daftar konfigurasi aplikasi yang mana ufw mengetahui cara bekerja sama dengannya dengan mengetik:

      Anda akan mendapat daftar profil aplikasi:

      Output

      Available applications: Nginx Full Nginx HTTP Nginx HTTPS OpenSSH

      Seperti yang ditunjukkan oleh keluaran, ada tiga profil yang tersedia untuk Nginx:

      • Nginx Full: Profil ini membuka baik porta 80 (lalu lintas web normal dan tidak terenkripsi) dan porta 443 (lalu lintas terenkripsi TLS/SSL)
      • Nginx HTTP: Profil ini hanya membuka porta 80 (lalu lintas web normal dan tidak terenkripsi)
      • Nginx HTTPS: Profil ini hanya membuka porta 443 (lalu lintas terenkripsi TLS/SSL)

      Anda disarankan untuk mengaktifkan profil yang paling ketat yang masih akan mengizinkan lalu lintas yang telah Anda konfigurasikan. Saat ini, kita hanya perlu mengizinkan lalu lintas pada porta 80.

      Anda dapat mengaktifkan ini dengan mengetik:

      • sudo ufw allow 'Nginx HTTP'

      Anda dapat memverifikasi perubahan dengan mengetik:

      Keluaran akan mengindikasikan lalu lintas HTTP mana yang diizinkan:

      Output

      Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx HTTP ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx HTTP (v6) ALLOW Anywhere (v6)

      Langkah 3 – Memeriksa Server Web Anda

      Pada akhir proses instalasi, Ubuntu 20.04 memulai Nginx. Server web seharusnya sudah aktif dan berjalan.

      Kita dapat memeriksa dengan sistem init systemd untuk memastikan layanan sedang berjalan dengan mengetik:

      Output

      ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2020-04-20 16:08:19 UTC; 3 days ago Docs: man:nginx(8) Main PID: 2369 (nginx) Tasks: 2 (limit: 1153) Memory: 3.5M CGroup: /system.slice/nginx.service ├─2369 nginx: master process /usr/sbin/nginx -g daemon on; master_process on; └─2380 nginx: worker process

      Sebagaimana dikonfirmasi oleh keluaran ini, layanan telah berhasil dimulai. Namun, cara terbaik untuk menguji ini adalah dengan benar-benar meminta suatu laman dari Nginx.

      Anda dapat mengakses laman landas Nginx asali untuk mengonfirmasi bahwa perangkat lunak berjalan dengan baik dengan bernavigasi ke alamat IP server Anda. Jika Anda tidak mengetahui alamat IP server Anda, Anda dapat menemukannya dengan menggunakan alat icanhazip.com, yang akan memberi Anda alamat IP publik Anda sebagaimana diterima dari lokasi lain di internet:

      Saat Anda memiliki alamat IP server Anda, masukkan alamat itu ke dalam bilah alamat peramban Anda:

      http://your_server_ip
      

      Anda akan menerima laman landas Nginx asali:

      Laman asali Nginx

      Jika Anda berada di laman ini, server Anda berjalan dengan benar dan siap untuk dikelola.

      Langkah 4 – Mengelola Proses Nginx

      Karena kini server web Anda sudah aktif dan berjalan, mari kita tinjau beberapa perintah manajemen dasar.

      Untuk menghentikan server web Anda, ketik:

      • sudo systemctl stop nginx

      Untuk memulai server web saat berhenti, ketik:

      • sudo systemctl start nginx

      Untuk menghentikan lalu memulai layanan lagi, ketik:

      • sudo systemctl restart nginx

      Jika Anda hanya membuat perubahan konfigurasi, Nginx seringkali dapat memuat ulang tanpa memutus koneksi. Untuk melakukan ini, ketik:

      • sudo systemctl reload nginx

      Secara asali, Nginx dikonfigurasikan untuk memulai secara otomatis saat server melakukan boot. Jika ini bukan apa yang Anda inginkan, Anda dapat menonaktifkan perilaku ini dengan mengetik:

      • sudo systemctl disable nginx

      Untuk mengaktifkan kembali layanan agar memulai saat boot, Anda dapat mengetik:

      • sudo systemctl enable nginx

      Anda kini telah mempelajari perintah manajemen dasar dan siap untuk mengonfigurasi situs untuk menjadi hos dari lebih dari satu domain.

      Langkah 5 – Menyiapkan Blok Server (Disarankan)

      Ketika menggunakan server web Nginx, blok server (serupa dengan hos virtual di Apache) dapat digunakan untuk mengenkapsulasi detail konfigurasi dan menjadi hos untuk lebih dari satu domain dari suatu server tunggal. Kita akan menyiapkan domain bernama your_domain, tetapi Anda harus menggantinya dengan nama domain Anda sendiri. Untuk mempelajari lebih lanjut tentang menyiapkan nama domain dengan DigitalOcean, silakan merujuk ke Pengantar DNS DigitalOcean yang kami sediakan.

      Nginx pada Ubuntu 20.04 memiliki satu blok server yang diaktifkan secara asali, yang dikonfigurasi untuk menampilkan dokumen dari suatu direktori di /var/www/html. Meskipun ini berfungsi baik untuk situs tunggal, ini bisa menjadi sulit dijalankan jika Anda menjadi hos dari beberapa situs. Alih-alih memodifikasi /var/www/html, mari kita buat suatu struktur direktori di dalam /var/www untuk situs your_domain kita, dengan membiarkan /var/www/html sebagai direktori asali yang akan ditampilkan jika permintaan klien tidak cocok dengan situs lain apa pun.

      Buat direktori untuk your_domain sebagai berikut, dengan menggunakan bendera -p untuk menciptakan direktori induk apa pun yang diperlukan:

      • sudo mkdir -p /var/www/your_domain/html

      Selanjutnya, tentukan kepemilikan direktori dengan variabel lingkungan $USER:

      • sudo chown -R $USER:$USER /var/www/your_domain/html

      Izin root web Anda seharusnya benar jika Anda belum mengubah nilai umask Anda, yang menetapkan izin berkas asali. Untuk memastikan izin Anda benar dan memperbolehkan pemilik untuk membaca, menulis, dan mengeksekusi berkas, sementara hanya memperbolehkan membaca dan mengeksekusi ke grup dan lainnya, Anda dapat memasukkan perintah berikut:

      • sudo chmod -R 755 /var/www/your_domain

      Selanjutnya, buat laman index.html dengan menggunakan nano atau editor favorit Anda:

      • nano /var/www/your_domain/html/index.html

      Di dalam, tambahkan HTML sampel berikut ini:

      /var/www/your_domain/html/index.html

      <html>
          <head>
              <title>Welcome to your_domain!</title>
          </head>
          <body>
              <h1>Success!  The your_domain server block is working!</h1>
          </body>
      </html>
      

      Simpan dan tutup berkas dengan menekan CTRL dan X lalu Y dan ENTER saat Anda selesai.

      Agar Nginx menyajikan konten ini, maka diperlukan untuk menciptakan blok server dengan arahan yang benar. Alih-alih memodifikasi berkas konfigurasi asali secara langsung, mari kita buat yang baru di /etc/nginx/sites-available/your_domain:

      • sudo nano /etc/nginx/sites-available/your_domain

      Tempel di blok konfigurasi berikut, yang serupa dengan yang asali, tetapi diperbarui untuk nama domain dan direktori baru kita:

      /etc/nginx/sites-available/your_domain

      server {
              listen 80;
              listen [::]:80;
      
              root /var/www/your_domain/html;
              index index.html index.htm index.nginx-debian.html;
      
              server_name your_domain www.your_domain;
      
              location / {
                      try_files $uri $uri/ =404;
              }
      }
      

      Perhatikan bahwa kita telah memperbarui konfigurasi root ke direktori baru kita, dan server_name ke nama domain kita.

      Selanjutnya, mari kita mengaktifkan berkas dengan menciptakan tautan darinya ke direktori sites-enabled, yang dibaca Nginx selama memulai:

      • sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

      Dua blok server sekarang telah diaktifkan dan dikonfigurasi untuk merespons permintaan berdasarkan arahan listen dan server_name (Anda dapat membaca lebih lanjut tentang cara Nginx memproses arahan ini di sini):

      • your_domain: Akan merespons permintaan untuk your_domain dan www.your_domain.
      • asali: Akan merespons permintaan apa pun pada porta 80 yang tidak cocok dengan dua blok lainnya.

      Untuk menghindari masalah memori hash bucket yang dapat muncul dari penambahan nama server tambahan, maka diperlukan untuk menyesuaikan satu nilai dalam berkas /etc/nginx/nginx.conf. Buka berkas:

      • sudo nano /etc/nginx/nginx.conf

      Cari arahan server_names_hash_bucket_size dan hapus simbol # untuk menghapus komentar pada baris itu. Jika Anda menggunakan nano, Anda dapat dengan cepat mencari kata-kata di dalam berkas dengan menekan CTRL dan w.

      /etc/nginx/nginx.conf

      ...
      http {
          ...
          server_names_hash_bucket_size 64;
          ...
      }
      ...
      

      Simpan dan tutup berkas saat Anda sudah selesai.

      Selanjutnya, uji untuk memastikan bahwa tidak ada kesalahan sintaks pada berkas Nginx Anda:

      Jika tidak ada masalah apa pun, mulai kembali Nginx untuk mengaktifkan perubahan Anda:

      • sudo systemctl restart nginx

      Nginx sekarang seharusnya menyajikan nama domain Anda. Anda dapat menguji ini dengan bernavigasi ke http://your_domain, di mana Anda akan melihat sesuatu seperti ini:

      Blok server pertama Nginx

      Langkah 6 – Membiasakan Diri dengan Berkas dan Direktori Penting Nginx

      Setelah Anda mengetahui cara mengelola layanan Nginx, Anda perlu waktu beberapa menit untuk membiasakan diri dengan beberapa direktori dan berkas penting.

      Isi

      • /var/www/html: Konten web yang sebenarnya, yang secara asali hanya terdiri dari halaman Nginx asali yang Anda lihat sebelumnya, disajikan dari direktori /var/www/html. Ini dapat diubah dengan mengubah berkas konfigurasi Nginx.

      Konfigurasi Server

      • /etc/nginx: Direktori konfigurasi Nginx. Semua berkas konfigurasi Nginx berada di sini.
      • /etc/nginx/nginx.conf: Berkas konfigurasi Nginx utama. Ini dapat diubah untuk membuat perubahan pada konfigurasi global Nginx.
      • /etc/nginx/sites-available/: Direktori tempat blok server per situs dapat disimpan. Nginx tidak akan menggunakan berkas konfigurasi yang ditemukan dalam direktori ini kecuali berkas tersebut terhubung ke direktori sites-enabled. Biasanya, semua konfigurasi blok server dilakukan dalam direktori ini, lalu diaktifkan dengan menghubungkannya ke direktori lain.
      • /etc/nginx/sites-enabled/: Direktori tempat blok server yang diaktifkan per situs disimpan. Biasanya, ini dibuat dengan menghubungkan ke berkas konfigurasi yang ditemukan dalam direktori sites-available.
      • /etc/nginx/snippets: Direktori ini berisi fragmen konfigurasi yang dapat disertakan di tempat lain dalam konfigurasi Nginx. Segmen konfigurasi yang berpotensi dapat diulang adalah kandidat yang baik untuk pemfaktoran ulang menjadi snippet.

      Log Server

      • /var/log/nginx/access.log: Setiap permintaan ke server web Anda direkam dalam berkas log ini kecuali Nginx dikonfigurasi untuk tidak melakukannya.
      • /var/log/nginx/error.log: Setiap kesalahan Nginx akan direkam dalam log ini.

      Kesimpulan

      Kini server web Anda telah terinstal, Anda memiliki banyak pilihan untuk tipe konten yang dilayani dan teknologi yang Anda ingin gunakan untuk menciptakan pengalaman yang lebih kaya.

      Jika Anda ingin membangun tumpukan aplikasi yang lebih lengkap, bacalah artikel Cara Menginstal Linux, Nginx, MySQL, PHP (tumpukan LEMP) pada Ubuntu 20.04.



      Source link

      Cara Mengamankan Nginx dengan Let’s Encrypt pada Ubuntu 20.04


      Pengantar

      Let’s Encrypt adalah Otoritas Sertifikat (CA) yang menyediakan cara mudah untuk memperoleh dan menginstal sertifikat TLS/SSL gratis, yang dengan demikian mengaktifkan HTTPS terenkripsi pada server web. Ini menyederhanakan proses dengan menyediakan klien perangkat lunak, Certbot, yang berusaha mengotomatiskan sebagian besar (jika bukan semua) langkah yang diperlukan. Saat ini, seluruh proses memperoleh dan menginstal sertifikat secara sepenuhnya berjalan otomatis baik pada Apache dan Nginx.

      Dalam tutorial ini, Anda akan menggunakan Certbot untuk memperoleh sertifikat SSL gratis untuk Nginx pada Ubuntu 20.04 dan menyiapkan sertifikat Anda untuk diperbarui secara otomatis.

      Tutorial ini akan menggunakan berkas konfigurasi server Nginx terpisah, alih-alih berkas asali. Kami menyarankan menciptakan berkas blok server Nginx baru untuk setiap domain karena hal ini membantu menghindari kesalahan umum dan mempertahankan berkas asali sebagai konfigurasi fallback.

      Prasyarat

      Untuk mengikuti tutorial ini, Anda akan membutuhkan:

      • Satu server Ubuntu 20.04 yang disiapkan dengan mengikuti tutorial penyiapan server awal untuk Ubuntu 20.04 ini, termasuk satu pengguna non-root yang mendukung sudo dan satu firewall.

      • Nama domain yang terdaftar. Tutorial ini akan menggunakan example.com di seluruh bagiannya. Anda dapat membeli nama domain dari Namecheap, mendapatkan nama domain gratis dengan Freenom, atau menggunakan registrar domain pilihan Anda.

      • Kedua catatan DNS berikut disiapkan untuk server Anda. Jika Anda menggunakan DigitalOcean, silakan lihat dokumentasi DNS kami untuk detail tentang cara menambahkannya.

        • Catatan A dengan example.com yang menunjuk ke alamat IP publik server Anda.
        • Catatan A dengan www.example.com yang menunjuk ke alamat IP publik server Anda.
      • Nginx yang terinstal dengan mengikuti Cara Menginstal Nginx pada Ubuntu 20.04. Pastikan Anda memiliki blok server untuk domain Anda. Tutorial ini akan menggunakan /etc/nginx/sites-available/example.com sebagai contoh.

      Langkah 1 — Menginstal Certbot

      Langkah pertama untuk menggunakan Let’s Encrypt untuk memperoleh sertifikat SSL adalah dengan menginstal perangkat lunak Certbot pada server Anda.

      Instal Certbot dan plugin Nginx dengan apt:

      • sudo apt install certbot python3-certbot-nginx

      Certbot kini siap digunakan, namun agar Certbot dapat mengonfigurasi SSL secara otomatis untuk Nginx, kita perlu memverifikasi beberapa konfigurasi Nginx.

      Langkah 2 — Mengonfirmasi Konfigurasi Nginx

      Certbot harus mampu menemukan blok server yang benar pada konfigurasi Nginx Anda agar dapat mengonfigurasi SSL secara otomatis. Secara khusus, Certbot melakukan ini dengan mencari arahan server_name yang sesuai dengan domain yang sertifikatnya Anda mintakan.

      Jika Anda mengikuti langkah penyiapan blok server dalam tutorial instalasi Nginx, Anda seharusnya memiliki blok server untuk domain Anda di /etc/nginx/sites-available/example.com dengan arahan server_name yang sudah disiapkan dengan benar.

      Untuk memeriksa, buka berkas konfigurasi untuk domain Anda dengan menggunakan nano atau editor teks favorit Anda:

      • sudo nano /etc/nginx/sites-available/example.com

      Cari baris server_name yang sudah ada. Baris itu akan terlihat seperti ini:

      /etc/nginx/sites-available/example.com

      ...
      server_name example.com www.example.com;
      ...
      

      Jika terlihat seperti itu, keluar dari editor Anda dan lanjutkan ke langkah selanjutnya.

      Jika tidak, perbarui supaya sesuai. Lalu simpan berkas itu, keluar dari editor Anda, dan lakukan verifikasi sintaks dari editan konfigurasi Anda:

      Jika Anda mendapat pesan kesalahan, buka kembali berkas blok server dan periksa adanya salah tik atau karakter yang hilang. Setelah sintaks berkas konfigurasi Anda benar, muat ulang Nginx untuk memuat konfigurasi baru:

      • sudo systemctl reload nginx

      Certbot sekarang dapat menemukan blok server yang benar dan memperbaruinya secara otomatis.

      Selanjutnya, mari kita perbarui firewall untuk mengizinkan lalu lintas HTTPS.

      Langkah 3 — Mengizinkan HTTPS Melewati Firewall

      Jika firewall ufw Anda sudah diaktifkan, seperti yang disarankan oleh panduan prasyarat, Anda perlu menyesuaikan pengaturan untuk mengizinkan lalu lintas HTTPS. Untungnya, Nginx mendaftarkan beberapa profil dengan ufw pada saat instalasi.

      Anda dapat melihat pengaturan saat ini dengan mengetik:

      Mungkin akan terlihat seperti ini, artinya bahwa hanya lalu lintas HTTP yang diizinkan ke server web:

      Output

      Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx HTTP ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx HTTP (v6) ALLOW Anywhere (v6)

      Untuk menambahkan lalu lintas HTTPS yang masuk, mengizinkan profil Nginx Full, dan menghapus izin profil HTTP Nginx yang lewah:

      • sudo ufw allow 'Nginx Full'
      • sudo ufw delete allow 'Nginx HTTP'

      Status Anda sekarang akan terlihat seperti ini:

      Output

      Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx Full ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx Full (v6) ALLOW Anywhere (v6)

      Selanjutnya, mari kita jalankan Certbot dan ambil sertifikat kita.

      Langkah 4 — Memperoleh Sertifikat SSL

      Certbot menyediakan berbagai cara untuk memperoleh sertifikat SSL melalui plugin. Plugin Nginx akan menangani konfigurasi ulang Nginx dan memuat ulang konfigurasi itu ketika diperlukan. Untuk menggunakan plugin ini, ketik yang berikut ini:

      • sudo certbot --nginx -d example.com -d www.example.com

      Ini menjalankan certbot dengan plugin --nginx, menggunakan -d untuk menentukan nama domain yang kita ingin sertifikatnya valid digunakan.

      Jika ini adalah pertama kalinya Anda menjalankan certbot, Anda akan diminta memasukkan alamat email dan menyetujui persyaratan layanan. Setelah melakukan itu, certbot akan berkomunikasi dengan server Let’s Encrypt, lalu menjalankan tantangan untuk memverifikasi bahwa Anda mengontrol domain yang Anda mintakan sertifikatnya.

      Jika itu berhasil, certbot akan bertanya bagaimana Anda ingin mengonfigurasi pengaturan HTTPS Anda.

      Output

      Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

      Tentukan pilihan Anda lalu tekan ENTER. Konfigurasi akan diperbarui, dan Nginx akan memuat ulang untuk menerapkan pengaturan baru. certbot akan merangkum dengan pesan yang memberi tahu Anda bahwa proses berhasil dan di mana tempat sertifikat Anda disimpan:

      Output

      IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/example.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/example.com/privkey.pem Your cert will expire on 2020-08-18. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

      Sertifikat Anda sudah diunduh, terinstal, dan dimuat. Coba muat ulang situs Anda dengan menggunakan https:// dan perhatikan indikator keamanan di peramban Anda. Seharusnya ada indikasi bahwa situs itu sudah diamankan dengan benar, biasanya dengan ikon kunci. Jika Anda menguji server Anda menggunakan SSL Labs Server Test, server akan mendapat nilai A.

      Mari kita selesaikan dengan menguji proses pembaruan ini.

      Langkah 5 — Memverifikasi Pembaruan Otomatis Certbot

      Sertifikat Let’s Encrypt hanya berlaku selama 90 hari. Ini dimaksudkan untuk mendorong pengguna untuk mengotomatiskan proses pembaruan sertifikat mereka. Paket certbot yang kita instal akan mengurus ini untuk kita dengan menambahkan pengatur waktu systemd yang akan berjalan dua kali sehari dan secara otomatis memperbarui sertifikat apa pun yang akan kedaluarsa dalam waktu 30 hari.

      Anda dapat menanyakan status pengatur waktu dengan systemctl:

      • sudo systemctl status certbot.timer

      Output

      ● certbot.timer - Run certbot twice daily Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled) Active: active (waiting) since Mon 2020-05-04 20:04:36 UTC; 2 weeks 1 days ago Trigger: Thu 2020-05-21 05:22:32 UTC; 9h left Triggers: ● certbot.service

      Untuk menguji proses pembaruan, Anda dapat melakukan uji coba dengan certbot:

      • sudo certbot renew --dry-run

      Jika Anda tidak melihat kesalahan, Anda sudah siap. Ketika diperlukan, Certbot akan memperbarui sertifikat Anda dan memuat ulang Nginx untuk menerapkan perubahan itu. Jika proses pembaruan otomatis itu terus-menerus gagal, Let’s Encrypt akan mengirim pesan ke surel yang Anda tentukan, memperingatkan Anda saat sertifikat Anda akan berakhir.

      Kesimpulan

      Dalam tutorial ini, Anda telah menginstal certbot klien Let’s Encrypt, mengunduh sertifikat SSL untuk domain Anda, mengonfigurasi Nginx untuk menggunakan sertifikat ini, dan menyiapkan pembaruan sertifikat otomatis. Jika Anda memiliki pertanyaan lebih lanjut tentang cara menggunakan Certbot, dokumentasi resmi ini adalah tempat yang baik untuk memulai.



      Source link

      Skalieren und Sichern einer Django-Anwendung mit Docker, Nginx und Let’s Encrypt


      Einführung

      In cloudbasierten Umgebungen gibt es mehrere Möglichkeiten, eine Django-Anwendung zu skalieren und zu sichern. Durch horizontale Skalierung und die Ausführung mehrerer Kopien Ihrer Anwendung können Sie ein fehlertolerantes und hochverfügbares System aufbauen und gleichzeitig den Durchsatz erhöhen, sodass Anfragen gleichzeitig verarbeitet werden können. Eine Möglichkeit zur horizontalen Skalierung einer Django-Anwendung besteht darin, zusätzliche App-Server bereitzustellen, die Ihre Django-Anwendung und Ihren WSGI-HTTP-Server (wie Gunicorn oder uWSGI) ausführen. Um eingehende Anfragen über diesen Satz von App-Servern zu leiten und zu verteilen, können Sie einen Load Balancer und Reverse Proxy wie Nginx verwenden. Nginx kann auch statische Inhalte zwischenspeichern und Transport Layer Security-Verbindungen (TLS-Verbindungen) beenden, die zur Bereitstellung von HTTPS- und sicheren Verbindungen zu Ihrer Anwendung verwendet werden.

      Die Ausführung Ihrer Django-Anwendung und des Nginx-Proxys innerhalb von Docker-Containern stellt sicher, dass sich diese Komponenten unabhängig von der Umgebung, in der sie bereitgestellt werden, gleich verhalten. Darüber hinaus bieten Container viele Funktionen, die das Paketieren und Konfigurieren Ihrer Anwendung erleichtern.

      In diesem Tutorial skalieren Sie eine containerisierte Django- und Gunicorn-Umfrageanwendung horizontal, indem Sie zwei App-Server bereitstellen, die jeweils eine Kopie eines Django- und Gunicorn-Anwendungscontainers ausführen.

      Des Weiteren aktivieren Sie HTTPS, indem Sie einen dritten Proxy-Server bereitstellen und konfigurieren, auf dem ein Nginx Reverse-Proxy-Container und ein Certbot-Client-Container ausgeführt werden. Certbot stellt TLS-Zertifikate für Nginx von der Let’s Encrypt Zertifizierungsstelle bereit. Dadurch wird sichergestellt, dass Ihre Website von SSL Labs eine hohe Sicherheitsbewertung erhält. Dieser Proxy-Server empfängt alle externen Anfragen Ihrer Anwendung und sitzt vor den beiden upstream Django-App-Servern. Schließlich härten Sie dieses verteilte System ab, indem Sie den externen Zugriff auf nur den Proxy-Server beschränken.

      Voraussetzungen

      Um dieser Anleitung zu folgen, benötigen Sie:

      • Drei Ubuntu 18.04-Server:

        • Zwei Server werden App-Server sein, die zum Ausführen Ihrer Django- und Gunicorn-Anwendung verwendet werden.
        • Ein Server wird ein Proxy-Server sein, auf dem Nginx und Certbot ausgeführt werden.
        • Alle Server sollten einen Nicht-Root-Benutzer mit sudo-Berechtigungen und eine aktive Firewall haben. Eine Anleitung für das Setup finden Sie im Leitfaden für die Ersteinrichtung des Servers.
      • Auf allen drei Servern installiertes Docker. Eine Anleitung zur Installation von Docker finden Sie in den Schritten 1 und 2 von Installieren und Verwenden von Docker unter Ubuntu 18.04.

      • Einen registrierten Domänennamen. In diesem Tutorial wird durchgängig your_domain.com verwendet. Einen Domänennamen können Sie kostenlos bei Freenom erhalten oder Sie nutzen eine Domänenregistrierungsstelle Ihrer Wahl.

      • Einen DNS-A-Eintrag mit your-domain.com, der auf die öffentliche IP-Adresse Ihres Proxy-Servers verweist. Falls Sie ein DigitalOcean-Konto nutzen, können Sie in dieser Einführung in DigitalOcean-DNS im Einzelnen nachlesen, wie Sie ihn hinzufügen.

      • Einen S3-Objektspeicher-Bucket wie beispielsweise einen DigitalOcean Space zur Speicherung der statischen Dateien Ihres Django-Projekts und einen Satz von Zugriffsschlüsseln für diesen Space. Um zu erfahren, wie Sie einen Space erstellen können, lesen Sie die Produktdokumentation Erstellen von Spaces. Um zu erfahren, wie Sie Zugriffsschlüssel für Spaces erstellen können, lesen Sie Zugriff auf Spaces mit Zugriffsschlüsseln gemeinsam nutzen. Mit geringfügigen Änderungen können Sie jeden Objektspeicherdienst verwenden, der das Plugin django-storages verwendet.

      • Eine PostgreSQL-Server-Instanz, Datenbank und Benutzer für Ihre Django-Anwendung. Mit geringfügigen Änderungen können Sie jede Datenbank verwenden, die Django unterstützt.

      Schritt 1 – Konfigurieren des ersten Django-App-Servers

      Wir klonen zunächst das Django-Anwendungs-Repository auf den ersten App-Server. Dann konfigurieren und erstellen wir das Docker-Image und testen die Anwendung durch Ausführung des Django-Containers.

      Anmerkung: Wenn Sie von Erstellen einer Django- und Gunicorn-Anwendung mit Docker fortfahren, haben Sie Schritt 1 bereits abgeschlossen und können mit Schritt 2 fortfahren, um den zweiten App-Server zu konfigurieren.

      Beginnen Sie mit der Anmeldung beim ersten der beiden Django-App-Server und verwenden Sie git, um den Zweig polls-docker der Django Tutorial Umfrageanwendung GitHub-Repository zu klonen. Dieses Repository enthält Code für die Umfrage-Beispielanwendung der Django-Dokumentation. Der Zweig polls-docker enthält eine dockerisierte Version der Umfrageanwendung. Um zu erfahren, wie die Umfrageanwendung modifiziert wurde, um effektiv in einer containerisierten Umgebung zu arbeiten, lesen Sie bitte Erstellen einer Django- und Gunicorn-Anwendung mit Docker.

      • git clone --single-branch --branch polls-docker https://github.com/do-community/django-polls.git

      Navigieren Sie in das Verzeichnis django-polls:

      cd django-polls
      

      Dieses Verzeichnis enthält den Python-Code der Django-Anwendung, ein Dockerfile, das Docker zum Erstellen des Container-Images verwendet, sowie eine Datei env, die eine Liste von Umgebungsvariablen enthält, die an die laufende Umgebung des Containers übergeben werden müssen. Prüfen Sie das Dockerfile mit cat:

      cat Dockerfile
      

      Output

      FROM python:3.7.4-alpine3.10 ADD django-polls/requirements.txt /app/requirements.txt RUN set -ex && apk add --no-cache --virtual .build-deps postgresql-dev build-base && python -m venv /env && /env/bin/pip install --upgrade pip && /env/bin/pip install --no-cache-dir -r /app/requirements.txt && runDeps="$(scanelf --needed --nobanner --recursive /env | awk '{ gsub(/,/, "nso:", $2); print "so:" $2 }' | sort -u | xargs -r apk info --installed | sort -u)" && apk add --virtual rundeps $runDeps && apk del .build-deps ADD django-polls /app WORKDIR /app ENV VIRTUAL_ENV /env ENV PATH /env/bin:$PATH EXPOSE 8000 CMD ["gunicorn", "--bind", ":8000", "--workers", "3", "mysite.wsgi"]

      Dieses Dockerfile verwendet das offizielle Python 3.7.4 Docker-Image als Basis und installiert die Python-Paketanforderungen von Django und Gunicorn, wie sie in der Datei django-polls/requirements.txt definiert sind. Anschließend entfernt es einige unnötige Builddateien, kopiert den Anwendungscode in das Image und legt den Ausführungspfad PATH fest. Schließlich gibt es an, dass Port 8000 verwendet wird, um eingehende Container-Verbindungen zu akzeptieren und gunicorn mit 3 Workern ausgeführt wird, die Port 8000 abhören.

      Um mehr über die einzelnen Schritte in diesem Dockerfile zu erfahren, lesen Sie bitte Schritt 6 von Erstellen einer Django- und Gunicorn-Anwendung mit Docker.

      Erstellen Sie nun das Image mit docker build:

      Wir benennen das Image polls mit dem Flag -t und übergeben im aktuellen Verzeichnis als Build-Kontext den Satz von Daten, auf den beim Erstellen des Images verwiesen werden soll.

      Nachdem Docker das Image erstellt und mit Tags versehen hat, listen wir die verfügbaren Images mit docker images auf:

      docker images
      

      Sie sollten die polls-Images aufgelistet sehen:

      Output

      REPOSITORY TAG IMAGE ID CREATED SIZE polls latest 80ec4f33aae1 2 weeks ago 197MB python 3.7.4-alpine3.10 f309434dea3a 8 months ago 98.7MB

      Bevor wir den Django-Container ausführen, müssen wir seine Betriebsumgebung mithilfe der im aktuellen Verzeichnis vorhandenen Datei env konfigurieren. Diese Datei wird an den Befehl docker run übergeben, der zum Ausführen des Containers verwendet wird, und Docker injiziert die konfigurierten Umgebungsvariablen in die Betriebsumgebung des Containers.

      Öffnen Sie die Datei env mit nano oder Ihrem bevorzugten Editor:

      nano env
      

      Wir werden die Datei wie nachfolgend beschrieben konfigurieren und Sie müssen einige zusätzliche Werte hinzufügen.

      django-polls/env

      DJANGO_SECRET_KEY=
      DEBUG=True
      DJANGO_ALLOWED_HOSTS=
      DATABASE_ENGINE=postgresql_psycopg2
      DATABASE_NAME=polls
      DATABASE_USERNAME=
      DATABASE_PASSWORD=
      DATABASE_HOST=
      DATABASE_PORT=
      STATIC_ACCESS_KEY_ID=
      STATIC_SECRET_KEY=
      STATIC_BUCKET_NAME=
      STATIC_ENDPOINT_URL=
      DJANGO_LOGLEVEL=info
      

      Geben Sie die fehlenden Werte für die folgenden Schlüssel ein:

      • DJANGO_SECRET_KEY: Setzen Sie diesen auf einen eindeutigen, nicht vorhersagbaren Wert, wie in den Django-Dokumentationen beschrieben. Eine Methode zur Generierung dieses Wertes wird in Anpassen der Anwendungseinstellungen in dem Tutorial Skalierbare Django-Anwendung angeboten.
      • DJANGO_ALLOWED_HOSTS: Diese Variable sichert die Anwendung und verhindert HTTP-Host-Header-Angriffe. Setzen Sie diese Variable für Testzwecke auf *, einen Platzhalter, der auf alle Hosts zutrifft. In der Produktion sollten Sie diese Variable auf your_domain.com setzen. Um mehr über diese Django-Einstellungen zu erfahren, konsultieren Sie die Core-Einstellungen der Django-Dokumentation.
      • DATABASE_USERNAME: Setzen Sie diesen auf den in den vorbereitenden Schritten erstellten PostgreSQL Datenbankbenutzer.
      • DATABASE_NAME: Setzen Sie diesen auf polls oder den in den vorbereitenden Schritten erstellten Namen der PostgreSQL-Datenbank.
      • DATABASE_PASSWORD: Setzen Sie dieses auf das in den vorbereitenden Schritten erstellte Passwort für den PostgreSQL Benutzer.
      • DATABASE_HOST: Setzen Sie diesen Wert auf den Hostnamen Ihrer Datenbank.
      • DATABASE_PORT: Setzen Sie diesen Wert auf den Port Ihrer Datenbank.
      • STATIC_ACCESS_KEY_ID: Setzen Sie diesen Wert auf den Zugriffsschlüssel Ihres S3-Buckets oder Space.
      • STATIC_SECRET_KEY: Setzen Sie diesen Wert auf das Zugriffsschlüsselgeheimnis Ihres S3-Bucket oder Space
      • STATIC_BUCKET_NAME: Setzen Sie diesen auf Ihren S3-Bucket- oder Space-Namen.
      • STATIC_ENDPOINT_URL: Setzen Sie diese auf die entsprechenden S3-Bucket- oder Space-Endpunkt-URL, z.B. https://space-name.nyc3.digitaloceanspaces.com, wenn sich Ihr Space in der Region nyc3 befindet.

      Wenn Sie die Bearbeitung abgeschlossen haben, speichern und schließen Sie die Datei.

      Wir verwenden nun docker run, um den CMD-Satz in dem Dockerfile zu überschreiben und das Datenbankschema mit den Befehlen manage.py makemigrations und manage.py migrate zu erstellen:

      docker run --env-file env polls sh -c "python manage.py makemigrations && python manage.py migrate"
      

      Wir führen das Container-Image polls:latest aus, übergeben die von uns gerade modifizierte Umgebungsvariablendatei und überschreiben den Dockerfile-Befehl mit sh -c "python manage.py makemigrations && python manage.py migrate", wodurch das durch den Anwendungscode definierte Datenbankschema erstellt wird. Wenn Sie dies zum ersten Mal ausführen, sollten Sie Folgendes sehen:

      Output

      No changes detected Operations to perform: Apply all migrations: admin, auth, contenttypes, polls, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying polls.0001_initial... OK Applying sessions.0001_initial... OK

      Dies zeigt an, dass das Datenbankschema erfolgreich erstellt wurde.

      Wenn Sie die Migration zu einem späteren Zeitpunkt ausführen, führt Django eine Nulloperation durch, es sei denn, das Datenbankschema wurde geändert.

      Als Nächstes führen wir eine weitere Instanz des Anwendungscontainers aus und verwenden darin eine interaktive Shell, um einen Administratorbenutzer für das Django-Projekt zu erstellen.

      docker run -i -t --env-file env polls sh
      

      Dadurch erhalten Sie eine Shell-Eingabeaufforderung innerhalb des laufenden Containers, die Sie zum Erstellen des Django-Benutzers verwenden können:

      python manage.py createsuperuser
      

      Geben Sie einen Benutzernamen, eine E-Mail-Adresse und ein Passwort für Ihren Benutzer ein. Drücken Sie nach dem Erstellen des Benutzers STRG+D, um den Container zu verlassen und zu beenden.

      Schließlich generieren wir die statischen Dateien für die Anwendung und laden sie mit collectstatic in den DigitalOcean Space hoch. Beachten Sie, dass dies möglicherweise einige Zeit dauern kann.

      docker run --env-file env polls sh -c "python manage.py collectstatic --noinput"
      

      Nachdem diese Dateien generiert und hochgeladen sind, erhalten Sie folgende Ausgabe.

      Output

      121 static files copied.

      Wir können die Anwendung nun ausführen:

      docker run --env-file env -p 80:8000 polls
      

      Output

      [2019-10-17 21:23:36 +0000] [1] [INFO] Starting gunicorn 19.9.0 [2019-10-17 21:23:36 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1) [2019-10-17 21:23:36 +0000] [1] [INFO] Using worker: sync [2019-10-17 21:23:36 +0000] [7] [INFO] Booting worker with pid: 7 [2019-10-17 21:23:36 +0000] [8] [INFO] Booting worker with pid: 8 [2019-10-17 21:23:36 +0000] [9] [INFO] Booting worker with pid: 9

      Hier führen wir den in dem Dockerfile definierten Standardbefehl gunicorn ---bind :8000 --workers 3 mysite.wsgi:application aus und stellen den Container-Port 8000 frei, sodass Port 80 auf dem Ubuntu-Server dem Port 8000 des Containers poll zugeordnet wird.

      Sie sollten nun über Ihren Webbrowser zu der Anwendung polls navigieren können, indem Sie http://APP_SERVER_1_IP in der URL-Leiste eingeben. Da für den Pfad / keine Route definiert ist, erhalten Sie wahrscheinlich einen 404 Page Not Found-Fehler, der zu erwarten ist.

      Warnung: Wenn Sie die UFW-Firewall mit Docker verwenden, umgeht Docker alle konfigurierten UFW-Firewallregeln, wie in diesem GitHub-Problem dokumentiert. Dies erklärt, warum Sie Zugriff auf Port 80 Ihres Servers haben, obwohl Sie in keinem vorbereitenden Schritt explizit eine UFW-Zugriffsregel erstellt haben. In Schritt 5 werden wir diese Sicherheitslücke schließen, indem wir die UFW-Konfiguration patchen. Wenn Sie UFW nicht verwenden und die Cloud Firewalls von DigitalOcean einsetzen, können Sie diese Warnung getrost ignorieren.

      Navigieren Sie zu http://APP_SERVER_1_IP/polls, um die Benutzeroberfläche der Umfrageanwendung zu sehen:

      Oberfläche der Umfrageanwendung

      Um die administrative Oberfläche anzuzeigen, besuchen Sie http://APP_SERVER_1_IP/admin. Sie sollten das Authentifizierungsfenster für den Administrator der Umfrageanwendung sehen:

      Authentifizierungsseite für Polls-Administrator

      Geben Sie den administrativen Benutzernamen und das Passwort ein, das Sie mit dem Befehl createsuperuser erstellt haben.

      Nach der Authentifizierung können Sie auf die administrative Oberfläche der Umfrageanwendung zugreifen:

      Administrative Hauptoberfläche von Polls

      Beachten Sie, dass statische Assets für die Anwendungen admin und polls direkt aus dem Objektspeicher bereitgestellt werden. Um dies zu bestätigen, konsultieren Sie Prüfen der statischen Dateizustellung von Spaces.

      Wenn Sie die Erkundung abgeschlossen haben, drücken Sie Strg+C im Terminalfenster, in dem der Docker-Container ausgeführt wird, um den Container zu beenden.

      Nachdem Sie nun bestätigt haben, dass der App-Container wie erwartet ausgeführt wird, können Sie ihn im getrennten (detached) Modus ausführen, wodurch er im Hintergrund ausgeführt wird und Ihnen ermöglicht, sich von Ihrer SSH-Sitzung abzumelden:

      docker run -d --rm --name polls --env-file env -p 80:8000 polls
      

      Das Flag -d weist Docker an, den Container im getrennten Modus auszuführen, das Flag -rm säubert das Dateisystem des Containers nach dem Verlassen des Containers und wir benennen den Container polls.

      Melden Sie sich von dem ersten Django App-Server ab und navigieren Sie zu http://APP_SERVER_1_IP/polls, um zu bestätigen, dass der Container wie erwartet ausgeführt wird.

      Nachdem Ihr erster Django-App-Server ausgeführt wird, können Sie nun Ihren zweiten Django-App-Server einrichten.

      Schritt 2 – Konfigurieren des zweiten Django-App-Servers

      Da viele der Befehle zur Einrichtung dieses Servers die gleichen sind wie im vorherigen Schritt, werden sie hier in abgekürzter Form dargestellt. Bitte lesen Sie Schritt 1 für weitere Informationen zu einem bestimmten Befehl in diesem Schritt.

      Beginnen Sie damit, sich bei dem zweiten Django-App-Server anzumelden.

      Klonen Sie den Zweig polls-docker des GitHub-Repositorys von django-polls:

      • git clone --single-branch --branch polls-docker https://github.com/do-community/django-polls.git

      Navigieren Sie in das Verzeichnis django-polls:

      cd django-polls
      

      Erstellen Sie das Image mit docker build:

      Öffnen Sie die Datei env mit nano oder Ihrem bevorzugten Editor:

      nano env
      

      django-polls/env

      DJANGO_SECRET_KEY=
      DEBUG=True
      DJANGO_ALLOWED_HOSTS=
      DATABASE_ENGINE=postgresql_psycopg2
      DATABASE_NAME=polls
      DATABASE_USERNAME=
      DATABASE_PASSWORD=
      DATABASE_HOST=
      DATABASE_PORT=
      STATIC_ACCESS_KEY_ID=
      STATIC_SECRET_KEY=
      STATIC_BUCKET_NAME=
      STATIC_ENDPOINT_URL=
      DJANGO_LOGLEVEL=info
      

      Geben Sie die fehlenden Werte wie in Schritt 1 ein. Wenn Sie die Bearbeitung abgeschlossen haben, speichern und schließen Sie die Datei.

      Führen Sie den App-Container anschließend im getrennten Modus aus:

      docker run -d --rm --name polls --env-file env -p 80:8000 polls
      

      Navigieren Sie zu http://APP_SERVER_2_IP/polls, um zu bestätigen, dass der Container wie erwartet ausgeführt wird. Sie können sich sicher von dem zweiten App-Server anmelden, ohne Ihren laufenden Container zu beenden.

      Da beide Django App-Container ausgeführt werden, können Sie mit der Konfiguration des Reverse-Proxy-Containers von Nginx fortfahren.

      Schritt 3 – Konfigurieren des Nginx Docker-Containers

      Nginx ist ein vielseitiger Webserver, der eine Reihe von Funktionen wie Reverse-Proxying, Load Balancing und Caching bietet. In diesem Tutorial haben wir die statischen Assets von Django in den Objektspeicher ausgelagert, sodass wir die Caching-Funktionen von Nginx nicht verwenden werden. Wir werden Nginx jedoch als Reverse-Proxy für unsere beiden Backend-Django-App-Server verwenden und eingehende Anfragen zwischen ihnen verteilen. Darüber hinaus wird Nginx TLS-Terminierung und -Umleitung unter Verwendung eines von Certbot bereitgestellten TLS-Zertifikats durchführen. Das bedeutet, dass es die Clients zwingen wird, HTTPS zu verwenden, und eingehende HTTPS-Anfragen an Port 443 umzuleiten. Anschließend entschlüsselt Nginx HTTPS-Anfragen und leitet sie an die vorgelagerten Django-Server weiter.

      In diesem Tutorial haben wir die Designentscheidung getroffen, die Nginx-Container von den Backend-Servern zu entkoppeln. Abhängig von Ihrem Anwendungsfall können Sie sich dafür entscheiden, den Nginx-Container auf einem der Django-App-Server auszuführen, das Proxying von Anfragen sowohl lokal als auch auf dem anderen Django-Server auszuführen. Eine weitere mögliche Architektur wäre die Ausführung von zwei Nginx-Containern, einer auf jedem Backend-Server, mit einem Cloud Load Balancer davor. Jede Architektur bietet andere Sicherheits- und Leistungsvorteile und Sie sollten Ihr System einem Lasttest unterziehen, um Engpässe aufzudecken. Die in diesem Tutorial beschriebene flexible Architektur ermöglicht es Ihnen, sowohl die Backend-Django-Anwendungsschicht als auch die Nginx-Proxying-Schicht zu skalieren. Sobald der einzelne Nginx-Container zum Engpass wird, können Sie auf mehrere Nginx-Proxys skalieren und einen Cloud Load Balancer oder schnellen L4 Load Balancer wie HAProxy hinzufügen.

      Da beide Django-App-Server ausgeführt werden, können wir mit dem Einrichten des Proxy-Servers beginnen. Melden Sie sich an Ihrem Proxy-Server an und erstellen Sie ein Verzeichnis namens conf:

      mkdir conf
      

      Erstellen Sie mit nano oder Ihrem bevorzugten Editor eine Konfigurationsdatei namens nginx.conf:

      nano conf/nginx.conf
      

      Fügen Sie die folgende Nginx-Konfiguration ein:

      conf/nginx.conf

      
      upstream django {
          server APP_SERVER_1_IP;
          server APP_SERVER_2_IP;
      }
      
      server {
          listen 80 default_server;
          return 444;
      }
      
      server {
          listen 80;
          listen [::]:80;
          server_name your_domain.com;
          return 301 https://$server_name$request_uri;
      }
      
      server {
          listen 443 ssl http2;
          listen [::]:443 ssl http2;
          server_name your_domain.com;
      
          # SSL
          ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
          ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;
      
          ssl_session_cache shared:le_nginx_SSL:10m;
          ssl_session_timeout 1440m;
          ssl_session_tickets off;
      
          ssl_protocols TLSv1.2 TLSv1.3;
          ssl_prefer_server_ciphers off;
      
          ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
      
          client_max_body_size 4G;
          keepalive_timeout 5;
      
              location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header Host $http_host;
                proxy_redirect off;
                proxy_pass http://django;
              }
      
          location ^~ /.well-known/acme-challenge/ {
              root /var/www/html;
          }
      
      }
      

      Diese Blöcke upstream, server und location konfigurieren Nginx so, dass HTTP-Anfragen an HTTPS umgeleitet werden und sorgen für einen Lastausgleich zwischen den beiden in Schritt 1 und 2 konfigurierten Django-App-Servern. Um mehr über die Nginx-Konfigurationsdatei zu erfahren, lesen Sie bitte in diesem Artikel über das Verstehen der Nginx-Konfigurationsdateistruktur und der Konfigurationskontexte. Außerdem kann dieser Artikel zum Verstehen von Nginx-Server und Location-Block-Auswahlalgorithmen hilfreich sein.

      Diese Konfiguration wurde aus Beispielkonfigurationsdateien zusammengestellt, die von Gunicorn, Certbot und Nginx bereitgestellt wurden, und ist als eine minimale Nginx-Konfiguration gedacht, um diese Architektur betriebsbereit zu machen. Die Feineinstellung dieser Nginx-Konfiguration geht über den Umfang dieses Artikels hinaus, Sie können jedoch ein Tool wie NGINXConfig verwenden, um performante und sichere Nginx-Konfigurationsdateien für Ihre Architektur zu generieren.

      Der Block upstream definiert die Gruppe von Servern, die zum Proxying von Anfragen zur Verwendung der Anweisung proxy_pass verwendet werden:

      conf/nginx.conf

      upstream django {
          server APP_SERVER_1_IP;
          server APP_SERVER_2_IP;
      }
      . . .
      

      In diesem Block nennen wir den upstream django und schließen die IP-Adressen der beiden Django-App-Server ein. Wenn die App-Server auf DigitalOcean ausgeführt werden und VPC Networking aktiviert haben, sollten Sie hier ihre privaten IP-Adressen verwenden. Um zu erfahren, wie Sie VPC-Networking auf DigitalOcean aktivieren können, lesen Sie bitte Aktivieren von VPC-Networking auf vorhandenen Droplets.

      Der erste Block server erfasst Anfragen, die nicht Ihrer Domäne entsprechen und beendet die Verbindung. Beispielsweise würde eine direkte HTTP-Anfrage an die IP-Adresse Ihres Servers von diesem Block bearbeitet werden:

      conf/nginx.conf

      . . .
      server {
          listen 80 default_server;
          return 444;
      }
      . . .
      

      Der nächste Block server leitet HTTP-Anfragen an Ihre Domäne über eine HTTP 301-Umleitung an HTTPS um. Diese Anfragen werden dann vom letzten Block server bearbeitet:

      conf/nginx.conf

      . . .
      server {
          listen 80;
          listen [::]:80;
          server_name your_domain.com;
          return 301 https://$server_name$request_uri;
      }
      . . .
      

      Diese zwei Anweisungen definieren die Pfade zum TLS-Zertifikat und geheimen Schlüssel. Diese werden mit Certbot bereitgestellt und im nächsten Schritt in den Nginx-Container eingebunden.

      conf/nginx.conf

      . . .
      ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;
      . . .
      

      Bei diesen Parametern handelt es sich um die von Certbot empfohlenen SSL-Sicherheitsstandards. Um mehr über sie zu erfahren, lesen Sie bitte das Modul ngx_http_ssl_module der Nginx-Dokumentation. Mozillas Sicherheits-/Serverseitiges TLS ist ein weiterer hilfreicher Leitfaden, den Sie für die Feinabstimmung Ihrer SSL-Konfiguration verwenden können.

      conf/nginx.conf

      . . .
          ssl_session_cache shared:le_nginx_SSL:10m;
          ssl_session_timeout 1440m;
          ssl_session_tickets off;
      
          ssl_protocols TLSv1.2 TLSv1.3;
          ssl_prefer_server_ciphers off;
      
          ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
      . . .
      

      Diese beiden Anweisungen aus Gunicorns Nginx-Beispielkonfiguration legen die maximal zulässige Größe des Client-Anfragekörpers fest und weisen das Timeout für Keep-Alive-Verbindungen mit dem Client zu. Nginx schließt Verbindungen mit dem Client nach keepalive_timeout-Sekunden.

      conf/nginx.conf

      . . .
      client_max_body_size 4G;
      keepalive_timeout 5;
      . . .
      

      Der erste Block location weist Nginx zum Proxying von Anfragen über HTTP an die upstream django-Server an. Er bewahrt zusätzlich Client HTTP-Header auf, die die Ursprungs-IP-Adresse, das zur Verbindung verwendete Protokoll und den Ziel-Host erfassen:

      conf/nginx.conf

      . . .
      location / {
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header Host $http_host;
          proxy_redirect off;
          proxy_pass http://django;
      }
      . . .
      

      Um mehr über diese Anweisungen zu erfahren, lesen Sie bitte Bereitstellen von Gunicorn und das Modul ngx_http_proxy_module der Nginx-Dokumentation.

      Der letzte Block location erfasst Anfragen an den Pfad /well-known/acme-Challenge/, der von Certbot für HTTP-01-Challenges verwendet wird, um Ihre Domäne mit Let’s Encrypt zu verifizieren und TLS-Zertifikate bereitzustellen oder zu erneuern. Weitere Informationen über die von Certbot verwendete HTTP-01-Challenge finden Sie unter Challenge-Arten in der Let’s Encrypt-Dokumentation.

      conf/nginx.conf

      . . .
      location ^~ /.well-known/acme-challenge/ {
              root /var/www/html;
      }
      

      Wenn Sie die Bearbeitung abgeschlossen haben, speichern und schließen Sie die Datei.

      Sie können diese Konfigurationsdatei nun verwenden, um einen Nginx Docker-Container auszuführen. In diesem Tutorial verwenden wir das Image nginx:1.19.0, Version 1.19.0 des offiziellen Docker-Images, das von Nginx verwaltet wird.

      Wenn wir den Container zum ersten Mal ausführen, wird Nginx einen Fehler ausgeben und fehlschlagen, da wir die in der Konfigurationsdatei definierten Zertifikate noch nicht bereitgestellt haben. Wir werden jedoch trotzdem den Befehl zum Herunterladen des Nginx-Images lokal ausführen und testen, ob alles andere korrekt funktioniert:

      docker run --rm --name nginx -p 80:80 -p 443:443 
          -v ~/conf/nginx.conf:/etc/nginx/conf.d/nginx.conf:ro 
          -v /var/www/html:/var/www/html 
          nginx:1.19.0
      

      Hier nennen wir den Container nginx und ordnen die Host-Ports 80 und 443 den jeweiligen Container-Ports zu. Das Flag -v bindet die Konfigurationsdatei unter /etc/nginx/conf.d/nginx.conf in den Nginx-Container ein, für dessen Laden das Nginx-Image vorkonfiguriert ist. Es wird im Modus ro oder „read-only“ eingebunden, sodass der Container die Datei nicht verändern kann. Das Web-Stammverzeichnis /var/www/html ist ebenfalls in den Container eingebunden. Schließlich weist nginx:1.19.0 Docker an, das Image nginx:1.19.0 aus Dockerhub zu ziehen und auszuführen.

      Docker wird das Image ziehen und ausführen, dann wird Nginx einen Fehler ausgeben, wenn es das konfigurierte TLS-Zertifikat und den geheimen Schlüssel nicht findet. Im nächsten Schritt stellen wir diese mithilfe eines dockerisierten Certbot-Clients und der Zertifizierungsstelle Let’s Encrypt bereit.

      Schritt 4 – Konfigurieren von Certbot und Let’s Encrypt-Zertifikaterneuerung

      Certbot ist ein Let’s Encrypt-Client, der von der Electronic Frontier Foundation entwickelt wurde. Er stellt kostenlose TLS-Zertifikate von der Let’s Encrypt-Zertifizierungsstelle zur Verfügung, mit denen Browser die Identität Ihrer Webserver überprüfen können. Da wir auf unserem Nginx-Proxy-Server Docker installiert haben, verwenden wir das Certbot Docker-Image zur Bereitstellung und Erneuerung der TLS-Zertifikate.

      Stellen Sie zunächst sicher, dass Sie über einen DNS-A-Eintrag verfügen, der der öffentlichen IP-Adresse des Proxy-Servers zugeordnet ist. Stellen Sie dann auf Ihrem Proxy-Server eine Staging-Version der Zertifikate unter Verwendung des Docker-Images certbot bereit:

      docker run -it --rm -p 80:80 --name certbot 
               -v "/etc/letsencrypt:/etc/letsencrypt" 
               -v "/var/lib/letsencrypt:/var/lib/letsencrypt" 
               certbot/certbot certonly --standalone --staging -d your_domain.com
      

      Dieser Befehl führt das certbot Docker-Image im interaktiven Modus aus und leitet Port 80 auf dem Host an den Container-Port 80 weiter. Er erstellt zwei Host-Verzeichnisse und bindet sie in die Container ein: /etc/letsencrypt/ und /var/lib/letsencrypt/. certbot wird im Modus standalone ohne Nginx ausgeführt und verwendet die Staging-Server von Let’s Encrypt, um die Domänenvalidierung durchzuführen.

      Geben Sie, wenn Sie dazu aufgefordert werden, Ihre E-Mail-Adresse ein und stimmen Sie den Nutzungsbedingungen zu. Wenn die Domänenvalidierung erfolgreich war, sollten Sie die folgende Ausgabe sehen:

      Output

      Obtaining a new certificate Performing the following challenges: http-01 challenge for stubb.dev Waiting for verification... Cleaning up challenges IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/your_domain.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/your_domain.com/privkey.pem Your cert will expire on 2020-09-15. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal.

      Sie können das Zertifikat mit cat inspizieren:

      sudo cat /etc/letsencrypt/live/your_domain.com/fullchain.pem
      

      Mit dem bereitgestellten TLS-Zertifikat können wir die im vorherigen Schritt eingebundene Nginx-Konfiguration testen:

      docker run --rm --name nginx -p 80:80 -p 443:443 
          -v ~/conf/nginx.conf:/etc/nginx/conf.d/nginx.conf:ro 
          -v /etc/letsencrypt:/etc/letsencrypt 
          -v /var/lib/letsencrypt:/var/lib/letsencrypt 
          -v /var/www/html:/var/www/html 
          nginx:1.19.0
      

      Dies ist derselbe Befehl, der in Schritt 3 ausgeführt wurde, mit dem Hinzufügen der beiden kürzlich erstellten Let’s Encrypt-Verzeichnisse:

      Sobald Nginx ausgeführt wird, navigieren Sie zu http://your_domain.com. Möglicherweise erhalten Sie in Ihrem Browser eine Warnung, dass die Zertifizierungsstelle ungültig ist. Dies ist zu erwarten, da wir Staging-Zertifikate und keine Produktions-Let’s Encrypt-Zertifikate bereitgestellt haben. Überprüfen Sie die URL-Leiste Ihres Browsers, um zu bestätigen, dass Ihre HTTP-Anfrage an HTTPS umgeleitet wurde.

      Drücken Sie zum Beenden von Nginx in Ihrem Terminal Strg+C und führen Sie den Client certbot erneut aus, diesmal ohne das Flag --staging:

      docker run -it --rm -p 80:80 --name certbot 
               -v "/etc/letsencrypt:/etc/letsencrypt" 
               -v "/var/lib/letsencrypt:/var/lib/letsencrypt" 
               certbot/certbot certonly --standalone -d your_domain.com
      

      Wenn Sie dazu aufgefordert werden, entweder das vorhandene Zertifikat beizubehalten oder es zu erneuern und zu ersetzen, drücken Sie 2 zum Erneuern und dann ENTER, um Ihre Wahl zu bestätigen.

      Wenn das Produktions-TLS-Zertifikat bereitgestellt ist, führen Sie den Nginx-Server erneut aus:

      docker run --rm --name nginx -p 80:80 -p 443:443 
          -v ~/conf/nginx.conf:/etc/nginx/conf.d/nginx.conf:ro 
          -v /etc/letsencrypt:/etc/letsencrypt 
          -v /var/lib/letsencrypt:/var/lib/letsencrypt 
          -v /var/www/html:/var/www/html 
          nginx:1.19.0
      

      Navigieren Sie in Ihrem Browser zu http://your_domain.com. Bestätigen Sie in der URL-Leiste, dass die HTTP-Anfrage an HTTPS umgeleitet wurde. Da für die Umfrageanwendung keine Standardroute konfiguriert ist, sollten Sie den Django-Fehler Page not found (Seite nicht gefunden) sehen. Navigieren Sie zu https://your_domain.com/polls und Sie sehen die Standardoberfläche der Umfrageanwendung:

      Oberfläche der Umfrageanwendung

      Zu diesem Zeitpunkt haben Sie mit dem Certbot Docker-Client ein Produktions-TLS-Zertifikat bereitgestellt und externe Anfragen an die beiden Django-App-Server durch Reverse Proxying und Lastausgleich umgeleitet.

      Die Let’s Encrypt-Zertifikate laufen alle 90 Tage ab. Um sicherzustellen, dass Ihr Zertifikat gültig bleibt, sollten Sie es regelmäßig vor dessen geplantem Ablauf erneuern. Wenn Nginx ausgeführt wird, sollten Sie den Certbot-Client im Modus webroot anstelle des Modus standalone verwenden. Das bedeutet, dass Certbot die Validierung durch die Erstellung einer Datei im Verzeichnis /var/www/html/.well-known/acme-challenge/ durchführt, und die Validierungsanforderungen von Let’s Encrypt an diesen Pfad werden von der in der Nginx-Konfiguration in Schritt 3 definierten Regel location erfasst. Certbot wird dann die Zertifikate rotieren, und Sie können Nginx neu laden, sodass es dieses neu bereitgestellte Zertifikat verwendet.

      Es gibt mehrere Möglichkeiten, um dieses Verfahren zu automatisieren und die automatische Erneuerung von TLS-Zertifikaten geht über den Umfang dieses Tutorials hinaus. Ein ähnliches Verfahren unter Verwendung des Scheduling-Dienstprogramms cron finden Sie in Schritt 6 von Sichern einer containerisierten Node.js-Anwendung mit Nginx, Let’s Encrypt, und Docker Compose.

      Drücken Sie zum Beenden des Nginx-Containers in Ihrem Terminal Strg+C. Führen Sie ihn erneut im getrennten Modus aus, indem Sie das Flag -d anhängen:

      docker run --rm --name nginx -d -p 80:80 -p 443:443 
          -v ~/conf/nginx.conf:/etc/nginx/conf.d/nginx.conf:ro 
          -v /etc/letsencrypt:/etc/letsencrypt 
          -v /var/lib/letsencrypt:/var/lib/letsencrypt 
        -v /var/www/html:/var/www/html 
          nginx:1.19.0
      

      Verwenden Sie mit im Hintergrund ausgeführtem Nginx den folgenden Befehl, um einen Probelauf des Zertifikatserneuerungsverfahrens auszuführen:

      docker run -it --rm --name certbot 
          -v "/etc/letsencrypt:/etc/letsencrypt" 
        -v "/var/lib/letsencrypt:/var/lib/letsencrypt" 
        -v "/var/www/html:/var/www/html" 
        certbot/certbot renew --webroot -w /var/www/html --dry-run
      

      Wir verwenden das Plugin --webroot, geben den Web-Stammpfad ein und verwenden das Flag --dry-run zum Überprüfen der ordnungsgemäßen Funktion, ohne die Zertifikatserneuerung tatsächlich durchzuführen.

      Wenn die Erneuerungssimulation erfolgreich ist, sollten Sie die folgende Ausgabe sehen:

      Output

      Cert not due for renewal, but simulating renewal for dry run Plugins selected: Authenticator webroot, Installer None Renewing an existing certificate Performing the following challenges: http-01 challenge for your_domain.com Using the webroot path /var/www/html for all unmatched domains. Waiting for verification... Cleaning up challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - new certificate deployed without reload, fullchain is /etc/letsencrypt/live/your_domain.com/fullchain.pem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates below have not been saved.) Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/your_domain.com/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

      In einer Produktionseinstellung sollten Sie nach der Erneuerung von Zertifikaten Nginx neu laden, damit die Änderungen wirksam werden. Führen Sie zum Neuladen von Nginx den folgenden Befehl aus:

      docker kill -s HUP nginx
      

      Dieser Befehl sendet ein HUP Unix-Signal an den Nginx-Prozess, der innerhalb des Docker-Containers nginx ausgeführt wird. Nach Empfang dieses Signals lädt Nginx seine Konfiguration und erneuerten Zertifikate neu.

      Wenn HTTPS aktiviert ist und alle Komponenten dieser Architektur ausgeführt werden, besteht der letzte Schritt darin, die Einrichtung zu sperren, indem der externe Zugriff auf die beiden Backend-App-Server verhindert wird; alle HTTP-Anfragen sollten über den Nginx-Proxy laufen.

      Schritt 5 – Verhindern des externen Zugriffs auf Django-App-Server

      In der in diesem Tutorial beschriebenen Architektur erfolgt die SSL-Terminierung am Nginx-Proxy. Das bedeutet, dass Nginx die SSL-Verbindung entschlüsselt und die Pakete unverschlüsselt an die Django-App-Server weitergeleitet werden. Für viele Anwendungsfälle ist diese Sicherheitsstufe ausreichend. Für Anwendungen mit Finanz- oder Gesundheitsdaten sollten Sie eventuell eine End-to-End-Verschlüsselung implementieren. Sie können dies tun, indem Sie verschlüsselte Pakete über den Load Balancer weiterleiten und auf den App-Servern entschlüsseln oder am Proxy neu verschlüsseln und auf den Django-App-Servern wieder entschlüsseln. Diese Techniken gehen über den Rahmen dieses Artikels hinaus. Um mehr zu erfahren, lesen Sie bitte End-to-End-Verschlüsselung.

      Der Nginx-Proxy fungiert als Gateway zwischen externem Datenverkehr und dem internen Netzwerk. Theoretisch sollten keine externen Clients direkten Zugriff auf die internen App-Server haben, und alle Anfragen sollten über den Nginx-Server laufen. Der Hinweis in Schritt 1 beschreibt kurz ein offenes Problem mit Docker, bei dem Docker standardmäßig die ufw-Firewalleinstellungen umgeht und Ports extern öffnet, die möglicherweise unsicher sind. Um dieses Sicherheitsproblem zu beheben wird empfohlen, bei der Arbeit mit Docker-fähigen Servern Cloud Firewalls zu verwenden. Weitere Informationen zum Erstellen von Cloud Firewalls mit DigitalOcean finden Sie unter Erstellen von Firewalls. Sie können iptables auch direkt manipulieren, anstatt ufw zu verwenden. Um mehr über die Verwendung von iptables mit Docker zu erfahren, lesen Sie bitte Docker und iptables.

      In diesem Schritt ändern wir die UFW-Konfiguration so, dass der externe Zugriff auf die von Docker geöffneten Host-Ports blockiert wird. Bei der Ausführung von Django auf den App-Servern haben wir das Flag -p 80:8000 an docker übergeben, das Port 80 auf dem Host an den Container-Port 8000 weiterleitet. Dadurch wurde Port 80 auch für externe Clients geöffnet, was Sie unter http://your_app_server_1_IP überprüfen können. Um den direkten Zugriff zu verhindern, ändern wir die UFW-Konfiguration mithilfe der im ufw-docker GitHub-Repository beschriebenen Methode.

      Beginnen Sie damit, sich bei dem ersten Django-App-Server anzumelden. Öffnen Sie dann die Datei /etc/ufw/after.rules mit superuser-Berechtigungen, indem Sie nano oder Ihren bevorzugten Editor verwenden:

      sudo nano /etc/ufw/after.rules
      

      Geben Sie bei Aufforderung Ihr Passwort ein und drücken Sie zur Bestätigung ENTER.

      Sie sollten die folgenden ufw-Regeln sehen:

      /etc/ufw/after.rules

      #
      # rules.input-after
      #
      # Rules that should be run after the ufw command line added rules. Custom
      # rules should be added to one of these chains:
      #   ufw-after-input
      #   ufw-after-output
      #   ufw-after-forward
      #
      
      # Don't delete these required lines, otherwise there will be errors
      *filter
      :ufw-after-input - [0:0]
      :ufw-after-output - [0:0]
      :ufw-after-forward - [0:0]
      # End required lines
      
      # don't log noisy services by default
      -A ufw-after-input -p udp --dport 137 -j ufw-skip-to-policy-input
      -A ufw-after-input -p udp --dport 138 -j ufw-skip-to-policy-input
      -A ufw-after-input -p tcp --dport 139 -j ufw-skip-to-policy-input
      -A ufw-after-input -p tcp --dport 445 -j ufw-skip-to-policy-input
      -A ufw-after-input -p udp --dport 67 -j ufw-skip-to-policy-input
      -A ufw-after-input -p udp --dport 68 -j ufw-skip-to-policy-input
      
      # don't log noisy broadcast
      -A ufw-after-input -m addrtype --dst-type BROADCAST -j ufw-skip-to-policy-input
      
      # don't delete the 'COMMIT' line or these rules won't be processed
      COMMIT
      

      Scrollen Sie nach unten und fügen Sie den folgenden Block mit UFW-Konfigurationsregeln ein:

      /etc/ufw/after.rules

      . . .
      
      # BEGIN UFW AND DOCKER
      *filter
      :ufw-user-forward - [0:0]
      :DOCKER-USER - [0:0]
      -A DOCKER-USER -j RETURN -s 10.0.0.0/8
      -A DOCKER-USER -j RETURN -s 172.16.0.0/12
      -A DOCKER-USER -j RETURN -s 192.168.0.0/16
      
      -A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN
      
      -A DOCKER-USER -j ufw-user-forward
      
      -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
      -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
      -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
      -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
      -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
      -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 172.16.0.0/12
      
      -A DOCKER-USER -j RETURN
      COMMIT
      # END UFW AND DOCKER
      

      Diese Regeln schränken den öffentlichen Zugriff auf die von Docker geöffneten Ports ein und ermöglichen den Zugriff aus den privaten IP-Bereichen 10.0.0/8, 172.16.0.0/12 und 192.168.0.0/16. Wenn Sie VPC mit DigitalOcean verwenden, dann haben Droplets in Ihrem VPC-Netzwerk über die private Netzwerkschnittstelle Zugriff auf den offenen Port, externe Clients jedoch nicht. Weitere Informationen über VPC finden Sie in der offiziellen VPC-Dokumentation. Um mehr über die in diesem Snippet implementierten Regeln zu erfahren, lesen Sie bitte Funktionsweise in der ufw-docker README.

      Wenn Sie VPC nicht mit DigitalOcean verwenden und die öffentlichen IP-Adressen der App-Server in den Block upstream Ihrer Nginx-Konfiguration eingegeben haben, müssen Sie die UFW-Firewall explizit ändern, um den Datenverkehr vom Nginx-Server über Port 80 auf den Django-App-Servern zuzulassen. Eine Anleitung zur Erstellung von allow-Regeln mit der UFW-Firewall finden Sie unter UFW Grundlagen: Allgemeine Firewallregeln und -befehle.

      Wenn Sie die Bearbeitung abgeschlossen haben, speichern und schließen Sie die Datei.

      Starten Sie ufw neu, damit die neue Konfiguration übernommen wird:

      sudo systemctl restart ufw
      

      Navigieren Sie in Ihrem Webbrowser zu http://APP_SERVER_1_IP, um zu bestätigen, dass Sie über Port 80 nicht mehr auf die App-Server zugreifen können.

      Wiederholen Sie diesen Vorgang auf dem zweiten Django-App-Server.

      Melden Sie sich bei dem ersten App-Server ab oder öffnen Sie ein anderes Terminalfenster und melden Sie sich bei dem zweiten Django-App-Server an. Öffnen Sie dann die Datei /etc/ufw/after.rules mit superuser-Berechtigungen, indem Sie nano oder Ihren bevorzugten Editor verwenden:

      sudo nano /etc/ufw/after.rules
      

      Geben Sie bei Aufforderung Ihr Passwort ein und drücken Sie zur Bestätigung ENTER.

      Scrollen Sie nach unten und fügen Sie den folgenden Block mit UFW-Konfigurationsregeln ein:

      /etc/ufw/after.rules

      . . .
      
      # BEGIN UFW AND DOCKER
      *filter
      :ufw-user-forward - [0:0]
      :DOCKER-USER - [0:0]
      -A DOCKER-USER -j RETURN -s 10.0.0.0/8
      -A DOCKER-USER -j RETURN -s 172.16.0.0/12
      -A DOCKER-USER -j RETURN -s 192.168.0.0/16
      
      -A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN
      
      -A DOCKER-USER -j ufw-user-forward
      
      -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
      -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
      -A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
      -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
      -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
      -A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 172.16.0.0/12
      
      -A DOCKER-USER -j RETURN
      COMMIT
      # END UFW AND DOCKER
      

      Wenn Sie die Bearbeitung abgeschlossen haben, speichern und schließen Sie die Datei.

      Starten Sie ufw neu, damit die neue Konfiguration übernommen wird:

      sudo systemctl restart ufw
      

      Navigieren Sie in Ihrem Webbrowser zu http://APP_SERVER_2_IP, um zu bestätigen, dass Sie über Port 80 nicht mehr auf die App-Server zugreifen können.

      Navigieren Sie abschließend zu https://your_domain_here/polls, um zu bestätigen, dass der Nginx-Proxy weiterhin Zugriff auf die upstream Django-Server hat. Sie sollten die Standardoberfläche der Umfrageanwendung sehen.

      Zusammenfassung

      In diesem Tutorial haben Sie mit Docker-Containern eine skalierbare Django Umfrageanwendung eingerichtet. Wenn Ihr Datenverkehr steigt und die Last auf dem System zunimmt, können Sie jede Schicht separat skalieren: die Nginx-Proxying-Schicht, die Django-Backend-Anwendungsschicht und die PostgreSQL-Datenbankschicht.

      Beim Aufbau eines verteilten Systems müssen Sie oft mehrere Designentscheidungen treffen, und mehrere Architekturen können Ihrem Anwendungsfall gerecht werden. Die in diesem Tutorial beschriebene Architektur ist als flexible Blaupause für den Entwurf skalierbarer Anwendungen mit Django und Docker gedacht.

      Möglicherweise möchten Sie das Verhalten Ihrer Container steuern, wenn sie auf Fehler stoßen, oder Container automatisch ausführen, wenn Ihr System gestartet wird. Zu diesem Zweck können Sie einen Prozessmanager wie Systemd verwenden oder Neustartrichtlinien implementieren. Weitere Informationen hierzu finden Sie unter Automatisches Starten von Containern in der Docker-Dokumentation.

      Wenn Sie im großen Maßstab mit mehreren Hosts arbeiten, die dasselbe Docker-Image ausführen, kann es effizient sein, Schritte mit einem Konfigurations-Managementtool wie Ansible oder Chef zu automatisieren. Um mehr über das Konfigurationsmanagement zu erfahren, lesen Sie bitte Eine Einführung in das Konfigurationsmanagement und Automatisieren der Servereinrichtung mit Ansible: Ein DigitalOcean-Workshop-Kit.

      Anstatt auf jedem Host dasselbe Image zu erstellen, können Sie die Bereitstellung auch mithilfe einer Image-Registrierung wie Docker Hub rationalisieren, bei der Docker-Images zentral erstellt, gespeichert und an mehrere Server verteilt werden. Zusammen mit einer Image-Registrierung kann Ihnen eine kontinuierliche Integrations- und Bereitstellungspipeline dabei helfen, Images zu erstellen, zu testen und auf Ihre App-Server zu verteilen. Weitere Informationen zu CI/CD finden Sie unter Eine Einführung in die CI/CD Best Practices.



      Source link