Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sivagao/4030471 to your computer and use it in GitHub Desktop.
Save sivagao/4030471 to your computer and use it in GitHub Desktop.
using Timeout, TCPServer, socket, net,ssh, pcaplet(packet analysis)/http#practical ruby for system administrator
require "socket"
socket = TCPSocket.open("www.theonion.com", "80")
TCPSocket.open("www.theonion.com", 80) do |socket|
socket.puts "GET / HTTP/1.0\n\n"
puts socket.read
end
attempts = 0
begin
attempts += 1
TCPSocket.open("www.example.com", 80) { |socket| ... }
rescue
if attempts < 3 then sleep 5 and retry
else puts "I've had enough of this"
end
end
require "timeout"
begin
Timeout::timeout(5) do
TCPSocket.open("www.example.com", 80) { |socket| ... }
end
rescue
puts "something untoward happened - how bothersome"
end
#timeout.rb
module Timeout
class Error< Interrupt
end
def timeout(sec, exception=Error)
return yield if sec == nil or sec.zero?
begin
x = Thread.current
y = Thread.start {
sleep sec
x.raise exception, "execution expired" if x.alive?
}
yield sec
# line omitted as irrelevant
ensure
y.kill if y and y.alive?
end
end
module_function :timeout
end
require "timeout"
class TCPSocket
def self.can_connect?(ip, port, wait_secs = 5)
Timeout::timeout(wait_secs) { open(ip, port) }
return true
rescue
return false
end
class DNSRecord
def value
return @ips.first unless @type == "A" and @ips.size > 1
@ips.find { |ip| TCPSocket.can_connect?(ip, 80) } || @ips.first
end
end
require "net/http"
Net::HTTP.new("slashdot.org").get("/").each_header do |key, value|
next if key == "x-powered-by" or not key =~ /x-(.*)/
puts "#{$1.capitalize} says #{value.inspect}"
break
end
require "cgi"
require "net/http"
class WebSession
def initialize(url, port = 80)
@session = Net::HTTP.new(host, port)
@cookies = {}
end
def get(path)
response = @session.get(path, retrieve_cookies(path))
collect_cookies(response)
return response.body
end
def post(path, pairs)
header = retrieve_cookies(path)
header["content-type"] = "application/x-www-form-urlencoded"
data = pairs.map { |k, v| "#{k}=#{CGI.escape(v.to_s)}") }.join("&")
response = @session.post(path, data, header)
collect_cookies(response)
return response.body
end
private
def collect_cookies(response)
cookie = response["set-cookie"]
return unless cookie
fields, cookie_path = {}, nil
cookie.split(";").each do |f|
raise "Unable to parse cookie from #{path.inspect}" unless➥
f =~ /^(.*?)=(.*?)$/
if $1 == "path" then cookie_path = $2
else fields[$1] = $2
end
end
raise "Unable to parse cookie [no path]: #{cookie.inspect}" unless cookie_path
@cookies[cookie_path] = fields
end
def retrieve_cookies(path)
cookies = @cookies[path] || @cookies["/"]
return {} unless cookies
return {"cookie" => cookies.map { |k, v| "#{k}=#{v}" }.join(";")}
end
end
class MegaFishCannon < WebSession
def initialize(url, uname, pass)
super(url, 5000)
post("/", "login" => uname, "password" => pass)
end
# Listing 8-9. Methods to Affect State Changes of the Cannon
def load_fish(name)
post("/loadfish.cgi", "name" => name)
end
def point_cannon(degrees, metres)
post("/movebarrel.cgi", "degrees" => degrees, "metres" => metres)
end
def fire
post("/fire.cgi")
end
end
require "socket"
server = TCPServer.new(34891)
while (session = server.accept)
command = session.readline.chomp
if command =~ /^([\d\.]+) ([\+-\/\*]) ([\d\.]+)$/
x, y = $1.to_f, $3.to_f
result = case $2
when "+" then x + y
when "-" then x - y
when "*" then x * y
when "/" then y == 0 ? "inf" : x / y
end
session.puts "= #{result}"
end
session.close
end
# select based to support multi client to connect
require "socket"
server = TCPServer.new(34891)
sockets = [server]
loop do
read_ready, write_ready, error_ready = IO.select(sockets)
read_ready.each do |socket|
if socket == server then sockets << server.accept
else
command = socket.readline.chomp
if command =~ /^([\d\.]+) ([\+-\/\*]) ([\d\.]+)$/
# etc...
end
socket.close
sockets.delete(socket)
end
end
end
# Listing 8-16. A Simple Arithmetic Server (Thread Based)
require "socket"
server = TCPServer.new(34891)
while (session = server.accept)
Thread.new(session) do |s|
command = s.readline.chomp
if command =~ /^([\d\.]+) ([\+-\/\*]) ([\d\.]+)$/
x, y = $1.to_f, $3.to_f
result = case $2
when "+" then x + y
when "-" then x - y
when "*" then x * y
when "/" then y == 0 ? "inf" : x / y
end
s.puts "= #{result}"
end
s.close
end
end
require "net/ssh"
Net::SSH.start(url, user, pass) do |ssh|
shell = ssh.shell.sync
puts shell.ruby("-v").stdout
end
require "net/ssh"
class RemoteHost
def initialize(url, user = root)
@shell = Net::SSH.start(url, user).shell.sync
end
def clear_dirs(*dirs)
dirs.each { |dir| @shell.send_command("rm -rf #{dir}/*") }
end
end
unsafe_hosts.each do |host|
RemoteHost.new(host).clear_dirs("/tmp", "/opt")
end
# install pcap , the packet analysis tool
$ tar -xzf ruby-pcap-0.6.tar.gz
$ cd pcap
$ ruby extconf.rb
$ make
$ make install
# Definition of a BWHost Class For Tracking BandWidth Usage
require "pcaplet"
sniffer = Pcap::Pcaplet.new
sniffer.each_packet { |pkt| p pkt }
sniffer.close
class BWHost
attr_reader :ip
def initialize(ip)
@ip = ip
@received, @sent = [], []
end
def received(bytes, from, at = Time.now)
@received << [bytes, from, at]
end
def sent(bytes, to, at = Time.now)
@sent << [bytes, from, at]
end
def total_received(options = {})
total(@received, options[:earliest], options[:latest])
end
def total_sent(options = {})
total(@sent, options[:earliest], options[:latest])
end
private
def total(events, earliest, latest)
events.inject(0) do |sum, event|
if ((earliest and event[2] >= earliest) or not earliest) and
((latest and event[2] <= latest) or not latest)
sum + event
else sum
end
end
end
end
# - Listing 8-21. Bandwidth-Monitoring Script
require "pcaplet"
hosts = {}
sniffer = Pcap::Pcaplet.new
sniffer.each_packet do |pkt|
next unless pkt.ip?
src, dst, = pkt.ip_src, pkt.ip_dst
size, time = pkt.size, pkt.time
(hosts[src] ||= BWHost.new(src)).sent(size, dst, time)
(hosts[dst] ||= BWHost.new(dst)).received(size, src, time)
end
sniffer.close
hosts.each do |ip, data|
puts "#{ip} sent #{data.total_sent}B and received #{data.total_received}B"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment