RHEL 8 Beta menawarkan banyak ciri baharu kepada pembangun, yang penyenaraiannya mungkin mengambil masa bermusim, tetapi mempelajari perkara baharu sentiasa lebih baik melalui latihan, jadi di bawah kami menawarkan panduan praktikal untuk mencipta infrastruktur aplikasi sebenar berdasarkan Red Hat Enterprise. Linux 8 Beta.

Kami akan mengambil Python, bahasa pengaturcaraan yang popular di kalangan pembangun, sebagai asas, gabungan Django dan PostgreSQL, satu himpunan yang agak biasa untuk mencipta aplikasi, dan mengkonfigurasi RHEL 8 Beta untuk berfungsi dengan mereka. Kemudian kami akan menambah beberapa lagi bahan (tidak dikelaskan).
Persekitaran ujian akan berubah kerana menarik untuk meneroka kemungkinan automasi, bekerja dengan bekas dan mencuba persekitaran dengan berbilang pelayan. Untuk memulakan projek baharu, anda boleh mulakan dengan mencipta prototaip yang kecil dan ringkas dengan tangan supaya anda boleh melihat dengan tepat apa yang perlu berlaku dan cara interaksi dijalankan, dan kemudian beralih kepada automasi dan mencipta konfigurasi yang lebih kompleks. Hari ini adalah cerita tentang penciptaan prototaip sedemikian.
Mari mulakan dengan menggunakan imej RHEL 8 Beta VM. Anda boleh memasang mesin maya dari awal, atau menggunakan imej tetamu KVM yang tersedia dengan langganan Beta. Apabila menggunakan imej tetamu, anda perlu menyediakan CD maya yang akan mengandungi metadata dan data pengguna untuk peruntukan awan (cloud-init). Anda tidak perlu melakukan sesuatu yang istimewa dengan struktur cakera atau pakej yang tersedia, sebarang konfigurasi akan dilakukan.
Mari kita lihat keseluruhan proses dengan lebih terperinci.
Memasang Django
Dengan versi terkini Django, anda memerlukan persekitaran maya (virtualenv) dengan Python 3.5 atau lebih baru. Anda boleh melihat dalam nota Beta bahawa Python 3.6 tersedia, mari semak sama ada ini benar-benar berlaku:
[cloud-user@8beta1 ~]$ python
-bash: python: command not found
[cloud-user@8beta1 ~]$ python3
-bash: python3: command not found
Red Hat secara aktif menggunakan Python sebagai kit alat sistem dalam RHEL, jadi mengapa ini hasilnya?
Hakikatnya ialah ramai pembangun yang menggunakan Python masih berfikir tentang beralih daripada Python 2 kepada Python 2, manakala Python 3 sendiri sedang dalam pembangunan aktif, dan semakin banyak versi baharu sentiasa muncul. Oleh itu, untuk memenuhi keperluan alat sistem yang stabil, sambil turut menawarkan pengguna akses kepada pelbagai versi baharu Python, sistem Python telah dialihkan ke pakej baharu, dan kedua-dua Python 2.7 dan 3.6 boleh dipasang. Maklumat lanjut tentang perubahan dan sebab ini dilakukan boleh diperolehi daripada siaran dalam (Langdon White).
Jadi, untuk mendapatkan Python yang berfungsi, anda perlu memasang hanya dua pakej, manakala python3-pip akan ditarik ke atas sebagai kebergantungan.
sudo yum install python36 python3-virtualenv
Mengapa tidak menggunakan panggilan modul langsung seperti yang dicadangkan Langdon dan memasang pip3? Dengan mengingati automasi, kami tahu bahawa Ansible memerlukan pip untuk dipasang, kerana modul pip tidak menyokong persekitaran maya (virtualenvs) dengan pip tersuai boleh laku.
Dengan penterjemah python3 yang boleh digunakan, kami boleh meneruskan proses pemasangan Django dan mempunyai sistem yang berfungsi bersama-sama komponen kami yang lain. Terdapat banyak pilihan pelaksanaan di web. Ini adalah satu versi, tetapi pengguna boleh menggunakan proses mereka sendiri.
Versi PostgreSQL dan Nginx yang tersedia dalam RHEL 8 akan dipasang secara lalai menggunakan Yum.
sudo yum install nginx postgresql-server
PostgreSQL memerlukan psycopg2, tetapi ia hanya perlu tersedia dalam persekitaran virtualenv, jadi kami akan memasangnya dengan pip3 bersama-sama dengan Django dan Gunicorn. Tetapi pertama-tama kita perlu menyediakan virtualenv.
Sentiasa terdapat banyak perdebatan tentang tempat yang betul untuk memasang projek Django, tetapi apabila ragu-ragu, anda sentiasa boleh merujuk kepada piawaian Linux Piawaian Hierarki Sistem Fail. Secara khususnya, FHS menyatakan bahawa /srv digunakan untuk: "menyimpan data khusus hos—data yang dihasilkan oleh sistem, seperti data dan skrip pelayan web, data yang disimpan pada pelayan FTP dan repositori sistem kawalan versi (yang muncul dalam FHS-2.3 pada tahun 2004)."
Ini hanya kes kami, jadi kami meletakkan semua yang kami perlukan dalam / srv, yang dimiliki oleh pengguna aplikasi kami (pengguna awan).
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
Menyediakan PostgreSQL dan Django adalah mudah: buat pangkalan data, buat pengguna, tetapkan kebenaran. Satu perkara yang perlu diingat semasa memasang PostgreSQL pada mulanya ialah skrip persediaan postgresql, yang dipasang dengan pakej pelayan postgresql. Skrip ini membantu anda melaksanakan tugas pentadbiran kluster pangkalan data asas, seperti pemulaan kluster atau proses naik taraf. Untuk menyediakan contoh PostgreSQL baharu pada sistem RHEL, kita perlu menjalankan arahan:
sudo /usr/bin/postgresql-setup -initdb
Selepas itu, anda boleh memulakan PostgreSQL menggunakan systemd, mencipta pangkalan data dan menyediakan projek dalam Django. Ingat untuk memulakan semula PostgreSQL selepas membuat perubahan pada fail konfigurasi pengesahan klien (biasanya pg_hba.conf) untuk mengkonfigurasi storan kata laluan untuk pengguna aplikasi. Jika anda menghadapi isu lain, pastikan anda menukar tetapan IPv4 dan IPv6 dalam 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
Dalam 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
Dalam 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 }}',
}
}
Selepas mengkonfigurasi fail settings.py dalam projek dan menyediakan konfigurasi pangkalan data, anda boleh memulakan pelayan pembangunan untuk memastikan semuanya berfungsi. Setelah pelayan pembangunan siap dan berjalan, adalah idea yang baik untuk mencipta pengguna pentadbir untuk menguji sambungan pangkalan data.
./manage.py runserver 0.0.0.0:8000
./manage.py createsuperuser
WSGI? Wai?
Pelayan pembangunan berguna untuk ujian, tetapi anda mesti mengkonfigurasi pelayan dan proksi yang sesuai untuk Antara Muka Gerbang Pelayan Web (WSGI) untuk menjalankan aplikasi anda. Terdapat beberapa berkas biasa, seperti Apache HTTPD dengan uWSGI atau Nginx dengan Gunicorn.
Tujuan Antara Muka Gerbang Pelayan Web adalah untuk menghantar permintaan daripada pelayan web Kepada rangka kerja web Python. WSGI merupakan peninggalan masa lalu yang dahsyat, ketika mekanisme CGI digunakan, dan hari ini WSGI merupakan standard de facto, tanpa mengira pelayan web atau rangka kerja Python yang digunakan. Walaupun penggunaannya meluas, masih terdapat banyak nuansa ketika bekerja dengan rangka kerja ini, dan pelbagai pilihan. Dalam kes ini, kami akan cuba mewujudkan komunikasi antara Gunicorn dan Nginx melalui soket.
Memandangkan kedua-dua komponen ini dipasang pada pelayan yang sama, mari cuba gunakan soket UNIX dan bukannya soket rangkaian. Oleh kerana komunikasi memerlukan soket pula, mari kita cuba melangkah lebih jauh dan sediakan pengaktifan soket untuk Gunicorn melalui systemd.
Proses mencipta perkhidmatan diaktifkan soket agak mudah. Mula-mula, fail unit dicipta yang mengandungi arahan ListenStream yang menunjuk ke titik di mana soket UNIX akan dibuat, kemudian fail unit untuk perkhidmatan, di mana arahan Memerlukan akan menghala ke fail unit soket. Kemudian, dalam fail unit perkhidmatan, yang tinggal hanyalah memanggil Gunicorn dari persekitaran maya dan mencipta pengikatan WSGI untuk soket UNIX dan aplikasi Django.
Berikut adalah beberapa contoh fail unit yang boleh diambil sebagai asas. Mula-mula kita sediakan soket.
[Unit]
Description=Gunicorn WSGI socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
Sekarang kita perlu mengkonfigurasi daemon 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
Untuk Nginx, ia semudah membuat fail konfigurasi proksi dan menyediakan direktori kandungan statik jika anda menggunakannya. Pada RHEL, fail konfigurasi Nginx ialah /etc/nginx/conf.d. Anda boleh menyalin contoh berikut di sana ke fail /etc/nginx/conf.d/default.conf dan mulakan perkhidmatan. Pastikan anda menetapkan nama_server agar sepadan dengan nama hos anda.
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;
}
}
Mulakan soket Gunicorn dan Nginx dengan systemd dan anda boleh pergi.
Ralat Gerbang Buruk?
Jika anda memasukkan alamat tersebut ke dalam pelayar, anda mungkin akan mendapat ralat 502 Bad Gateway. Ini mungkin disebabkan oleh kebenaran yang dikonfigurasikan secara salah pada soket UNIX, atau mungkin disebabkan oleh isu yang lebih kompleks berkaitan dengan kawalan akses dalam SE.Linux.
Dalam log ralat nginx, anda boleh mencari baris seperti ini:
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"
Jika kami menguji Gunicorn secara langsung, kami mendapat jawapan kosong.
curl —unix-socket /run/gunicorn.sock 8beta1.example.com
Mari kita fikirkan mengapa ini berlaku. Jika anda membuka log, kemungkinan besar anda akan melihat bahawa masalahnya berkaitan dengan SE.LinuxOleh kerana kita menjalankan daemon yang tidak mempunyai dasar sendiri, ia ditanda sebagai init_t. Mari kita uji teori ini dalam praktik.
sudo setenforce 0
Semua ini boleh menyebabkan kritikan dan air mata berdarah, tetapi ini hanya menyahpepijat prototaip. Mari matikan cek hanya untuk memastikan bahawa ini adalah masalahnya, selepas itu kami akan mengembalikan semuanya ke tempatnya.
Dengan menyegarkan halaman dalam penyemak imbas atau dengan menjalankan semula arahan curl kami, kami boleh melihat halaman ujian Django.
Jadi, selepas memastikan semuanya berfungsi dan tiada lagi masalah dengan kebenaran, kami menghidupkan SE sekali lagiLinux.
sudo setenforce 1
Artikel ini tidak akan merangkumi audit2allow atau penciptaan dasar berasaskan amaran menggunakan sepolgen, kerana pada masa ini tiada aplikasi Django yang sebenar, jadi tiada peta lengkap tentang apa yang Gunicorn mungkin mahu akses dan apa yang harus ditolak. Oleh itu, adalah penting untuk memastikan SE terus berjalan.Linux untuk melindungi sistem, sambil masih membenarkan aplikasi dijalankan dan meninggalkan mesej dalam log audit supaya dasar sebenar kemudiannya boleh dibuat berdasarkannya.
Menentukan Domain Permisif
Perihal domain yang dibenarkan dalam SELinux Bukan semua orang pernah mendengarnya, tetapi ia bukanlah sesuatu yang baharu. Ramai yang pernah menggunakannya tanpa menyedarinya. Apabila dasar dicipta berdasarkan mesej audit, dasar yang terhasil mewakili domain yang dibenarkan. Mari cuba cipta dasar kebenaran yang mudah.
Untuk mencipta domain khusus yang dibenarkan untuk Gunicorn, anda memerlukan beberapa jenis dasar, dan anda juga perlu menandakan fail yang sesuai. Di samping itu, alat diperlukan untuk menyusun dasar baharu.
sudo yum install selinux-policy-devel
Mekanisme Domain Dibenarkan ialah alat yang hebat untuk mengenal pasti masalah, terutamanya apabila ia berkaitan dengan aplikasi tersuai atau aplikasi yang datang tanpa dasar yang telah dibuat. Dalam kes ini, dasar domain yang dibenarkan untuk Gunicorn adalah semudah mungkin - kami akan mengisytiharkan jenis utama (gunicorn_t), kami akan mengisytiharkan jenis yang akan kami gunakan untuk menandakan berbilang fail boleh laku (gunicorn_exec_t), dan kemudian kami akan mengkonfigurasi peralihan (peralihan) untuk sistem menandakan dengan betul proses yang sedang berjalan . Baris terakhir menetapkan dasar sebagai didayakan secara lalai apabila ia dimuatkan.
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;
Anda boleh menyusun fail dasar ini dan menambahkannya pada sistem anda.
make -f /usr/share/selinux/devel/Makefile
sudo semodule -i gunicorn.pp
sudo semanage permissive -a gunicorn_t
sudo semodule -l | grep permissive
Mari kita periksa sama ada SE menyekatLinux sesuatu yang lain selain daripada apa yang sedang ditangani oleh syaitan kita yang tidak dikenali.
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 menghalang Nginx daripada menulis data ke soket UNIX yang digunakan oleh Gunicorn. Biasanya, dasar diubah dalam kes sedemikian, tetapi isu lain masih perlu ditangani. Anda juga boleh menukar tetapan domain, menukarnya daripada domain terhad kepada domain permisif. Sekarang mari kita alihkan httpd_t ke domain permisif. Ini akan menyediakan Nginx dengan akses yang diperlukan, dan kita boleh meneruskan penyahpepijatan.
sudo semanage permissive -a httpd_t
Jadi, bilakah anda berjaya menyelamatkan perlindungan SE?Linux (malah, anda tidak sepatutnya meninggalkan projek itu dengan SELinux Jika sistem berada dalam mod terhad dan domain kebenaran sedang dimuatkan, kita perlu memikirkan apa sebenarnya yang perlu ditanda sebagai gunicorn_exec_t agar semuanya berfungsi dengan betul semula. Mari cuba akses laman web untuk melihat sebarang mesej baharu tentang sekatan akses.
sudo ausearch -m AVC -c gunicorn
Anda boleh melihat banyak mesej yang mengandungi 'comm="gunicorn"' yang melakukan pelbagai tindakan pada fail dalam /srv/djangoapp, jadi ini jelas merupakan salah satu arahan yang patut dibenderakan.
Tetapi sebagai tambahan, mesej seperti ini muncul:
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
Jika anda melihat status perkhidmatan gunicorn atau menjalankan arahan ps, tidak akan ada sebarang proses berjalan. Nampaknya gunicorn cuba mengakses penterjemah Python dalam virtualenv kami, mungkin untuk menjalankan skrip pekerja. Jadi sekarang mari tandakan kedua-dua boleh laku ini dan lihat sama ada halaman ujian Django kami boleh dibuka.
chcon -t gunicorn_exec_t /srv/djangoapp/django/bin/gunicorn /srv/djangoapp/django/bin/python3.6
Perkhidmatan gunicorn perlu dimulakan semula sebelum label baharu boleh dipilih. Anda boleh memulakan semula dengan segera atau menghentikan perkhidmatan dan biarkan soket memulakannya apabila anda membuka tapak dalam penyemak imbas. Sahkan bahawa proses telah menerima label yang betul menggunakan ps.
ps -efZ | grep gunicorn
Jangan lupa untuk membuat dasar SE biasa kemudianLinux!
Melihat kepada mesej AVC sekarang, mesej terakhir mengandungi permisif=1 untuk semua yang berkaitan dengan aplikasi dan permisif=0 untuk seluruh sistem. Jika anda memahami dengan tepat jenis akses yang diperlukan oleh aplikasi sebenar, anda boleh mencari cara terbaik untuk menyelesaikan masalah sedemikian dengan cepat. Tetapi sehingga itu, adalah lebih baik untuk memastikan sistem selamat dan mendapatkan audit yang jelas dan boleh digunakan bagi projek Django.
sudo ausearch -m AVC
Terjadi!
Projek Django yang berfungsi muncul dengan bahagian hadapan pada Nginx dan Gunicorn WSGI. Kami telah mengkonfigurasi Python 3 dan PostgreSQL 10 daripada repositori RHEL 8 Beta. Anda kini boleh meneruskan dan mencipta (atau hanya menggunakan) aplikasi Django atau meneroka alat lain yang tersedia dalam RHEL 8 Beta untuk mengautomasikan proses menyesuaikan, meningkatkan prestasi, atau bahkan menyimpan konfigurasi itu.
Sumber: www.habr.com
