Hi Alexey/Ryan,
Here is a simple example. Below is the code for TestDaemon. If you compile
that, install jsvc (should be a package on most platforms), and run the
command as follows:
sudo jsvc -cp "PATH_TO_JAKARTKA_COMMONS_JAR:PATH_TO_TEST_DAEMON" -user
SOME_USER -outfile /tmp/out.log -errfile /tmp/err.log TestDaemon
then maybe try telnetting, then:
sudo jsvc -cp "PATH_TO_JAKARTKA_COMMONS_JAR:PATH_TO_TEST_DAEMON" -user
SOME_USER -outfile /tmp/out.log -errfile /tmp/err.log -stop TestDaemon
and then you look at the output of out.log:
[init()]
Binding to 80...
[start()]
Tried to bind to to test port 81 from start(), but failed! - "Permission
denied"
Accepting connections on 80...
Stopping....
exiting thread...
Destroying...
You can see that the server was able to bind to a privileged port in init,
but not in start. What I didnt fully understand is that JSVC appears to be
using Linux capabilities to pull all this off (CAP_NET_BIND_SERVICE).
Therefore, the danger of starting something from init is less than I
thought (I cant open a file owned and only readable by root, for example).
This little experiment has suggested I should probably talk to the JSVC
guys a bit more before you make any changes... Once I hear back more lets
continue this discussion.
Thanks for the really quick response!
- Scott
---------------------------------------------------------------------------------------
Source of TestDaemon.java:
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class TestDaemon {
private final ServerSocket socket;
private int port = 80;
private int testPort = 81;
private Thread thread = new Thread() {
@Override
public void run() {
while (true) {
Socket connection = null;
OutputStream stream = null;
try {
connection = socket.accept();
stream = connection.getOutputStream();
stream.write("Hello World!\r\n".getBytes());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (stream != null)
stream.close();
if (connection != null)
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (Thread.interrupted())
break;
}
System.out.println("exiting thread...");
}
};
public TestDaemon() throws Exception {
//unbound
socket = new ServerSocket();
}
public void init(String[] args) throws Exception {
System.out.println("[init()]");
System.out.println("Binding to " + port + "...");
socket.bind(new InetSocketAddress(port));
}
public void start() throws Exception {
System.out.println("[start()]");
try {
new ServerSocket(testPort);
} catch (Exception e) {
System.out.println("Tried to bind to to test port " + testPort + " from
start(), but failed! - \"" + e.getMessage() + "\"");
}
System.out.println("Accepting connections on " + port + "...");
thread.start();
}
public void stop() throws Exception {
System.out.println("Stopping....");
//close socket first to get out of blocking on accept
socket.close();
thread.interrupt();
thread.join();
}
public void destroy() {
System.out.println("Destroying...");
}
}
On Wed, Jul 10, 2013 at 5:34 PM, Oleksiy Stashok <oleksiy.stashok_at_oracle.com
> wrote:
> Hi Scott,
>
> it's not possible at the moment, but if you can provide more details on
> JSVC (based on your question, it should have some programmatic API),
> specifically how you think it should work with Grizzly HttpServer, may be
> some *fake* code, which will demonstrate that (I see you spent some time
> learning Grizzly code, so probably you have some ideas :)). We can try to
> implement this feature and include it into the 2.3.4 release (we're
> planning 2.3.4 release this week).
>
> Thank you.
>
> WBR,
> Alexey.
>
>
> On 10.07.13 13:41, mccluresc_at_gmail.com wrote:
>
>> Hi all,
>>
>> I am trying to use JSVC to bind to a privileged port while root, than
>> run the application as a separate user. This would require that I bind
>> the port separate from starting the server (accepting connections /
>> creating a thread pool, etc)
>>
>> The issue I am facing is in NetworkListener.start() - this call
>> combines the TCPNIOTransport.bind and the TCPNIOTransport.start.
>>
>> Additionally, it appears that TCPNIOTransport.bind also listens on the
>> port as well.
>>
>> Any suggestions on how to separate binding to the port from the rest of
>> the operations? Or alternatively, any suggestions on how to bind to
>> Grizzly a privileged port? Specifically - has anyone used authbind with
>> Grizzly?
>>
>> Thanks!
>> - Scott
>>
>
>