我需要在基于 CentOS 7.5 的系统上运行某个应用程序。该应用程序需要绑定到端口 389 才能公开 ldap 服务。该应用程序由 SystemD 运行,但无法启动,因为我必须用于运行该应用程序的用户不允许绑定到低于 1024 的端口。我已经尝试过,setcap 'cap_net_bind_service=+ep' /opt/jdk8/bin/java
但在此之后 Java 甚至无法启动。
我已经见过基于 iptables 转发、ssh 隧道等的解决方案。我必须使用的系统不允许所有这些“魔法”。我想这同样适用于setcap
.
我可以在 SystemD 中使用一些设置吗?我确信它可以以某种方式完成,因为我必须使用同一用户nginx
在端口上运行80
并且它可以工作。
由于我没有应用程序的源代码,我无法更改它打开端口的方式。
答案1
如果您可以为 java(或任何使用动态库的东西)提供提升的功能,那么攻击者就可以切换库来获得功能。
一个办法
编写一个最小的 C 程序(静态链接),让它打开端口,并将其附加到文件描述符 3。然后执行 java 程序。 java 程序必须执行 fdopen,以使其从 java 的角度看起来像一个文件 ( open "/dev/fd/3"
) 这个包装器需要这些功能。
答案2
您可以在这里使用许多解决方案,因为您使用的是 systemd,这似乎是可行的方法,使用ListenStream
:
$ cat /etc/systemd/system/gitea.socket
[Unit]
Description=Gitea socket
[Socket]
ListenStream=80
NoDelay=true
然后,一旦定义了.socket
文件,就可以像这样使用它来定义单元文件:
[Unit]
Description=Gitea (Git with a cup of tea)
Requires=gitea.socket
After=syslog.target
After=network.target
After=postgresql.service
[Service]
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/home/git/go/src/code.gitea.io/gitea
ExecStart=/home/git/go/src/code.gitea.io/gitea/gitea web
Restart=always
Environment=USER=git HOME=/home/git
NonBlocking=true
[Install]
WantedBy=multi-user.target