Saya perlu mengizinkan pengguna (berbeda dari root) untuk menjalankan server mendengarkan pada port 80.
Apakah ada cara untuk melakukan ini?
Saya perlu mengizinkan pengguna (berbeda dari root) untuk menjalankan server mendengarkan pada port 80.
Apakah ada cara untuk melakukan ini?
Jawaban:
setcap 'cap_net_bind_service=+ep' /path/to/program
ini akan bekerja untuk proses spesifik. Tetapi untuk memungkinkan pengguna tertentu untuk mengikat port di bawah 1024 Anda harus menambahkannya ke sudoers.
Lihat diskusi ini untuk informasi lebih lanjut.
(Beberapa metode ini telah disebutkan dalam jawaban lain; Saya memberikan beberapa pilihan yang mungkin dalam urutan kasar preferensi.)
Anda dapat mengarahkan port rendah ke port tinggi dan mendengarkan port tinggi.
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 1080
Anda dapat memulai server Anda sebagai hak istimewa root dan drop setelah mulai mendengarkan pada port yang diistimewakan. Lebih disukai, daripada mengkode sendiri, mulai server Anda dari pembungkus yang melakukan pekerjaan untuk Anda. Jika server Anda memulai satu instance per koneksi, mulai dari inetd
(atau program serupa seperti xinetd
). Untuk inetd
, gunakan baris seperti ini di /etc/inetd.conf
:
http stream tcp nowait username:groupname /path/to/server/executable argv[0] argv[1]…
Jika server Anda mendengarkan dalam satu contoh, mulai dari program seperti authbind
. Baik membuat file kosong /etc/authbind/byport/80
dan membuatnya dapat dieksekusi untuk pengguna yang menjalankan server; atau buat /etc/authbind/byuid/1234
, di mana 1234 adalah UID yang menjalankan server, berisi baris 0.0.0.0/0:80,80
.
Jika server Anda dapat dieksekusi disimpan pada sistem file yang mendukung kemampuan, Anda dapat memberikannya kemampuan . Berhati-hatilah karena kemampuannya masih relatif baru dan masih memiliki beberapa ketegaran .cap_net_bind_service
setcap cap_net_bind_service=ep /path/to/server/executable
-A INPUT -p tcp --dport 1080 -j ACCEPT
kalau tidak akan bekerja (saya juga punya -j DROP
catch-all.) Jadi saya pergi dengan dua soket mendengarkan.
Jawaban singkatnya adalah bahwa ini tidak dimungkinkan oleh desain.
Jawaban panjangnya adalah bahwa di dunia open source ada banyak orang yang bermain dengan desain dan datang dengan metode alternatif. Secara umum adalah praktik yang diterima secara luas bahwa ini seharusnya tidak mungkin. Fakta bahwa Anda mencoba mungkin berarti Anda memiliki kesalahan desain lain di sistem Anda dan harus mempertimbangkan kembali arsitektur sistem Anda secara keseluruhan mengingat praktik terbaik dan implikasi keamanan.
Yang mengatakan, satu program untuk otorisasi akses non-root ke port rendah adalah authbind . Baik selinux dan grsecurity juga menyediakan kerangka kerja untuk otentikasi yang disesuaikan tersebut.
Terakhir, jika Anda ingin pengguna tertentu menjalankan program tertentu sebagai root dan yang benar-benar Anda butuhkan hanyalah mengizinkan pengguna untuk memulai kembali apache atau sesuatu seperti itu, sudo
adalah teman Anda!
Anda bisa menggunakan penerusan port netcat atau xinetd atau iptables, atau menggunakan apache sebagai proxy ujung depan dan menjalankan proses pada port yang tidak memiliki hak istimewa.
Authbind , @Gilles sudah menyebutkannya, tapi saya ingin sedikit mengembangkannya.
Ini memiliki kontrol akses yang mudah (detail dalam halaman manual): Anda dapat memfilter akses berdasarkan port, alamat antarmuka, uid, rentang alamat atau port dan kombinasi dari semuanya.
Ini memiliki parameter yang sangat berguna --depth
:
- Tingkat kedalaman
Menyebabkan authbind mempengaruhi program yang levelnya jauh di dalam grafik panggilan. Standarnya adalah 1.
"Levels deep" artinya ketika skrip (atau program), menjalankan skrip lain, skrip ini turun satu level. Jadi jika Anda memilikinya --depth 5
berarti pada level 1 (atau 0?) Hingga 5 Anda memiliki izin untuk mengikat, sedangkan pada level 6 dan seterusnya, Anda tidak. Berguna saat Anda ingin skrip memiliki akses, tetapi bukan program yang dijalankan dengan atau tanpa sepengetahuan Anda.
Sebagai ilustrasi, Anda dapat memiliki sesuatu seperti ini: demi keamanan, Anda memiliki pengguna java
yang dimaksudkan untuk hanya menjalankan java dan Anda ingin memberinya akses ke port 80:
echo > /etc/authbind/byport/80
chown root:java /etc/authbind/byport/80
chmod 710 /etc/authbind/byport/80
Saya telah membuat ../byport/80 file
, memberikannya ke java
grup pengguna (setiap pengguna memiliki grup sendiri), dan membuatnya dapat dijalankan oleh grup, yang berarti itu dapat dieksekusi oleh java
pengguna. Jika Anda memberikan akses dengan port, file harus dapat dieksekusi oleh pengguna yang seharusnya memiliki akses, jadi kami melakukannya.
Ini mungkin cukup untuk Joe rata-rata, tetapi karena Anda tahu cara menggunakan --depth
parameter, Anda menjalankan (sebagai java
pengguna) authbind --depth [depth] my_web_app's_start_script
mulai --depth 1
dan bekerja sampai Anda menemukan kedalaman terkecil yang berfungsi dan menggunakannya.
Saya mencoba metode iptables PREROUTING REDIRECT, tetapi ternyata itu juga mempengaruhi paket yang diteruskan. Yaitu, jika mesin juga meneruskan paket antar antarmuka (mis. Jika itu bertindak sebagai titik akses Wi-Fi yang terhubung ke jaringan Ethernet), maka aturan iptables juga akan menangkap koneksi klien yang terhubung ke tujuan Internet, dan mengarahkan mereka ke mesin. Bukan itu yang saya inginkan — saya hanya ingin mengarahkan kembali koneksi yang diarahkan ke mesin itu sendiri.
Salah satu kemungkinan adalah menggunakan penerusan port TCP. Misalnya menggunakan socat
:
socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080
Namun satu kelemahan dengan metode itu adalah, aplikasi yang mendengarkan pada port 8080 kemudian tidak tahu alamat sumber koneksi yang masuk (misalnya untuk logging atau keperluan identifikasi lainnya).