linux内核端口绑定,有没有办法让非root进程绑定到Linux上的“特权”端口?

在我的开发盒上有这个限制是非常烦人的,因为除了我之外不会有任何用户。

我知道标准的解决方法 ,但它们都没有完全符合我的要求:

authbind (Debian测试中的版本,1.0,仅支持IPv4)

使用iptables REDIRECT目标将低端口重定向到高端口 (对于ip6tables,iptables的IPv6版本尚未实现“nat”表)

sudo(以root身份运行是我想避免的)

SELinux(或类似)。 (这只是我的开发盒,我不想引入很多额外的复杂性。)

是否有一些简单的sysctl变量允许非root进程绑定到Linux上的“特权”端口(端口小于1024),或者我只是运气不好?

编辑:在某些情况下,您可以使用功能来执行此操作。

#1楼

在启动时:

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

然后,您可以绑定到前进的端口。

#2楼

您可以执行端口重定向。 这就是我在Linux机器上运行的Silverlight策略服务器所做的

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 943 -j REDIRECT --to-port 1300

#3楼

您可以设置本地SSH隧道,例如,如果您希望端口80命中绑定到3000的应用程序:

sudo ssh $USERNAME@localhost -L 80:localhost:3000 -N

这具有使用脚本服务器的优点,并且非常简单。

#4楼

还有'djb方式'。 您可以使用此方法以root身份在tcpserver下的任何端口上运行启动流程,然后它将在流程启动后立即将流程控制权交给您指定的用户。

#!/bin/sh

UID=`id -u yourusername`

GID=`id -g yourusername`

exec tcpserver -u $UID -g $GID -RHl0 0 portnumber /path/to/your/process &

#5楼

TLDR:对于“答案”(如我所见),请跳到本答案的>> TLDR <

好吧,我已经弄明白了(这次是真实的),这个问题的答案,我的这个答案也是一种道歉的方式,以促进另一个答案 (在这里和在推特上)我认为是“最好的“但是在尝试之后,发现我错了。 从我的错误中学习孩子:在你真正尝试过之前不要宣传一些东西!

我再次回顾了这里的所有答案。 我尝试了其中一些 (并选择不尝试其他人,因为我根本不喜欢这些解决方案)。 我认为解决方案是使用systemd及其Capabilities=和CapabilitiesBindingSet= settings。 经过一段时间的摔跤后,我发现这不是解决方案, 因为:

功能旨在限制根进程!

由于OP明智地指出,它始终是最好避免(对所有的守护程序如果可能的话!)。

您不能在systemd单元文件中使用与功能相关的选项与User=和Group= ,因为在execev (或任何函数)时,功能始终会重置。 换句话说,当systemd分叉并丢弃其权限时,功能将被重置。 没有办法解决这个问题,内核中的所有绑定逻辑都是基于uid = 0的基础,而不是功能。 这意味着Capabilities不太可能成为这个问题的正确答案(至少在很短的时间内)。 顺便setcap ,正如其他人所提到的, setcap不是解决方案。 它对我不起作用,它对脚本不起作用,并且无论何时文件发生变化都会重置。

在我微薄的辩护中,我确实陈述了(在我现在删除的评论中),詹姆斯的iptables建议(OP也提到了),是“第二好的解决方案”。 :-P

>> TLDR <<

解决方案是将systemd与on-the-fly iptables命令结合使用,如下所示( 取自DNSChain ):

[Unit]

Description=dnschain

After=network.target

Wants=namecoin.service

[Service]

ExecStart=/usr/local/bin/dnschain

Environment=DNSCHAIN_SYSD_VER=0.0.1

PermissionsStartOnly=true

ExecStartPre=/sbin/sysctl -w net.ipv4.ip_forward=1

ExecStartPre=-/sbin/iptables -D INPUT -p udp --dport 5333 -j ACCEPT

ExecStartPre=-/sbin/iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333

ExecStartPre=/sbin/iptables -A INPUT -p udp --dport 5333 -j ACCEPT

ExecStartPre=/sbin/iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333

ExecStopPost=/sbin/iptables -D INPUT -p udp --dport 5333 -j ACCEPT

ExecStopPost=/sbin/iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333

User=dns

Group=dns

Restart=always

RestartSec=5

WorkingDirectory=/home/dns

PrivateTmp=true

NoNewPrivileges=true

ReadOnlyDirectories=/etc

# Unfortunately, capabilities are basically worthless because they're designed to restrict root daemons. Instead, we use iptables to listen on privileged ports.

# Capabilities=cap_net_bind_service+pei

# SecureBits=keep-caps

[Install]

WantedBy=multi-user.target

在这里我们完成以下任务:

守护进程侦听5333,但是由于iptables ,连接在53上被成功接受

我们可以将命令包含在单元文件本身中,从而节省人们的头痛。 systemd为我们清理防火墙规则,确保在守护程序未运行时删除它们。

我们从不以root身份运行,并且我们无法进行权限提升(至少是systemd声明),据说即使守护程序被泄露并设置uid=0 。

不幸的是, iptables仍然是一个非常丑陋且难以使用的实用工具。 例如,如果守护程序正在侦听eth0:0而不是eth0 ,则命令略有不同 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值