RHEL 8 Beta: Tsim kev ua haujlwm hauv lub vev xaib

RHEL 8 Beta muab cov neeg tsim tawm ntau yam tshiab, cov npe uas tuaj yeem siv cov nplooj ntawv, txawm li cas los xij, kev kawm yam tshiab yeej ib txwm zoo dua hauv kev xyaum, yog li hauv qab no peb muab kev cob qhia txog kev tsim cov ntawv thov tsim nyog raws li Red Hat Enterprise Linux 8 Beta.

RHEL 8 Beta: Tsim kev ua haujlwm hauv lub vev xaib

Cia peb coj Python, cov lus programming nrov ntawm cov neeg tsim khoom, ua lub hauv paus, kev sib xyaw ntawm Django thiab PostgreSQL, kev sib xyaw ua ke zoo rau kev tsim cov ntawv thov, thiab teeb tsa RHEL 8 Beta ua haujlwm nrog lawv. Tom qab ntawd peb yuav ntxiv ob peb ntxiv (tsis suav) cov khoom xyaw.

Qhov kev sim ib puag ncig yuav hloov pauv, vim nws yog qhov txaus siab los tshawb txog qhov muaj peev xwm ntawm automation, ua haujlwm nrog cov ntim thiab sim ua ib puag ncig nrog ntau lub servers. Txhawm rau pib nrog ib txoj haujlwm tshiab, koj tuaj yeem pib los ntawm kev tsim cov qauv me me, yooj yim los ntawm tes kom koj tuaj yeem pom raws nraim li cas yuav tsum tau tshwm sim thiab nws cuam tshuam li cas, thiab tom qab ntawd txav mus rau automate thiab tsim ntau txoj kev teeb tsa. Niaj hnub no peb tab tom tham txog kev tsim cov qauv zoo li no.

Cia peb pib los ntawm kev xa cov duab RHEL 8 Beta VM. Koj tuaj yeem nruab lub tshuab virtual los ntawm kos, lossis siv KVM cov duab qhua uas muaj nrog koj li Beta subscription. Thaum siv cov duab qhua, koj yuav tsum tau teeb tsa lub CD virtual uas yuav muaj cov ntaub ntawv metadata thiab cov ntaub ntawv siv rau huab pib (cloud-init). Koj tsis tas yuav ua dab tsi tshwj xeeb nrog cov qauv disk lossis cov pob khoom muaj; txhua qhov kev teeb tsa yuav ua.

Cia peb ua tib zoo saib tag nrho cov txheej txheem.

Txhim kho Django

Nrog rau qhov tshiab tshaj plaws ntawm Django, koj yuav xav tau ib puag ncig virtual (virtualenv) nrog Python 3.5 lossis tom qab ntawd. Hauv cov ntawv Beta koj tuaj yeem pom tias Python 3.6 muaj, cia peb xyuas seb qhov no puas muaj tseeb:

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

Red Hat nquag siv Python ua cov cuab yeej siv hauv RHEL, yog li vim li cas qhov no tshwm sim?

Qhov tseeb yog tias ntau tus neeg tsim tawm Python tseem tab tom xav txog kev hloov pauv ntawm Python 2 mus rau Python 2, thaum Python 3 nws tus kheej yog nyob rau hauv kev txhim kho, thiab ntau thiab ntau dua tshiab tau tshwm sim tas li. Yog li ntawd, kom ua tau raws li qhov xav tau ntawm cov cuab yeej ruaj khov thaum muab cov neeg siv nkag mus rau ntau yam tshiab ntawm Python, system Python tau hloov mus rau hauv pob tshiab thiab muab lub peev xwm rau nruab ob Python 2.7 thiab 3.6. Xav paub ntau ntxiv txog cov kev hloov pauv thiab vim li cas lawv tau tsim muaj nyob rau hauv kev tshaj tawm hauv Langdon White's blog (Langdon Dawb).

Yog li, kom tau txais kev ua haujlwm Python, koj tsuas yog yuav tsum tau nruab ob lub pob, nrog python3-pip suav nrog kev vam khom.

sudo yum install python36 python3-virtualenv

Vim li cas ho tsis siv kev hu ncaj qha raws li Langdon qhia thiab nruab pip3? Nco ntsoov lub automation tom ntej no, nws paub tias Ansible yuav xav tau pip ntsia kom khiav, vim pip module tsis txhawb virtualenvs nrog kev cai pip executable.

Nrog tus neeg txhais lus ua haujlwm python3 ntawm koj qhov pov tseg, koj tuaj yeem txuas ntxiv nrog Django txheej txheem kev teeb tsa thiab muaj kev ua haujlwm nrog rau peb lwm cov khoom. Muaj ntau ntau txoj kev xaiv muaj nyob rau hauv Internet. Muaj ib qho version nthuav tawm ntawm no, tab sis cov neeg siv tuaj yeem siv lawv tus kheej cov txheej txheem.

Peb yuav nruab PostgreSQL thiab Nginx versions muaj nyob rau hauv RHEL 8 los ntawm lub neej ntawd siv Yum.

sudo yum install nginx postgresql-server

PostgreSQL yuav xav tau psycopg2, tab sis nws yuav tsum muaj nyob rau hauv ib puag ncig virtualenv nkaus xwb, yog li peb yuav nruab nws siv pip3 nrog rau Django thiab Gunicorn. Tab sis ua ntej peb yuav tsum teeb tsa virtualenv.

Muaj ib txwm muaj kev sib cav ntau ntawm cov ncauj lus ntawm kev xaiv qhov chaw zoo rau nruab Django cov haujlwm, tab sis thaum tsis ntseeg, koj tuaj yeem tig mus rau Linux Filesystem Hierarchy Standard. Tshwj xeeb, FHS hais tias / srv yog siv los: "kho cov ntaub ntawv tshwj xeeb-cov ntaub ntawv uas lub kaw lus tsim tawm, xws li cov ntaub ntawv web server thiab cov ntawv sau, cov ntaub ntawv khaws cia ntawm FTP servers, thiab tswj cov chaw khaws cia." versions (tso tawm hauv FHS -2.3 nyob rau hauv 2004).

Qhov no yog raws nraim li peb cov ntaub ntawv, yog li peb muab txhua yam peb xav tau rau hauv / srv, uas yog los ntawm peb cov neeg siv daim ntawv thov (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

Teeb tsa PostgreSQL thiab Django yog qhov yooj yim: tsim cov ntaub ntawv, tsim tus neeg siv, teeb tsa kev tso cai. Ib yam uas yuav tsum nco ntsoov thaum pib txhim kho PostgreSQL yog postgresql-setup tsab ntawv uas tau nruab nrog lub pob postgresql-server. Tsab ntawv no pab koj ua cov haujlwm yooj yim cuam tshuam nrog kev tswj hwm pawg database, xws li kev pib ua pawg lossis cov txheej txheem txhim kho. Txhawm rau teeb tsa PostgreSQL tshiab ntawm RHEL system, peb yuav tsum tau khiav cov lus txib:

sudo /usr/bin/postgresql-setup -initdb

Tom qab ntawd koj tuaj yeem pib PostgreSQL siv systemd, tsim database, thiab teeb tsa ib qhov project hauv Django. Nco ntsoov rov pib dua PostgreSQL tom qab hloov pauv rau cov neeg siv khoom pov thawj kev teeb tsa cov ntaub ntawv (feem ntau pg_hba.conf) txhawm rau txhim kho tus password rau tus neeg siv daim ntawv thov. Yog tias koj ntsib lwm yam teeb meem, nco ntsoov hloov IPv4 thiab IPv6 teeb tsa hauv cov ntaub ntawv 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

Hauv cov ntaub ntawv /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

Hauv cov ntaub ntawv /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 }}',
   }
}

Tom qab teeb tsa cov ntaub ntawv settings.py hauv qhov project thiab teeb tsa lub database configuration, koj tuaj yeem pib qhov kev txhim kho server kom paub tseeb tias txhua yam ua haujlwm. Tom qab pib qhov kev txhim kho server, nws yog ib lub tswv yim zoo los tsim ib tus neeg siv admin txhawm rau txhawm rau kuaj kev sib txuas rau cov ntaub ntawv.

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

WSGI? Wai?

Kev txhim kho neeg rau zaub mov muaj txiaj ntsig zoo rau kev sim, tab sis txhawm rau khiav daim ntawv thov koj yuav tsum teeb tsa lub server tsim nyog thiab npe rau Web Server Gateway Interface (WSGI). Muaj ntau qhov sib xyaw ua ke, piv txwv li, Apache HTTPD nrog uWSGI lossis Nginx nrog Gunicorn.

Txoj haujlwm ntawm Web Server Gateway Interface yog xa cov lus thov los ntawm lub vev xaib server mus rau Python lub vev xaib. WSGI yog qhov tseem ceeb ntawm yav dhau los txaus ntshai thaum CGI xyaw nyob ib puag ncig, thiab niaj hnub no WSGI yog tus qauv de facto, tsis hais lub web server lossis Python lub moj khaum siv. Tab sis txawm tias nws siv dav, tseem muaj ntau yam nuances thaum ua haujlwm nrog cov qauv no, thiab ntau txoj kev xaiv. Hauv qhov no, peb yuav sim tsim kev sib cuam tshuam ntawm Gunicorn thiab Nginx ntawm lub qhov (socket).

Txij li ob qho tib si ntawm cov khoom no tau teeb tsa rau tib lub server, cia peb sim siv UNIX qhov (socket) es tsis txhob siv lub qhov (socket) network. Txij li thaum kev sib txuas lus xav tau lub qhov (socket) nyob rau hauv txhua rooj plaub, cia peb sim ua ib kauj ruam ntxiv thiab teeb tsa lub qhov (socket activation) rau Gunicorn ntawm systemd.

Cov txheej txheem ntawm kev tsim lub qhov (socket activated services) yog qhov yooj yim heev. Ua ntej, ib chav tsev cov ntaub ntawv raug tsim uas muaj cov lus qhia ListenStream taw tes rau qhov chaw uas UNIX lub qhov (socket) yuav raug tsim, tom qab ntawd ib chav tsev cov ntaub ntawv rau cov kev pabcuam uas xav tau cov lus qhia yuav taw tes rau lub qhov (socket unit file). Tom qab ntawd, hauv cov ntaub ntawv pabcuam, txhua yam uas tseem tshuav yog hu Gunicorn los ntawm ib puag ncig virtual thiab tsim WSGI khi rau UNIX qhov (socket) thiab daim ntawv thov Django.

Nov yog qee qhov piv txwv ntawm chav tsev cov ntaub ntawv uas koj tuaj yeem siv ua lub hauv paus. Ua ntej peb teeb tsa lub qhov (socket).

[Unit]
Description=Gunicorn WSGI socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

Tam sim no koj yuav tsum teeb tsa tus 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

Rau Nginx, nws yog ib qho teeb meem yooj yim ntawm kev tsim cov ntaub ntawv pov thawj kev teeb tsa thiab teeb tsa cov npe khaws cov ntsiab lus zoo li qub yog tias koj siv ib qho. Hauv RHEL, Nginx teeb tsa cov ntaub ntawv nyob hauv /etc/nginx/conf.d. Koj tuaj yeem luam cov piv txwv hauv qab no rau hauv cov ntaub ntawv /etc/nginx/conf.d/default.conf thiab pib qhov kev pabcuam. Nco ntsoov teem lub server_name kom phim koj lub npe host.

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

Pib lub qhov (socket) Gunicorn thiab Nginx siv systemd thiab koj npaj txhij pib sim.

Bad Gateway yuam kev?

Yog tias koj nkag mus rau qhov chaw nyob rau hauv koj tus browser, koj feem ntau yuav tau txais qhov yuam kev 502 Bad Gateway. Tej zaum nws yuav tshwm sim los ntawm kev teeb tsa tsis raug UNIX qhov tso cai tso cai, lossis nws yuav yog vim muaj teeb meem ntau ntxiv ntsig txog kev nkag mus rau hauv SELinux.

Hauv nginx yuam kev cav koj tuaj yeem pom kab zoo li no:

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"

Yog tias peb sim Gunicorn ncaj qha, peb yuav tau txais cov lus teb khoob.

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

Cia peb xav seb vim li cas qhov no tshwm sim. Yog tias koj qhib lub cav, koj feem ntau yuav pom tias qhov teeb meem cuam tshuam nrog SELinux. Txij li thaum peb tab tom khiav ib tus daemon uas tsis muaj txoj cai tau tsim, nws tau cim tias yog init_t. Cia peb sim qhov kev xav no hauv kev xyaum.

sudo setenforce 0

Tag nrho cov no yuav ua rau kev thuam thiab kua muag ntshav, tab sis qhov no tsuas yog debugging tus qauv. Cia peb lov tes taw daim tshev tsuas yog kom paub tseeb tias qhov no yog qhov teeb meem, tom qab ntawd peb yuav rov qab txhua yam rov qab rau nws qhov chaw.

Los ntawm refreshing nplooj ntawv hauv browser lossis rov ua peb cov lus txib curl, koj tuaj yeem pom Django nplooj ntawv xeem.

Yog li, tau ua kom paub tseeb tias txhua yam ua haujlwm thiab tsis muaj teeb meem kev tso cai ntxiv, peb qhib SELinux dua.

sudo setenforce 1

Kuv yuav tsis tham txog audit2allow lossis tsim kev ceeb toom-raws li txoj cai nrog sepolgen ntawm no, vim tias tsis muaj daim ntawv thov Django tiag tiag tam sim no, yog li tsis muaj daim ntawv qhia tiav ntawm dab tsi Gunicorn yuav xav nkag thiab nws yuav tsum tsis kam nkag mus rau. Yog li ntawd, nws yog ib qho tsim nyog yuav tsum ua kom SELinux khiav los tiv thaiv lub kaw lus, thaum tib lub sijhawm tso cai rau daim ntawv thov khiav thiab tawm cov lus hauv cov ntawv txheeb xyuas kom cov cai tiag tiag tuaj yeem tsim los ntawm lawv.

Qhia qhov tso cai tso cai

Tsis yog txhua tus tau hnov ​​​​txog cov npe tso cai hauv SELinux, tab sis lawv tsis muaj dab tsi tshiab. Ntau tus txawm ua haujlwm nrog lawv yam tsis tau paub txog nws. Thaum ib txoj cai raug tsim raws li kev tshuaj xyuas cov lus, txoj cai tsim los sawv cev rau qhov kev daws teeb meem. Cia peb sim tsim txoj cai tso cai yooj yim.

Txhawm rau tsim ib qho kev tso cai tshwj xeeb rau Gunicorn, koj xav tau qee txoj cai, thiab koj kuj yuav tsum tau kos cov ntaub ntawv tsim nyog. Tsis tas li ntawd, cov cuab yeej xav tau los sib sau ua ke cov cai tshiab.

sudo yum install selinux-policy-devel

Cov kev tso cai tswj hwm yog ib qho cuab yeej zoo rau kev txheeb xyuas cov teeb meem, tshwj xeeb tshaj yog thaum nws los txog rau daim ntawv thov kev cai lossis cov ntawv thov uas tsis muaj cai tau tsim. Hauv qhov no, txoj cai sau npe tso cai rau Gunicorn yuav yooj yim li sai tau - tshaj tawm hom tseem ceeb (gunicorn_t), tshaj tawm hom peb yuav siv los kos ntau qhov kev ua tiav (gunicorn_exec_t), thiab tom qab ntawd teeb tsa kev hloov pauv rau lub kaw lus kom raug cim khiav cov txheej txheem. Cov kab kawg tau teeb tsa txoj cai raws li tau qhib los ntawm lub neej ntawd thaum lub sijhawm nws thauj khoom.

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;

Koj tuaj yeem sau cov ntaub ntawv txoj cai no thiab ntxiv rau koj qhov system.

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

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

Cia peb kuaj xyuas seb SELinux thaiv lwm yam uas tsis yog qhov peb tsis paub dab tsi nkag mus.

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 tiv thaiv Nginx los ntawm kev sau cov ntaub ntawv rau UNIX socket siv los ntawm Gunicorn. Feem ntau, nyob rau hauv cov xwm txheej zoo li no, cov cai pib hloov pauv, tab sis muaj lwm yam kev sib tw ua ntej. Koj tuaj yeem hloov qhov chaw sau npe los ntawm qhov txwv txwv mus rau qhov tso cai sau npe. Tam sim no cia peb txav httpd_t mus rau qhov tso cai sau. Qhov no yuav muab Nginx nkag mus rau qhov tsim nyog thiab peb tuaj yeem txuas ntxiv nrog kev ua haujlwm debugging ntxiv.

sudo semanage permissive -a httpd_t

Yog li, thaum koj tau tswj hwm kom SELinux tiv thaiv (koj yuav tsum tsis txhob tawm ntawm SELinux qhov project hauv hom txwv) thiab cov ntawv tso cai raug thauj khoom, koj yuav tsum xyuas seb qhov twg yuav tsum tau cim raws li gunicorn_exec_t kom tau txhua yam ua haujlwm zoo. dua. Wb sim mus saib lub vev xaib kom pom cov lus tshiab txog kev txwv kev nkag.

sudo ausearch -m AVC -c gunicorn

Koj yuav pom ntau cov lus uas muaj 'comm = "gunicorn"' uas ua ntau yam ntawm cov ntaub ntawv hauv / srv / djangoapp, yog li qhov no yog qhov tseeb ib qho ntawm cov lus txib tsim nyog chij.

Tab sis ntxiv rau, cov lus zoo li no tshwm sim:

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

Yog tias koj saib cov xwm txheej ntawm kev pabcuam phom lossis khiav ps hais kom ua, koj yuav tsis pom cov txheej txheem khiav. Nws zoo li gunicorn tab tom sim nkag mus rau tus neeg txhais lus Python hauv peb ib puag ncig virtualenv, tej zaum yuav khiav cov ntawv sau ua haujlwm. Yog li tam sim no cia peb kos ob cov ntaub ntawv ua tau zoo thiab xyuas seb peb puas tuaj yeem qhib peb nplooj ntawv Django xeem.

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

Qhov kev pabcuam phom phom yuav tsum tau rov pib dua ua ntej lub cim tshiab tuaj yeem raug xaiv. Koj tuaj yeem rov pib dua tam sim lossis nres qhov kev pabcuam thiab cia lub qhov (socket) pib nws thaum koj qhib qhov chaw hauv qhov browser. Xyuas kom tseeb tias cov txheej txheem tau txais cov ntawv sau raug siv ps.

ps -efZ | grep gunicorn

Tsis txhob hnov ​​​​qab tsim ib txwm SELinux txoj cai tom qab!

Yog tias koj saib ntawm AVC cov lus tam sim no, cov lus kawg muaj kev tso cai = 1 rau txhua yam ntsig txog daim ntawv thov, thiab tso cai = 0 rau tag nrho cov kab ke. Yog tias koj nkag siab tias hom kev nkag mus rau qhov kev thov tiag tiag xav tau, koj tuaj yeem nrhiav txoj hauv kev zoo tshaj plaws los daws cov teeb meem no. Tab sis txog thaum ntawd, nws yog qhov zoo tshaj los ua kom lub kaw lus ruaj ntseg thiab tau txais qhov tseeb, siv tau tshawb xyuas ntawm Django qhov project.

sudo ausearch -m AVC

tshwm sim!

Ib txoj haujlwm Django ua haujlwm tau tshwm sim nrog lub ntsej muag raws li Nginx thiab Gunicorn WSGI. Peb teeb tsa Python 3 thiab PostgreSQL 10 los ntawm RHEL 8 Beta repositories. Tam sim no koj tuaj yeem txav mus tom ntej thiab tsim (lossis tsuas yog xa tawm) Django daim ntawv thov lossis tshawb nrhiav lwm cov cuab yeej muaj nyob hauv RHEL 8 Beta kom ua kom cov txheej txheem teeb tsa, txhim kho kev ua haujlwm, lossis txawm tias ntim cov txheej txheem no.

Tau qhov twg los: www.hab.com

Ntxiv ib saib