RHEL 8 Бета семинары: Жумушчу веб тиркемелерди түзүү

RHEL 8 Beta иштеп чыгуучуларга көптөгөн жаңы функцияларды сунуштайт, алардын тизмеси барактарды алат, бирок жаңы нерселерди үйрөнүү иш жүзүндө дайыма жакшыраак, ошондуктан төмөндө биз Red Hat Enterprise Linux 8 Beta базасында иш жүзүндө тиркеме инфраструктурасын түзүү боюнча семинарды сунуштайбыз.

RHEL 8 Бета семинары: Жумушчу веб тиркемелерди түзүү

Келгиле, Python, иштеп чыгуучулардын арасында популярдуу программалоо тилин негиз катары, Django жана PostgreSQL айкалышы, тиркемелерди түзүү үчүн кеңири таралган комбинацияны алалы жана RHEL 8 Beta версиясын алар менен иштөө үчүн конфигурациялайлы. Андан кийин дагы бир нече (классификацияланбаган) ингредиенттерди кошобуз.

Сыноо чөйрөсү өзгөрөт, анткени автоматташтыруунун мүмкүнчүлүктөрүн изилдөө, контейнерлер менен иштөө жана бир нече серверлер менен чөйрөлөрдү сынап көрүү кызыктуу. Жаңы долбоор менен баштоо үчүн, сиз кол менен кичинекей, жөнөкөй прототибин түзүү менен баштасаңыз болот, ошондо сиз эмне болушу керектигин жана анын өз ара аракеттенишүүсүн так көрө аласыз, андан кийин автоматташтырууга жана татаал конфигурацияларды түзүүгө өтүңүз. Бүгүн биз мындай прототибин түзүү жөнүндө сөз болуп жатат.

Келгиле, RHEL 8 Beta VM сүрөтүн жайылтуу менен баштайлы. Сиз виртуалдык машинаны нөлдөн баштап орното аласыз же Бета жазылууңуз менен жеткиликтүү KVM конок сүрөтүн колдоно аласыз. Коноктун сүрөтүн колдонууда, булутту инициализациялоо үчүн метаберилиштерди жана колдонуучунун маалыматтарын камтыган виртуалдык CDди конфигурациялашыңыз керек болот (cloud-init). Дисктин структурасы же жеткиликтүү пакеттер менен өзгөчө эч нерсе кылуунун кереги жок.

Келгиле, бүт процессти кененирээк карап чыгалы.

Django орнотулууда

Django'нун эң жаңы версиясы менен сизге Python 3.5 же андан кийинкиси менен виртуалдык чөйрө (virtualenv) керек болот. Бета эскертүүлөрүндө сиз Python 3.6 жеткиликтүү экенин көрө аласыз, келгиле, бул чындап эле ушундай экенин текшерип көрөлү:

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

Red Hat Pythonду RHELде тутумдук шайман катары активдүү колдонот, анда эмне үчүн бул натыйжага алып келет?

Чындыгында, көптөгөн Python иштеп чыгуучулары дагы эле Python 2ден Python 2ге өтүүнү ойлонуштуруп жатышат, ал эми Python 3 өзү активдүү иштеп чыгууда жана барган сайын жаңы версиялар пайда болууда. Ошондуктан, колдонуучуларга Python'дун ар кандай жаңы версияларына кирүү мүмкүнчүлүгүн сунуштоо менен туруктуу тутум куралдарына болгон муктаждыкты канааттандыруу үчүн Python системасы жаңы пакетке көчүрүлүп, Python 2.7 жана 3.6 экөөнү тең орнотуу мүмкүнчүлүгүн берген. Өзгөртүүлөр жана алар эмне үчүн киргизилгендиги жөнүндө көбүрөөк маалыматты басылмадан таба аласыз Лангдон Уайттын блогу (Лэнгдон Уайт).

Ошентип, Python менен иштөө үчүн, көз карандылык катары python3-pip камтылган эки пакетти орнотуу керек.

sudo yum install python36 python3-virtualenv

Эмне үчүн Лэнгдон сунуштагандай түз модулдук чалууларды колдонуп, pip3 орнотууга болбойт? Алдыдагы автоматташтырууну эске алып, Ansible иштеши үчүн орнотулган пипти талап кылары белгилүү, анткени pip модулу ыңгайлаштырылган пиптин аткарылышы менен virtualenvтерди колдобойт.

Иштеп жаткан python3 котормочусу менен сиз Django орнотуу процессин уланта аласыз жана башка компоненттерибиз менен бирге иштөө тутумуна ээ боло аласыз. Интернетте көптөгөн ишке ашыруу варианттары бар. Бул жерде берилген бир версия бар, бирок колдонуучулар өз процесстерин колдоно алышат.

Биз RHEL 8де жеткиликтүү PostgreSQL жана Nginx версияларын демейки боюнча Yum аркылуу орнотобуз.

sudo yum install nginx postgresql-server

PostgreSQL psycopg2ди талап кылат, бирок ал virtualenv чөйрөсүндө гана жеткиликтүү болушу керек, ошондуктан биз аны Django жана Gunicorn менен бирге pip3 аркылуу орнотобуз. Бирок адегенде virtualenv орнотуубуз керек.

Django долбоорлорун орнотуу үчүн туура жерди тандоо темасында ар дайым көп талаш-тартыштар бар, бирок күмөн санасаңыз, Linux Filesystem Ierarchy Standard стандартына кайрылсаңыз болот. Тактап айтканда, FHS /srv төмөнкүлөр үчүн колдонулат деп айтылат: "система чыгарган веб-сервердин маалыматтары жана скрипттери, FTP серверлеринде сакталган маалыматтар жана системанын репозиторийлери (FHSде пайда болгон) сыяктуу маалыматтарды сактоо." 2.3-жылы -2004).

Бул так биздин жагдай, ошондуктан биз керектүү нерселердин бардыгын биздин тиркеме колдонуучуга (булут-колдонуучу) таандык болгон /srvге салабыз.

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

PostgreSQL жана Django орнотуу оңой: маалымат базасын түзүү, колдонуучуну түзүү, уруксаттарды конфигурациялоо. PostgreSQLди адегенде орнотуп жатканда эстен чыгарбоо керек болгон бир нерсе, postgresql-сервер пакети менен орнотулган postgresql орнотуу скрипти. Бул скрипт маалымат базасынын кластерин башкаруу менен байланышкан негизги тапшырмаларды аткарууга жардам берет, мисалы, кластерди инициализациялоо же жаңыртуу процесси. RHEL системасында жаңы PostgreSQL инстанциясын конфигурациялоо үчүн биз төмөнкү буйрукту аткарышыбыз керек:

sudo /usr/bin/postgresql-setup -initdb

Андан кийин сиз PostgreSQLди systemd аркылуу баштасаңыз, маалымат базасын түзүп, Djangoдо долбоорду орното аласыз. Колдонмонун колдонуучусу үчүн сырсөз сактагычты конфигурациялоо үчүн кардар аныктыгын текшерүү конфигурация файлына (көбүнчө pg_hba.conf) өзгөртүүлөрдү киргизгенден кийин PostgreSQLди өчүрүп күйгүзүүнү унутпаңыз. Башка кыйынчылыктарга туш болсоңуз, pg_hba.conf файлындагы IPv4 жана IPv6 жөндөөлөрүн өзгөртүңүз.

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

/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

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

Долбоордогу settings.py файлын конфигурациялагандан жана маалымат базасынын конфигурациясын орноткондон кийин, бардыгы иштеп жатканын текшерүү үчүн иштеп чыгуу серверин баштасаңыз болот. Иштеп чыгуу серверин ишке киргизгенден кийин, маалымат базасына байланышты текшерүү үчүн администратор колдонуучуну түзүү жакшы идея.

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

WSGI? Wai?

Иштеп чыгуу сервери тестирлөө үчүн пайдалуу, бирок тиркемени иштетүү үчүн Web Server Gateway Interface (WSGI) үчүн тиешелүү серверди жана проксиди конфигурациялашыңыз керек. Бир нече жалпы айкалыштар бар, мисалы, uWSGI менен Apache HTTPD же Gunicorn менен Nginx.

Web Server Gateway Interface жумушу веб-серверден Python веб алкагына суроо-талаптарды жөнөтүү болуп саналат. WSGI - бул CGI кыймылдаткычтары пайда болгон кездеги коркунучтуу өткөндүн реликти, ал эми бүгүнкү күндө WSGI веб-серверге же Python фреймворк колдонулганына карабастан, де-факто стандарты болуп саналат. Бирок анын кеңири колдонулушуна карабастан, бул алкактар ​​менен иштөөдө дагы эле көптөгөн нюанстар жана көптөгөн тандоолор бар. Бул учурда, биз розетка аркылуу Gunicorn жана Nginx ортосунда өз ара аракеттенүүнү орнотууга аракет кылабыз.

Бул компоненттердин экөө тең бир серверге орнотулгандыктан, келгиле, тармак розеткасынын ордуна UNIX розеткасын колдонуп көрөлү. Байланыш үчүн кандай болгон күндө да розетка керек болгондуктан, келгиле, дагы бир кадам жасап, Gunicorn үчүн розеткаларды systemd аркылуу активдештирүүнү конфигурациялап көрөлү.

Розеткага кошулган кызматтарды түзүү процесси абдан жөнөкөй. Биринчиден, UNIX розеткасынын түзүлө турган жерин көрсөткөн ListenStream директивасын камтыган бирдик файл түзүлөт, андан кийин Requires директивасы розетка бирдигинин файлын көрсөтө турган кызматтын бирдик файлы түзүлөт. Андан кийин, тейлөө бирдигинин файлында, виртуалдык чөйрөдөн Gunicorn чакырып, UNIX розеткасына жана Django тиркемесине WSGI байланышын түзүү гана калды.

Бул жерде сиз негиз катары колдоно турган бирдик файлдарынын кээ бир мисалдары келтирилген. Алгач розетка орноттук.

[Unit]
Description=Gunicorn WSGI socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

Эми сиз 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

Nginx үчүн прокси конфигурация файлдарын түзүү жана эгер сиз колдонуп жатсаңыз, статикалык мазмунду сактоо үчүн каталогду түзүү жөнөкөй маселе. RHELде, Nginx конфигурация файлдары /etc/nginx/conf.d ичинде жайгашкан. Сиз төмөнкү мисалды /etc/nginx/conf.d/default.conf файлына көчүрүп, кызматты баштасаңыз болот. Server_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;
   }
}

Gunicorn розеткасын жана Nginxти systemd аркылуу баштаңыз жана сиз тестирлөөнү баштоого даярсыз.

Bad Gateway катасы?

Даректи браузерге киргизсеңиз, сиз 502 Bad Gateway катасын аласыз. Бул туура эмес конфигурацияланган UNIX розеткасынын уруксаттарынан улам келип чыгышы мүмкүн же SELinux'та кирүү мүмкүнчүлүгүн башкарууга байланыштуу татаалыраак маселелерден улам болушу мүмкүн.

Nginx ката журналында төмөнкүдөй сапты көрө аласыз:

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"

Эгер биз Gunicornду түз сынап көрсөк, биз бош жооп алабыз.

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

Келгиле, бул эмне үчүн экенин аныктап көрөлү. Эгер сиз журналды ачсаңыз, көйгөй SELinux менен байланыштуу экенин көрөсүз. Биз эч кандай саясат түзүлбөгөн демонду иштетип жаткандыктан, ал init_t деп белгиленген. Келгиле, бул теорияны практикада сынап көрөлү.

sudo setenforce 0

Мунун баары сынга жана кандын көз жашына алып келиши мүмкүн, бирок бул жөн гана прототибин оңдоо. Бул көйгөй экенине ынануу үчүн текшерүүнү өчүрөлү, андан кийин биз бардыгын өз ордуна кайтарабыз.

Браузердеги баракты жаңылоо менен же curl буйругубузду кайра иштетүү менен, сиз Django сыноо барагын көрө аласыз.

Ошентип, баары иштегенине жана башка уруксат көйгөйлөрү жок экенине ынангандан кийин, биз SELinux-ту кайра иштетебиз.

sudo setenforce 1

Мен бул жерде audit2allow же сеполген менен эскертүүгө негизделген саясаттарды түзүү жөнүндө сөз кылбайм, анткени учурда чыныгы Django тиркемеси жок, андыктан Gunicorn эмнеге киргиси келиши мүмкүн жана ал эмнеге кирүү мүмкүнчүлүгүнөн баш тартуу керектигинин толук картасы жок. Ошондуктан, системаны коргоо үчүн SELinux иштеп турушу керек, ошол эле учурда колдонмонун иштешине жана текшерүү журналында билдирүүлөрдү калтырууга мүмкүндүк берет, ошондо алардан чыныгы саясат түзүлөт.

Уруксат берүүчү домендерди көрсөтүү

SELinux'та уруксат берилген домендер жөнүндө баары эле уккан эмес, бирок алар жаңы нерсе эмес. Көбү түшүнбөй эле алар менен иштешкен. Саясат аудит билдирүүлөрүнүн негизинде түзүлгөндө, түзүлгөн саясат чечилген доменди билдирет. Келгиле, жөнөкөй уруксат саясатын түзүүгө аракет кылалы.

Gunicorn үчүн белгилүү бир уруксат берилген доменди түзүү үчүн, сизге кандайдыр бир саясат керек, ошондой эле тиешелүү файлдарды белгилөө керек. Мындан тышкары, жаңы саясаттарды чогултуу үчүн куралдар керек.

sudo yum install selinux-policy-devel

Уруксат берилген домендердин механизми көйгөйлөрдү аныктоо үчүн эң сонун курал болуп саналат, айрыкча, мурунтан эле түзүлгөн саясатсыз жөнөтүлгөн ыңгайлаштырылган тиркеме же тиркемелерге келгенде. Бул учурда, Gunicorn үчүн уруксат берилген домен саясаты мүмкүн болушунча жөнөкөй болот - негизги түрүн жарыялаңыз (gunicorn_t), биз бир нече аткарылуучуларды белгилөө үчүн колдоно турган түрдү жарыялаңыз (gunicorn_exec_t), андан кийин системага туура белгилөө үчүн өтүүнү орнотуңуз иштеп жаткан процесстер. Акыркы сап саясатты жүктөө учурунда демейки боюнча иштетилгендей орнотот.

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;

Бул саясат файлын түзүп, аны системаңызга кошсоңуз болот.

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

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

Келгиле, SELinux биздин белгисиз демон кирүүдөн башка нерсени блоктоп жатканын текшерип көрөлү.

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 Nginxтин Gunicorn колдонгон UNIX розеткасына маалыматтарды жазуусуна жол бербейт. Адатта, мындай учурларда саясат өзгөрө баштайт, бирок алдыда башка кыйынчылыктар бар. Сиз ошондой эле домен жөндөөлөрүн чектөө доменинен уруксат доменине өзгөртө аласыз. Эми httpd_t уруксаттар доменине жылдыралы. Бул Nginxке керектүү мүмкүнчүлүк берет жана биз андан ары мүчүлүштүктөрдү оңдоо иштерин уланта алабыз.

sudo semanage permissive -a httpd_t

Ошентип, сиз SELinuxту корголгондон кийин (сиз чындыгында SELinux долбоорун чектелген режимде калтырбаңыз) жана уруксат домендери жүктөлгөндөн кийин, бардыгы туура иштеши үчүн gunicorn_exec_t деп эмнени белгилеш керек экенин аныкташыңыз керек. кайра. Кирүү чектөөлөрү жөнүндө жаңы билдирүүлөрдү көрүү үчүн веб-сайтка кирип көрөлү.

sudo ausearch -m AVC -c gunicorn

Сиз /srv/djangoapp ичиндеги файлдарда ар кандай иштерди жасаган 'comm="gunicorn"' камтыган көптөгөн билдирүүлөрдү көрөсүз, андыктан бул, албетте, белгилөө керек болгон буйруктардын бири.

Бирок, андан тышкары, мындай билдирүү пайда болот:

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

Эгер сиз gunicorn кызматынын абалын карасаңыз же ps буйругун иштетсеңиз, анда эч кандай иштеп жаткан процессти көрбөйсүз. gunicorn биздин virtualenv чөйрөбүздө Python котормочуна кирүүгө аракет кылып жатат окшойт, балким жумушчу скрипттерин иштетүү үчүн. Эми ушул эки аткарылуучу файлды белгилеп, Django тест барагыбызды ача аларыбызды текшерип көрөлү.

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

Жаңы тег тандалганга чейин gunicorn кызматын кайра иштетүү керек болот. Сиз аны дароо өчүрүп же кызматты токтотуп, браузерде сайтты ачканда розеткага аны иштете аласыз. ps аркылуу процесстер туура энбелгилерди алганын текшериңиз.

ps -efZ | grep gunicorn

Кадимки SELinux саясатын кийинчерээк түзүүнү унутпаңыз!

Эгерде сиз азыр AVC билдирүүлөрүн карасаңыз, акыркы билдирүүдө колдонмого тиешелүү бардык нерселер үчүн уруксат берүүчү=1 жана системанын калган бөлүгү үчүн уруксат берүүчү=0 бар. Эгер сиз чыныгы тиркемеге кандай мүмкүнчүлүк керек экенин түшүнсөңүз, анда мындай көйгөйлөрдү чечүүнүн эң жакшы жолун тез таба аласыз. Бирок ага чейин системаны коопсуз сактап, Django долбоорунун так, колдонууга жарамдуу аудитин алуу эң жакшы.

sudo ausearch -m AVC

Болду!

Nginx жана Gunicorn WSGI негизиндеги фронтонду менен жумушчу Django долбоору пайда болду. Биз RHEL 3 Бета репозиторийлеринен Python 10 жана PostgreSQL 8 конфигурацияладык. Эми сиз алдыга жылып, конфигурациялоо процессин автоматташтыруу, аткарууну жакшыртуу, жада калса бул конфигурацияны контейнерлештирүү үчүн Django тиркемелерин түзө аласыз (же жөн эле орното аласыз) же RHEL 8 Бетадагы башка жеткиликтүү куралдарды изилдей аласыз.

Source: www.habr.com

Комментарий кошуу