Creating a service to be managed by xinted
super-server
Refer to the slide presentation entitled "socket demo."
[ Color-coding note: this exercise involves a client and a server machine.
Some commands below are to be executed on the client, others on the server, as
follows:
blue - on client
red - on server
1) prepare a directory to house the executable file that will perform the service:
mkdir /opt/socketdemo/
chmod 755 /opt/socketdemo/
cd /opt/socketdemo
2) we're going to set it up so this file gets executed by user "nobody," when run as a service for some remote client. First obtain the file with this command, or else per your instructor:
cp /home/public/byteme /opt/socketdemo
The byteme program is a simple script:
#!/bin/bash
/bin/echo "GIGA-BYTE ME!" | /usr/bin/tee /tmp/bytelog.txt
/bin/date >> /tmp/bytelog.txt
so you can read it and run it to note what it does. Do so:
cat byteme
chmod +x
byteme
./byteme
You are running it as an ordinary local program. But we are now going to install it as a managed service for xinetd to run when called upon by clients instead. Give byteme user and group ownership by "nobody," and permissions that let "nobody" read and execute it:
chown nobody.nobody /opt/socketdemo/byteme
chmod 500 /opt/socketdemo/byteme
3) the executable is written to employ a logfile. The logfile is /tmp/bytelog.txt. Create this file, give it user and group ownership by "nobody," and permissions that let "nobody" read and write it.
touch /tmp/bytelog.txt
chown nobody.nobody /tmp/bytelog.txt
chmod 600 /tmp/bytelog.txt
4) this program will need a port number. That number will be inserted in the /etc/services file, also in a configuration file for this service that we're going to place in /etc/xinetd.d/. We need to avoid choosing a port number already in use by some other service. Choose your number, then search for it in those two places. If you find it, move on to some other choice till you find a number that's unused. For example:
grep 54321 /etc/services
5) xinetd will need a name by which to know this service. Use "chomper." Reflect the new service in /etc/services by adding the appropriate line, "chomper 54321/tcp". Use an editor, or this command will do it:
sed -i '$a chomper 54321/tcp' /etc/services
Check the last few lines of the file to verify your new line is there:
tail /etc/services
Also reflect the new "chomper" name with a service configuration file under /etc/xinetd.d/. Obtain the "chomper" file with this command, or else per your instructor:
cp /home/public/chomper /etc/xinetd.d
cd /etc/xinetd.d/
cat chomper
Because file "chomper" contains a line reading "service chomper", it will map into the line in /etc/services that starts with "chomper..." followed by some port number (54321 in this example). That causes this service to pick up and utilize that port number. Edit /etc/xinetd.d/chomper to enable this service, by making sure you have "disable = no." Use an editor, or this command will do it:
sed
-i '/disable/s/yes/no/' /etc/xinetd.d/chomper
Check the file to verify the "disable" line says
"no":
cat chomper
6) restart xinetd, so that it will read its /etc/xinetd.d/chomper configuration file and make the changes take effect:
systemctl
restart xinetd
netstat -pant
netstat should show that xinetd is now listening on port 54321.
7) run byteme as a service from another station with nc ("net cat"):
nc <address of server> <port number you picked>
Observe the screen output on the client, and view the content of the log file on the server. Run it twice more, while at the server running tcpdump 2 different ways:
tcpdump -ti
enp0s3 [ I use
interface name "enp0s3" here; you please use the actual name of your
interface, which may differ. ]
tcpdump -nnti enp0s3
Note the difference in output, which is due to the change you made in /etc/services. tcpdump is one of many programs that perform lookups in that file.
8) transform byteme into an echo server. A managed server like byteme inherits the xinetd-provided network connection on its ordinary standard input and standard output. That is, xinetd gives the server as standard input whatever it takes in through the connection, and xinetd takes any standard output from the server and puts it out the connection. If the far-side client sends anything, it will reach the server's standard input. And if the server produces any standard output, the client will receive it (we've already seen the second part).
Modify byteme to absorb a line of its standard input into a variable, then echo that variable (instead of the constant "GIGA-BYTE ME!") to its standard output.
#!/bin/bash
read INCOMING
/bin/echo "$INCOMING" | /usr/bin/tee /tmp/bytelog.txt
/bin/date >> /tmp/bytelog.txt
Modify the client to actively send something:
echo hello | nc <address of server> <port number you picked>
Repeat, changing "hello" to "goodbye".
echo goodbye | nc <address of server> <port number you picked>
Repeat again, sending both words, separated by a newline:
echo -e "hello\ngoodbye" | nc <address of server> <port number you picked>
If you didn't get the full echo of everything you sent, modify the server again:
#!/bin/bash
while read INCOMING
do
/bin/echo "$INCOMING" | /usr/bin/tee /tmp/bytelog.txt
/bin/date >> /tmp/bytelog.txt
done
Try the previous command again:
echo -e "hello\ngoodbye" | nc <address of server> <port number you picked>
Now echo a whole lot of stuff:
nc <address of server> <port number you picked> < /etc/services
Anybody can use xinetd to start arbitrary special purpose servers. Servers can participate is full bi-directional use of the network connection as if they'd utilized the socket API directly, and they can be written in any language.
With the server on 164.67.79.151 and client on 164.67.79.150, here is the
network traffic captured by ethereal/wireshark on the server while running the
baseline byteme. Here is the same wireshark/tcpdump
capture file zipped for download, if you wish to load it into wireshark and examine
it live yourself (unzip first).