Ruby - telnet behaving inconsistently - ruby

I am experiencing some funny behaviour with telnet. Below is my code:
#!/usr/bin/env ruby
require 'net/telnet'
ipaddress = "182.201.120.218"
j = Net::Telnet::new("Host" => '127.0.0.1',
"Port" => 2605,
"Output_log" => "output.log",
"Dump_log" => "dump.log",
"Prompt" => /[#>]/ ,
"Telnetmode" => true,
"Timeout" => 10,
)
response = j.cmd("show ip bgp 182.201.120.218\n")
puts response
This is the output I get trying to run it a few times (dont worry no sensitive info there, all sanitized):
[root#dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root#dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root#dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root#dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root#dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
[root#dummyserver tmp]# ./telnet.rb
dummyserver.com.au> show ip bgp 182.255.120.248
BGP routing table entry for 182.235.96.0/19
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Not advertised to any peer
Local
202.158.215.52 from 202.158.215.52 (202.158.215.6)
Origin IGP, localpref 100, valid, internal, best
Community: 7575:1000 7575:2406 7575:3002
Originator: 202.158.215.6, Cluster list: 202.158.215.52 202.158.215.10
Last update: Mon Sep 21 06:46:58 2020
[root#dummyserver tmp]# ./telnet.rb
dummyserver.com.au>
As you can see above, telnet refuses to run the command show ip bgp 182.201.120.218\n even though the telnet session was established/connected. It finally succeeded in the 6th run but 7th failed etc. If I run it another random times it works again, only to fail. Manual telnet is always successful, aka :
[root#dummyserver]# telnet 127.0.0.1 2605
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
dummyserver.com.au>show ip bgp 182.255.120.248
BGP routing table entry for 182.255.96.0/19
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Not advertised to any peer
Local
202.158.215.52 from 202.158.215.52 (202.158.215.6)
Origin IGP, localpref 100, valid, internal, best
Community: 7575:1000 7575:2406 7575:3002
Originator: 202.158.215.6, Cluster list: 202.158.215.52 202.158.215.10
Last update: Mon Sep 21 06:46:58 2020
dummyserver.com.au>
Output log shows the following:
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au> show ip bgp 182.255.120.248
BGP routing table entry for 182.255.96.0/19
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Not advertised to any peer
Local
202.158.215.52 from 202.158.215.52 (202.158.215.6)
Origin IGP, localpref 100, valid, internal, best
Community: 7575:1000 7575:2406 7575:3002
Originator: 202.158.215.6, Cluster list: 202.158.215.52 202.158.215.10
Last update: Mon Sep 21 06:46:58 2020
dummyserver.com.au>
dummyserver.com.au>
dummyserver.com.au>
dummyserver.com.au> Trying 127.0.0.1...
Connected to 127.0.0.1.
dummyserver.com.au>
I'm scratching my head trying to understand why telnet is behaving this way when normal telnet has got no issues.
Rvm version :
# rvm version rvm 1.29.10 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io]
Running on Redhat 7.8
If anyone have any idea or would like to provide more details, let me know. I'm stumped :(
(If you are curious - I'm trying to query BGP route info from Quagga/zebra using telnet to run the commands with no credentials required. I could do this easily and with no issue with Perl, but we have to port the scripts to Ruby for internal reasons).

With your :Prompt specification, you tell the telnet client that the telnet prompt of the server is any line which contains a # or > character.
The telnet client reads all received output of the server until it has observed a line looking like a prompt. Now in your case, your first line of the show ip bgp command output already contains a # character, matching your prompt specification.
With that, you are now running into a race-condition. You will see some output if the server send more than the first line in the first TCP packet of its response, which results in the telnet client to read all of this sent output. If the server sends each line separately in one packet, the telnet client bails out quicker since it already sees the designated prompt.
To fix this, it might already be sufficient to specify a stricter :Prompt, e.g. /[$%#>] \z/n as shown in the example at https://github.com/ruby/net-telnet#usage

OK, not sure if this is the best way, but I appear to have resolved it by the adding waitfor. Complete code :
#!/usr/bin/env ruby
require 'net/telnet'
ipaddress = "182.255.120.248"
j = Net::Telnet::new("Host" => '127.0.0.1',
"Port" => 2605,
"Output_log" => "output.log", # default: nil (no output)
"Dump_log" => "dump.log", # default: nil (no output)
"Prompt" => /[$%#>] \z/n ,
"Telnetmode" => true, # default: true
"Timeout" => 10, # default: 10
)
j.waitfor(/[\>\# ]$/) {
response = j.cmd("show ip bgp 182.255.120.248")
puts response
}

Related

ssh client to show server-supported algorithms

In order to check that all the servers across a fleet aren't supporting deprecated algorithms, I'm (programmatically) doing this:
telnet localhost 22
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
SSH-2.0-OpenSSH_8.0p1 Ubuntu-6build1
SSH-2.0-Censor-SSH2
4&m����&F �V��curve25519-sha256,curve25519-sha256#libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1Arsa-sha2-512,rsa-sha2-256,ssh-rsa,ecdsa-sha2-nistp256,ssh-ed25519lchacha20-poly1305#openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm#openssh.com,aes256-gcm#openssh.comlchacha20-poly1305#openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm#openssh.com,aes256-gcm#openssh.com�umac-64-etm#openssh.com,umac-128-etm#openssh.com,hmac-sha2-256-etm#openssh.com,hmac-sha2-512-etm#openssh.com,hmac-sha1-etm#openssh.com,umac-64#openssh.com,umac-128#openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1�umac-64-etm#openssh.com,umac-128-etm#openssh.com,hmac-sha2-256-etm#openssh.com,hmac-sha2-512-etm#openssh.com,hmac-sha1-etm#openssh.com,umac-64#openssh.com,umac-128#openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1none,zlib#openssh.comnone,zlib#openssh.comSSH-2.0-Censor-SSH2
Connection closed by foreign host.
Which is supposed to be a list of supported algorithms for the various phases of setting up a connection. (kex, host key, etc). Every time I run, I get a different piece of odd data at the start - always a different length.
There's an nmap plugin - ssh2-enum-algos - which returns the data in it's complete form, but I don't want to run nmap; I have a go program which opens the port, and sends the query, but it gets the same as telnet. What am I missing, and how do I fix it?
For comparison, here's the top few lines from the output of nmap script:
$ nmap --script ssh2-enum-algos super
Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-27 22:15 GMT
Nmap scan report for super (192.168.50.1)
Host is up (0.0051s latency).
rDNS record for 192.168.50.1: supermaster
Not shown: 998 closed ports
PORT STATE SERVICE
22/tcp open ssh
| ssh2-enum-algos:
| kex_algorithms: (12)
| curve25519-sha256
| curve25519-sha256#libssh.org
| ecdh-sha2-nistp256
| ecdh-sha2-nistp384
| ecdh-sha2-nistp521
Opening a tcp connection to port 22, (in golang, with net.Dial) then accepting and sending connection strings leaves us able to Read() from the Reader for the connection. Thence the data is in a standard format described by the RFC. From this, I can list the algorithms supported in each phase of an ssh connection. This is very useful for measuring what is being offered, rather than what the appears to be configured (it's easy to configure sshd to use a different config file).
It's a useful thing to be able to do from a security POV.
Tested on every version of ssh I can find from 1.x on a very old solaris or AIX box, to RHEL 8.1.
In some cases you can specify an algorithm to use, and if you specify one that is not supported the server will reply with a list of supported algorithms.
For example, to check for supported key exchange algorithms you can use:
ssh 127.0.0.1 -oKexAlgorithms=diffie-hellman-group1-sha1
diffie-hellman-group1-sha1 is insecure and should be missing from most modern servers. The server will probably respond with something like:
Unable to negotiate with 127.0.0.1 port 22: no matching key exchange method found. Their offer: curve25519-sha256,curve25519-sha256#libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256
Exit 255
Typing: "ssh -Q cipher | cipher-auth | mac | kex | key"
will give you a list of the algorithms supported by your client
Typing: "man ssh"
will let you see what options you can specify with the -o argument, including Cipher, MACs, and KexAlgorithms

How to allow external connection to elastic search on GCE instance

I'm setting elasticsearch cluster on GCE, eventualy it will be used from within the application which is on the same network, but for now while developing, i want to have access from my dev env. Also even on long term i would have to access kibana from external network so need to know how to allow that. For now i'm not taking care of any security considirations.
The cluster (currently one node) on GCE instance, centos7.
It has external host enabled, the ephemeral option.
I can access 9200 from within the instance:
es-instance-1 ~]$ curl -XGET 'localhost:9200/?pretty'
But not via the external ip which when i test it shows 9200 closed:
es-instance-1 ~]$ nmap -v -A my-external-ip | grep 9200
9200/tcp closed wap-wsp
localhost as expected is good:
es-instance-1 ~]$ nmap -v -A localhost | grep 9200
Discovered open port 9200/tcp on 127.0.0.1
I see a similar question here and following it i went to create a firewall rule. First added a tag 'elastic-cluster' to the instance and then a rule
$ gcloud compute instances describe es-instance-1
tags:
items:
- elastic-cluster
$ gcloud compute firewall-rules create allow-elasticsearch --allow TCP:9200 --target-tags elastic-cluster
Here it's listed as created:
gcloud compute firewall-rules list
NAME NETWORK SRC_RANGES RULES SRC_TAGS TARGET_TAGS
allow-elasticsearch default 0.0.0.0/0 tcp:9200 elastic-cluster
so now there is a rule which supposed to allow 9200
but still not reachable
es-instance-1 ~]$ nmap -v -A my-external-ip | grep 9200
9200/tcp closed wap-wsp
What am i missing?
Thanks

Bash ping server with addres and port and get short info

How I can connect to sever by ip and port, and get short info about it?
I tried to do it with netcat and curl, but info is too long. I also tried to use telnet but it is not a good way for me.
I have a script which connect to some addresses on specified ports and I if it is connected I want to show short info about it.
Is it possible? Is any other method to solve this problem?
IP addresses are different. They can be a http, mysql, ssl, etc.
I attach a code with a connection's function:
if nc -w 10 -z $1 $i; then
printf "\n$1:$i - Port is open\n\nSERVER INFO:\n";
printf "\n$(curl -IL $1)\n";
else
printf "\n$1:$i - Port is closed\n"
fi;
EDIT:
Example of response from server I would like to get
{IP number}: ssh - OpenSSH 6.0pl1, http - apache 1.3.67, https - httpd 2.0.57
You were pretty close. You can include the host just as you have in your script.
for port in $(seq 21 23); do
out=$(nc -w 1 -q 1 localhost $port)
echo port ${port}: $out
done
#port 21:
#port 22: SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.7
#port 23:

Telnet Not Working in Ruby

I need to Telnet into my associate's server for a project I'm working on:
telnet = Net::Telnet::new(
"Host" => "example_ip",
"Port" => 80,
"Timeout"=>90,
"Waittime" => 1,
"Output_log"=>"output_log.log",
"Dump_log"=> "dump_log.log"
)# => #<Net::Telnet:0x007f8142321c00 ...
telnet.cmd('ls') # => "HTTP/1.1 0 ERROR\n\nERROR 0\n"
My output_log looks like:
Trying example_ip...
Connected to example_ip.
HTTP/1.1 0 ERROR
ERROR 0
I know his server is running and I can connect to it. Why can't I connect from Ruby?
(from the OSX terminal)
$ telnet example_ip 80
Trying example_ip...
Connected to c-example_ip...comcast.net.
Escape character is '^]'.
...
$ ls
_~1 .TRA 22 4096
TRASHE~1. 12 0
FSEVEN~1. 12 0
20110221.LOG 0 73
CONFIG . 0 573
20110223.LOG 0 95
20110224.LOG 0 17
20110225.LOG 0 17
20110315.LOG 0 73
...
Edit:
I tried setting Binmode to false, Telnetmode to false, and some different values for the Prompt (but I don't know what the right one would be).
One problem is you're telnetting to port 80 in your code, which is the HTTPd port. That's why you are getting:
HTTP/1.1 0 ERROR
The server is expecting you to send a HTTP command, such as GET /index.html, but instead you're sending "ls".
You don't say what host OS you are using on your machine's command-line to connect to the server, but, it's possible the telnet command on that machine expects the port command to be separated from the host IP or FQDN using a colon:
telnet example_ip:80
Failing to use the colon on that type of client causes the connection to occur to the standard telnet port on port 23, which seems to be backed up by your ls command working. A HTTPd on port 80 wouldn't know what you meant by ls.
You can use the Telnet protocol to connect to a HTTPd, and you can use a telnet client app also. You have to use the right command-set with it though. Try adjusting your code to telnet.cmd("GET /index.html\r\n") and see if you get a response back.
EDIT:
Use OpenURI to experiment. It's a very simple and convenient way to poke at web servers:
require 'open-uri'
doc = open('http://example.com').read
puts doc[0, 100]
That will open the connection to port 80 at the host given, following redirects, and returning the document received. It then prints the first 100 characters which look like:
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
<meta http-
You don't say why you "need" to telnet to a web server. They don't support the same commands you can issue via a normal telnet session, and won't give you access to the file system, unless code has been written for those purposes.

<UNKNOWN> value for host in snmptraps

while executing
"snmptrap -v 1 -c public localhost TRAP-TEST-MIB::demotraps localhost 4 0 '' IF-MIB::ifIndex i 1"
on my system,I am getting host ,ip & OID values as
host = localhost.localdomain :ip = UDP: [127.0.0.1]:49109->[127.0.0.1] :OID =DISMAN-EVENT-MIB::sysUpTimeInstance 0:3:12:38.28
But when traps are coming from outside its showing
host = :ip = UDP: [192.168.1.73]:52346->[192.168.1.23]:OID =DISMAN-EVENT-MIB::sysUpTimeInstance 7:1:05:54.27 .
Now its clearly shown above that host value didn't show up ...I want to know why & how it get to be resolve.
Thanks in advance
the one reason is if you are using VMware/virtual OS and you have not configured different IP than your host machine IP.
Simply keep ip & its corresponding host-name in /etc/hosts file..That's All
My /etc/hosts file is-
127.0.0.1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
192.168.1.150 ZYXEL
192.168.1.73 CISCO
192.168.1.135 DIGISOL

Resources