I am working on RedHat7.5.
I made a systemd socket (/etc/systemd/system/barfoo.socket):
[Unit]
Description=This is the barfoo socket
[Socket]
ListenStream=0.0.0.0:123
NoDelay=true
BindIPv6Only=both
For learners: BindIPv6Only=both opens the port for IPv6 and IPv4. The format ListenStream=0.0.0.0:123 opens the port explicitly for IPv4.
and a corresponding systemd service (/etc/systemd/system/barfoo.service):
For learners: It is important that the service file and the socket file have the same name
[Unit]
Description=This is the barfoo service
Requires=barfoo.socket
[Service]
RestartSec=2s
User=installation
Group=installation
ExecStart=/home/installation/tests/a.out
Restart=always
[Install]
WantedBy=multi-user.target
For learners: "Requires=barfoo.socket" makes the socket available to this service. RestartSec and Restart will make the service restarted every 2 seconds (after exit). User and Group make the service run with the privileges of installation. ExecStart is the actual binary to start.
I also made a small test program (test.c):
#include<stdio.h>
#include<arpa/inet.h>
int main()
{
int server = socket(AF_INET, SOCK_STREAM, 0);
if (server < 0)
printf("Error in server creating\n");
else
printf("Server Created\n");
struct sockaddr_in my_addr, peer_addr;
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = INADDR_ANY;
my_addr.sin_addr.s_addr = inet_addr("10.0.1.10");
int b = 1, i = 123;
my_addr.sin_port = htons(i);
b = bind(server, (struct sockaddr*) &my_addr, sizeof(my_addr));
if(b)
printf("Error binding to port %d, return %d\n", i, b);
else
printf("Bound to port %d, return %d\n", i, b);
return 0;
}
Then I did:
gcc test.c
(which creates a.out)systemctl daemon-reload
(which makes systemd read my barfoo files)systemctl start barfoo
When I do netstat -tulpen
I can see that systemd has opened the port. But the service (a.out) returns always "Error binding to port...".
The idea is to make the port 123 available to a program which is running with non-root privileges. Normally ports below 1024 are only available to root.
My Question is: Why is it not working/ What am I doing wrong?