GNU/Linux >> Belajar Linux >  >> Linux

Izinkan proses non-root untuk mengikat ke port 80 dan 443?

Saya tidak yakin apa yang dirujuk oleh jawaban dan komentar lain di sini. Ini mungkin agak mudah. Ada dua opsi, keduanya memungkinkan akses ke port bernomor rendah tanpa harus meningkatkan proses ke 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 port bernomor rendah melalui setcap perintah:

sudo setcap CAP_NET_BIND_SERVICE=+eip /path/to/binary

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 menggunakan setcap pada biner itu sendiri daripada symlink.

Opsi 2:Gunakan authbind untuk memberikan akses satu kali, dengan kontrol pengguna/grup/port yang lebih baik:

authbind (halaman manual) alat ada tepat untuk ini.

  1. Instal authbind menggunakan pengelola paket favorit Anda.

  2. Konfigurasikan untuk memberikan akses ke port yang relevan, mis. untuk mengizinkan 80 dan 443 dari semua pengguna dan grup:

    sudo touch /etc/authbind/byport/80
    sudo touch /etc/authbind/byport/443
    sudo chmod 777 /etc/authbind/byport/80
    sudo chmod 777 /etc/authbind/byport/443
    
  3. Sekarang jalankan perintah Anda melalui authbind (secara opsional tentukan --deep atau argumen lain, lihat halaman manual):

    authbind --deep /path/to/binary command line args
    

    Mis.

    authbind --deep java -jar SomeServer.jar
    

Ada keuntungan dan kerugian dari 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 versi yang lebih lama hanya mendukung IPv4 (karena saya awalnya menulis ini, versi yang lebih baru dengan dukungan IPv6 dirilis).


Dale Hagglund sangat tepat. Jadi saya hanya akan mengatakan hal yang sama tetapi dengan cara yang berbeda, dengan beberapa hal spesifik dan contoh. ☺

Hal yang benar untuk dilakukan di dunia Unix dan Linux adalah:

  • untuk memiliki program kecil, sederhana, mudah diaudit, yang berjalan sebagai pengguna super dan mengikat soket pendengar;
  • untuk memiliki program lain yang kecil, sederhana, mudah diaudit, yang menghilangkan hak istimewa, yang dihasilkan oleh program pertama;
  • untuk mendapatkan inti dari layanan, di ketiga yang terpisah program, dijalankan di bawah akun non-pengguna super dan rantai dimuat oleh program kedua, berharap untuk mewarisi deskriptor file terbuka untuk soket.

Anda salah paham tentang di mana risiko tinggi itu. Risiko tinggi adalah membaca dari jaringan dan menindaklanjuti apa yang dibaca bukan dalam tindakan sederhana membuka soket, mengikatnya ke port, dan memanggil listen() . Ini adalah bagian dari layanan yang melakukan komunikasi sebenarnya yang berisiko tinggi. Bagian yang terbuka, bind() , dan listen() , dan bahkan (sampai batas tertentu) bagian accepts() , tidak berisiko tinggi dan dapat dijalankan di bawah perlindungan pengguna super. Mereka tidak menggunakan dan menindaklanjuti (dengan pengecualian alamat IP sumber di accept() kasus) yang berada di bawah kendali orang asing yang tidak dipercaya melalui jaringan.

Ada banyak cara untuk melakukan ini.

inetd

Seperti yang dikatakan Dale Hagglund, "superserver jaringan" lama inetd Melakukan hal ini. Akun tempat proses layanan dijalankan adalah salah satu kolom di inetd.conf . Itu tidak memisahkan bagian mendengarkan dan menjatuhkan hak istimewa menjadi dua program terpisah, kecil dan mudah diaudit, tetapi memisahkan kode layanan utama menjadi program terpisah, exec() ed dalam proses layanan yang muncul dengan deskriptor file terbuka untuk soket.

Sulitnya mengaudit tidak terlalu menjadi masalah, karena hanya perlu mengaudit satu program saja. inetd masalah utama adalah tidak terlalu banyak mengaudit tetapi tidak memberikan kontrol layanan waktu proses yang sederhana dan terperinci, dibandingkan dengan alat yang lebih baru.

UCSPI-TCP dan daemontools

Paket UCSPI-TCP dan daemontools Daniel J. Bernstein dirancang untuk melakukan hal ini bersamaan. Sebagai alternatif, seseorang dapat menggunakan perangkat daemontools-encore Bruce Guenter yang sebagian besar setara.

Program untuk membuka deskriptor file soket dan mengikat ke port lokal istimewa adalah tcpserver , dari UCSPI-TCP. Ia melakukan keduanya listen() dan accept() .

tcpserver kemudian memunculkan program layanan yang menghapus hak akses root itu sendiri (karena protokol yang dilayani melibatkan memulai sebagai pengguna super dan kemudian "masuk", seperti halnya, misalnya, daemon FTP atau SSH) atau setuidgid yang merupakan program mandiri kecil dan mudah diaudit yang hanya membuang hak istimewa dan kemudian memuat rantai ke program layanan yang tepat (tidak ada bagian yang pernah berjalan dengan hak istimewa pengguna super, seperti halnya dengan, katakanlah, qmail-smtpd ).

Layanan run skrip dengan demikian misalnya (yang ini untuk dummyidentd untuk menyediakan layanan null IDENT):

#!/bin/sh -e
exec 2>&1
exec \
tcpserver 0 113 \
setuidgid nobody \
dummyidentd.pl

tidak

Paket nosh saya dirancang untuk melakukan ini. Ini memiliki setuidgid kecil utilitas, sama seperti yang lain. Satu perbedaan kecil adalah dapat digunakan dengan systemd -style layanan "LISTEN_FDS" serta dengan layanan UCSPI-TCP, jadi tcpserver tradisional program diganti dengan dua program terpisah:tcp-socket-listen dan tcp-socket-accept .

Sekali lagi, utilitas tujuan tunggal menelurkan dan memuat rantai satu sama lain. Satu kekhasan yang menarik dari desain ini adalah seseorang dapat melepaskan hak superuser setelah listen() tetapi bahkan sebelum accept() . Ini adalah run skrip untuk qmail-smtpd yang memang melakukan hal itu:

#!/bin/nosh
fdmove -c 2 1
clearenv --keep-path --keep-locale
envdir env/
softlimit -m 70000000
tcp-socket-listen --combine4and6 --backlog 2 ::0 smtp
setuidgid qmaild
sh -c 'exec \
tcp-socket-accept -v -l "${LOCAL:-0}" -c "${MAXSMTPD:-1}" \
ucspi-socket-rules-check \
qmail-smtpd \
'

Program-program yang berjalan di bawah naungan superuser adalah alat pemuat berantai layanan-agnostik kecil fdmove , clearenv , envdir , softlimit , tcp-socket-listen , dan setuidgid . Sampai-sampai sh dimulai, soket terbuka dan terikat ke smtp port, dan prosesnya tidak lagi memiliki hak superuser.

s6, s6-networking, dan execline

Paket jaringan s6 dan s6 Laurent Bercot dirancang untuk melakukan ini bersamaan. Perintah secara struktural sangat mirip dengan daemontools dan UCSPI-TCP.

run skrip akan hampir sama, kecuali untuk penggantian s6-tcpserver untuk tcpserver dan s6-setuidgid untuk setuidgid . Namun, seseorang juga dapat memilih untuk menggunakan perangkat execline M. Bercot pada saat yang sama.

Berikut adalah contoh layanan FTP, dimodifikasi ringan dari versi asli Wayne Marshall, yang menggunakan execline, s6, s6-networking, dan program server FTP dari publicfile:

#!/command/execlineb -PW
multisubstitute {
    define CONLIMIT 41
    define FTP_ARCHIVE "/var/public/ftp"
}
fdmove -c 2 1
s6-envuidgid pubftp 
s6-softlimit -o25 -d250000 
s6-tcpserver -vDRH -l0 -b50 -c ${CONLIMIT} -B '220 Features: a p .' 0 21 
ftpd ${FTP_ARCHIVE}

ipsvd

Ipsvd Gerrit Pape adalah perangkat lain yang berjalan di jalur yang sama dengan ucspi-tcp dan s6-networking. Alatnya adalah chpst dan tcpsvd kali ini, tetapi mereka melakukan hal yang sama, dan kode berisiko tinggi yang melakukan pembacaan, pemrosesan, dan penulisan hal-hal yang dikirim melalui jaringan oleh klien yang tidak dipercaya masih dalam program terpisah.

Inilah contoh M. Pape dalam menjalankan fnord dalam run skrip:

#!/bin/sh
exec 2>&1
cd /public/10.0.5.4
exec \
chpst -m300000 -Uwwwuser \
tcpsvd -v 10.0.5.4 443 sslio -v -unobody -//etc/fnord/jail -C./cert.pem \
fnord

systemd

systemd , pengawasan layanan baru dan sistem init yang dapat ditemukan di beberapa distribusi Linux, dimaksudkan untuk melakukan apa inetd bisa lakukan. Namun, itu tidak menggunakan serangkaian program mandiri kecil. Seseorang harus mengaudit systemd secara keseluruhan, sayangnya.

Dengan systemd seseorang membuat file konfigurasi untuk menentukan soket yang systemd mendengarkan, dan layanan yang systemd dimulai. File "unit" layanan memiliki setelan yang memungkinkan seseorang mengontrol banyak proses layanan, termasuk pengguna yang menjalankannya.

Dengan pengguna tersebut ditetapkan sebagai bukan pengguna super, systemd melakukan semua pekerjaan membuka soket, mengikatnya ke port, dan memanggil listen() (dan, jika diperlukan, accept() ) dalam proses #1 sebagai pengguna super, dan proses layanan yang dihasilkannya berjalan tanpa hak pengguna super.


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 lain. Jadi saya memulai server pada port 3000 dan menyiapkan port forward dari port 80 ke port 3000.

Tautan ini menyediakan perintah aktual yang dapat digunakan untuk melakukan ini. Inilah perintahnya -

localhost/loopback

sudo iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 3000

eksternal

sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 3000

Saya telah menggunakan perintah kedua dan berhasil untuk saya. Jadi menurut saya ini adalah jalan tengah untuk tidak mengizinkan proses pengguna mengakses port yang lebih rendah secara langsung, tetapi memberi mereka akses menggunakan penerusan port.


Linux
  1. UNIX / Linux :Bagaimana crontab memvalidasi akses berdasarkan file cron.allow dan cron.deny

  2. Bagaimana Mengidentifikasi Port ke Suatu Proses?

  3. Blokir akses jaringan dari suatu proses?

  1. Ikat ke port kurang dari 1024 tanpa akses root

  2. lalu lintas vpn stunnel dan pastikan itu terlihat seperti lalu lintas SSL pada port 443

  3. Mengapa penyedia hosting tidak mengizinkan SSL melalui port 443?

  1. Cara Membuka Port 80 &443 di FirewallD

  2. Instal SoftHSM dan Akses melalui Program Java

  3. Mencegah aplikasi lain mengikat ke port 80 dan 443