RHEL 8 Beta Workshop: Pagtukod ug Mga Aplikasyon sa Web nga Nagtrabaho

Ang RHEL 8 Beta nagtanyag sa mga developers og daghang mga bag-ong feature, ang listahan niini mahimong magkuha og mga pahina, bisan pa, ang pagkat-on og bag-ong mga butang kanunay nga mas maayo sa praktis, mao nga sa ubos nagtanyag kami og workshop sa aktuwal nga paghimo sa usa ka imprastraktura sa aplikasyon base sa Red Hat Enterprise Linux 8 Beta.

RHEL 8 Beta Workshop: Pagtukod ug Mga Aplikasyon sa Web nga Nagtrabaho

Atong kuhaon ang Python, usa ka popular nga programming language taliwala sa mga developers, isip basehan, usa ka kombinasyon sa Django ug PostgreSQL, usa ka komon nga kombinasyon alang sa pagmugna og mga aplikasyon, ug i-configure ang RHEL 8 Beta aron magtrabaho uban kanila. Dayon magdugang kami og usa ka magtiayon pa (wala'y klase) nga mga sangkap.

Ang pagsulay nga palibot mausab, tungod kay kini makapaikag sa pag-usisa sa mga posibilidad sa automation, pagtrabaho uban sa mga sudlanan ug pagsulay nga mga palibot nga adunay daghang mga server. Aron makasugod sa usa ka bag-ong proyekto, mahimo ka magsugod pinaagi sa paghimo og gamay, yano nga prototype pinaagi sa kamot aron makita nimo kung unsa gyud ang kinahanglan nga mahitabo ug kung giunsa kini interaksyon, ug dayon magpadayon sa pag-automate ug paghimo og mas komplikado nga mga pag-configure. Karon naghisgot kami bahin sa paghimo sa ingon nga prototype.

Magsugod kita pinaagi sa pag-deploy sa RHEL 8 Beta VM nga imahe. Mahimo nimong i-install ang usa ka virtual nga makina gikan sa wala, o gamiton ang imahe sa bisita sa KVM nga magamit sa imong suskrisyon sa Beta. Kung mogamit usa ka imahe sa bisita, kinahanglan nimo nga i-configure ang usa ka virtual nga CD nga adunay sulud nga metadata ug data sa gumagamit alang sa pagsugod sa panganod (cloud-init). Dili nimo kinahanglan nga buhaton ang bisan unsang espesyal sa istruktura sa disk o magamit nga mga pakete; ang bisan unsang pagsulud mahimo.

Atong tan-awon pag-ayo ang tibuok proseso.

Pag-instalar sa Django

Uban sa pinakabag-o nga bersyon sa Django, kinahanglan nimo ang usa ka virtual nga palibot (virtualenv) nga adunay Python 3.5 o sa ulahi. Sa mga nota sa Beta makita nimo nga magamit ang Python 3.6, atong susihon kung kini ba gyud ang kahimtang:

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

Aktibo nga gigamit sa Red Hat ang Python isip usa ka toolkit sa sistema sa RHEL, busa nganong kini resulta?

Ang tinuod mao nga daghang mga developer sa Python ang naghunahuna gihapon sa transisyon gikan sa Python 2 ngadto sa Python 2, samtang ang Python 3 mismo ubos sa aktibong pag-uswag, ug nagkadaghang bag-ong mga bersyon ang kanunay nga nagpakita. Busa, aron matubag ang panginahanglan alang sa lig-on nga mga himan sa sistema samtang nagtanyag sa mga tiggamit og access sa lain-laing mga bag-ong bersyon sa Python, ang sistema sa Python gibalhin ngadto sa usa ka bag-ong pakete ug naghatag sa abilidad sa pag-instalar sa Python 2.7 ug 3.6. Ang dugang nga kasayuran bahin sa mga pagbag-o ug kung ngano nga gihimo kini makita sa publikasyon sa Blog ni Langdon White (Langdon White).

Mao nga, aron makatrabaho ang Python, kinahanglan nimo nga i-install ang duha nga mga pakete, nga adunay python3-pip nga gilakip ingon usa ka dependency.

sudo yum install python36 python3-virtualenv

Ngano nga dili gamiton ang direkta nga mga tawag sa module sama sa gisugyot ni Langdon ug i-install ang pip3? Sa paghinumdom sa umaabot nga automation, nahibal-an nga ang Ansible magkinahanglan og pip nga gi-install aron modagan, tungod kay ang pip module wala nagsuporta sa virtualenvs nga adunay custom nga pip executable.

Uban sa usa ka nagtrabaho nga python3 interpreter nga imong magamit, mahimo nimong ipadayon ang proseso sa pag-install sa Django ug adunay usa ka sistema sa pagtrabaho kauban ang among ubang mga sangkap. Adunay daghang mga kapilian sa pagpatuman nga magamit sa Internet. Adunay usa ka bersyon nga gipresentar dinhi, apan ang mga tiggamit makagamit sa ilang kaugalingon nga mga proseso.

Atong i-install ang PostgreSQL ug Nginx nga mga bersyon nga anaa sa RHEL 8 pinaagi sa default gamit ang Yum.

sudo yum install nginx postgresql-server

Ang PostgreSQL nanginahanglan og psycopg2, apan kini kinahanglan nga magamit lamang sa usa ka virtualenv nga palibot, mao nga among i-install kini gamit ang pip3 kauban ang Django ug Gunicorn. Apan una kinahanglan naton nga i-set up ang virtualenv.

Kanunay adunay daghang debate sa hilisgutan sa pagpili sa husto nga lugar aron ma-install ang mga proyekto sa Django, apan kung adunay pagduhaduha, mahimo ka kanunay nga modangup sa Linux Filesystem Hierarchy Standard. Sa espesipiko, ang FHS nag-ingon nga ang /srv gigamit sa: "pagtipig sa piho nga host nga datos-data nga gihimo sa sistema, sama sa data sa web server ug mga script, datos nga gitipigan sa mga FTP server, ug pagkontrol sa mga repositoryo sa sistema." nga mga bersyon (nga makita sa FHS -2.3 niadtong 2004).

Mao gyud kini ang among kaso, mao nga among gibutang ang tanan nga among gikinahanglan sa /srv, nga gipanag-iya sa among user nga aplikasyon (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

Ang pag-set up sa PostgreSQL ug Django sayon: paghimo og database, paghimo og user, pag-configure sa mga permiso. Usa ka butang nga hinumdoman kung ang una nga pag-install sa PostgreSQL mao ang postgresql-setup script nga gi-install sa postgresql-server package. Kini nga script makatabang kanimo sa paghimo sa mga batakang buluhaton nga may kalabutan sa database cluster administration, sama sa cluster initialization o ang proseso sa pag-upgrade. Aron ma-configure ang usa ka bag-ong postgreSQL nga pananglitan sa usa ka sistema sa RHEL, kinahanglan namon nga ipadagan ang mando:

sudo /usr/bin/postgresql-setup -initdb

Mahimo nimong sugdan ang PostgreSQL gamit ang systemd, paghimo og database, ug pag-set up og proyekto sa Django. Hinumdumi nga i-restart ang PostgreSQL pagkahuman sa paghimo og mga pagbag-o sa file sa pagsumpo sa pagkumpirma sa kliyente (kasagaran pg_hba.conf) aron ma-configure ang pagtipig sa password alang sa tiggamit sa aplikasyon. Kung makasugat ka ug ubang mga kalisud, siguroha nga usbon ang IPv4 ug IPv6 setting sa pg_hba.conf file.

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

Sa 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

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

Human sa pag-configure sa settings.py file sa proyekto ug pag-set up sa database configuration, mahimo nimong sugdan ang development server aron masiguro nga ang tanan molihok. Human masugdan ang development server, maayong ideya nga maghimo ug admin user aron masulayan ang koneksyon sa database.

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

WSGI? Wai?

Ang development server mapuslanon alang sa pagsulay, apan sa pagpadagan sa aplikasyon kinahanglan nimo nga i-configure ang angay nga server ug proxy alang sa Web Server Gateway Interface (WSGI). Adunay daghang mga komon nga kombinasyon, pananglitan, Apache HTTPD uban sa uWSGI o Nginx uban sa Gunicorn.

Ang trabaho sa Web Server Gateway Interface mao ang pagpasa sa mga hangyo gikan sa web server ngadto sa Python web framework. Ang WSGI usa ka relic sa makalilisang nga nangagi sa dihang ang mga makina sa CGI anaa sa palibot, ug karon ang WSGI mao ang de facto nga sumbanan, bisan unsa pa ang gigamit nga web server o Python framework. Apan bisan pa sa kaylap nga paggamit niini, adunay daghang mga nuances kung nagtrabaho uban niini nga mga balangkas, ug daghang mga kapilian. Sa kini nga kaso, sulayan namon nga magtukod og interaksyon tali sa Gunicorn ug Nginx pinaagi sa usa ka socket.

Tungod kay ang duha niini nga mga sangkap gi-install sa parehas nga server, atong sulayan ang paggamit sa UNIX socket imbes sa network socket. Tungod kay ang komunikasyon nanginahanglan usa ka socket sa bisan unsang kaso, sulayan naton ang paghimo usa pa nga lakang ug i-configure ang pagpaaktibo sa socket alang sa Gunicorn pinaagi sa systemd.

Ang proseso sa paghimo sa socket activated nga mga serbisyo yano ra. Una, gihimo ang usa ka file sa unit nga adunay sulud nga direktiba sa ListenStream nga nagtudlo sa punto kung diin himuon ang socket sa UNIX, dayon usa ka file sa yunit alang sa serbisyo diin ang direktiba nga Gikinahanglan magpunting sa file sa socket unit. Unya, sa service unit file, ang nahabilin mao ang pagtawag sa Gunicorn gikan sa virtual nga palibot ug paghimo usa ka WSGI binding alang sa UNIX socket ug ang Django nga aplikasyon.

Ania ang pipila ka mga pananglitan sa mga file sa yunit nga mahimo nimong gamiton isip basehan. Una among gipahimutang ang socket.

[Unit]
Description=Gunicorn WSGI socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

Karon kinahanglan nimo nga i-configure ang Gunicorn daemon.

[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

Alang sa Nginx, kini usa ka yano nga butang sa paghimo sa mga file sa pag-configure sa proxy ug pag-set up sa usa ka direktoryo aron matipigan ang static nga sulud kung naggamit ka usa. Sa RHEL, ang mga file sa pagsumpo sa Nginx nahimutang sa /etc/nginx/conf.d. Mahimo nimong kopyahon ang mosunod nga pananglitan sa file /etc/nginx/conf.d/default.conf ug sugdi ang serbisyo. Siguroha nga itakda ang server_name nga mohaum sa imong host name.

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

Sugdi ang Gunicorn socket ug Nginx gamit ang systemd ug andam ka na nga magsugod sa pagsulay.

Bad Gateway error?

Kon imong isulod ang adres sa imong browser, lagmit makadawat kag 502 Bad Gateway error. Mahimo kini tungod sa sayop nga pag-configure sa UNIX socket permissions, o kini tungod sa mas komplikadong mga isyu nga may kalabutan sa access control sa SELinux.

Sa nginx error log makita nimo ang usa ka linya nga sama niini:

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"

Kung direkta namon nga sulayan ang Gunicorn, makakuha kami usa ka walay sulod nga tubag.

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

Atong hisgotan kon nganong nahitabo kini. Kung ablihan nimo ang log, lagmit imong makita nga ang problema adunay kalabotan sa SELinux. Tungod kay nagdagan kami usa ka daemon nga wala’y palisiya nga nahimo, gimarkahan kini nga init_t. Atong sulayan kini nga teorya sa praktis.

sudo setenforce 0

Kining tanan mahimong hinungdan sa pagsaway ug mga luha sa dugo, apan kini nag-debug lang sa prototype. Atong i-disable ang tseke aron lang masiguro nga kini ang problema, pagkahuman atong ibalik ang tanan sa iyang lugar.

Pinaagi sa pag-refresh sa panid sa browser o pag-usab sa among curl command, imong makita ang Django test page.

Mao nga, sa pagsiguro nga ang tanan molihok ug wala nay mga problema sa pagtugot, mahimo namon pag-usab ang SELinux.

sudo setenforce 1

Dili ko maghisgot bahin sa audit2allow o paghimo sa mga palisiya nga nakabase sa alerto nga adunay sepolgen dinhi, tungod kay wala’y aktuwal nga aplikasyon sa Django sa pagkakaron, mao nga wala’y kompleto nga mapa kung unsa ang gusto nga ma-access sa Gunicorn ug kung unsa ang kinahanglan nga isalikway ang pag-access. Busa, gikinahanglan nga ipadayon ang pagdagan sa SELinux aron mapanalipdan ang sistema, samtang sa samang higayon tugotan ang aplikasyon nga modagan ug magbilin ug mga mensahe sa audit log aron ang aktuwal nga polisiya mahimo dayon gikan kanila.

Pagtino sa permissive nga mga dominyo

Dili tanan nakadungog bahin sa gitugotan nga mga domain sa SELinux, apan dili kini bag-o. Daghan gani ang nagtrabaho uban kanila nga wala gani makaamgo niini. Kung ang usa ka palisiya gihimo base sa mga mensahe sa pag-audit, ang gihimo nga palisiya nagrepresentar sa nasulbad nga domain. Atong sulayan ang paghimo og usa ka yano nga palisiya sa pagtugot.

Aron makahimo usa ka piho nga gitugotan nga domain alang sa Gunicorn, kinahanglan nimo ang usa ka matang sa palisiya, ug kinahanglan nimo nga markahan ang angay nga mga file. Dugang pa, gikinahanglan ang mga himan aron matigom ang mga bag-ong polisiya.

sudo yum install selinux-policy-devel

Ang gitugutan nga mga domain nga mekanismo usa ka maayo nga himan alang sa pag-ila sa mga problema, labi na kung bahin sa usa ka naandan nga aplikasyon o mga aplikasyon nga gipadala nga wala’y mga palisiya nga nahimo na. Sa kini nga kaso, ang gitugotan nga polisiya sa domain alang sa Gunicorn mahimong yano kutob sa mahimo - ipahayag ang usa ka panguna nga tipo (gunicorn_t), ipahayag ang usa ka tipo nga among gamiton aron markahan ang daghang mga executable (gunicorn_exec_t), ug dayon i-set up ang usa ka transisyon alang sa sistema aron mamarkahan sa husto. nagdagan nga mga proseso. Ang katapusan nga linya nagtakda sa palisiya ingon nga mahimo pinaagi sa default sa panahon nga kini gikarga.

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;

Mahimo nimong kolektahon kini nga file sa palisiya ug idugang kini sa imong sistema.

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

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

Atong tan-awon kon ang SELinux nag-ali sa laing butang gawas sa gi-access sa atong wala mailhi nga daemon.

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

Gipugngan sa SELinux ang Nginx sa pagsulat sa datos sa UNIX socket nga gigamit sa Gunicorn. Kasagaran, sa ingon nga mga kaso, ang mga palisiya magsugod sa pagbag-o, apan adunay uban pang mga hagit sa unahan. Mahimo usab nimo usbon ang mga setting sa domain gikan sa usa ka restriction domain ngadto sa usa ka permission domain. Karon atong ibalhin ang httpd_t ngadto sa permissions domain. Kini maghatag sa Nginx sa gikinahanglan nga pag-access ug kita makapadayon sa dugang nga debugging nga trabaho.

sudo semanage permissive -a httpd_t

Mao nga, sa higayon nga mapadayon nimo nga mapanalipdan ang SELinux (dili gyud nimo biyaan ang usa ka proyekto sa SELinux sa gipugngan nga mode) ug ang mga domain sa pagtugot gikarga, kinahanglan nimo mahibal-an kung unsa gyud ang kinahanglan nga markahan ingon gunicorn_exec_t aron magamit ang tanan nga maayo. pag-usab. Atong sulayan ang pagbisita sa website aron makita ang mga bag-ong mensahe bahin sa mga pagdili sa pag-access.

sudo ausearch -m AVC -c gunicorn

Makita nimo ang daghang mga mensahe nga adunay 'comm="gunicorn"' nga naghimo sa lainlaing mga butang sa mga file sa / srv / djangoapp, mao nga kini klaro nga usa sa mga mando nga angay i-flag.

Apan dugang pa, usa ka mensahe nga sama niini makita:

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

Kung imong tan-awon ang status sa serbisyo sa gunicorn o ipadagan ang ps command, dili nimo makita ang bisan unsang mga proseso nga nagdagan. Morag gisulayan sa gunicorn nga ma-access ang tighubad sa Python sa among virtualenv nga palibot, posible nga magpadagan sa mga script sa trabahante. Busa karon atong markahan kining duha ka executable nga mga file ug susiha kon maablihan ba nato ang atong Django test page.

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

Ang serbisyo sa gunicorn kinahanglan nga i-restart sa dili pa mapili ang bag-ong tag. Mahimo nimo kini i-restart dayon o ihunong ang serbisyo ug tugoti nga magsugod ang socket kung imong ablihan ang site sa browser. Tinoa nga ang mga proseso nakadawat sa husto nga mga label gamit ang ps.

ps -efZ | grep gunicorn

Ayaw kalimti ang paghimo usa ka normal nga palisiya sa SELinux sa ulahi!

Kung imong tan-awon ang mga mensahe sa AVC karon, ang katapusan nga mensahe adunay permissive=1 alang sa tanan nga may kalabutan sa aplikasyon, ug permissive=0 alang sa nahabilin nga sistema. Kung nahibal-an nimo kung unsang klase sa pag-access ang kinahanglan sa usa ka tinuud nga aplikasyon, dali nimo makit-an ang labing kaayo nga paagi aron masulbad ang ingon nga mga problema. Apan hangtod niadto, labing maayo nga huptan nga luwas ang sistema ug makakuha usa ka klaro, magamit nga pag-audit sa proyekto sa Django.

sudo ausearch -m AVC

Nahitabo!

Ang usa ka nagtrabaho nga proyekto sa Django nagpakita nga adunay usa ka frontend nga gibase sa Nginx ug Gunicorn WSGI. Among gi-configure ang Python 3 ug PostgreSQL 10 gikan sa RHEL 8 Beta repository. Karon mahimo ka nga magpadayon ug maghimo (o mag-deploy lang) mga aplikasyon sa Django o mag-usisa sa uban pang magamit nga mga himan sa RHEL 8 Beta aron ma-automate ang proseso sa pag-configure, mapaayo ang pasundayag, o bisan ang sulud niini nga pag-configure.

Source: www.habr.com

Idugang sa usa ka comment