Workshop RHEL 8 Beta: Ngawangun aplikasi wéb anu tiasa dianggo

RHEL 8 Beta nawiskeun pamekar seueur fitur anyar, daptar anu tiasa nyandak halaman, tapi, diajar hal-hal énggal langkung saé dina prakna, janten di handap ieu kami nawiskeun bengkel ngeunaan nyiptakeun infrastruktur aplikasi dumasar kana Red Hat Enterprise Linux 8 Beta.

Workshop RHEL 8 Beta: Ngawangun aplikasi wéb anu tiasa dianggo

Hayu urang nyandak Python, basa pamrograman anu populer di kalangan pamekar, salaku dasar, kombinasi Django sareng PostgreSQL, kombinasi anu cukup umum pikeun nyiptakeun aplikasi, sareng ngonpigurasikeun RHEL 8 Beta pikeun damel sareng aranjeunna. Teras kami bakal nambihan sababaraha deui bahan (unclassified).

Lingkungan uji bakal robih, sabab éta pikaresepeun pikeun ngajalajah kemungkinan otomatisasi, damel sareng wadah sareng nyobian lingkungan kalayan sababaraha server. Pikeun ngamimitian ku proyék anyar, anjeun tiasa mimitian ku nyieun hiji leutik, prototipe basajan ku leungeun sangkan anjeun tiasa ningali kahayang kudu lumangsung sarta kumaha interaksi, lajeng ngaléngkah ka ngajadikeun otomatis tur nyieun konfigurasi leuwih kompleks. Dinten ieu kami ngobrol ngeunaan kreasi prototipe misalna.

Hayu urang mimitian ku nyebarkeun gambar RHEL 8 Beta VM. Anjeun tiasa masang mesin virtual ti mimiti, atanapi nganggo gambar tamu KVM anu sayogi sareng langganan Beta anjeun. Nalika nganggo gambar tamu, anjeun kedah ngonpigurasikeun CD virtual anu ngandung metadata sareng data pangguna pikeun inisialisasi awan (cloud-init). Anjeun teu kedah ngalakukeun nanaon khusus sareng struktur disk atanapi bungkusan anu sayogi; konfigurasi naon waé bakal dilakukeun.

Hayu urang nyandak hiji tampilan ngadeukeutan dina sakabéh prosés.

Masang Django

Kalayan versi Django panganyarna, anjeun peryogi lingkungan virtual (virtualenv) sareng Python 3.5 atanapi engké. Dina catetan Beta anjeun tiasa ningali yén Python 3.6 sayogi, hayu urang pariksa naha ieu leres-leres:

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

Red Hat aktip ngagunakeun Python salaku toolkit sistem di RHEL, jadi naha ieu hasilna?

Kanyataan yén loba pamekar Python masih contemplating transisi tina Python 2 mun Python 2, bari Python 3 sorangan dina ngembangkeun aktip, sarta beuki loba versi anyar terus muncul. Ku alatan éta, pikeun nyumponan kabutuhan alat sistem anu stabil nalika nawiskeun aksés ka pangguna kana sababaraha versi anyar Python, sistem Python dipindahkeun kana pakét énggal sareng nyayogikeun kamampuan pikeun masang Python 2.7 sareng 3.6. Inpo nu langkung lengkep ihwal parobihan sareng naha éta dilakukeun tiasa dipendakan dina publikasi dina blog Langdon Bodas (Langdon Bodas).

Janten, pikeun damel Python, anjeun ngan ukur kedah masang dua bungkusan, kalayan python3-pip kalebet salaku kagumantungan.

sudo yum install python36 python3-virtualenv

Naha henteu nganggo telepon modul langsung sakumaha anu disarankeun Langdon sareng pasang pip3? Émut kana otomatisasi anu bakal datang, dipikanyaho yén Ansible ngabutuhkeun pip dipasang pikeun ngajalankeun, sabab modul pip henteu ngadukung virtualenvs sareng pip khusus anu tiasa dieksekusi.

Kalayan penerjemah python3 anu tiasa dianggo, anjeun tiasa neraskeun prosés pamasangan Django sareng gaduh sistem anu tiasa dianggo sareng komponén kami anu sanés. Aya loba pilihan palaksanaan sadia on Internét. Aya hiji versi dibere dieu, tapi pamaké bisa ngagunakeun prosés sorangan.

Kami bakal masang versi PostgreSQL sareng Nginx anu sayogi dina RHEL 8 sacara standar nganggo Yum.

sudo yum install nginx postgresql-server

PostgreSQL ngabutuhkeun psycopg2, tapi kedahna ngan ukur aya dina lingkungan virtualenv, ku kituna kami bakal masangna nganggo pip3 sareng Django sareng Gunicorn. Tapi mimitina urang kedah nyetél virtualenv.

Sok aya seueur perdebatan ngeunaan topik milih tempat anu pas pikeun masang proyék Django, tapi nalika ragu, anjeun tiasa teras-terasan ngalih ka Linux Filesystem Hierarchy Standard. Sacara husus, FHS nyebutkeun yén /srv dipaké pikeun: "nyimpen data host-spésifik-data anu sistem ngahasilkeun, kayaning data web server na Aksara, data disimpen dina server FTP, sarta repositories sistem kontrol." versi (nembongan dina FHS). -2.3 taun 2004).

Ieu persis hal urang, jadi urang nempatkeun sagalana urang peryogi kana / srv, nu dipiboga ku pamaké aplikasi urang (awan-pamaké).

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

Nyetel PostgreSQL sareng Django gampang: ngadamel database, nyiptakeun pangguna, ngonpigurasikeun idin. Hiji hal anu kedah diémutan nalika mimitina masang PostgreSQL nyaéta skrip pangaturan postgresql anu dipasang sareng pakét postgresql-server. Skrip ieu ngabantosan anjeun ngalaksanakeun tugas dasar anu aya hubunganana sareng administrasi klaster database, sapertos inisialisasi klaster atanapi prosés pamutahiran. Pikeun ngonpigurasikeun conto PostgreSQL anyar dina sistem RHEL, urang kedah ngajalankeun paréntah:

sudo /usr/bin/postgresql-setup -initdb

Anjeun teras tiasa ngamimitian PostgreSQL nganggo systemd, nyiptakeun pangkalan data, sareng nyetél proyék di Django. Inget pikeun balikan deui PostgreSQL sanggeus nyieun parobahan dina file konfigurasi auténtikasi klien (biasana pg_hba.conf) pikeun ngonpigurasikeun gudang sandi pikeun pamaké aplikasi. Upami anjeun ngalaman kasusah anu sanés, pastikeun pikeun ngarobih setélan IPv4 sareng IPv6 dina 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

Dina 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

Dina 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 }}',
   }
}

Saatos ngonpigurasikeun file settings.py dina proyék sareng nyetél konfigurasi database, anjeun tiasa ngamimitian pangladén pangembangan pikeun mastikeun yén sadayana jalan. Saatos ngamimitian server pamekaran, éta hadé pikeun nyiptakeun pangguna admin pikeun nguji sambungan kana pangkalan data.

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

WSGI? Wai?

Pangladén pamekaran mangpaat pikeun nguji, tapi pikeun ngajalankeun aplikasi anjeun kedah ngonpigurasikeun server sareng proxy anu cocog pikeun Web Server Gateway Interface (WSGI). Aya sababaraha kombinasi umum, contona, Apache HTTPD sareng uWSGI atanapi Nginx sareng Gunicorn.

Pakasaban Web Server Gateway Interface nyaéta pikeun neraskeun pamundut ti pangladén wéb ka kerangka wéb Python. WSGI mangrupakeun relic tina kaliwat dahsyat nalika mesin CGI éta sabudeureun, tur kiwari WSGI mangrupakeun standar de facto, paduli web server atawa kerangka Python dipaké. Tapi sanajan pamakéan nyebar na, aya kénéh loba nuances nalika gawé bareng frameworks ieu, sarta loba pilihan. Dina hal ieu, urang bakal nyoba ngadegkeun interaksi antara Gunicorn na Nginx via stop kontak a.

Kusabab duanana komponén ieu dipasang dina server sarua, hayu urang coba ngagunakeun stop kontak UNIX tinimbang stop kontak jaringan. Kusabab komunikasi merlukeun stop kontak dina sagala hal, hayu urang coba hiji deui léngkah tur ngonpigurasikeun aktivasina stop kontak pikeun Gunicorn via systemd.

Prosés nyieun jasa stop kontak diaktipkeun cukup basajan. Kahiji, file Unit dijieun nu ngandung diréktif ListenStream nunjuk ka titik di mana stop kontak UNIX bakal dijieun, lajeng file Unit pikeun layanan nu diréktif Merlukeun bakal nunjuk kana file Unit stop kontak. Teras, dina file unit jasa, anu tetep nyaéta nyauran Gunicorn tina lingkungan virtual sareng nyiptakeun WSGI ngariung pikeun stop kontak UNIX sareng aplikasi Django.

Ieu sababaraha conto file unit anu anjeun tiasa dianggo salaku dasar. Mimiti urang nyetél stop kontak.

[Unit]
Description=Gunicorn WSGI socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

Ayeuna anjeun kedah ngonpigurasikeun 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

Pikeun Nginx, éta saderhana pikeun nyiptakeun file konfigurasi proxy sareng nyetél diréktori pikeun nyimpen eusi statik upami anjeun nganggo. Dina RHEL, file konfigurasi Nginx aya di /etc/nginx/conf.d. Anjeun tiasa nyalin conto di handap ieu kana file /etc/nginx/conf.d/default.conf tur mimitian layanan. Pastikeun pikeun ngeset server_name pikeun cocog ngaran host anjeun.

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;
   }
}

Mimitian stop kontak Gunicorn sareng Nginx nganggo systemd sareng anjeun siap ngamimitian nguji.

Kasalahan Bad Gateway?

Upami anjeun ngasupkeun alamat kana panyungsi anjeun, anjeun paling dipikaresep bakal nampi kasalahan 502 Bad Gateway. Éta tiasa disababkeun ku idin stop kontak UNIX anu teu leres, atanapi tiasa disababkeun ku masalah anu langkung kompleks anu aya hubunganana sareng kontrol aksés di SELinux.

Dina log kasalahan nginx anjeun tiasa ningali garis sapertos kieu:

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"

Lamun urang nguji Gunicorn langsung, urang bakal meunang jawaban kosong.

curl —unix-socket /run/gunicorn.sock 8beta1.example.com

Hayu urang terang naha ieu kajadian. Upami anjeun muka log, anjeun paling dipikaresep bakal ningali yén masalahna aya hubunganana sareng SELinux. Kusabab urang ngajalankeun daemon anu teu aya kawijakan anu diciptakeun, éta ditandaan salaku init_t. Hayu urang nguji téori ieu dina praktekna.

sudo setenforce 0

Sadaya ieu tiasa nyababkeun kritik sareng cimata getih, tapi ieu ngan ukur debugging prototipe. Hayu urang nganonaktipkeun cék ngan pikeun mastikeun yén ieu masalahna, nu satutasna urang bakal balik sagalana deui ka tempatna.

Ku nyegerkeun halaman dina browser atanapi ngajalankeun deui paréntah curl kami, anjeun tiasa ningali halaman uji Django.

Janten, saatos mastikeun yén sadayana jalan sareng teu aya deui masalah idin, kami ngaktifkeun SELinux deui.

sudo setenforce 1

Kuring moal ngobrol ngeunaan audit2allow atawa nyieun kawijakan dumasar-waspada kalawan sepolgen dieu, saprak euweuh aplikasi Django sabenerna dina momen, jadi euweuh peta lengkep naon Gunicorn bisa hayang aksés jeung naon eta kudu mungkir aksés ka. Kituna, perlu tetep SELinux ngajalankeun ngajaga sistem, bari dina waktos anu sareng ngamungkinkeun aplikasi pikeun ngajalankeun sarta ninggalkeun pesen dina log Inok ku kituna kawijakan sabenerna bisa lajeng dijieun ti aranjeunna.

Nangtukeun domain permisif

Henteu sadayana kantos ngupingkeun domain anu diidinan dina SELinux, tapi aranjeunna henteu énggal. Seueur anu damel sareng aranjeunna tanpa disadari. Nalika kawijakan dijieun dumasar kana pesen Inok, kawijakan dijieun ngagambarkeun domain direngsekeun. Hayu urang coba nyieun kawijakan permitting basajan.

Pikeun nyieun hiji domain diwenangkeun husus pikeun Gunicorn, anjeun peryogi sababaraha jenis kawijakan, jeung anjeun ogé kudu nyirian file luyu. Sajaba ti éta, parabot diperlukeun pikeun ngumpul kawijakan anyar.

sudo yum install selinux-policy-devel

Mékanisme domain anu diidinan mangrupikeun alat anu saé pikeun ngaidentipikasi masalah, khususna dina aplikasi khusus atanapi aplikasi anu dikirimkeun tanpa kawijakan anu parantos didamel. Dina hal ieu, kawijakan domain anu diidinan pikeun Gunicorn bakal sasederhana mungkin - nyatakeun jinis utama (gunicorn_t), nyatakeun jinis anu kami bakal dianggo pikeun nyirian sababaraha executable (gunicorn_exec_t), teras nyetél transisi pikeun sistem anu leres ditandaan. prosés ngajalankeun. Baris panungtungan nyetél kawijakan sakumaha diaktipkeun sacara standar dina waktu eta 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;

Anjeun tiasa nyusun file kawijakan ieu sareng nambihan kana sistem anjeun.

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

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

Hayu urang parios upami SELinux ngahalangan anu sanés sanés anu diaksés ku daemon anu teu dipikanyaho.

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 nyerat data kana stop kontak UNIX anu dianggo ku Gunicorn. Biasana, dina kasus sapertos kitu, kawijakan mimiti robih, tapi aya tangtangan anu sanés. Anjeun oge bisa ngarobah setelan domain ti domain pangwatesan kana domain idin. Ayeuna hayu urang mindahkeun httpd_t kana domain idin. Ieu bakal masihan Nginx aksés anu diperyogikeun sareng urang tiasa neraskeun karya debugging salajengna.

sudo semanage permissive -a httpd_t

Janten, saatos anjeun junun ngajaga SELinux dijagi (anjeun leres-leres henteu kedah ngantunkeun proyék SELinux dina modeu diwatesan) sareng domain ijin dimuat, anjeun kedah terang naon anu kedah ditandaan salaku gunicorn_exec_t supados sadayana jalan leres. deui. Hayu urang cobian nganjang ka halaman wéb pikeun ningali pesen énggal ngeunaan larangan aksés.

sudo ausearch -m AVC -c gunicorn

Anjeun bakal ningali seueur pesen anu ngandung 'comm="gunicorn"' anu ngalakukeun sagala rupa hal dina file dina /srv/djangoapp, janten ieu écés mangrupikeun salah sahiji paréntah anu patut dibanda.

Tapi salian ti éta, pesen sapertos kieu muncul:

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

Upami anjeun ningali status jasa gunicorn atanapi ngajalankeun paréntah ps, anjeun moal ningali prosés anu ngajalankeun. Sigana mah gunicorn nyobian ngaksés juru Python di lingkungan virtualenv urang, sigana pikeun ngajalankeun skrip worker. Janten ayeuna hayu urang cirian dua file anu tiasa dieksekusi ieu sareng pariksa naha urang tiasa muka halaman uji Django.

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

Ladenan gunicorn kedah di-restart sateuacan tag énggal tiasa dipilih. Anjeun tiasa langsung balikan deui atanapi ngeureunkeun jasa sareng ngantepkeun stop kontak nalika anjeun muka situs dina browser. Pariksa yén prosés parantos nampi labél anu leres nganggo ps.

ps -efZ | grep gunicorn

Tong hilap ngadamel kawijakan SELinux normal engké!

Upami anjeun ningali pesen AVC ayeuna, pesen terakhir ngandung permisif = 1 pikeun sadayana anu aya hubunganana sareng aplikasi, sareng permisif = 0 pikeun sistem anu sanés. Upami anjeun ngartos naon jinis aksés anu diperyogikeun aplikasi nyata, anjeun tiasa gancang mendakan jalan anu pangsaéna pikeun ngabéréskeun masalah sapertos kitu. Tapi dugi ka waktos éta, langkung saé pikeun ngajaga sistem aman sareng kéngingkeun pamariksaan anu jelas sareng tiasa dianggo pikeun proyék Django.

sudo ausearch -m AVC

Kajadian!

Proyék Django anu damel parantos muncul kalayan frontend dumasar kana Nginx sareng Gunicorn WSGI. Kami ngonpigurasi Python 3 sareng PostgreSQL 10 tina repositori RHEL 8 Beta. Ayeuna anjeun tiasa maju sareng nyiptakeun (atanapi ngan saukur nyebarkeun) aplikasi Django atanapi ngajalajah alat-alat sanés anu aya dina RHEL 8 Beta pikeun ngajadikeun otomatis prosés konfigurasi, ningkatkeun kinerja, atanapi bahkan wadahna konfigurasi ieu.

sumber: www.habr.com

Tambahkeun komentar