I wanted to try socket activation with Systemd and Java on my ubuntu server 16.04. My idea is to make my program able to open directly a standard socket number with a user that is not root.

I currently use the iptable NAT rules, but I wanted to put it away after reading [the article of liquidat](https://liquidat.wordpress.com/2018/01/04/howto-run-programs-as-non-root-user-on-privileged-ports-via-systemd/) and this one from [Pid Eins](http://0pointer.de/blog/projects/socket-activation.html), 

My test environement is pretty simple. I've got the following java program :

```
package com.test.bindTCP;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class App 
{

private static void acceptConnection(ServerSocket serverSocket) {
    while (true) {
        try (
                Socket clientSocket = serverSocket.accept();
                PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
                BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        ) {
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                out.println(inputLine);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public static void main( String[] args )
{
    int portNumber = Integer.parseInt(args[0]);
    try (
        ServerSocket serverSocket = new ServerSocket(portNumber);
    ) {
        acceptConnection(serverSocket);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

```

I can call it though the following command line : 
`java -cp target/bindTCP-1.0-SNAPSHOT.jar com.test.bindTCP.App 60606`

It echoes all commands sent though tcp, it's able to serve only one client at time. I tested with "nc" and it work properly on socket upper than 1000. 

To set my systemd deamon, I wrote the following config files :

`cat /lib/systemd/system/bindTCP.socket`

```
[Unit]
Description=bindTCP Java 23

[Socket]
ListenStream=23

```

`cat /lib/systemd/system/bindTCP.service`

```
[Unit]
Description=bindTCP service
Requires=bindTCP.socket
After=syslog.target
After=network.target

[Service]
User=mylogin
Group=mygroup

ExecStart=/usr/lib/jvm/oracle-java8-jdk-amd64/bin/java  -cp /home/mylogin/bindTCP-1.0-SNAPSHOT.jar com.test.bindTCP.App 23
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=bindTCP
Restart=always

[Install]
WantedBy=multi-user.target

```

`cat /etc/rsyslog.d/bindTCP.conf`

```
$template bindTCPlog,"%msg%\n"
if $programname == 'bindTCP' then /var/log/bindTCP.log;bindTCPlog
if $programname == 'bindTCP' then stop

```

Then I reload my systemctl config :
`sudo systemctl daemon-reload`

I restart rsyslog deamon :
`sudo systemctl restart rsyslog`

And then, I try to start my own service 
`sudo systemctl start bindTCP`

But it doen't work, in my log (`/var/log/bindTCP.log`), I found the following java stacktrace 

```
 java.net.BindException: Permission denied (Bind failed)
    at java.net.PlainSocketImpl.socketBind(Native Method)
    at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
    at java.net.ServerSocket.bind(ServerSocket.java:375)
    at java.net.ServerSocket.<init>(ServerSocket.java:237)
    at java.net.ServerSocket.<init>(ServerSocket.java:128)
    at com.test.bindTCP.App.main(App.java:38)  

```

Any idea how to setup my service properly ?

EDIT: [A solution based on authbind](https://stackoverflow.com/questions/413807/is-there-a-way-for-non-root-processes-to-bind-to-privileged-ports-on-linux#answer-27989419) is working. The one proposed with setcap 'cap\_net\_bind\_service=+ep' doesn't change anything. Clearly systemd is able to deal with this issue, so I'm still looking for a solution 100% based on Systemd. I'm thinking is more secure.