【Linux系統編程】普通用戶綁定(bind)特權端口

有些知識不常使用真的容易忘啊,即便沒有忘記,知識提取速度也夠下午茶的。linux

背景

最近在學Haskell,今天用HaskellNetwork.Socket模塊實現了一個簡單的基於TCP的daytime服務程序。程序運行階段報瞭如下的錯誤:spa

Network.Socket.bind: permission denied (Permission denied)

個人第一反應懷疑是否是本地有服務程序佔用端口號13,而後用命令netstat -tunl | grep 13查看,端口號並無佔用,因此第一種可能性不成立。.net

是否是這個模塊有相似的bug呢?但並無查到。不放心,用C語言寫了一樣功能的程序,而後運行也會出錯:code

bind error: Permission denied

那是否是端口的問題,隱隱約約記得好像是小於1024的端口號不是預留給用戶的。而後換了一個>=1024的端口,果真運行成功了。至此,思路才走上正軌。圖片

實際上小於1024的端口是特權端口,普通用戶是沒有權限綁定的。rem

那若是我就是要用端口13呢,怎麼解決呢?get

解決方案

1.使用root權限運行
最簡單的方式就是登陸root賬號,或者使用su切換到root。若是本機有配置sudo,普通用戶也可以使用該命令運行服務程序。it

2.使用setcap給服務程序賦予能力
上一種方式是使用具備特權的用戶,而該種方式是給程序賦予綁定特權端口的能力。操做以下:io

  • 使用setcap 'CAP_NET_BIND_SERVICE=+ep' /path/to/program賦予(raise)綁定特權端口的能力
  • 使用setcap 'CAP_NET_BIND_SERVICE=-ep' /path/to/program清除(lower)綁定特權端口的能力
  • 也可以使用setcap -r /path/to/program清除(remove)該程序的全部能力

setcap簡單使用說明

  • 除了CAP_NET_BIND_SERVICE,還有好多能力,能夠參考capabilities(7)
  • =-是運算符,除此以外還有+ep是標記,除此以外還有i。可參考cap_from_text(3) Textual Representation一節的說明。
  • setcap命令對內核有要求,必須>=2.6.24

請關注個人公衆號哦。
圖片描述class

相關文章
相關標籤/搜索