RHEL 8 Beta семинары: жұмыс істейтін веб-қосымшаларды құру

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

RHEL 8 Beta семинары: жұмыс істейтін веб-қосымшаларды құру

Әзірлеушілер арасында танымал бағдарламалау тілі Python-ды негіз ретінде Django және PostgreSQL тіркесімін алайық, бұл қолданбаларды жасау үшін жеткілікті кең таралған комбинация және олармен жұмыс істеу үшін RHEL 8 Beta нұсқасын конфигурациялаңыз. Содан кейін біз тағы бірнеше (жіктелмеген) ингредиенттерді қосамыз.

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

RHEL 8 Beta VM кескінін қолданудан бастайық. Виртуалды машинаны нөлден орнатуға немесе Бета жазылымында қолжетімді KVM қонақ кескінін пайдалануға болады. Қонақ кескінін пайдаланған кезде бұлтты инициализациялау үшін метадеректер мен пайдаланушы деректерін қамтитын виртуалды ықшам дискіні конфигурациялау қажет болады (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 RHEL жүйесінде жүйелік құралдар жинағы ретінде Python-ды белсенді пайдаланады, сондықтан бұл нәтиже неге әкеледі?

Көптеген 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 модулі теңшелетін pip орындалатын файлы бар виртуалды бағдарламаларды қолдамайды.

Қолыңызда жұмыс істейтін python3 аудармашы арқылы сіз Django орнату процесін жалғастыра аласыз және басқа құрамдастармен бірге жұмыс жүйесіне ие бола аласыз. Интернетте іске асырудың көптеген нұсқалары бар. Мұнда ұсынылған бір нұсқа бар, бірақ пайдаланушылар өз процестерін пайдалана алады.

RHEL 8 жүйесінде қолжетімді PostgreSQL және Nginx нұсқаларын Yum арқылы әдепкі бойынша орнатамыз.

sudo yum install nginx postgresql-server

PostgreSQL үшін psycopg2 қажет болады, бірақ ол тек virtualenv ортасында қол жетімді болуы керек, сондықтан біз оны Django және Gunicorn бірге pip3 арқылы орнатамыз. Бірақ алдымен virtualenv орнатуымыз керек.

Django жобаларын орнату үшін дұрыс орынды таңдау тақырыбы бойынша әрқашан көп пікірталастар болады, бірақ күмән туындаған кезде әрқашан Linux файлдық жүйе иерархиясы стандартына жүгінуге болады. Атап айтқанда, 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-setup сценарийі. Бұл сценарий дерекқор кластерін басқарумен байланысты негізгі тапсырмаларды орындауға көмектеседі, мысалы, кластерді баптандыру немесе жаңарту процесі. 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? Вай?

Әзірлеу сервері тестілеу үшін пайдалы, бірақ қолданбаны іске қосу үшін веб-сервер шлюзі интерфейсі (WSGI) үшін сәйкес сервер мен проксиді теңшеу керек. Бірнеше жалпы комбинациялар бар, мысалы, uWSGI бар Apache HTTPD немесе Gunicorn бар Nginx.

Веб-сервер шлюзі интерфейсінің жұмысы веб-серверден 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 арқылы іске қосыңыз және сіз тестілеуді бастауға дайынсыз.

Нашар шлюз қатесі?

Браузерге мекенжайды енгізсеңіз, сіз 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

Мен Audi2allow туралы немесе сеполгенмен ескертуге негізделген саясаттарды жасау туралы айтпаймын, себебі қазіргі уақытта нақты 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 Beta нұсқасындағы басқа қолжетімді құралдарды зерттеуге болады.

Ақпарат көзі: www.habr.com

пікір қалдыру