Apakah mungkin untuk menyetel parameter kernel untuk memungkinkan program userland untuk mengikat port 80 dan 443?
Alasan saya bertanya adalah saya pikir itu bodoh untuk membiarkan proses istimewa membuka soket dan mendengarkan. Apa pun yang membuka soket dan mendengarkan adalah risiko tinggi, dan aplikasi berisiko tinggi tidak boleh berjalan sebagai root.
Saya lebih suka mencoba mencari tahu apa proses tidakrivasi mendengarkan pada port 80 daripada mencoba untuk menghapus malware yang bersembunyi dengan hak akses root.
Jawaban:
Saya tidak yakin apa yang dimaksud dengan jawaban dan komentar lain di sini. Ini mungkin agak mudah. Ada dua opsi, keduanya memungkinkan akses ke port bernomor rendah tanpa harus meningkatkan proses root:
Opsi 1: Gunakan
CAP_NET_BIND_SERVICE
untuk memberikan akses port bernomor rendah ke suatu proses:Dengan ini, Anda dapat memberikan akses permanen ke biner tertentu untuk mengikat ke port bernomor rendah melalui
setcap
perintah:Untuk detail lebih lanjut tentang bagian e / i / p, lihat
cap_from_text
.Setelah melakukan ini,
/path/to/binary
akan dapat mengikat ke port bernomor rendah. Perhatikan bahwa Anda harus menggunakansetcap
biner itu sendiri daripada symlink.Opsi 2: Gunakan
authbind
untuk memberikan akses satu kali, dengan kontrol pengguna / grup / port yang lebih baik:Alat
authbind
( halaman manual ) ada tepat untuk ini.Instal
authbind
menggunakan pengelola paket favorit Anda.Konfigurasikan untuk memberikan akses ke port yang relevan, misalnya untuk memungkinkan 80 dan 443 dari semua pengguna dan grup:
Sekarang jalankan perintah Anda melalui
authbind
(tentukan opsional--deep
atau argumen lain, lihat halaman manual):Misalnya
Ada kelebihan dan kekurangan untuk kedua hal di atas. Opsi 1 memberikan kepercayaan kepada biner tetapi tidak memberikan kontrol atas akses per-port. Opsi 2 memberikan kepercayaan kepada pengguna / grup dan memberikan kontrol atas akses per-port tetapi, AFAIK, hanya mendukung IPv4.
sumber
rwx
izin?-p
intead of+eip
?setcap
izin pada executable ruby versi khusus , misalnya/usr/bin/ruby1.9.1
chmod
untuk 777byport
file adalah ide terbaik. Saya telah melihat memberikan izin mulai dari500
hingga744
. Saya akan terjebak dengan yang paling ketat yang bekerja untuk Anda.Dale Hagglund tepat. Jadi saya hanya akan mengatakan hal yang sama tetapi dengan cara yang berbeda, dengan beberapa spesifik dan contoh. ☺
Hal yang benar untuk dilakukan di dunia Unix dan Linux adalah:
Anda memiliki gagasan yang salah tentang di mana risiko tinggi berada. Risiko tinggi adalah membaca dari jaringan dan bertindak berdasarkan apa yang dibaca bukan dalam tindakan sederhana membuka soket, mengikatnya ke port, dan menelepon
listen()
. Ini adalah bagian dari layanan yang melakukan komunikasi aktual yang berisiko tinggi. Bagian-bagian yang membuka,,bind()
danlisten()
, dan bahkan (sampai batas tertentu) bagian ituaccepts()
, tidak berisiko tinggi dan dapat dijalankan di bawah pengawasan superuser. Mereka tidak menggunakan dan bertindak atas (dengan pengecualian alamat IP sumber dalamaccept()
kasus ini) data yang berada di bawah kendali orang asing yang tidak dipercaya melalui jaringan.Ada banyak cara untuk melakukan ini.
inetd
Seperti kata Dale Hagglund, "superserver jaringan" lama
inetd
melakukan ini. Akun tempat proses layanan dijalankan adalah salah satu kolom diinetd.conf
. Itu tidak memisahkan bagian mendengarkan dan bagian hak istimewa jatuh ke dalam dua program terpisah, kecil dan mudah diaudit, tetapi itu memisahkan kode layanan utama menjadi program terpisah,exec()
ed dalam proses layanan yang muncul dengan deskriptor file terbuka untuk soket.Kesulitan mengaudit tidak begitu menjadi masalah, karena seseorang hanya perlu mengaudit satu program.
inetd
Masalah utama adalah tidak terlalu banyak mengaudit tetapi lebih karena tidak memberikan kontrol layanan runtime sederhana yang halus, dibandingkan dengan alat yang lebih baru.UCSPI-TCP dan daemontools
Paket UCSPI-TCP dan daemontools dari Daniel J. Bernstein dirancang untuk melakukan hal ini bersamaan. Satu alternatif dapat menggunakan toolset daemontools-encore Bruce Guenter yang sebagian besar setara .
Program untuk membuka deskriptor file socket dan mengikat ke port lokal istimewa adalah
tcpserver
, dari UCSPI-TCP. Itu baiklisten()
danaccept()
.tcpserver
kemudian memunculkan salah satu program layanan yang menjatuhkan hak root itu sendiri (karena protokol yang dilayani melibatkan mulai sebagai superuser dan kemudian "masuk", seperti halnya dengan, misalnya, FTP atau daemon SSH) atausetuidgid
yang merupakan program kecil mandiri dan mudah diaudit yang semata-mata menjatuhkan hak istimewa dan kemudian mengaitkan muatan ke program layanan dengan semestinya (tidak ada bagian yang dengan demikian dijalankan dengan hak pengguna super, seperti halnya dengan, katakanlah,qmail-smtpd
).Jadi
run
skrip layanan misalnya (ini untuk dummyidentd karena menyediakan layanan IDENT nol):tidak
Paket nosh saya dirancang untuk melakukan ini. Ini memiliki
setuidgid
utilitas kecil , sama seperti yang lain. Satu perbedaan kecil adalah bahwa itu dapat digunakan dengansystemd
-style "LISTEN_FDS" layanan serta dengan layanan UCSPI-TCP, sehinggatcpserver
program tradisional digantikan oleh dua program terpisah:tcp-socket-listen
dantcp-socket-accept
.Sekali lagi, utilitas serba guna menelurkan dan saling memuat satu sama lain. Satu kekhasan desain yang menarik adalah bahwa seseorang dapat kehilangan hak superuser setelah
listen()
tetapi bahkan sebelumaccept()
. Berikutrun
skrip untukqmail-smtpd
itu memang melakukan hal itu:Program yang dijalankan di bawah naungan superuser adalah alat rantai-loading layanan-agnostik kecil
fdmove
,clearenv
,envdir
,softlimit
,tcp-socket-listen
, dansetuidgid
. Pada titik yangsh
dimulai, soket terbuka dan terikat kesmtp
port, dan proses tidak lagi memiliki hak pengguna super.s6, s6-networking, dan execline
Paket jaringan s6 dan s6 Laurent Bercot dirancang untuk melakukan hal ini bersamaan. Perintah-perintah secara struktural sangat mirip dengan
daemontools
dan dari UCSPI-TCP.run
skrip akan sama, kecuali untuk penggantis6-tcpserver
untuktcpserver
dans6-setuidgid
untuksetuidgid
. Namun, orang mungkin juga memilih untuk menggunakan toolset execline M. Bercot pada saat yang sama.Berikut ini adalah contoh dari layanan FTP, sedikit dimodifikasi dari aslinya Wayne Marshall , yang menggunakan execline, s6, s6-networking, dan program server FTP dari publicfile :
ipsvd
Ipsvd Gerrit Pape adalah toolset lain yang berjalan di sepanjang jalur yang sama dengan ucspi-tcp dan s6-networking. Alatnya ada
chpst
dantcpsvd
kali ini, tetapi mereka melakukan hal yang sama, dan kode risiko tinggi yang melakukan pembacaan, pemrosesan, dan penulisan hal-hal yang dikirim melalui jaringan oleh klien yang tidak terpercaya masih dalam program terpisah.Berikut contoh M. Pape menjalankan
fnord
dalamrun
skrip:systemd
systemd
, pengawasan layanan baru dan sistem init yang dapat ditemukan di beberapa distribusi Linux, dimaksudkan untuk melakukan apa yanginetd
bisa dilakukan . Namun, itu tidak menggunakan serangkaian program mandiri kecil.systemd
Sayangnya, kita harus mengaudit secara keseluruhan.Dengan
systemd
satu menciptakan file konfigurasi untuk menentukan soket yangsystemd
mendengarkan, dan layanan yangsystemd
dimulai. File "unit" layanan memiliki pengaturan yang memungkinkan seseorang mengendalikan proses layanan, termasuk pengguna yang dijalankannya.Dengan pengguna yang ditetapkan sebagai bukan pengguna super,
systemd
melakukan semua pekerjaan membuka soket, mengikatnya ke port, dan memanggillisten()
(dan, jika perlu,accept()
) dalam proses # 1 sebagai superuser, dan proses layanan yang dilakukan memunculkan berjalan tanpa hak pengguna super.sumber
Saya memiliki pendekatan yang agak berbeda. Saya ingin menggunakan port 80 untuk server node.js. Saya tidak dapat melakukannya karena Node.js diinstal untuk pengguna non-sudo. Saya mencoba menggunakan symlink, tetapi tidak berhasil untuk saya.
Kemudian saya mengetahui bahwa saya dapat meneruskan koneksi dari satu port ke port lainnya. Jadi saya memulai server pada port 3000 dan mengatur port forward dari port 80 ke port 3000.
Tautan ini memberikan perintah aktual yang dapat digunakan untuk melakukan ini. Ini perintahnya -
Saya telah menggunakan perintah kedua dan itu berhasil untuk saya. Jadi saya pikir ini adalah jalan tengah untuk tidak mengizinkan proses pengguna untuk mengakses port yang lebih rendah secara langsung, tetapi memberi mereka akses menggunakan port-forwarding.
sumber
Naluri Anda sepenuhnya benar: adalah ide yang buruk untuk menjalankan program kompleks yang besar sebagai root, karena kompleksitasnya membuat mereka sulit dipercaya.
Tapi, itu juga ide yang buruk untuk memungkinkan pengguna biasa untuk mengikat port istimewa, karena port tersebut biasanya merupakan layanan sistem yang penting.
Pendekatan standar untuk menyelesaikan kontradiksi yang tampak ini adalah pemisahan hak istimewa . Ide dasarnya adalah untuk memisahkan program Anda menjadi dua (atau lebih) bagian, yang masing-masing berfungsi dengan baik dari keseluruhan aplikasi, dan yang berkomunikasi dengan antarmuka terbatas yang sederhana.
Dalam contoh yang Anda berikan, Anda ingin memisahkan program Anda menjadi dua bagian. Salah satu yang berjalan sebagai root dan terbuka dan mengikat ke soket istimewa, dan kemudian menyerahkannya entah bagaimana ke bagian lain, yang berjalan sebagai pengguna biasa.
Dua cara utama untuk mencapai pemisahan ini.
Satu program yang dimulai sebagai root. Hal pertama yang dilakukannya adalah membuat soket yang diperlukan, sesederhana dan sebatas mungkin. Kemudian, itu menjatuhkan hak istimewa, yaitu, itu mengubah dirinya menjadi proses mode pengguna biasa, dan melakukan semua pekerjaan lainnya. Menjatuhkan hak istimewa dengan benar itu sulit, jadi silakan luangkan waktu untuk mempelajari cara yang benar untuk melakukannya.
Sepasang program yang berkomunikasi melalui pasangan soket yang dibuat oleh proses induk. Program driver non-istimewa menerima argumen awal dan mungkin melakukan beberapa validasi argumen dasar. Ini menciptakan sepasang soket yang terhubung melalui socketpair (), dan kemudian bercabang dan mengeksekusi dua program lain yang akan melakukan pekerjaan nyata, dan berkomunikasi melalui pasangan soket. Salah satunya adalah privilege dan akan membuat socket server, dan operasi privilege lainnya, dan lainnya akan melakukan eksekusi aplikasi yang lebih kompleks dan karenanya kurang dapat dipercaya.
[1] http://en.m.wikipedia.org/wiki/Privilege_separation
sumber
Solusi paling sederhana: hapus semua port istimewa di linux
Bekerja di ubuntu / debian:
(berfungsi dengan baik untuk VirtualBox dengan akun non-root)
Sekarang, berhati-hatilah dengan keamanan karena semua pengguna dapat mengikat semua port!
sumber