Workshop RHEL 8 Beta: Nggawe aplikasi web sing bisa digunakake

RHEL 8 Beta nawakake pangembang akeh fitur-fitur anyar, dhaptar sing bisa njupuk kaca, nanging sinau bab-bab anyar mesthi luwih apik ing praktik, mula ing ngisor iki kita nawakake lokakarya babagan nggawe infrastruktur aplikasi adhedhasar Red Hat Enterprise Linux 8 Beta.

Workshop RHEL 8 Beta: Nggawe aplikasi web sing bisa digunakake

Ayo njupuk Python, basa pemrograman populer ing antarane pangembang, minangka basis, kombinasi Django lan PostgreSQL, kombinasi sing cukup umum kanggo nggawe aplikasi, lan ngatur RHEL 8 Beta kanggo nggarap. Banjur kita bakal nambah saperangan liyane (unclassified) bahan.

Lingkungan tes bakal ganti, amarga menarik kanggo njelajah kemungkinan otomatisasi, nggarap wadhah lan nyoba lingkungan kanthi macem-macem server. Kanggo miwiti karo proyek anyar, sampeyan bisa miwiti nggawe cilik, prototipe prasaja dening tangan supaya sampeyan bisa ndeleng persis apa sing kudu kelakon lan carane sesambungan, lan banjur pindhah menyang otomatis lan nggawe konfigurasi luwih Komplek. Dina iki kita ngomong babagan nggawe prototipe kasebut.

Ayo dadi miwiti nganggo gambar RHEL 8 Beta VM. Sampeyan bisa nginstal mesin virtual saka ngeruk, utawa nggunakake gambar tamu KVM kasedhiya karo langganan Beta. Nalika nggunakake gambar tamu, sampeyan kudu ngatur CD virtual sing bakal ngemot metadata lan data pangguna kanggo initialization maya (cloud-init). Sampeyan ora perlu nindakake apa-apa khusus karo struktur disk utawa paket sing kasedhiya; konfigurasi apa wae bakal ditindakake.

Ayo padha nliti kabeh proses.

Nginstal Django

Kanthi versi paling anyar saka Django, sampeyan kudu lingkungan virtual (virtualenv) karo Python 3.5 utawa mengko. Ing cathetan Beta sampeyan bisa ndeleng manawa Python 3.6 kasedhiya, ayo priksa manawa iki pancen kedadeyan:

[cloud-user@8beta1 ~]$ python
-bash: python: command not found
[cloud-user@8beta1 ~]$ python3
-bash: python3: command not found

Red Hat kanthi aktif nggunakake Python minangka toolkit sistem ing RHEL, dadi kenapa asil iki?

Kasunyatan iku akeh pangembang Python sing isih mikir transisi saka Python 2 kanggo Python 2, nalika Python 3 dhewe ing pembangunan aktif, lan liyane lan liyane versi anyar terus-terusan muncul. Mulane, kanggo nyukupi kabutuhan alat sistem sing stabil nalika nawakake akses menyang macem-macem versi Python anyar, sistem Python dipindhah menyang paket anyar lan nyedhiyakake kemampuan kanggo nginstal Python 2.7 lan 3.6. Informasi liyane babagan owah-owahan lan ngapa padha digawe bisa ditemokakΓ© ing publikasi ing Blog Langdon White (Langdon Putih).

Dadi, kanggo nggarap Python, sampeyan mung kudu nginstal rong paket, kanthi python3-pip kalebu minangka dependensi.

sudo yum install python36 python3-virtualenv

Napa ora nggunakake telpon modul langsung kaya sing disaranake Langdon lan nginstal pip3? Elinga babagan otomatisasi sing bakal teka, dingerteni manawa Ansible mbutuhake pip diinstal kanggo mbukak, amarga modul pip ora ndhukung virtualenvs kanthi eksekusi pip khusus.

Kanthi interpreter python3 sing bisa digunakake, sampeyan bisa nerusake proses instalasi Django lan duwe sistem kerja bebarengan karo komponen liyane. Ana akeh opsi implementasine sing kasedhiya ing Internet. Ana siji versi sing ditampilake ing kene, nanging pangguna bisa nggunakake proses dhewe.

Kita bakal nginstal versi PostgreSQL lan Nginx sing kasedhiya ing RHEL 8 kanthi standar nggunakake Yum.

sudo yum install nginx postgresql-server

PostgreSQL mbutuhake psycopg2, nanging kudu kasedhiya mung ing lingkungan virtualenv, supaya kita bakal nginstal nggunakake pip3 bebarengan karo Django lan Gunicorn. Nanging pisanan kita kudu nyiyapake virtualenv.

Ana tansah akeh debat babagan topik milih panggonan sing tepat kanggo nginstal proyek Django, nanging yen ana keraguan, sampeyan bisa tansah nguripake menyang Linux Filesystem Hierarchy Standard. Secara khusus, FHS ujar manawa /srv digunakake kanggo: "nyimpen data khusus host-data sing diprodhuksi sistem, kayata data lan skrip server web, data sing disimpen ing server FTP, lan repositori sistem kontrol." (katon ing FHS. -2.3 ing 2004).

Iki persis kaya kita, mula kita sijine kabeh sing kita butuhake menyang / srv, sing diduweni dening pangguna aplikasi kita (cloud-user).

sudo mkdir /srv/djangoapp
sudo chown cloud-user:cloud-user /srv/djangoapp
cd /srv/djangoapp
virtualenv django
source django/bin/activate
pip3 install django gunicorn psycopg2
./django-admin startproject djangoapp /srv/djangoapp

Nggawe PostgreSQL lan Django gampang: nggawe database, nggawe pangguna, ngatur ijin. Siji bab sing kudu dieling-eling nalika wiwitan nginstal PostgreSQL yaiku skrip persiyapan postgresql sing diinstal karo paket postgresql-server. Skrip iki mbantu sampeyan nindakake tugas dhasar sing ana gandhengane karo administrasi kluster database, kayata initialization cluster utawa proses upgrade. Kanggo ngatur conto PostgreSQL anyar ing sistem RHEL, kita kudu mbukak printah:

sudo /usr/bin/postgresql-setup -initdb

Sampeyan banjur bisa miwiti PostgreSQL nggunakake systemd, nggawe database, lan nyetel proyek ing Django. Elinga miwiti maneh PostgreSQL sawise nggawe owahan kanggo file konfigurasi otentikasi klien (biasane pg_hba.conf) kanggo konfigurasi panyimpenan sandi kanggo pangguna aplikasi. Yen sampeyan nemoni kesulitan liyane, priksa manawa sampeyan ngganti setelan IPv4 lan IPv6 ing file pg_hba.conf.

systemctl enable -now postgresql

sudo -u postgres psql
postgres=# create database djangoapp;
postgres=# create user djangouser with password 'qwer4321';
postgres=# alter role djangouser set client_encoding to 'utf8';
postgres=# alter role djangouser set default_transaction_isolation to 'read committed';
postgres=# alter role djangouser set timezone to 'utc';
postgres=# grant all on DATABASE djangoapp to djangouser;
postgres=# q

Ing file /var/lib/pgsql/data/pg_hba.conf:

# IPv4 local connections:
host    all        all 0.0.0.0/0                md5
# IPv6 local connections:
host    all        all ::1/128                 md5

Ing file /srv/djangoapp/settings.py:

# Database
DATABASES = {
   'default': {
       'ENGINE': 'django.db.backends.postgresql_psycopg2',
       'NAME': '{{ db_name }}',
       'USER': '{{ db_user }}',
       'PASSWORD': '{{ db_password }}',
       'HOST': '{{ db_host }}',
   }
}

Sawise ngonfigurasi file settings.py ing proyek lan nyetel konfigurasi database, sampeyan bisa miwiti server pangembangan kanggo mesthekake yen kabeh bisa digunakake. Sawise miwiti server pangembangan, luwih becik nggawe pangguna admin kanggo nyoba sambungan menyang database.

./manage.py runserver 0.0.0.0:8000
./manage.py createsuperuser

WSGI? Wai?

Pangembangan server migunani kanggo testing, nanging kanggo mbukak aplikasi sampeyan kudu ngatur server cocok lan proxy kanggo Web Server Gateway Interface (WSGI). Ana sawetara kombinasi umum, contone, Apache HTTPD karo uWSGI utawa Nginx karo Gunicorn.

Tugas Web Server Gateway Interface yaiku nerusake panjalukan saka server web menyang kerangka web Python. WSGI minangka peninggalan jaman kepungkur nalika mesin CGI ana, lan saiki WSGI minangka standar de facto, preduli saka server web utawa kerangka Python sing digunakake. Nanging senadyan panggunaan sing nyebar, isih ana akeh nuansa nalika nggarap kerangka kasebut, lan akeh pilihan. Ing kasus iki, kita bakal nyoba nggawe interaksi antarane Gunicorn lan Nginx liwat soket.

Amarga loro komponen kasebut diinstal ing server sing padha, ayo nyoba nggunakake soket UNIX tinimbang soket jaringan. Wiwit komunikasi mbutuhake soket ing kasus apa wae, ayo nyoba njupuk langkah liyane lan ngatur aktivasi soket kanggo Gunicorn liwat systemd.

Proses nggawe layanan soket sing diaktifake cukup prasaja. Kaping pisanan, file unit digawe sing ngemot arahan ListenStream sing ngarahake menyang titik ing ngendi soket UNIX bakal digawe, banjur file unit kanggo layanan sing direktif Requires bakal nuding menyang file unit soket. Banjur, ing file unit layanan, kabeh sing isih ana yaiku nelpon Gunicorn saka lingkungan virtual lan nggawe ikatan WSGI kanggo soket UNIX lan aplikasi Django.

Ing ngisor iki sawetara conto file unit sing bisa digunakake minangka basis. Pisanan kita nyetel soket.

[Unit]
Description=Gunicorn WSGI socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

Saiki sampeyan kudu ngatur daemon Gunicorn.

[Unit]
Description=Gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=cloud-user
Group=cloud-user
WorkingDirectory=/srv/djangoapp

ExecStart=/srv/djangoapp/django/bin/gunicorn 
         β€”access-logfile - 
         β€”workers 3 
         β€”bind unix:gunicorn.sock djangoapp.wsgi

[Install]
WantedBy=multi-user.target

Kanggo Nginx, prasaja nggawe file konfigurasi proxy lan nyetel direktori kanggo nyimpen konten statis yen sampeyan nggunakake. Ing RHEL, file konfigurasi Nginx dumunung ing /etc/nginx/conf.d. Sampeyan bisa nyalin conto ing ngisor iki menyang file /etc/nginx/conf.d/default.conf lan miwiti layanan. Priksa manawa sampeyan nyetel server_name supaya cocog karo jeneng host sampeyan.

server {
   listen 80;
   server_name 8beta1.example.com;

   location = /favicon.ico { access_log off; log_not_found off; }
   location /static/ {
       root /srv/djangoapp;
   }

   location / {
       proxy_set_header Host $http_host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_pass http://unix:/run/gunicorn.sock;
   }
}

Miwiti soket Gunicorn lan Nginx nggunakake systemd lan sampeyan siyap miwiti nyoba.

Bad Gateway kesalahan?

Yen sampeyan ngetik alamat menyang browser, sampeyan bakal nampa kesalahan 502 Bad Gateway. Iki bisa uga disebabake dening ijin soket UNIX sing ora dikonfigurasi kanthi bener, utawa bisa uga amarga masalah sing luwih rumit sing ana gandhengane karo kontrol akses ing SELinux.

Ing log kesalahan nginx sampeyan bisa ndeleng baris kaya iki:

2018/12/18 15:38:03 [crit] 12734#0: *3 connect() to unix:/run/gunicorn.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.122.1, server: 8beta1.example.com, request: "GET / HTTP/1.1", upstream: "http://unix:/run/gunicorn.sock:/", host: "8beta1.example.com"

Yen kita nyoba langsung Gunicorn, kita bakal entuk jawaban kosong.

curl β€”unix-socket /run/gunicorn.sock 8beta1.example.com

Ayo dipikirake apa sebabe kedadeyan kasebut. Yen sampeyan mbukak log, sampeyan bakal bisa ndeleng manawa masalah kasebut ana gandhengane karo SELinux. Amarga kita mbukak daemon sing ora ana kabijakan sing digawe, mula ditandhani minangka init_t. Ayo nyoba teori iki ing praktik.

sudo setenforce 0

Kabeh iki bisa nyebabake kritik lan nangis getih, nanging iki mung debugging prototipe. Ayo mateni mriksa mung kanggo mesthekake yen iki masalah, sawise kang kita bakal bali kabeh menyang panggonan.

Kanthi refresh kaca ing browser utawa mbukak maneh printah curl, sampeyan bisa ndeleng kaca test Django.

Dadi, sawise nggawe manawa kabeh bisa digunakake lan ora ana masalah ijin maneh, kita ngaktifake SELinux maneh.

sudo setenforce 1

Aku ora bakal pirembagan bab audit2allow utawa nggawe kawicaksanan basis tandha karo sepolgen kene, wiwit ora ana aplikasi Django nyata ing wayahe, supaya ana map lengkap apa Gunicorn bisa uga pengin ngakses lan apa kudu nolak akses kanggo. Mulane, perlu supaya SELinux tetep mlaku kanggo nglindhungi sistem kasebut, lan ing wektu sing padha ngidini aplikasi kasebut mbukak lan ninggalake pesen ing log audit supaya kabijakan nyata bisa digawe saka wong-wong mau.

Nemtokake domain permisif

Ora kabeh wong wis krungu babagan domain sing diidini ing SELinux, nanging ora ana sing anyar. Malah akeh sing kerja bareng tanpa disadari. Nalika kabijakan digawe adhedhasar pesen audit, kabijakan sing digawe nggambarake domain sing wis ditanggulangi. Ayo nyoba nggawe kabijakan ijin sing gampang.

Kanggo nggawe domain tartamtu diijini kanggo Gunicorn, sampeyan kudu sawetara jenis kawicaksanan, lan sampeyan uga kudu nandhani file cocok. Kajaba iku, alat dibutuhake kanggo ngumpulake kabijakan anyar.

sudo yum install selinux-policy-devel

Mekanisme domain sing diidinake minangka alat sing apik kanggo ngenali masalah, utamane nalika nerangake aplikasi khusus utawa aplikasi sing dikirim tanpa kabijakan sing wis digawe. Ing kasus iki, kabijakan domain sing diidinake kanggo Gunicorn bakal dadi prasaja sabisa - ngumumake jinis utama (gunicorn_t), nyatakake jinis sing bakal digunakake kanggo nandhani pirang-pirang eksekusi (gunicorn_exec_t), banjur atur transisi kanggo sistem kanggo menehi tandha kanthi bener. proses mlaku. Baris pungkasan nyetel kabijakan minangka diaktifake kanthi gawan nalika dimuat.

gunicorn.te:

policy_module(gunicorn, 1.0)

type gunicorn_t;
type gunicorn_exec_t;
init_daemon_domain(gunicorn_t, gunicorn_exec_t)
permissive gunicorn_t;

Sampeyan bisa ngumpulake file kabijakan iki lan ditambahake menyang sistem sampeyan.

make -f /usr/share/selinux/devel/Makefile
sudo semodule -i gunicorn.pp

sudo semanage permissive -a gunicorn_t
sudo semodule -l | grep permissive

Ayo priksa manawa SELinux ngalangi perkara liya tinimbang apa sing diakses daemon sing ora dingerteni.

sudo ausearch -m AVC

type=AVC msg=audit(1545315977.237:1273): avc:  denied { write } for pid=19400 comm="nginx" name="gunicorn.sock" dev="tmpfs" ino=52977 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:var_run_t:s0 tclass=sock_file permissive=0

SELinux nyegah Nginx nulis data menyang soket UNIX sing digunakake dening Gunicorn. Biasane, ing kasus kaya mengkono, kabijakan wiwit owah, nanging ana tantangan liyane ing ngarep. Sampeyan uga bisa ngganti setelan domain saka domain watesan menyang domain ijin. Saiki ayo pindhah httpd_t menyang domain ijin. Iki bakal menehi Nginx akses sing dibutuhake lan kita bisa nerusake karya debugging luwih lanjut.

sudo semanage permissive -a httpd_t

Dadi, yen sampeyan wis bisa njaga SELinux dilindhungi (sampeyan ora kudu ninggalake proyek SELinux ing mode sing diwatesi) lan domain ijin dimuat, sampeyan kudu ngerti apa sing kudu ditandhani minangka gunicorn_exec_t supaya kabeh bisa digunakake kanthi bener maneh. Coba bukak situs web kanggo ndeleng pesen anyar babagan watesan akses.

sudo ausearch -m AVC -c gunicorn

Sampeyan bakal weruh akeh pesen sing ngemot 'comm="gunicorn"' sing nindakake macem-macem perkara ing file ing / srv / djangoapp, mula iki minangka salah sawijining prentah sing kudu ditandhani.

Nanging saliyane, pesen kaya iki katon:

type=AVC msg=audit(1545320700.070:1542): avc:  denied { execute } for pid=20704 comm="(gunicorn)" name="python3.6" dev="vda3" ino=8515706 scontext=system_u:system_r:init_t:s0 tcontext=unconfined_u:object_r:var_t:s0 tclass=file permissive=0

Yen sampeyan ndeleng status layanan gunicorn utawa mbukak printah ps, sampeyan ora bakal weruh proses sing mlaku. Katon kaya gunicorn nyoba ngakses interpreter Python ing lingkungan virtualenv kita, bisa uga kanggo mbukak skrip pekerja. Dadi saiki ayo tandhani rong file sing bisa dieksekusi iki lan priksa manawa kita bisa mbukak kaca uji Django.

chcon -t gunicorn_exec_t /srv/djangoapp/django/bin/gunicorn /srv/djangoapp/django/bin/python3.6

Layanan gunicorn kudu diwiwiti maneh sadurunge tag anyar bisa dipilih. Sampeyan bisa langsung miwiti maneh utawa mungkasi layanan lan supaya soket miwiti nalika mbukak situs ing browser. Priksa manawa pangolahan wis nampa label sing bener nggunakake ps.

ps -efZ | grep gunicorn

Aja lali nggawe kabijakan SELinux normal mengko!

Yen sampeyan ndeleng pesen AVC saiki, pesen pungkasan ngemot permisif = 1 kanggo kabeh sing ana gandhengane karo aplikasi, lan permisif = 0 kanggo sistem liyane. Yen sampeyan ngerti jinis akses apa sing dibutuhake aplikasi nyata, sampeyan bisa kanthi cepet nemokake cara paling apik kanggo ngatasi masalah kasebut. Nanging nganti saiki, paling apik kanggo njaga sistem kasebut kanthi aman lan entuk audit sing jelas lan bisa digunakake kanggo proyek Django.

sudo ausearch -m AVC

Kedadeyan!

Proyek Django sing kerja wis muncul kanthi frontend adhedhasar Nginx lan Gunicorn WSGI. Kita ngatur Python 3 lan PostgreSQL 10 saka repositori RHEL 8 Beta. Saiki sampeyan bisa maju lan nggawe (utawa mung nyebarake) aplikasi Django utawa njelajah alat liyane sing kasedhiya ing RHEL 8 Beta kanggo ngotomatisasi proses konfigurasi, nambah kinerja, utawa malah nggawe konfigurasi iki.

Source: www.habr.com

Add a comment