我正在尝试以root身份启动https端口443,然后使用嵌入式jetty降级到非root用户。我经历了 https://www.eclipse.org/jetty/documentation/current/setting-port80-access.html#configuring-jetty-setuid-feature 但是没有从java程序中获得任何解决方案。
这是嵌入式码头代码:
package com.jetty.startup;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.annotations.ServletContainerInitializersStarter;
import org.eclipse.jetty.apache.jsp.JettyJasperInitializer;
import org.eclipse.jetty.plus.annotation.ContainerInitializer;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.apache.log4j.Logger;
import org.eclipse.jetty.setuid.*;
/**
* Handles Webapp server's serviice
*
*
*/
class MyServer {
private static Logger logger = Logger.getLogger(MyServer.class);
private static Server server;
private String jettyHome;
/**
* Creates an instance of {@link MyServer}
*
* @param jettyHome
* jetty home path
*/
public MyServer(String jettyHome) {
this.jettyHome = jettyHome;
}
/**
* Initializes Webapp server:
*
*/
public Server init() throws Exception {
server = new Server();
int httpsPort = 443;
String keyStoreFile = "/home/jetty/webserver/etc/keystore";
String keyStorePassword = "secret";
String keyManagerPassword = "secret";
String trustStorePassword = "secret";
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(keyStoreFile);
sslContextFactory.setKeyStoreType("JKS");
sslContextFactory.setKeyStorePassword(keyStorePassword);
sslContextFactory.setKeyManagerPassword(keyManagerPassword);
SetUIDListener set = new SetUIDListener();
set.setStartServerAsPrivileged(true);
set.setUsername("jetty");
set.setGroupname("jetty");
set.setUmask(002);
server.addLifeCycleListener(set);
HttpConfiguration httpConfiguration = new HttpConfiguration();
httpConfiguration.setSecurePort(httpsPort);
httpConfiguration.setSecureScheme("https");
httpConfiguration.addCustomizer(new SecureRequestCustomizer());
ServerConnector serverConnector = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory, "http/1.1"),
new HttpConnectionFactory(httpConfiguration));
serverConnector.setPort(httpsPort);
server.setConnectors(new Connector[] { serverConnector });
WebAppContext myContext = new WebAppContext();
myContext.setContextPath("/myapp");
myContext.setWar(jettyHome + "/webapps/myapp/");
myContext.setDefaultsDescriptor(jettyHome + "/etc/webdefault.xml");
File overrideFile = new File(jettyHome
+ "/webapps/myapp/WEB-INF/generated-web.xml");
if (overrideFile.exists()) {
myContext.setOverrideDescriptor(jettyHome
+ "/webapps/myapp/WEB-INF/generated-web.xml");
}
server.setHandler(myContext);
JettyJasperInitializer sci = new JettyJasperInitializer();
ServletContainerInitializersStarter sciStarter =
new ServletContainerInitializersStarter(myContext);
ContainerInitializer initializer = new ContainerInitializer(sci, null);
List<ContainerInitializer> initializers = new ArrayList<>();
initializers.add(initializer);
myContext.setAttribute("org.eclipse.jetty.containerInitializers", initializers);
myContext.addBean(sciStarter, true);
ContextHandlerCollection contexts = new ContextHandlerCollection();
contexts.setHandlers(new Handler[] { myContext });
server.setHandler(contexts);
return server;
}
public static void main(String args[]) {
String jetty_home = "/home/jetty/webServer";
MyServer myServer = new MyServer(jetty_home);
try {
server = myServer.init();
server.start();
} catch (Exception excp) {
}
}
}
至于libsetuid-linux.so我已经使用mvn clean install
项目中的jetty-setuid
创建了它的原生版本。
如果httpsPort = 2400
那么这是日志文件的详细信息:
记录
2016-02-11 15:36:16.413:INFO::main: Logging initialized @2424ms
2016-02-11 15:36:16.593:INFO:oejs.SetUIDListener:main: Setting umask=02
2016-02-11 15:36:16.603:INFO:oejs.SetUIDListener:main: Opened ServerConnector@b96fde{SSL,[ssl, http/1.1]}{0.0.0.0:2400}
2016-02-11 15:36:16.603:INFO:oejs.SetUIDListener:main: Setting GID=504
2016-02-11 15:36:16.676:INFO:oejs.SetUIDListener:main: Setting UID=504
2016-02-11 15:36:16.680:INFO:oejs.Server:main: jetty-9.3.7.v20160115
而当httpsPort = 443
这就是日志文件的外观:
记录
2016-02-11 15:37:35.049:INFO::main: Logging initialized @2199ms
2016-02-11 15:37:35.228:INFO:oejs.SetUIDListener:main: Setting umask=02
在此日志之后没有任何事情发生,并且webapp也无法正常工作。
答案 0 :(得分:1)
这最终是一个操作系统权限问题,您需要一种解决方法。
这意味着您提出的任何解决方案也将是特定于操作系统的
一个例子是使用jetty-setuid-java
工件和适当的jetty-setuid-native
库来完成此任务。
在开始这项工作之前,请确保您完全了解setuid在所需操作系统上的功能
至于启用jetty setuid特定部分,您可以使用XmlConfiguration
将适当的生命周期监听器注入Server
,或者您可以完全使用代码。
请向Jetty Distribution&#39; etc/jetty-setuid.xml
寻求帮助。
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
"http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ================================================================ -->
<!-- Configure the Jetty SetUIDListener -->
<!-- ================================================================ -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addLifeCycleListener">
<Arg>
<New class="org.eclipse.jetty.setuid.SetUIDListener">
<Set name="startServerAsPrivileged">false</Set>
<Set name="umaskOctal">002</Set>
<Set name="username">jetty</Set>
<Set name="groupname">jetty</Set>
<!-- uncomment to change the limits on number of open file descriptors for root -->
<!--
<Call name="setRLimitNoFiles">
<Arg>
<New class="org.eclipse.jetty.setuid.RLimit">
<Set name="soft">20000</Set>
<Set name="hard">40000</Set>
</New>
</Arg>
</Call>
-->
</New>
</Arg>
</Call>
</Configure>
答案 1 :(得分:1)
最后,我能够通过为32位创建一个libsetuid-linux.so来实现我在上述问题中提出的要求,这是一个随jetty-9.3.7提供的那个用于64位。
我是如何创建32位libsetuid-linux.so的?
此链接有助于http://www.eclipse.org/jetty/documentation/current/setting-port80-access.html 第5点是准确的
但不幸的是,jetty-setuid项目的链接已不再适用。
此外,sudo
必须使用sudo -E
完成。