RHEL 8 Beta piedÄvÄ izstrÄdÄtÄjiem daudzas jaunas iespÄjas, kuru uzskaitÄ«Å”ana varÄtu aizÅemt lapas, tomÄr praksÄ apgÅ«t jaunas lietas vienmÄr ir labÄk, tÄpÄc zemÄk piedÄvÄjam seminÄru par aplikÄciju infrastruktÅ«ras reÄlu izveidi uz Red Hat Enterprise Linux 8 Beta bÄzes.
Å
emsim par pamatu Python, izstrÄdÄtÄju vidÅ« populÄro programmÄÅ”anas valodu, Django un PostgreSQL kombinÄciju, kas ir diezgan izplatÄ«ta kombinÄcija lietojumprogrammu izveidei, un konfigurÄsim RHEL 8 Beta darbam ar tÄm. Tad pievienosim vÄl pÄris (neklasificÄtas) sastÄvdaļas.
Testa vide mainÄ«sies, jo ir interesanti izpÄtÄ«t automatizÄcijas iespÄjas, strÄdÄt ar konteineriem un izmÄÄ£inÄt vides ar vairÄkiem serveriem. Lai sÄktu darbu ar jaunu projektu, varat ar roku izveidot nelielu, vienkÄrÅ”u prototipu, lai varÄtu precÄ«zi redzÄt, kam jÄnotiek un kÄ tas mijiedarbojas, un pÄc tam pÄriet uz automatizÄciju un sarežģītÄku konfigurÄciju izveidi. Å odien mÄs runÄjam par Å”Äda prototipa izveidi.
SÄksim ar RHEL 8 Beta VM attÄla izvietoÅ”anu. Varat instalÄt virtuÄlo maŔīnu no jauna vai izmantot KVM viesa attÄlu, kas pieejams jÅ«su Beta abonementÄ. Izmantojot viesa attÄlu, jums bÅ«s jÄkonfigurÄ virtuÄlais kompaktdisks, kurÄ bÅ«s metadati un lietotÄja dati mÄkoÅa inicializÄÅ”anai (Cloud-init). Ar diska struktÅ«ru vai pieejamajÄm pakotnÄm nekas Ä«paÅ”s nav jÄdara; derÄs jebkura konfigurÄcija.
ApskatÄ«sim visu procesu tuvÄk.
Django instalÄÅ”ana
Izmantojot jaunÄko Django versiju, jums bÅ«s nepiecieÅ”ama virtuÄlÄ vide (virtualenv) ar Python 3.5 vai jaunÄku versiju. Beta piezÄ«mÄs varat redzÄt, ka Python 3.6 ir pieejams, pÄrbaudÄ«sim, vai tas tÄ ir:
[cloud-user@8beta1 ~]$ python
-bash: python: command not found
[cloud-user@8beta1 ~]$ python3
-bash: python3: command not found
Red Hat aktÄ«vi izmanto Python kÄ sistÄmas rÄ«kkopu RHEL, kÄpÄc tas rodas?
Fakts ir tÄds, ka daudzi Python izstrÄdÄtÄji joprojÄm apsver pÄreju no Python 2 uz Python 2, savukÄrt pats Python 3 tiek aktÄ«vi izstrÄdÄts, un pastÄvÄ«gi parÄdÄs arvien jaunas versijas. TÄpÄc, lai apmierinÄtu vajadzÄ«bu pÄc stabiliem sistÄmas rÄ«kiem, vienlaikus piedÄvÄjot lietotÄjiem piekļuvi dažÄdÄm jaunÄm Python versijÄm, sistÄma Python tika pÄrvietota uz jaunu pakotni un nodroÅ”inÄja iespÄju instalÄt gan Python 2.7, gan 3.6. PlaÅ”Äku informÄciju par izmaiÅÄm un to izdarÄ«Å”anas iemeslu var atrast publikÄcijÄ
TÄtad, lai strÄdÄtu ar Python, jums ir jÄinstalÄ tikai divas pakotnes, un python3-pip ir iekļauta kÄ atkarÄ«ba.
sudo yum install python36 python3-virtualenv
KÄpÄc neizmantot tieÅ”os moduļu izsaukumus, kÄ to iesaka Lengdons, un instalÄt pip3? Paturot prÄtÄ gaidÄmo automatizÄciju, ir zinÄms, ka Ansible darbÄ«bai bÅ«s nepiecieÅ”ams instalÄt pip, jo pip modulis neatbalsta virtualenvs ar pielÄgotu pip izpildÄmo failu.
Ja jÅ«su rÄ«cÄ«bÄ ir strÄdÄjoÅ”s python3 tulks, varat turpinÄt Django instalÄÅ”anas procesu un izveidot funkcionÄjoÅ”u sistÄmu kopÄ ar citiem mÅ«su komponentiem. InternetÄ ir pieejamas daudzas ievieÅ”anas iespÄjas. Å eit ir viena versija, taÄu lietotÄji var izmantot savus procesus.
MÄs instalÄsim PostgreSQL un Nginx versijas, kas pÄc noklusÄjuma ir pieejamas RHEL 8, izmantojot Yum.
sudo yum install nginx postgresql-server
PostgreSQL bÅ«s nepiecieÅ”ams psycopg2, taÄu tam ir jÄbÅ«t pieejamam tikai virtualenv vidÄ, tÄpÄc mÄs to instalÄsim, izmantojot pip3 kopÄ ar Django un Gunicorn. Bet vispirms mums ir jÄiestata virtualenv.
VienmÄr ir daudz diskusiju par tÄmu, kÄ izvÄlÄties pareizo vietu Django projektu instalÄÅ”anai, taÄu, ja rodas Å”aubas, vienmÄr varat vÄrsties pie Linux failu sistÄmas hierarhijas standarta. KonkrÄti, FHS saka, ka /srv tiek izmantots, lai: āsaglabÄtu resursdatoram raksturÄ«gus datus ā datus, ko sistÄma ražo, piemÄram, tÄ«mekļa servera datus un skriptus, datus, kas tiek glabÄti FTP serveros un kontroles sistÄmas krÄtuvÄs.ā versijas (parÄdÄs FHS -2.3 2004. gadÄ).
Tas ir tieÅ”i mÅ«su gadÄ«jums, tÄpÄc visu nepiecieÅ”amo ievietojam /srv, kas pieder mÅ«su lietojumprogrammas lietotÄjam (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
PostgreSQL un Django iestatÄ«Å”ana ir vienkÄrÅ”a: izveidojiet datu bÄzi, izveidojiet lietotÄju, konfigurÄjiet atļaujas. Viena lieta, kas jÄpatur prÄtÄ, sÄkotnÄji instalÄjot PostgreSQL, ir postgresql-setup skripts, kas tiek instalÄts kopÄ ar postgresql-servera pakotni. Å is skripts palÄ«dz veikt pamata uzdevumus, kas saistÄ«ti ar datu bÄzes klasteru administrÄÅ”anu, piemÄram, klastera inicializÄÅ”anu vai jauninÄÅ”anas procesu. Lai konfigurÄtu jaunu PostgreSQL gadÄ«jumu RHEL sistÄmÄ, mums ir jÄpalaiž komanda:
sudo /usr/bin/postgresql-setup -initdb
PÄc tam varat startÄt PostgreSQL, izmantojot systemd, izveidot datu bÄzi un iestatÄ«t projektu Django. Neaizmirstiet restartÄt PostgreSQL pÄc izmaiÅu veikÅ”anas klienta autentifikÄcijas konfigurÄcijas failÄ (parasti pg_hba.conf), lai konfigurÄtu paroles krÄtuvi lietojumprogrammas lietotÄjam. Ja rodas citas grÅ«tÄ«bas, noteikti mainiet IPv4 un IPv6 iestatÄ«jumus failÄ 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
FailÄ /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
FailÄ /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 }}',
}
}
PÄc faila settings.py konfigurÄÅ”anas projektÄ un datu bÄzes konfigurÄcijas iestatÄ«Å”anas varat startÄt izstrÄdes serveri, lai pÄrliecinÄtos, ka viss darbojas. PÄc izstrÄdes servera palaiÅ”anas ieteicams izveidot administratora lietotÄju, lai pÄrbaudÄ«tu savienojumu ar datu bÄzi.
./manage.py runserver 0.0.0.0:8000
./manage.py createsuperuser
WSGI? Vai?
IzstrÄdes serveris ir noderÄ«gs testÄÅ”anai, taÄu, lai palaistu lietojumprogrammu, ir jÄkonfigurÄ atbilstoÅ”ais serveris un starpniekserveris tÄ«mekļa servera vÄrtejas saskarnei (WSGI). Ir vairÄkas izplatÄ«tas kombinÄcijas, piemÄram, Apache HTTPD ar uWSGI vai Nginx ar Gunicorn.
TÄ«mekļa servera vÄrtejas saskarnes uzdevums ir pÄrsÅ«tÄ«t pieprasÄ«jumus no tÄ«mekļa servera uz Python tÄ«mekļa ietvaru. WSGI ir Å”ausmÄ«gÄs pagÄtnes relikts, kad pastÄvÄja CGI dzinÄji, un mÅ«sdienÄs WSGI ir de facto standarts neatkarÄ«gi no izmantotÄ tÄ«mekļa servera vai Python ietvara. Bet, neskatoties uz tÄ plaÅ”o izmantoÅ”anu, strÄdÄjot ar Å”iem ietvariem, joprojÄm ir daudz nianses un daudzas izvÄles iespÄjas. Å ajÄ gadÄ«jumÄ mÄs mÄÄ£inÄsim izveidot mijiedarbÄ«bu starp Gunicorn un Nginx, izmantojot ligzdu.
TÄ kÄ abi Å”ie komponenti ir instalÄti vienÄ serverÄ«, mÄÄ£inÄsim tÄ«kla ligzdas vietÄ izmantot UNIX ligzdu. TÄ kÄ saziÅai jebkurÄ gadÄ«jumÄ ir nepiecieÅ”ama ligzda, mÄÄ£inÄsim spert vÄl vienu soli un konfigurÄt Gunicorn ligzdas aktivizÄÅ”anu, izmantojot systemd.
Socket aktivizÄto pakalpojumu izveides process ir diezgan vienkÄrÅ”s. Vispirms tiek izveidots vienÄ«bas fails, kurÄ ir ListenStream direktÄ«va, kas norÄda uz vietu, kurÄ tiks izveidota UNIX ligzda, pÄc tam pakalpojuma vienÄ«bas fails, kurÄ direktÄ«va Requires norÄda uz ligzdas vienÄ«bas failu. PÄc tam servisa vienÄ«bas failÄ atliek tikai izsaukt Gunicorn no virtuÄlÄs vides un izveidot WSGI saiti UNIX ligzdai un Django lietojumprogrammai.
Å eit ir daži vienÄ«bas failu piemÄri, kurus varat izmantot par pamatu. Vispirms mÄs uzstÄdÄm kontaktligzdu.
[Unit]
Description=Gunicorn WSGI socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
Tagad jums ir jÄkonfigurÄ Gunicorn dÄmons.
[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 ir vienkÄrÅ”i izveidot starpniekservera konfigurÄcijas failus un iestatÄ«t direktoriju statiskÄ satura glabÄÅ”anai, ja tÄdu izmantojat. RHEL Nginx konfigurÄcijas faili atrodas mapÄ /etc/nginx/conf.d. Varat kopÄt Å”o piemÄru failÄ /etc/nginx/conf.d/default.conf un sÄkt pakalpojumu. Noteikti iestatiet servera_nosaukumu, lai tas atbilstu jÅ«su resursdatora nosaukumam.
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;
}
}
Palaidiet Gunicorn ligzdu un Nginx, izmantojot systemd, un esat gatavs sÄkt testÄÅ”anu.
Slikta vÄrtejas kļūda?
Ja ievadÄt adresi pÄrlÅ«kprogrammÄ, visticamÄk, tiks parÄdÄ«ta kļūda 502 Bad Gateway. To var izraisÄ«t nepareizi konfigurÄtas UNIX ligzdas atļaujas vai arÄ« sarežģītÄkas problÄmas, kas saistÄ«tas ar piekļuves kontroli SELinux.
Nginx kļūdu žurnÄlÄ var redzÄt Å”Ädu rindiÅu:
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"
Ja pÄrbaudÄ«sim Gunicorn tieÅ”i, mÄs saÅemsim tukÅ”u atbildi.
curl āunix-socket /run/gunicorn.sock 8beta1.example.com
Noskaidrosim, kÄpÄc tas notiek. Atverot žurnÄlu, visticamÄk, redzÄsit, ka problÄma ir saistÄ«ta ar SELinux. TÄ kÄ mÄs darbinÄm dÄmonu, kuram nav izveidota politika, tas ir atzÄ«mÄts kÄ init_t. PÄrbaudÄ«sim Å”o teoriju praksÄ.
sudo setenforce 0
Tas viss var izraisÄ«t kritiku un asiÅu asaras, taÄu tas ir tikai prototipa atkļūdoÅ”ana. AtspÄjosim pÄrbaudi, lai pÄrliecinÄtos, ka tÄ ir problÄma, un pÄc tam visu atgriezÄ«sim savÄs vietÄs.
Atsvaidzinot lapu pÄrlÅ«kprogrammÄ vai atkÄrtoti palaižot mÅ«su curl komandu, varat redzÄt Django testa lapu.
TÄtad, pÄrliecinÄjuÅ”ies, ka viss darbojas un vairs nav atļauju problÄmu, mÄs atkal iespÄjojam SELinux.
sudo setenforce 1
Å eit es nerunÄÅ”u par audit2allow vai uz brÄ«dinÄjumiem balstÄ«tu politiku izveidi, izmantojot sepolgen, jo paÅ”laik nav Ä«stas Django lietojumprogrammas, tÄpÄc nav pilnÄ«gas kartes par to, kam Gunicorn varÄtu vÄlÄties piekļūt un kam tai vajadzÄtu liegt piekļuvi. TÄpÄc ir nepiecieÅ”ams, lai SELinux darbotos, lai aizsargÄtu sistÄmu, vienlaikus ļaujot lietojumprogrammai darboties un atstÄt ziÅojumus audita žurnÄlÄ, lai pÄc tam no tiem varÄtu izveidot faktisko politiku.
AtļaujoÅ”o domÄnu norÄdÄ«Å”ana
Ne visi ir dzirdÄjuÅ”i par atļautajiem domÄniem SELinux, taÄu tie nav nekas jauns. Daudzi pat strÄdÄja ar viÅiem, pat neapzinoties. Kad politika tiek izveidota, pamatojoties uz audita ziÅojumiem, izveidotÄ politika atspoguļo atrisinÄto domÄnu. MÄÄ£inÄsim izveidot vienkÄrÅ”u atļauju izsniegÅ”anas politiku.
Lai izveidotu konkrÄtu atļauto domÄnu Gunicorn, jums ir nepiecieÅ”ama sava veida politika, kÄ arÄ« jÄatzÄ«mÄ atbilstoÅ”i faili. TurklÄt ir nepiecieÅ”ami instrumenti, lai izveidotu jaunas politikas.
sudo yum install selinux-policy-devel
Atļauto domÄnu mehÄnisms ir lielisks rÄ«ks problÄmu identificÄÅ”anai, Ä«paÅ”i, ja runa ir par pielÄgotu lietojumprogrammu vai lietojumprogrammÄm, kas tiek piegÄdÄtas bez jau izveidotÄm politikÄm. Å ajÄ gadÄ«jumÄ Gunicorn atļautÄ domÄna politika bÅ«s pÄc iespÄjas vienkÄrÅ”Äka ā deklarÄjiet galveno tipu (gunicorn_t), deklarÄjiet veidu, ko izmantosim, lai atzÄ«mÄtu vairÄkus izpildÄmos failus (gunicorn_exec_t), un pÄc tam iestatiet pÄreju, lai sistÄma pareizi atzÄ«mÄtu. darbojas procesi. PÄdÄjÄ rindÄ politika tiek iestatÄ«ta kÄ iespÄjota pÄc noklusÄjuma tÄs ielÄdes laikÄ.
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;
Varat apkopot Å”o politikas failu un pievienot to savai sistÄmai.
make -f /usr/share/selinux/devel/Makefile
sudo semodule -i gunicorn.pp
sudo semanage permissive -a gunicorn_t
sudo semodule -l | grep permissive
PÄrbaudÄ«sim, vai SELinux nebloÄ·Ä kaut ko citu, nevis to, kam piekļūst mÅ«su nezinÄmais dÄmons.
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 neļauj Nginx ierakstÄ«t datus UNIX ligzdÄ, ko izmanto Gunicorn. Parasti Å”Ädos gadÄ«jumos politika sÄk mainÄ«ties, taÄu priekÅ”Ä ir citi izaicinÄjumi. Varat arÄ« mainÄ«t domÄna iestatÄ«jumus no ierobežojuma domÄna uz atļauju domÄnu. Tagad pÄrvietosim httpd_t uz atļauju domÄnu. TÄdÄjÄdi Nginx tiks nodroÅ”inÄta nepiecieÅ”amÄ piekļuve, un mÄs varÄsim turpinÄt turpmÄko atkļūdoÅ”anas darbu.
sudo semanage permissive -a httpd_t
TÄtad, kad jums ir izdevies saglabÄt SELinux aizsardzÄ«bu (jums tieÅ”Äm nevajadzÄtu atstÄt SELinux projektu ierobežotÄ režīmÄ) un atļauju domÄni ir ielÄdÄti, jums ir jÄizdomÄ, kas tieÅ”i ir jÄatzÄ«mÄ kÄ gunicorn_exec_t, lai viss darbotos pareizi. atkal. MÄÄ£inÄsim apmeklÄt vietni, lai redzÄtu jaunus ziÅojumus par piekļuves ierobežojumiem.
sudo ausearch -m AVC -c gunicorn
JÅ«s redzÄsit daudz ziÅojumu, kas satur ācomm="gunicorn", kas veic dažÄdas darbÄ«bas failos, kas atrodas /srv/djangoapp, tÄpÄc Ŕī acÄ«mredzami ir viena no komandÄm, ko ir vÄrts atzÄ«mÄt.
Bet papildus tiek parÄdÄ«ts Å”Äds ziÅojums:
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
Ja skatÄties uz gunicorn pakalpojuma statusu vai palaižat komandu ps, jÅ«s neredzÄsit nevienu darbÄ«gu procesu. Å Ä·iet, ka gunicorn mÄÄ£ina piekļūt Python tulkam mÅ«su virtualenv vidÄ, iespÄjams, lai palaistu darbinieku skriptus. Tagad atzÄ«mÄsim Å”os divus izpildÄmos failus un pÄrbaudÄ«sim, vai varam atvÄrt mÅ«su Django testa lapu.
chcon -t gunicorn_exec_t /srv/djangoapp/django/bin/gunicorn /srv/djangoapp/django/bin/python3.6
Lai varÄtu atlasÄ«t jauno atzÄ«mi, ir jÄrestartÄ lielradža pakalpojums. Varat to nekavÄjoties restartÄt vai apturÄt pakalpojumu un ļaut ligzdai to palaist, atverot vietni pÄrlÅ«kprogrammÄ. PÄrbaudiet, vai procesi ir saÅÄmuÅ”i pareizÄs etiÄ·etes, izmantojot ps.
ps -efZ | grep gunicorn
Neaizmirstiet vÄlÄk izveidot normÄlu SELinux politiku!
Ja tagad aplÅ«kojat AVC ziÅojumus, pÄdÄjÄ ziÅojumÄ ir permissive=1 visam, kas saistÄ«ts ar lietojumprogrammu, un permissive=0 pÄrÄjai sistÄmai. Ja saprotat, kÄda veida piekļuve nepiecieÅ”ama reÄlai lietojumprogrammai, varat Ätri atrast labÄko veidu, kÄ atrisinÄt Å”Ädas problÄmas. Bet lÄ«dz tam vislabÄk ir nodroÅ”inÄt sistÄmas droŔību un iegÅ«t skaidru, izmantojamu Django projekta auditu.
sudo ausearch -m AVC
Notika!
Ir parÄdÄ«jies strÄdÄjoÅ”s Django projekts ar priekÅ”galu, kura pamatÄ ir Nginx un Gunicorn WSGI. MÄs konfigurÄjÄm Python 3 un PostgreSQL 10 no RHEL 8 Beta krÄtuvÄm. Tagad varat virzÄ«ties uz priekÅ”u un izveidot (vai vienkÄrÅ”i izvietot) Django lietojumprogrammas vai izpÄtÄ«t citus pieejamos rÄ«kus RHEL 8 Beta, lai automatizÄtu konfigurÄcijas procesu, uzlabotu veiktspÄju vai pat konteinerizÄtu Å”o konfigurÄciju.
Avots: www.habr.com