Meskipun 80 dan 443 adalah port sistem, bagaimana sebagian besar server web dapat mengikatnya?

18

Menjalankan layanan web yang berikatan dengan port 80 biasanya tidak memerlukan hak akses sudoer. Karena port 80/443 adalah port sistem, artinya port hanya dapat digunakan oleh pengguna yang memiliki hak istimewa, mengapa layanan tersebut masih dapat mengikat port ini?

adaml
sumber
1
"biasanya tidak memerlukan hak sudoer" tidak benar.
tedder42

Jawaban:

29

Pada dasarnya ada dua pendekatan yang berbeda:

  1. Awalnya mulai berjalan sebagai root, ikat ke port yang diistimewakan, dan kemudian drop down ke pengguna yang tidak memiliki hak.

  2. inetd, atau xinetd menjalankan privilege, dan meneruskan permintaan ke server web yang berjalan tanpa hak.

Joe Sniderman
sumber
3
Di Linux Anda juga dapat menerapkan kapabilitas CAP_NET_BIND_SERVICE ke program atau Anda dapat menggunakan iptables untuk mengarahkan ulang port sistem ke port biasa.
Zan Lynx
10
dan hanya untuk mengklarifikasi untuk OP: alasan bahwa opsi # 1 berfungsi adalah karena ketika proses menjatuhkan hak istimewa, mereka diizinkan untuk mempertahankan deskriptor file terbuka - bahkan jika mereka tidak akan diizinkan untuk membukanya untuk kedua kalinya.
strugee
Ada juga Authbind .
Boris the Spider
5

Karena port 80/443 adalah port sistem, artinya port tersebut hanya dapat digunakan oleh pengguna yang memiliki hak istimewa

Saya pikir Anda salah. Siapa pun dapat menggunakan porta ini. Mengikat mereka adalah operasi istimewa.

Alasannya di sini adalah bahwa beberapa pengguna Joe seharusnya tidak dapat menulis server web jahat dan kemudian membuat beberapa host di mana ia tidak memiliki hak administratif. Tentu saja ini adalah model yang cukup lemah. Biasanya tidak ada yang mencegah Joe meletakkan komputernya sendiri di jaringan, dan ia dapat memiliki hak administratif untuk mesin apa pun yang ia miliki akses fisiknya.

Saya akan melakukan demonstrasi dengan netcat.

Sebagai pengguna biasa, saya tidak dapat mengikat ke port 80:

$ nc -l -p 80
Can't grab 0.0.0.0:80 with bind : Permission denied

Saya dapat mengikat ke port 8080:

$ nc -l -p 8080

Sementara itu di terminal lain, saya dapat terhubung ke port 80 dan mengirim beberapa data, dan melihatnya muncul di server saya baru saja mulai:

$ nc 127.0.0.1 8080 <<<"Hello world"

Jika saya ingin mengikat ke port 80, saya harus menjadi root:

$ sudo nc -l -p 80

Atau saya dapat menetapkan CAP_NET_BIND_SERVICEkemampuan ke ncbiner:

$ cp `which nc` .
$ sudo setcap 'cap_net_bind_service=+ep' ./nc
$ ./nc -l -p 80

Pilihan lain adalah menulis program server sehingga setelah itu disebut listen()hak akses root. Ini adalah solusi yang cukup umum, dan Anda akan melihatnya dengan sebagian besar daemon. Apache, misalnya, memulai dari init sebagai root, dan kemudian menjatuhkan hak akses root dan menjadi pengguna www-dataatau sesuatu yang serupa setelah itu terikat ke port 80. Coba jalankan /etc/init.d/apache startsebagai bukan root dan Apache mungkin akan gagal untuk memulai.

Phil Frost
sumber
Pertanyaannya mengatakan "ikat ke port ini". Mengapa menurut Anda dia salah?
Barmar