如何在Eclipse中以超级用户身份运行我的应用程序?

29

在Eclipse中尝试运行我的服务器应用程序时,我遇到了一个错误。错误信息是java.net.BindException: Permission denied。我认为这是因为我正在使用端口443来建立SSL连接。如果我在命令行上使用java和sudo运行代码,我可以解决这个问题。有没有办法在按下运行按钮时,设置Eclipse以sudo权限执行我的应用程序?


为什么javac需要sudo访问权限?您可能希望编辑问题以避免混淆。 - ring bearer
就像我在问题中所说的,我认为这是因为我正在尝试使用SSLServerSocket绑定到端口443。不过,我的想法可能是错误的。 - Ronald
如果我理解问题正确的话,Ronald使用javac进行编译,然后使用sudo执行。如果程序尝试绑定端口443,则可能会导致问题,因为在UNIX/Linux系统中,任何低于1024的端口号都保留供root访问。 - Zoltán Ujhelyi
是的,在Eclipse之外,我会执行以下操作:1)javac Server.java 2)sudo java Server。这个方法可以运行,但我想继续使用Eclipse,所以我需要找出如何让Eclipse以sudo身份运行应用程序。我开始觉得这是不可能的。 - Ronald
2
但问题不在于 javac,而在于java(可执行文件)。 - Bozho
9个回答

16
您可以按照以下步骤以超级用户身份编译/调试应用程序。
  1. Rename your java-application

    sudo mv /usr/lib/jvm/java-6-openjdk/jre/bin/java /usr/lib/jvm/java-6-openjdk/jre/bin/java.ori

  2. Create following script and store it as /usr/lib/jvm/java-6-openjdk/jre/bin/java

    #!/bin/bash
    # file:  /usr/lib/jvm/java-6-openjdk/jre/bin/java
    # descr: Starter for jdk. Runs jdk as root when 
    #        cmd-line-arg "--run-as-root" is specified.
    #
    jre="/usr/lib/jvm/java-6-openjdk/jre/bin/java.ori"
    run_as_root=false
    args=
    
    # Filter command-line argument
    for arg in "$@"
    do
      case "$arg" in
      --run-as-root)  run_as_root=true
                      ;;
      *)              args="$args $arg"
                      ;;
    
      esac
    done
    
    # Remove leading whitespaces
    args=$(echo $args | sed -e 's/^[ \t]*//')
    
    if $run_as_root
    then
      echo "WARNING: Running as root!"
      gksu "$jre $args"
    else
      $jre $args
    fi
    
  3. Change the permissions to make it executable

    sudo chmod 0755 /usr/lib/jvm/java-6-openjdk/jre/bin/java

  4. Startup eclipse

  5. Go to Window->Preferences->Java->Installed JREs
  6. Duplicate java-6-openjdk to java-6-openjdk-root
  7. Edit JRE and add "--run-as-root" as Default VM Argument
要以root身份运行项目,您需要按照以下步骤进行操作:
  1. 进入Project(项目)->Properties(属性)->Java Build Path(Java构建路径)
  2. 双击JRE System Library并在Alternate JRE(备选JRE)中选择“java-6-openjdk-root”

注意:这个想法来自http://www.eclipse.org/forums/index.php/mv/msg/87353/724852/#msg_724852


对于 Fedora 19,我通过使用 pkexec(不带双引号)而不是 gksu 来使其工作:pkexec $jre $args - Giuliano
嗨,我尝试了这种方法,但出现了以下错误: 无法识别的选项:--run-as-root 错误:无法创建Java虚拟机。 错误:发生致命异常。程序将退出。 有什么想法吗?谢谢。 - adrian.nicolau
@adrian.nicolau:请再次检查我的答案,并确保您按照描述的每个步骤进行操作。您提到的错误可能是因为您直接使用--run-as-root调用了jre,而不是使用bash脚本。 - rednammoc
很好!还要考虑在gksu中使用--message选项,否则您可能会得到一个包含非常长命令行的巨大对话框。 - Andrew Fielden
我对这个解决方案有两个问题:1.它会要求输入密码(还好);2.它在某个地方更改了我的项目设置,由于在原始相对路径中添加了“/root/”,因此找不到配置文件。我正在使用Fedora 20。 - 5YrsLaterDBA

2
假设您正在使用Linux (*nix),您可以通过sudo命令启动eclipse会话,比如:
sudo ~/eclipse/eclipse

现在你从Eclipse中进行的任何操作都将具有sudo上下文吗?

15
这是不可取的...也很危险。使用Eclipse编写的所有文件都将归属于root,更糟糕的是,由于Eclipse正在以root身份运行,它有权限读取、写入或删除任何文件或目录。如果修改或删除错误的文件,可能会带来严重后果。 - Stephen C
5
哎呀,那很疼。我原以为我已经完全回答了他所寻找的内容。当我在我的开发环境时,我不会为你提到的各种可能性而感到担忧。 - ring bearer
4
在以 sudo 模式运行 Eclipse 中还有一个问题是,如果您稍后想将 Eclipse 切换回非 sudo 模式,则会遇到各种问题,因为 Eclipse 将无法写入现在由 root 拥有的各种文件。这会导致 Eclipse 的未指定行为。 - Amit

1

此主题中所述:

在Unix / Linux系统中要打开低于1024的端口,您需要成为"root"。

我还使用了参数-Dorg.eclipse.equinox.http.jetty.port=8080来更改侦听端口,但是这似乎被忽略了(根据堆栈跟踪)

请使用"-Dorg.osgi.service.http.port=8080"。


根据HTTP Service中提到的内容:
  • org.osgi.service.http.port - 指定用于http服务的端口号。根据OSGi规范,此属性的默认值为80(需要root权限)。

  • org.osgi.service.http.port.secure - 指定用于安全http服务的端口号。根据OSGi规范,此属性的默认值为443(需要root权限)。

也许如果您尝试将最后一个属性修改为大于1024的值,就可以在不需要特殊权限的情况下运行。


1

另一个选择是使用iptables或ipfilter将端口80转发到1024以上的端口。

(有人可以提供一个实用且易于理解的解释链接吗?)


或者SSH:热爱本地加密隧道。 - kagali-san
1
这是一个使用iptables的实用链接: http://wiki.eclipse.org/Jetty/Howto/Port80 - djondal

1
也许更好的答案,并且如果这能满足你的需求并且可行,可以在你的路由器上进行简单的端口重定向。
在你只是开发而不是安装,并且想要在调试器中运行时,不要试图强制你的Linux/Unix打开一个保留端口,设置你的路由器将传入(外部)端口443重定向到更适合你当前需求的端口(比如4443)。
我认为大多数路由器都支持此功能,如果你的路由器不支持,那就给你妈妈一个好的圣诞节或生日礼物的建议吧!

哎呀,我刚才意识到上面有人提到了iptables...其实是一样的。抱歉,不是想抄袭你的想法! - Sean

1

我写的是 C 代码而不是 Java,但是这个方法在两种语言中都可以使用。 我使用远程调试 - 定义一个连接到 LOCALHOST 的 "remote" 连接,允许你指定连接的用户并指定 ROOT。然后在调试配置连接中定义一个远程应用程序:LOCALHOST。确保在主选项卡底部以及连接属性窗口下方勾选 "跳过下载到目标路径"。


1

您可以使用远程Java应用程序机制来实现此目的。

  1. 运行 -> 调试配置...中创建远程Java应用程序部分的调试配置
  2. 设置您的项目名称
  3. 选择连接类型为标准(Socket附加)
  4. 为您的绑定配置连接属性参数(对于您来说,它将是localhost443)。
  5. 在您的应用程序中设置断点(例如,在main方法的开头)
  6. 以超级用户身份从终端运行以下命令启动您的应用程序:java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=443 MyApp
  7. 点击Eclipse中早期创建的远程Java应用程序的调试按钮
  8. 您的代码应该在Eclipse上的断点处停止!

0

如果您使用外部工具(运行菜单/外部工具或工具栏上运行/调试图标旁边的图标),则可以使用任何脚本或其他内容。这些脚本可能会给您提供升级权限或其他功能。

另一方面,这种方式调试应用程序可能会变得非常困难,因为运行和调试命令都不会与此外部工具配置相关联。也许可以连接应用程序的Eclipse调试器,但我不知道如何实现。


0

你可以按照以下步骤进行:

  1. 创建一个包含javac调用的Makefile文件
  2. 添加以下代码行:
setcap 'cap_net_admin=+ep' Server
配置sudo以允许您的Eclipse用户运行setcap。 这样,您将拥有透明调试(无需sudo包装器-gdb可用)。 缺点:这是一种本地安全漏洞。
解决方案: 将此放置到/opt/my-stupid-eclipse #!/bin/sh setcap 'cap_net_admin=+ep cap_net_raw=+ep' $1
chmod +x此脚本,并在sudo配置中加入白名单。 username ALL=(ALL) NOPASSWD: /opt/my-stupid-eclipse 将其添加到您的makefile中,指定路径到您的服务器二进制文件。
现在您拥有了一个相当奇怪但安全的脚本,其他用户无法更改它... 仍然存在一些被替换为任何恶意代码的服务器二进制文件的小漏洞,这将获取caps,因此没有文件名检查/严格将有帮助.. $1是否可能被污染bash命令?我猜不会。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接