当我的开发盒上没有除了我之外的任何用户时,我的开发盒受到这种限制是非常烦人的。
我知道标准解决方法,但它们都没有完全达到我想要的效果:
- authbind (Debian 测试中的版本为 1.0,仅支持 IPv4)
- 使用 iptables REDIRECT 目标将低端口重定向到高端口(“nat”表尚未为 ip6tables(iptables 的 IPv6 版本)实现
- sudo(我试图避免以 root 身份运行)
- SELinux(或类似)。 (这只是我的开发框,我不想引入很多额外的复杂性。)
是否有一些简单的 sysctl 变量允许非根进程绑定到“特权”端口(端口小于 1024) 在 Linux 上,还是我只是运气不好?
编辑:在某些情况下,您可以 使用功能来执行此操作。
It's very annoying to have this limitation on my development box, when there won't ever be any users other than me.
I'm aware of the standard workarounds, but none of them do exactly what I want:
- authbind (The version in Debian testing, 1.0, only supports IPv4)
- Using the iptables REDIRECT target to redirect a low port to a high port (the "nat" table is not yet implemented for ip6tables, the IPv6 version of iptables)
- sudo (Running as root is what I'm trying to avoid)
- SELinux (or similar). (This is just my dev box, I don't want to introduce a lot of extra complexity.)
Is there some simple sysctl
variable to allow non-root processes to bind to "privileged" ports (ports less than 1024) on Linux, or am I just out of luck?
EDIT: In some cases, you can use capabilities to do this.
发布评论
评论(25)
好的,感谢指出功能系统和 CAP_NET_BIND_SERVICE 功能的人。 如果您有最新的内核,确实可以使用它以非 root 身份启动服务但绑定低端口。 简而言之,您可以这样做:
然后,此后任何时候执行
程序
,它都将具有CAP_NET_BIND_SERVICE
功能。setcap
位于 debian 软件包libcap2-bin
中。现在需要注意的是:
#!
行启动解释器)。 在这种情况下,据我所知,您必须将该功能应用于解释器可执行文件本身,这当然是一个安全噩梦,因为任何使用该解释器的程序都将具有该功能。 我无法找到任何干净、简单的方法来解决这个问题。setcap
或suid
)的程序
上禁用LD_LIBRARY_PATH
。 因此,如果您的程序
使用自己的.../lib/
,您可能需要考虑其他选项,例如端口转发。资源:
setcap
。注意:RHEL 首先在 v6 中添加了此内容。
Okay, thanks to the people who pointed out the capabilities system and
CAP_NET_BIND_SERVICE
capability. If you have a recent kernel, it is indeed possible to use this to start a service as non-root but bind low ports. The short answer is that you do:And then anytime
program
is executed thereafter it will have theCAP_NET_BIND_SERVICE
capability.setcap
is in the debian packagelibcap2-bin
.Now for the caveats:
#!
line to launch an interpreter). In this case, as far I as understand, you'd have to apply the capability to the interpreter executable itself, which of course is a security nightmare, since any program using that interpreter will have the capability. I wasn't able to find any clean, easy way to work around this problem.LD_LIBRARY_PATH
on anyprogram
that has elevated privileges likesetcap
orsuid
. So if yourprogram
uses its own.../lib/
, you might have to look into another option like port forwarding.Resources:
setcap
.Note: RHEL first added this in v6.
更新2017:
使用authbind
免责声明(2021 年更新): 请注意,
authbind
通过LD_PRELOAD
工作,仅当您的程序使用libc
时才使用它code>,如果您的程序是使用 GO 或任何其他避免使用 C 的编译器编译的,则情况并非如此(或可能)。如果您使用 go,请为受保护的端口范围设置内核参数,请参阅帖子底部。Authbind
比CAP_NET_BIND_SERVICE
或自定义内核好得多。CAP_NET_BIND_SERVICE
向二进制文件授予信任,但不提供控制每个端口的访问。
Authbind
授予信任用户/组并提供对每个端口访问的控制,以及
支持 IPv4 和 IPv6(最近已添加 IPv6 支持)。
安装:
apt-get install authbind
为所有用户和组配置对相关端口的访问,例如 80 和 443:
<块引用>
sudo touch /etc/authbind/byport/80
sudo touch /etc/authbind/byport/443
须藤 chmod 777 /etc/authbind/byport/80
sudo chmod 777 /etc/authbind/byport/443
通过
authbind
执行命令(可以选择指定
--deep
或其他参数,请参阅man authbind
):作为 Joshua 非常棒(=不推荐,除非你知道自己在做什么)建议破解内核:
我已经首先发布它这里。
简单的。 对于普通或旧的内核,则不需要。
正如其他人指出的,
iptables
可以转发端口。正如其他人也指出的那样,
CAP_NET_BIND_SERVICE
也可以完成这项工作。当然,如果您从脚本启动程序,
CAP_NET_BIND_SERVICE
将会失败,除非您在 shell 解释器上设置上限,这是毫无意义的,您也可以以 root 身份运行您的服务...例如对于Java,你必须将其应用到JAVA JVM
显然,这意味着任何Java程序都可以绑定系统端口。
Mono/.NET 也是如此。
我也很确定 xinetd 不是最好的主意。
但既然这两种方法都是 hack,为什么不直接通过解除限制来解除限制呢?
没有人说你必须运行普通的内核,所以你可以运行你自己的内核。
您只需下载最新内核的源代码(或您当前拥有的相同内核)。
然后,您转到:
在那里查找这一行
并将其更改为:
如果您不想出现不安全的 ssh 情况,请将其更改为:
一般来说,我会使用您需要的最低设置,例如http 为 79,在端口 25 上使用 SMTP 时为 24。
这已经是全部了。
编译内核,并安装它。
重新启动。
完成了 - 这个愚蠢的限制已经消失了,这也适用于脚本。
以下是编译内核的方法:
https://help.ubuntu.com/community/Kernel/Compile
简而言之:
iptables
;sysctl 方法
注意:
到目前为止,不再需要更新内核。
您现在可以设置:
或者保留:
如果这会产生错误,只需使用 nano 编辑
/etc/sysctl.conf
并在那里设置参数以在重新启动后保持不变。或通过
procfs
Update 2017:
Use authbind
Disclaimer (update per 2021): Note that
authbind
works viaLD_PRELOAD
, which is only used if your program useslibc
, which is (or might) not be the case if your program is compiled with GO, or any other compiler that avoids C. If you use go, set the kernel parameter for the protected port range, see bottom of post. </EndUpdate>Authbind
is much better thanCAP_NET_BIND_SERVICE
or a custom kernel.CAP_NET_BIND_SERVICE
grants trust to the binary but provides nocontrol over per-port access.
Authbind
grants trust to theuser/group and provides control over per-port access, and
supports both IPv4 and IPv6 (IPv6 support has been added as of late).
Install:
apt-get install authbind
Configure access to relevant ports, e.g. 80 and 443 for all users and groups:
Execute your command via
authbind
(optionally specifying
--deep
or other arguments, seeman authbind
):As a follow-up to Joshua's fabulous (=not recommended unless you know what you do) recommendation to hack the kernel:
I've first posted it here.
Simple. With a normal or old kernel, you don't.
As pointed out by others,
iptables
can forward a port.As also pointed out by others,
CAP_NET_BIND_SERVICE
can also do the job.Of course
CAP_NET_BIND_SERVICE
will fail if you launch your program from a script, unless you set the cap on the shell interpreter, which is pointless, you could just as well run your service as root...e.g. for Java, you have to apply it to the JAVA JVM
Obviously, that then means any Java program can bind system ports.
Ditto for mono/.NET.
I'm also pretty sure xinetd isn't the best of ideas.
But since both methods are hacks, why not just lift the limit by lifting the restriction ?
Nobody said you have to run a normal kernel, so you can just run your own.
You just download the source for the latest kernel (or the same you currently have).
Afterwards, you go to:
There you look for this line
and change it to:
if you don't want to have an insecure ssh situation, you alter it to this:
Generally, I'd use the lowest setting that you need, e.g. 79 for http, or 24 when using SMTP on port 25.
That's already all.
Compile the kernel, and install it.
Reboot.
Finished - that stupid limit is GONE, and that also works for scripts.
Here's how you compile a kernel:
https://help.ubuntu.com/community/Kernel/Compile
In a nutshell:
iptables
if you want to stay secure,sysctl method
Note:
As of late, updating the kernel is no longer required.
You can now set:
Or to persist:
And if that yields an error, simply edit
/etc/sysctl.conf
with nano and set the parameter there for persistence across reboots.or via
procfs
由于某种原因,没有人提到将 sysctl net.ipv4.ip_unprivileged_port_start 降低到您需要的值。
示例:我们需要将我们的应用程序绑定到 443 端口。
有人可能会说,这存在潜在的安全问题:非特权用户现在可以绑定到其他特权端口(444-1024)。
但是你可以使用 iptables 轻松解决这个问题,通过阻止其他端口:
与其他方法的比较。 这种方法:
例如,要捕获启用功能的应用程序的核心转储,您需要更改 sysctl fs.suid_dumpable (这会导致另一个潜在的安全问题)
另外,当设置 CAP/suid 时,/proc/PID 目录由 root 用户拥有,因此您的非 root 用户将无法获得正在运行的进程的完整信息/控制权,例如,用户将无法(在常见情况下)通过 /proc/PID/fd/ (netstat -aptn | grep PID) 确定哪些连接属于应用程序。
根据情况,我会在 sysctl、CAP、authbind 和 iptables-redirect 之间进行选择。 我们有这么多选择,这真是太好了。
For some reason no one mention about lowering sysctl net.ipv4.ip_unprivileged_port_start to the value you need.
Example: We need to bind our app to 443 port.
Some may say, there is a potential security problem: unprivileged users now may bind to the other privileged ports (444-1024).
But you can solve this problem easily with iptables, by blocking other ports:
Comparison with other methods. This method:
For example, to catch a coredump of capability-enabled application you will need to change sysctl fs.suid_dumpable (which leads to another potential security problems)
Also, when CAP/suid is set, /proc/PID directory is owned by root, so your non-root user will not have full information/control of running process, for example, user will not be able (in common case) to determine which connections belong to application via /proc/PID/fd/ (netstat -aptn | grep PID).
Depending on the situation, I would choose between sysctl, CAP, authbind and iptables-redirect. And this is great that we have so many options.
您可以进行端口重定向。 这就是我对 Linux 机器上运行的 Silverlight 策略服务器所做的事情
You can do a port redirect. This is what I do for a Silverlight policy server running on a Linux box
或者修补你的内核并删除检查。
(最后的选择,不推荐)。
在
net/ipv4/af_inet.c
中,删除读取的两行,内核将不再检查特权端口。
Or patch your kernel and remove the check.
(Option of last resort, not recommended).
In
net/ipv4/af_inet.c
, remove the two lines that readand the kernel won't check privileged ports anymore.
标准方法是让它们“setuid”,以便它们以 root 身份启动,然后在绑定到端口后但在开始接受与其连接之前就放弃 root 特权。 您可以在 Apache 和 INN 的源代码中看到很好的示例。 我听说 Lighttpd 是另一个很好的例子。
另一个例子是 Postfix,它使用多个通过管道进行通信的守护进程,并且只有其中一两个(除了接受或发出字节之外几乎不执行任何操作)以 root 身份运行,其余的以较低权限运行。
The standard way is to make them "setuid" so that they start up as root, and then they throw away that root privilege as soon as they've bound to the port but before they start accepting connections to it. You can see good examples of that in the source code for Apache and INN. I'm told that Lighttpd is another good example.
Another example is Postfix, which uses multiple daemons that communicate through pipes, and only one or two of them (which do very little except accept or emit bytes) run as root and the rest run at a lower privilege.
现代 Linux 支持
/sbin/sysctl -w net.ipv4.ip_unprivileged_port_start=0
。Modern Linux supports
/sbin/sysctl -w net.ipv4.ip_unprivileged_port_start=0
.您可以设置本地 SSH 隧道,例如,如果您希望端口 80 访问绑定到 3000 的应用程序:
这具有使用脚本服务器的优点,并且非常简单。
You can setup a local SSH tunnel, eg if you want port 80 to hit your app bound to 3000:
This has the advantage of working with script servers, and being very simple.
我知道这是一个老问题,但现在有了最近的(> = 4.3)内核,终于有了一个很好的答案 - 环境功能。
快速的答案是获取最新(尚未发布)版本的 libcap 来自 git 并编译它。 将生成的
progs/capsh
二进制文件复制到某处(/usr/local/bin
是一个不错的选择)。 然后,以 root 身份启动您的程序。 按顺序,我们
cap_net_bind_service
功能添加到继承的 & 环境设置--
之后的参数启动 bash)Forking
bash -c 'your-command'
(因为capsh
自动使用 在这里的引擎盖下。首先,我们以 root 身份运行,因此默认情况下,我们可以获得全套功能。 其中包括切换 uid 和 uid 的能力。 gid 与
setuid
和setgid
系统调用。 然而,通常当程序执行此操作时,它会失去其功能集 - 这样一来,使用setuid
删除 root 的旧方法仍然有效。--keep=1
标志告诉capsh
发出prctl(PR_SET_KEEPCAPS)
系统调用,这会在更改用户时禁止删除功能。capsh
对用户的实际更改是通过--user
标志进行的,该标志运行setuid
和setgid
。我们需要解决的下一个问题是如何以在我们
exec
子项之后继续执行的方式设置功能。 功能系统始终具有一组“继承”的功能,即“跨 execve(2) 保留的一组功能”[功能(7)]。 虽然这听起来像是解决了我们的问题(只需将 cap_net_bind_service 功能设置为继承,对吧?),但这实际上仅适用于特权进程 - 并且我们的进程不再是特权进程,因为我们已经更改了用户(与--user
标志)。新的环境功能集解决了这个问题 - 它是“在非特权程序的 execve(2) 中保留的一组功能”。 通过将
cap_net_bind_service
放入环境集中,当capsh
exec 是我们的服务器程序时,我们的程序将继承此功能并能够将侦听器绑定到低端口。如果您有兴趣了解更多信息,请参阅功能手册页对此进行了非常详细的解释。 通过
strace
运行capsh
也能提供非常丰富的信息!I know this is an old question, but now with recent (>= 4.3) kernels there is finally a good answer to this - ambient capabilities.
The quick answer is to grab a copy of the latest (as-yet-unreleased) version of libcap from git and compile it. Copy the resulting
progs/capsh
binary somewhere (/usr/local/bin
is a good choice). Then, as root, start your program withIn order, we are
cap_net_bind_service
capability to the inherited & ambient setsbash -c 'your-command'
(sincecapsh
automatically starts bash with the arguments after--
)There's a lot going on under the hood here.
Firstly, we are running as root, so by default, we get a full set of capabilities. Included in this is the ability to switch uid & gid with the
setuid
andsetgid
syscalls. However, ordinarily when a program does this, it loses its set of capabilities - this is so that the old way of dropping root withsetuid
still works. The--keep=1
flag tellscapsh
to issue theprctl(PR_SET_KEEPCAPS)
syscall, which disables the dropping of capabilities when changing user. The actual changing of users bycapsh
happens with the--user
flag, which runssetuid
andsetgid
.The next problem we need to solve is how to set capabilities in a way that carries on after we
exec
our children. The capabilities system has always had an 'inherited' set of capabilities, which is " a set of capabilities preserved across an execve(2)" [capabilities(7)]. Whilst this sounds like it solves our problem (just set thecap_net_bind_service
capability to inherited, right?), this actually only applies for privileged processes - and our process is not privileged anymore, because we already changed user (with the--user
flag).The new ambient capability set works around this problem - it is "a set of capabilities that are preserved across an execve(2) of a program that is not privileged." By putting
cap_net_bind_service
in the ambient set, whencapsh
exec's our server program, our program will inherit this capability and be able to bind listeners to low ports.If you're interested to learn more, the capabilities manual page explains this in great detail. Running
capsh
throughstrace
is also very informative!文件功能并不理想,因为它们可能会在软件包更新后中断。
恕我直言,理想的解决方案应该能够创建具有可继承的 CAP_NET_BIND_SERVICE 集的 shell。
下面是一个有点复杂的方法:
capsh 实用程序可以在 Debian/Ubuntu 发行版的 libcap2-bin 包中找到。 发生的情况如下:
sg
将有效组 ID 更改为守护程序用户的 ID。 这是必要的,因为capsh
使 GID 保持不变,而我们绝对不希望如此。$DAEMONUSER
--keep=1
,所有大写字母仍然存在),可继承的cap_net_bind_service
除外结果是具有指定用户和组以及
cap_net_bind_service
权限的进程。例如,
ejabberd
启动脚本中的一行:File capabilities are not ideal, because they can break after a package update.
The ideal solution, IMHO, should be an ability to create a shell with inheritable
CAP_NET_BIND_SERVICE
set.Here's a somewhat convoluted way to do this:
capsh
utility can be found in libcap2-bin package in Debian/Ubuntu distributions. Here's what goes on:sg
changes effective group ID to that of the daemon user. This is necessary becausecapsh
leaves GID unchanged and we definitely do not want it.$DAEMONUSER
--keep=1
), except inheritablecap_net_bind_service
The result is a process with specified user and group, and
cap_net_bind_service
privileges.As an example, a line from
ejabberd
startup script:我的“标准解决方法”使用 socat 作为用户空间重定向器:
请注意,这不会扩展,分叉很昂贵,但这就是 socat 的工作方式。
My "standard workaround" uses socat as the user-space redirector:
Beware that this won't scale, forking is expensive but it's the way socat works.
TLDR:对于“答案”(据我所知),请跳至>>TLDR<<
好吧,我已经弄清楚了(这次是真的),这个问题的答案,我的这个答案也是对推广 另一个答案(在这里和推特上)我认为是“最好的”,但在尝试之后,发现我错了那。 孩子们,从我的错误中吸取教训:在您亲自尝试过某件事之前,不要推广它!
我再次回顾了这里的所有答案。 我已经尝试了其中的一些(并选择不尝试其他解决方案,因为我根本不喜欢这些解决方案)。 我认为解决方案是使用
systemd
及其Capability=
和CapabilityBindingSet=
设置。 经过一段时间的研究,我发现这不是解决方案因为:功能旨在限制根进程!
作为OP明智地说,最好总是避免这种情况(如果可能的话,对于所有守护进程!)。
您不能在
systemd
单元文件中使用与User=
和Group=
相关的功能选项,因为功能始终当调用 execev (或任何函数)时重置。 换句话说,当 systemd 分叉并放弃其权限时,功能将被重置。 没有办法解决这个问题,内核中的所有绑定逻辑都是围绕 uid=0 的,而不是功能。 这意味着能力不太可能成为这个问题的正确答案(至少在短期内)。 顺便说一句,正如其他人提到的,setcap 不是一个解决方案。 它对我不起作用,它不能很好地与脚本一起工作,并且每当文件更改时这些脚本都会重置。在我微薄的辩护中,我确实声明了(在我现已删除的评论中)詹姆斯的 iptables 建议(其中OP还提到),是“第二最佳解决方案”。 :-P
>>TLDR<<
解决方案是将
systemd
与即时iptables 命令,如下所示(取自 DNSChain):
此处我们完成以下任务:
systemd
为我们清理防火墙规则,确保在守护进程未运行时将其删除。uid=0
,我们也无法进行权限升级(至少systemd
声称如此)。不幸的是,iptables 仍然是一个相当丑陋且难以使用的实用程序。 例如,如果守护进程正在侦听
eth0:0
而不是eth0
,则命令为 略有不同。TLDR: For "the answer" (as I see it), jump down to the >>TLDR<< part in this answer.
OK, I've figured it out (for real this time), the answer to this question, and this answer of mine is also a way of apologizing for promoting another answer (both here and on twitter) that I thought was "the best", but after trying it, discovered that I was mistaken about that. Learn from my mistake kids: don't promote something until you've actually tried it yourself!
Again, I reviewed all the answers here. I've tried some of them (and chose not to try others because I simply didn't like the solutions). I thought that the solution was to use
systemd
with itsCapabilities=
andCapabilitiesBindingSet=
settings. After wrestling with this for some time, I discovered that this is not the solution because:Capabilities are intended to restrict root processes!
As the OP wisely stated, it is always best to avoid that (for all your daemons if possible!).
You cannot use the Capabilities related options with
User=
andGroup=
insystemd
unit files, because capabilities are ALWAYS reset whenexecev
(or whatever the function is) is called. In other words, whensystemd
forks and drops its perms, the capabilities are reset. There is no way around this, and all that binding logic in the kernel is basic around uid=0, not capabilities. This means that it is unlikely that Capabilities will ever be the right answer to this question (at least any time soon). Incidentally,setcap
, as others have mentioned, is not a solution. It didn't work for me, it doesn't work nicely with scripts, and those are reset anyways whenever the file changes.In my meager defense, I did state (in the comment I've now deleted), that James' iptables suggestion (which the OP also mentions), was the "2nd best solution". :-P
>>TLDR<<
The solution is to combine
systemd
with on-the-flyiptables
commands, like this (taken from DNSChain):Here we accomplish the following:
iptables
systemd
cleans up the firewall rules for us, making sure to remove them when the daemon isn't running.systemd
claims to), supposedly even if the daemon is compromised and setsuid=0
.iptables
is still, unfortunately, quite an ugly and difficult-to-use utility. If the daemon is listening oneth0:0
instead ofeth0
, for example, the commands are slightly different.另外两个简单的可能性:守护进程和代理
守护进程
对于“守护进程”,有一种古老的(不流行的)解决方案“绑定在低端口上的守护进程,并将控制权交给您的服务器”。守护进程”。 它称为 inetd(或 xinetd)。
缺点是:
优点:
进程
。 >更强大)从特权端口到可以运行目标守护程序的任意高编号端口。 (Netcat 显然不是一个生产解决方案,而是“只是我的开发盒”,对吧?)。 这样您就可以继续使用服务器的支持网络的版本,只需要 root/sudo 来启动代理(在启动时),而不会依赖于复杂/可能脆弱的功能。
Two other simple possibilities: Daemon and Proxy
Daemon
There is an old (unfashionable) solution to the "a daemon that binds on a low port and hands control to your daemon". It's called inetd (or xinetd).
The cons are:
Pros:
Proxy
Another alternative: a hacked-up proxy (
netcat
or even something more robust) from the privileged port to some arbitrary high-numbered port where you can run your target daemon. (Netcat is obviously not a production solution, but "just my dev box", right?). This way you could continue to use a network-capable version of your server, would only need root/sudo to start proxy (at boot), wouldn't be relying on complex/potentially fragile capabilities.Linux 支持功能来支持更细粒度的权限,而不仅仅是“此应用程序以 root 身份运行” 。 其中一项功能是
CAP_NET_BIND_SERVICE
,它与绑定到特权端口(<1024)有关。不幸的是,我不知道如何利用它来以非 root 身份运行应用程序,同时仍然为其提供 CAP_NET_BIND_SERVICE(可能使用
setcap
,但肯定有一个现有的解决方案)。Linux supports capabilities to support more fine-grained permissions than just "this application is run as root". One of those capabilities is
CAP_NET_BIND_SERVICE
which is about binding to a privileged port (<1024).Unfortunately I don't know how to exploit that to run an application as non-root while still giving it
CAP_NET_BIND_SERVICE
(probably usingsetcap
, but there's bound to be an existing solution for this).systemd 是 sysvinit 的替代品,它可以选择启动具有特定功能的守护进程。 systemd.exec(5) 联机帮助页中的选项 Capability=、CapabilityBoundingSet=。
systemd is a sysvinit replacement which has an option to launch a daemon with specific capabilities. Options Capabilities=, CapabilityBoundingSet= in systemd.exec(5) manpage.
使用 systemd,您只需稍微修改您的服务即可接受预激活的套接字。
您稍后可以使用 systemd 套接字激活。
不需要任何功能、iptables 或其他技巧。
示例中相关 systemd 文件的内容
这是简单 python http 服务器文件
httpd- true.service
文件
httpd-true.socket
With systemd, you just need to slightly modify your service to accept preactivated sockets.
You can later use systemd socket activate.
No capabilities, iptables or other tricks are needed.
This is content of relevant systemd files from this example of simple python http server
File
httpd-true.service
File
httpd-true.socket
端口重定向对我们来说最有意义,但我们遇到了一个问题,即我们的应用程序将在本地解析也需要重新路由的 URL; (这意味着您shindig)。
这也将允许您在访问本地计算机上的 url 时进行重定向。
Port redirect made the most sense for us, but we ran into an issue where our application would resolve a url locally that also needed to be re-routed; (that means you shindig).
This will also allow you to be redirected when accessing the url on the local machine.
启动时:
然后您可以绑定到您转发到的端口。
At startup:
Then you can bind to the port you forward to.
还有“djb 方式”。 您可以使用此方法以 root 身份启动进程,并在 tcpserver 下的任何端口上运行,然后在进程启动后立即将进程的控制权交给您指定的用户。
有关详细信息,请参阅:http://thedjbway.b0llix.net/daemontools/uidgid.html< /a>
There is also the 'djb way'. You can use this method to start your process as root running on any port under tcpserver, then it will hand control of the process to the user you specify immediately after the process starts.
For more info, see: http://thedjbway.b0llix.net/daemontools/uidgid.html
将8080端口绑定到80并打开80端口:
然后以普通用户身份在8080端口运行程序。
然后您将能够在端口
80
上访问http://127.0.0.1
Bind port 8080 to 80 and open port 80:
and then run program on port 8080 as a normal user.
you will then be able to access
http://127.0.0.1
on port80
使用 privbind 实用程序:它允许绑定到保留端口的非特权应用程序。
Use the privbind utility: it allows an unprivileged application to bind to reserved ports.
我尝试了 iptables PREROUTING REDIRECT 方法。 在较旧的内核中,IPv6 似乎不支持这种类型的规则。 但显然现在 ip6tables v1.4.18 和 Linux kernel v3.8 支持它。
我还发现 PREROUTING REDIRECT 不适用于机器内发起的连接。 要从本地计算机进行连接,还需要添加 OUTPUT 规则 - 请参阅 iptables 端口重定向不适用于 localhost。 例如:
我还发现 PREROUTING REDIRECT 也会影响转发的数据包。 也就是说,如果机器还在接口之间转发数据包(例如,如果它充当连接到以太网的 Wi-Fi 接入点),则 iptables 规则还将捕获已连接客户端到 Internet 目的地的连接,并将它们重定向到机器。 这不是我想要的 - 我只想重定向定向到机器本身的连接。 我发现通过添加 -m addrtype --dst-type LOCAL 可以使其仅影响发送到该盒子的数据包。 例如:
另一种可能性是使用 TCP 端口转发。 例如,使用socat:
然而,该方法的一个缺点是,在端口8080 上侦听的应用程序不知道传入连接的源地址(例如,用于日志记录或其他识别目的)。
I tried the iptables PREROUTING REDIRECT method. In older kernels it seems this type of rule wasn't supported for IPv6. But apparently it is now supported in ip6tables v1.4.18 and Linux kernel v3.8.
I also found that PREROUTING REDIRECT doesn't work for connections initiated within the machine. To work for conections from the local machine, add an OUTPUT rule also — see iptables port redirect not working for localhost. E.g. something like:
I also found that PREROUTING REDIRECT also affects forwarded packets. That is, if the machine is also forwarding packets between interfaces (e.g. if it's acting as a Wi-Fi access point connected to an Ethernet network), then the iptables rule will also catch connected clients' connections to Internet destinations, and redirect them to the machine. That's not what I wanted—I only wanted to redirect connections that were directed to the machine itself. I found I can make it only affect packets addressed to the box, by adding
-m addrtype --dst-type LOCAL
. E.g. something like:One other possibility is to use TCP port forwarding. E.g. using
socat
:However one disadvantage with that method is, the application that is listening on port 8080 then doesn't know the source address of incoming connections (e.g. for logging or other identification purposes).
由于 OP 只是开发/测试,不太流畅的解决方案可能会有所帮助:
可以在脚本的解释器上使用 setcap 来向脚本授予功能。 如果全局解释器二进制文件上的 setcaps 不可接受,请制作二进制文件的本地副本(任何用户都可以)并获得 root 权限以在此副本上进行 setcap。 Python2(至少)可以与脚本开发树中解释器的本地副本一起正常工作。 不需要 suid,因此 root 用户可以控制用户有权访问的功能。
如果您需要跟踪解释器的系统范围更新,请使用如下所示的 shell 脚本来运行脚本:
Since the OP is just development/testing, less than sleek solutions may be helpful:
setcap
can be used on a script's interpreter to grant capabilities to scripts. If setcaps on the global interpreter binary is not acceptable, make a local copy of the binary (any user can) and get root to setcap on this copy. Python2 (at least) works properly with a local copy of the interpreter in your script development tree. No suid is needed so the root user can control to what capabilities users have access.If you need to track system-wide updates to the interpreter, use a shell script like the following to run your script:
2015 年 9 月回答:
ip6tables 现在支持 IPV6 NAT:http ://www.netfilter.org/projects/iptables/files/changes-iptables-1.4.17.txt
您将需要内核 3.7+
证明:
Answer at 2015/Sep:
ip6tables now supports IPV6 NAT: http://www.netfilter.org/projects/iptables/files/changes-iptables-1.4.17.txt
You will need kernel 3.7+
Proof:
有一个使用支持文件的共享库执行此操作的有效示例链接到 libcap 网站上的非特权应用程序。 最近在有关向共享库添加功能的问题的回答中提到了这一点。
There is a worked example of doing this with a file capable shared library linked to an unprivileged application on the libcap website. It was recently mentioned in an answer to a question about adding capabilities to shared libraries.