Connect to netcat through telnet and shut down computer - bash

I'm using the following bash script to start listening to connections on port 8585. When connected by telnet and sending the text "shutdown" I would like the host computer to shut down. As of now I'm using my mac.
#!/bin/bash
echo "Start listening on port 8585..."
while read line
do
if [ "$line" == 'shutdown' ]; then
# Execute shutdown now on the computer.
break
else
echo "$line"
fi
done < <((echo "Welcome.") | nc -k -l 8585)
echo "Good bye"
When I try to connect to it through telnet I just get this as response:
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Welcome.
Connection closed by foreign host.
Do any of you guys know why the connection gets closed straight away? Do you have any ideas?
I got the example code from here: https://askubuntu.com/questions/873788/bash-read-lines-from-netcat-connection#873794

Remove the (echo "Welcome.") |:
#!/bin/bash
echo "Start listening on port 8585..."
while read line
do
if [ "$line" == 'shutdown' ]; then
# Execute shutdown now on the computer.
break
else
echo "$line"
fi
done < <(nc -k -l 8585)
echo "Good bye"
Keep in mind that will only break the loop with the word shutdown but nc will continue listening

Related

How to adjust this bash script to run telnet commands successfully while being in SSH?

I am attempting to write a bash script that will do the following work flow:
Telnet into networked device via IP address on port 9100 telnet x.x.x.x 9100
Run SGD command ! U1 getvar \"internal_wired.ip.timeout.value\".
Expect output value of "10".
Here is the bash script I've written so far:
#!/bin/bash
IP=(x.x.x.x)
for i in ${IP}
do
echo " "
echo "Welcome! This script will check the timeout value of this networked device."
echo "The expected output should be `"10`". Let's get started!!"
echo " "
sleep 4
echo "5....."
sleep 1
echo "4...."
sleep 1
echo "3..."
sleep 1
echo "2.."
sleep 1
echo "1."
sleep 1
echo " "
telnet ${i} 9100 << END_SSH
sleep 5
getvar \"internal_wired.ip.timeout.value\"
sleep 5
END_SSH
done
When I run this script via bash mycode.sh, I get the following output in Terminal.app:
$ bash mycode.sh
Welcome! This script will check the timeout value of this networked device.
The expected output should be "10". Let's get started!!
5.....
4....
3...
2..
1.
Trying x.x.x.x...
Connected to x.x.x.x.
Escape character is '^]'.
Connection closed by foreign host.
[user#server ~]$
x.x.x.x is an IP placeholder just to add.
In theory, after the Escape character is '^]'. line, the script should have ran the ! U1 getvar "internal_wired.ip.timeout.value\" command.
Also, we should have had an expected output of "10".
When I first wrote this script, I initially did not have the END_SSH command in it. A colleague introduced that to me and said to wrap the telnet commands in the END_SSH because of how Terminal technically jumps out of SSH when you are in telnet. I've tried utilizing END_SSH, but am not successful.
How do I get the telnet command to run successfully and get the expected output value?
You misunderstand what "END_SSH" is. It's not a "command" - it's what's called "Here-document" in bash.
Essentially the text between the <<END_SSH and the END_SSH is a "here-document" that is piped into stdin of telnet ${i} 9100. So, the sleep 5 commands are never actually executed and the input reaches EOF before the connection is even established.
I don't know what exactly you are trying to accomplish, but I would guess that the following will work better. Oh, and what's with that weird IP=(x.x.x.x) declaration? Is that supposed to be an array?
#!/bin/bash
declare -a IP=(1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4)
for i in "${IP[#]}"; do
echo " "
echo "Welcome! This script will check the timeout value of this networked device."
echo "The expected output should be \"10\". Let's get started!!"
sleep 4
for j in {5..1}; do
echo $j
sleep 1
done
{ sleep 5; echo -n $'! U1 getvar "internal_wired.ip_timeout.value"\n'; sleep 5; } | telnet ${i} 9100
done
so here is what I suggest to use for the telnet part. Connect is a function being called later in a while loop, which will run over IPs ready from a file.
Connect()
{
(
sleep 10 # depending upon your network and device response, better to keep this first sleep value a little high
echo "command 1"
sleep 2
echo "command 2"
sleep 2
) | telnet $1 9100 | tee -a ${1}.log
}
while read -r IP
do
Connect $IP
done < filewithIPs

Bash script with netcat operations on different server and port

I am a bit lost. I have created a script which starts by retrieving data from a CSV file. Each line contains an IP address and a few ports to test. The goal is to verify that it is possible to connect to each server (under the given IP) on specifics ports. In order to verify, the following code is used:
nc -w 3 -v $ipValeur >> retour.txt 2>&1
Nevertheless, it doesn't work and it returns Connection Timed out. It is strange. In fact, if I launch a telnet command from a terminal, it works. Nevertheless, the goal is to check if a server can be connected to a lot of others. So, if telnet is used, it will be very long (one or two days ?)...
So, I am looking for a way which permits to automatically verify the access from one server to thirty others on a few ports. You can find the code which is actually used at How to continue next iteration when an error occurs in Bash.
Thank you for your help.
Solution
#!/bin/bash
INPUT_FILE=$1
while IFS='' read -r line || [ -n "$line" ]; do
IFS=';' read -ra cvsline <<<${line}
HOSTNAME=${cvsline[0]}
ports=("${cvsline[#]:1}")
for port in ${ports[*]}; do
echo -n "Verification ${HOSTNAME}:${port}..."
echo 'QUIT' | nc -w 3 -v "${HOSTNAME}" "${port}" >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "OK"
else
echo "KO"
fi
done
done < $INPUT_FILE
Vinz
The answer may be, that in command: nc -w 3 -v $ipValeur >> retour.txt 2>&1 you not passed port number, and was used default one all the times
I not really able to understand your source code, so i have written my own based on description:
#!/bin/bash
INPUT_FILE=$1
while IFS='' read -r line || [ -n "$line" ]; do
IFS=';' read -ra cvsline <<<${line}
HOSTNAME=${cvsline[0]}
ports=("${cvsline[#]:1}")
for port in ${ports[*]}; do
echo -n "Cheking ${HOSTNAME}:${port}..."
nc -zw 3 "${HOSTNAME}" "${port}" >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "connected"
else
echo "not connected"
fi
done
done < $INPUT_FILE
Usage:
./script hostlist.cvs
Where hostlist.cvs:
127.0.0.1;80;90;100;
127.0.0.2;80;88;21;
10.255.0.1;80;443;
And output sample:
$ ./test.sh /tmp/1
Cheking 127.0.0.1:80...not connected
Cheking 127.0.0.1:90...not connected
Cheking 127.0.0.1:100...not connected
Cheking 127.0.0.2:80...not connected
Cheking 127.0.0.2:88...not connected
Cheking 127.0.0.2:21...not connected
Cheking 10.255.0.1:80...connected
Cheking 10.255.0.1:443...not connected

How to check ssh availability if check ssh OK then connect to server 1 and if ssh NOT OK then connect to server 2?

I have 2 servers.
The first server is always active and the second server is always in the stanby state.
I'm trying to write a bash script to check the status of these two servers before doing the task.
If the first host dies (or the connect SSH to server 1 not OK) then it will connect SSH to the second host for execution to task.
Any idea on how to do it?
EDIT2: since OP mentioned that there is a file named IP.list from which server names should be read then following may help you here.
while read server
do
if [[ -n $(ssh user_name#"$server" "ls -ld /tmp") ]]
then
echo "$server is up."
echo "Exiting from script now.."
exit;
else
echo "$server is NOT up, look for another server."
fi
done < "IP.txt"
EDIT: Since OP is saying ping is not an option to check server's availability then using ssh only for servers. Considering that your source server(from where you are running the script) and target server(whose status you are checking are having passwordless connection between them so that you will NOT be prompted for any password)
if [[ -n $(ssh user_name#server_name "ls -ld /tmp") ]]
then
echo "Server 1 is up."
else
echo "Server is NOT up, look for another server."
fi
You could simple do ping to SERVER1 and see if that is happening successfully in case it not it means server is not up and you could move your things to another stand up server.
if [[ $(ping -c5 SERVER1 | grep -q "5 packets transmitted, 5 received") -eq 0 ]]
then
echo "Server1 is up."
else
echo "Server is NOT up, look for another server."
fi

Bash script that accepts TCP connection, when a client connection occurs, send the time of day as a response to the client

I'm not going to lie this is an homework assignment, but I've been googling constantly to try to get some idea on how the heck to approach this particular question.
"Create a script named lab6s6 that accepts TCP connections. When a client connection
occurs, send the time of day as a response to client. You may choose any port number as
the listening port, and don’t forget to close your connections."
I'm running the latest fedora OS on my virtualbox
So far after doing some research I've come across this particular piece of code
$ exec {file-descriptor}<>/dev/{protocol}/{host}/{port}
What i've come up with after doing some research would be
exec 3<>/dev/TCP/127.0.0.1/8000
So from my general understanding the file descriptor tends to always be set to 3 (is this because of the stdin, stdout, stderr, what is the purpose of this?) also the "<>" which represents reading and writing, and the directory is a way to actually use those protocols. and lastly, for my ip I read somewhere that I shouldnt be using the loopback that this wouldn't work but I'll be honest I was a bit clueless while reading the article, and for the port I never really understood that, is it like the higher the number the more available your signal is?
and another side question, do I need to install any other type of software to even accomplish something like this? If anyone could clarify if I'm basically opening up like a phone line on my computer to be able to talk to other computers at are on my LAN, is that even possible?
I'm not asking for direct answers, but if someone could nudge me in the right direction I would appreciate it greatly!
Thanks again!
I have prepared for you two scripts: client and server
after giving them the execution right: chmod u+x script_name you can run them in any order (client -> server or server -> client)
bash_server.sh
#!/usr/bin/env bash
#define port on which the server will listen
#and the output file that will be used to store the client port to send an answer
readonly PORT_LISTEN=22222;
readonly SERVER_FILE=server_file_tmp.out;
echo "Removing the server temporary file: ${SERVER_FILE}";
rm -f "${SERVER_FILE}";
#will open/bind/listen on PORT_LISTEN and whenever some information is received
#it will write it in the SERVER FILE
echo "Starting the server on port: ${PORT_LISTEN} with configuration file: ${SERVER_FILE}";
nc -k -l "${PORT_LISTEN}" | tee "${SERVER_FILE}" &
echo "Waiting for connection..."
#active listening to entry connection
while true;
do
#get always information about the external connection trying to connect to our open port
tmpNetworkString=$(lsof -i:"${PORT_LISTEN}" | grep "localhost:${PORT_LISTEN} (ESTABLISHED)" | awk '{print $9}');
echo -n "${tmpNetworkString}";
if [ -s "${SERVER_FILE}" ] && [ ! -z "${tmpNetworkString}" ]; then
answerPORT=$(cat "${SERVER_FILE}");
echo "Connection received on port ${PORT_LISTEN}...";
incomingIP=$(echo $tmpNetworkString | cut -d':' -f1);
incomingPort=$(echo $tmpNetworkString | cut -d'-' -f1 | cut -d':' -f2);
echo ">>Incoming traffic IP: ${incomingIP}";
echo ">>Incoming traffic Port: ${incomingPort}";
echo "Answering on IP: ${incomingIP}, port: ${answerPORT}...";
#wait client port to be ready
nc -z "${incomingIP}" "${answerPORT}";
isOpen=$?;
while [ ! "${isOpen}" -eq 0 ];
do
nc -z "${incomingIP}" "${answerPORT}";
isOpen=$?;
done
echo $(date) | nc -q 2 "${incomingIP}" "${answerPORT}";
echo "Closing the server, port: ${PORT_LISTEN}";
fuser -k -n tcp "${PORT_LISTEN}";
echo "Removing the server temporary file: ${SERVER_FILE}";
rm -f "${SERVER_FILE}";
exit 0;
fi
done
bash_client.sh
#!/usr/bin/env bash
#define port on which the client will listen
#and the output file that will be used to store the answer from the server
readonly PORT_LISTEN=33333;
readonly CLIENT_FILE=client_file_tmp.out;
readonly SERVER_PORT=22222;
readonly SERVER_IP=localhost
echo "Removing the client temporary file: ${CLIENT_FILE}";
rm -f "${CLIENT_FILE}";
#will open/bind/listen on PORT_LISTEN and whenever some information is received
#it will write it in the CLIENT FILE
echo "Starting the server on port: ${PORT_LISTEN} with configuration file: ${CLIENT_FILE}";
nc -k -l "${PORT_LISTEN}" > "${CLIENT_FILE}" &
echo "Connecting to the server: ${SERVER_IP}, on port: ${SERVER_PORT} and waiting for answer";
#sending port information for answer:
#wait client port to be ready
nc -z "${SERVER_IP}" "${SERVER_PORT}";
isOpen=$?;
while [ ! "${isOpen}" -eq 0 ];
do
nc -z "${SERVER_IP}" "${SERVER_PORT}";
isOpen=$?;
done
echo "${PORT_LISTEN}" | nc -q 2 "${SERVER_IP}" "${SERVER_PORT}";
while true;
do
if [ -s "${CLIENT_FILE}" ]; then
echo "Answer received from server...";
echo "##############################";
echo "##############################";
cat "${CLIENT_FILE}";
echo "##############################";
echo "##############################";
#sleep 10;
echo "Closing the open port of the client, port: ${PORT_LISTEN}";
fuser -k -n tcp "${PORT_LISTEN}";
echo "Removing the answer file: ${CLIENT_FILE}";
rm -f "${CLIENT_FILE}";
exit 0;
fi
done

Shell Script - telnet multiple hosts:ports

I'm not an expert in shell script by any means.
I got the structure idea from another post (Bash script telnet to test multiple addresses and ports)
My need is to verify LAN connections between specific hosts and ports via telnet.
The reason for using telnet is the fact that both the LAN and machines are heavily secure and I don't have access to netcat, nmap or /dev/tcp. I'm also no where near comfortable with Python or Pearl to try that route... ( I know silly me, I'll get there though :P ).
The following code works, however for reasons beyond my understanding the while loop iterates only once and no more... :( .
Note: it is important for me to know if the connection failed due to timeout or was refused (port is closed at the endpoint).
Can anyone help me in 1) fixing it and 2) understanding why?
FYI: For anyone else that might have a similar need here's the fully operational updated code for the script.
In this case connection refused is being handled as a success (testing firewall rules) which can be changed to failed depending on necessities.
#!/bin/bash
path=`pwd`;
touch $path/test_telnet.out || exit;
touch $path/success.log || exit;
touch $path/failed.log || exit;
echo "10.192.168.1 1200
10.10.10.2 80
10.220.2.8 6090
10.220.2.9 6090" | ( while read host port; do
telnet $host $port </dev/null > $path/test_telnet.out 2>&1 & sleep 1; kill $!;
if grep Connected $path/test_telnet.out >/dev/null;
then
echo # $(date +"%b %d %H:%M %Y") $host:$port [ OPEN ] | tee -a $path/success_log.txt;
elif grep refused $path/telnet_test.txt >/dev/null; then
echo # $(date +"%b %d %H:%M %Y") $host:$port [ REFUSED ] | tee -a $path/success_log.txt;
else
echo # $(date +"%b %d %H:%M %Y") $host:$port [ TIMEOUT ] | tee -a $path/failed_log.txt;
fi;
cp /dev/null $path/test_telnet.out;
done
) 2>/dev/null #avoid bash messages
As Etan commented, telnet is eating the rest of your input. The fix is to redirect the input for telnet.
Change this:
telnet $host $port > ~/test_con/telnet_test.txt
to this:
telnet $host $port </dev/null > ~/test_con/telnet_test.txt
I have added a shell script file and just run this. This script get servers and ports from below list.
for i in {10.21.xxx.yyy,10.21.xxx.yyy,10.23.xxx.yyy};
do
for j in {5501,5502,5503,5504,7701,7702,7703,7704,5551,5552,5553,7771,7772,7773};
do
(echo > /dev/tcp/${i}/${j}) > /dev/null 2>&1 && echo "${i}:${j} :: it's getting connected" || echo "${i}:${j} :: it's not connecting"
done
done

Resources