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