Linux非root用戶(hù)程序使用小于1024端口
在Linux下,默認(rèn)端口1024下的程序是要在root下才能使用的,在其他用戶(hù)下,如果嘗試使用將會(huì)報(bào)錯(cuò)。在有的時(shí)候,我們可能考慮程序運(yùn)行在root帳戶(hù)下,可能會(huì)給Linux系統(tǒng)帶來(lái)安全風(fēng)險(xiǎn)。那如何能夠讓非root用戶(hù)運(yùn)行的程序能夠?qū)ν鈫⒂眯∮?024的端口呢?本文嘗試給出一些方法:
***種方法:
SetUID
為用戶(hù)的應(yīng)用程序在執(zhí)行位設(shè)置user ID能夠使程序可以有root權(quán)限來(lái)運(yùn)行,這個(gè)方法讓程序能夠像在root下運(yùn)行有同樣的效果,不過(guò)需要非常小心,這種方法同樣會(huì)帶來(lái)安全風(fēng)險(xiǎn),特別是當(dāng)要執(zhí)行的程序本身存在安全風(fēng)險(xiǎn)。使用的方法是:
- chown root.root /path/to/application
- #使用SetUID
- chmod u+s /path/to/application
我們可以看到在系統(tǒng)下,/usr/bin/passwd
這種文件,就使用了SetUID,使得每個(gè)系統(tǒng)的用戶(hù)都能用passwd
來(lái)修改密碼——這是要修改/etc/passwd
的文件(而這個(gè)只有root有權(quán)限)。
既然要使用非root用戶(hù)運(yùn)行程序,目的就是要降低程序本身給系統(tǒng)帶來(lái)的安全風(fēng)險(xiǎn),因此,本方法使用的時(shí)候需要特別謹(jǐn)慎。
第二種方法:
CAP_NET_BIND_SERVICE
從2.1開(kāi)始,Linux內(nèi)核有了能力的概念,這使得普通用戶(hù)也能夠做只有超級(jí)用戶(hù)才能完成的工作,這包括使用端口1。
獲取CAP_NET_BIND_SERVICE
能力,即使服務(wù)程序運(yùn)行在非root帳戶(hù)下,也能夠banding到低端口。使用的方法:
- #設(shè)置CAP_NET_BIND_SERVICE
- setcap cap_net_bind_service =+ep /path/to/application
Note:
1. 這個(gè)方法并不是所有Linux系統(tǒng)通適,內(nèi)核在2.1之前的并沒(méi)有提供,因此你需要檢查要使用此方法所在系統(tǒng)是否支持(Linux must support capacity);
2. 另外需要注意的是,如果要運(yùn)行的程序文件是一個(gè)腳本,這個(gè)方法是沒(méi)有辦法正常工作的(Script won't work)。
第三種方法:
Port Forwarding
如果要運(yùn)行的程序有權(quán)限監(jiān)聽(tīng)其他端口,那么這個(gè)方法是可以使用的,首先讓程序運(yùn)行在非root帳戶(hù)下,并綁定高于1024的端口,在確保能正常工作的時(shí)候,將低端口通過(guò)端口轉(zhuǎn)發(fā),將低端口轉(zhuǎn)到高端口,從而實(shí)現(xiàn)非root運(yùn)行的程序綁定低端口。要使用此方法可以使用下面的方式:
- # Enable the IP FORWARD kernel parameter.
- sysctl -w net.ipv4.ip_forward=1
- # Use iptables rules to redirect packets
- iptables -F -t nat
- iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to:8088
***步使用sysctl
確保啟用IP FORWARD功能(此功能在Red Hat/CentOS默認(rèn)是被禁用的),注意,代碼中使用的sysctl
設(shè)置是臨時(shí)性設(shè)置,重啟之后將會(huì)被重置,如果要長(zhǎng)久保存,需要在/etc/sysctl.conf
文件內(nèi)修改:
- # Default value is 0, need change to 1.
- # net.ipv4.ip_forward = 0
- net.ipv4.ip_forward = 1
然后從文件中加載新的配置
- # load new sysctl.conf
- sysctl -p /etc/sysctl.conf
- # or sysctl -p
- # default filename is /etc/sysctl.conf
第二步就是使用iptables
的規(guī)則來(lái)實(shí)現(xiàn)端口轉(zhuǎn)發(fā)到程序所在的端口,示例中我們要將80端口轉(zhuǎn)發(fā)到8088。
此種方法能夠比較好的達(dá)到我們的目的,我們的程序可以通過(guò)非root用戶(hù)來(lái)運(yùn)行,并能夠?qū)ν馓峁┑投丝谔?hào)的服務(wù)。
第四種方法:
RINETD2
這種方法使用的也是端口轉(zhuǎn)發(fā),此工具可以將本地端口映射到遠(yuǎn)程端口,但此功能對(duì)于我們當(dāng)前的功能來(lái)說(shuō),有點(diǎn)雞肋,畢竟我們新增了一個(gè)額外的程序,這將可能會(huì)增加我們系統(tǒng)的風(fēng)險(xiǎn)性。在此不做推薦。
參考說(shuō)明:
1. Linux capabilities文檔,參見(jiàn)其中CAP_NET_BIND_SERVIC,文中的內(nèi)核是否從2.1開(kāi)始有這個(gè)功能并不完全確定,此信息來(lái)自網(wǎng)上。
2. 官網(wǎng)地址:RINETD