Bir kullanıcının 1024'ün altındaki bir bağlantı noktasını dinlemesine izin verme


63

Bir kullanıcının (root'tan farklı) 80 numaralı bağlantı noktasını dinleyen bir sunucuyu çalıştırmasına izin vermem gerekiyor.

Bunu yapmanın bir yolu var mı?


1
Bu soru yoruma açık. "Sizin (root olarak) güvenlik nedeniyle imtiyazsız bir hesapta çalıştırmak istediğiniz yeni bir sistem servisi yarattınız" (iyi uygulama olarak kabul edilir) değil, "yapabilirlerse sorulan bir kullanıcım var" demek istediğinizi umuyorum. kendi web sunucularını sistemimde çalıştırın, erişimine nasıl izin veririm? " (oldukça kötü bir uygulama olarak kabul edilir)
Michael Shaw,

3
@Ptolemy, asıl sebep şudur: makinem, herhangi bir bağlantı noktasını 80'den fazla engelleyen bir güvenlik duvarının arkasındadır. Bir sunucuyu barındırmak istiyorum (ayrıcalıkları düşürmez!), Bu nedenle 80 numaralı bağlantı noktasını dinlemesini gerekir; root olarak çalıştığına güvenmeyin (bariz güvenlik nedenleriyle). Bunu umursamda yapabilirim.
peoro

Yanıtlar:


50

setcap 'cap_net_bind_service=+ep' /path/to/program

bu belirli süreçler için işe yarayacaktır. Ancak belirli bir kullanıcının 1024'ün altındaki bağlantı noktalarına bağlanmasına izin vermek için onu sudo'lara eklemeniz gerekir.

Daha fazla bilgi için bu tartışmaya bir göz atın .


31

(Bu yöntemlerden bazıları diğer cevaplarda da belirtilmiştir; Ben kaba tercih sırasına göre birkaç olası seçenek veriyorum.)

Düşük bağlantı noktasını yüksek bağlantı noktasına yönlendirebilir ve yüksek bağlantı noktasını dinleyebilirsiniz.

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 1080

Ayrıcalıklı bağlantı noktasını dinlemeye başladıktan sonra sunucunuzu kök olarak atabilir ve ayrıcalık olarak bırakabilirsiniz. Tercihen, kendiniz kodlamak yerine, sunucunuzu sizin için işi yapan bir paketleyiciden başlatın. Sunucunuz bağlantı başına bir örnek başlatırsa, onu başlatın inetd(veya benzeri bir programdan xinetd). Bunun için aşağıdaki inetdgibi bir satır kullanın /etc/inetd.conf:

http  stream  tcp  nowait  username:groupname  /path/to/server/executable  argv[0] argv[1]…

Sunucunuz tek bir durumda dinliyorsa, onu gibi bir programdan başlatın authbind. Ya boş bir dosya oluşturun /etc/authbind/byport/80ve sunucuyu çalıştıran kullanıcı tarafından çalıştırılabilir hale getirin; veya /etc/authbind/byuid/12341234 sunucuyu çalıştıran UID'nin olduğu, satırı içeren oluşturma 0.0.0.0/0:80,80.

Sunucu yürütülebilir özelliklerini destekleyen dosya sistemi üzerinde saklanıyorsa, bunu verebilir yeteneği . Yeteneklerin hala göreceli olarak yeni olduklarını ve hala birkaç sorun yaşadıklarını unutmayın .cap_net_bind_service

setcap cap_net_bind_service=ep /path/to/server/executable

4
Başa çıkmam gereken her durumda, yürütülebilir dosya java veya python'u başlatan bir betikti. İnce noktalara harcamak için 10 saati olmayan bir adam olarak, iptables çözümünüz onu acısız şekilde kapsar.
sr

Iptables çözümü için, -A INPUT -p tcp --dport 1080 -j ACCEPTişe yaramadığı gibi bir filtre kuralı da eklemek zorunda kaldım (aynı zamanda -j DROPhepsini yakaladım.) Bu yüzden iki dinleme soketi ile ayrıldım.
thom_nic

4

Kısa cevap, bunun tasarım tarafından mümkün olmadığıdır.

Uzun cevap, açık kaynak dünyalarında, tasarıma oynayan ve alternatif yöntemlerle ortaya çıkan birçok insan var. Genel olarak, bunun mümkün olmaması gerektiği yaygın olarak kabul gören bir uygulamadır. Muhtemelen denediğiniz gerçeği, sisteminizde başka bir tasarım hatası olduğunu ve tüm sistem mimarinizi * nix en iyi uygulamalar ve güvenlik uygulamaları ışığında yeniden gözden geçirmeniz gerektiği anlamına gelir.

Bununla birlikte, düşük bağlantı noktalarına root dışı erişim yetkisi veren bir program authbind'dir . Hem selinux hem de grsecurity ayrıca bu gibi ince ayarlanmış kimlik doğrulama için çerçeveler sağlar.

Son olarak, belirli kullanıcıların belirli programları root olarak çalıştırmasını istiyorsanız ve gerçekte ihtiyacınız olan şey sadece bir kullanıcının apache'yi veya benzer bir şeyi yeniden başlatmasına izin vermek sudo, arkadaşınız!


8
Port "güvenlik" modern dünyada size pek bir şey vermiyor.
pjc50

3
@ pjc50: Evet öyle. Bu ima edilen güven hakkında. Düşük port numaraları yüksek güven demektir. SSH, POP, FTP ve diğer servis sahiplerinin bağlantı noktaları açıldığında sistem düzeyinde şifreler ve diğer bilgiler istemeleri beklenir. Kullanıcıların bir kutudaki düşük bağlantı noktalarını dinlemelerine izin verilirse, kullanılmayan (veya çökmüş) bağlantı noktalarındaki sahte telefon numaralarını başlatabilir ve şüphesiz kullanıcılardan gelen şifreleri toplayabilirler. Bu şifreler daha sonra root dahil diğer hesapları tehlikeye atmak için bu kutuda kullanılabilir.
Caleb

8
Bu oldukça zayıf bir güvenlik şekli. Bir şeye bağlıysanız ve sertifika işlemi yapmadıysanız, kiminle konuştuğunuzu bilmiyorsunuz - yani MITM saldırıları.
pjc50

5
Sanırım portlar için ihtiyaç duyulan şey boğuldu: o zaman "mail port25'i" boğabilirsin o zaman (a) mail servetinin kök erlerle başlatılması gerekmiyor ve (b) başkasının kaçırması gerekmiyor.
pjc50

7
Linux bebeklik döneminde bu, "tasarım tarafından" doğru olsa da, o zaman ve şimdi çok az mantıklı geliyor. Güvenlik, kullanıcının yapabilecekleri ve yapamadıkları ile ilgilidir. Örneğin, yalnızca kök kullanıcının 80 numaralı bağlantı noktasını kullanmasına izin vermek çok büyük bir güvenlik riskidir, çünkü bu, 80 numaralı bağlantı noktasını kullanması gereken, ancak kök erişimi olmayan kişilere kök erişimi vermeniz gerektiği anlamına gelir . 80 numaralı bağlantı noktasını kullanmak için root kullanıcısı X'e güvenmiyorsanız, bu güveni işletim sisteminizde kodlayabilmelisiniz. Neyse ki, dediğiniz gibi, authbind gibi buna izin veren berbat bir çalışma ortamı var.
BT,

3

Sen kullanabilirsiniz Netcat'i veya Xinetd veya iptables port yönlendirme veya bir ön uç proxy gibi apache kullanmak ve ayrıcalıklı olmayan bağlantı noktasında işlemini çalıştırın.


3

Authbind , @Gilles zaten ondan bahsetti, ama biraz genişletmek istiyorum.

Elverişli erişim kontrolüne sahiptir (man sayfasındaki detaylar): girişi port, arayüz adresi, kullanıcı adı, adres veya port aralığına ve bunların birleşimine göre filtreleyebilirsiniz.

Çok faydalı bir parametresi var --depth:

- seviye seviyeleri

Authbind'in, çağıran grafikte derin olan programları etkilemesine neden olur. Varsayılan 1'dir.

"Derinlik seviyeleri", bir komut dosyasının (veya programın) başka bir komut dosyasını çalıştırdığında, bir seviyeye indiği anlamına gelir. Öyleyse --depth 5, 5 üzerinden seviye 1 (veya 0 mı?) Anlamına gelirse , bağlama izniniz vardır, oysa seviye 6 ve üzeri ise, bunu yapamazsınız. Bir komut dosyasının erişime sahip olmasını istediğinizde, ancak sizin bilginizle veya habersiz çalıştığı programları kullanmamanız durumunda kullanışlıdır.


Açıklamak gerekirse, bunun gibi bir şeye sahip olabilirsiniz: güvenlik uğruna, javayalnızca java çalıştıracak bir kullanıcınız var ve ona 80 numaralı bağlantı noktasına erişmesine izin vermek istiyorsunuz:

echo > /etc/authbind/byport/80
chown root:java /etc/authbind/byport/80
chmod 710 /etc/authbind/byport/80

Oluşturduğum ../byport/80 file, bunu verilen javakullanıcılar grubuna (her kullanıcının kendi grubu vardır) ve bu tarafından çalıştırılabilir demektir grup tarafından çalıştırılabilir yapılan javakullanıcı. Bağlantı noktasına göre erişim veriyorsanız, dosyanın erişimi olması gereken kullanıcı tarafından çalıştırılabilir olması gerekir, bu yüzden bunu yaptık.

Bu ortalama Joe için yeterli olabilir, ancak nasıl kullanılacağını biliyorum çünkü --depthparametre, siz (olarak çalıştırmak javakullanıcı) authbind --depth [depth] my_web_app's_start_scriptbaşlayan --depth 1ve çalışır en küçük derinlik bulacak ve kullanana kadar yol kadar çalışan.

Detaylar için man sayfasını okuyun .


1

İptables PREROUTING REDIRECT yöntemini denedim, ancak bunun iletilen paketleri de etkilediğini gördüm. Diğer bir deyişle, makine arabirimler arasında da paketleri iletiyorsa (örneğin, bir Ethernet ağına bağlı bir Wi-Fi erişim noktası görevi görüyorsa), iptables kuralı ayrıca bağlı müşterilerin İnternet hedeflerine olan bağlantılarını yakalar ve yönlendirir. makine. İstediğim bu değildi; sadece makineye yönlendirilen bağlantıları yönlendirmek istemiştim.

Bir olasılık, TCP portu yönlendirmeyi kullanmaktır. Örneğin socat:

socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080

Bununla birlikte, bu yöntemin bir dezavantajı, 8080 nolu bağlantı noktasını dinleyen uygulamanın gelen bağlantıların kaynak adresini bilmemesidir (örneğin, günlük kaydı veya diğer tanımlama amaçları için).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.