namespace :vps do namespace :firewall do # Allow for defining task named `open': class << self undef_method :open if private_method_defined? :open end task(:default) { rules } desc <<-DESC Open a port from the Internet to a VPS. For example, if you choose to open port 443 of a VPS foo, it will be accessible from the Internet on a port greater than or equal to 1025, like 1047. As a result, packets would arrive like this: Internet <=> (Firewall:1047) <=> VPS:443 Following on this example: $ #{command 'vps:firewall:open'} PORT=443 As 443 is the default HTTP SSL port number, you can a host site over SSL and it will be accessible from the Internet on port 1047, for example at https://www.example.com:1047. By default, a port is open from the Internet. But you can restrict the access to only one or several of your VPS's by specifying the $FROM variable. For example, to open port 3306 (MySQL) of VPS #{q 'trever'} to another VPS #{q 'christina'}: $ #{command 'vps:firewall:open'} FROM=christina ID=trever PORT=3306 Environment variables: (mandatory) $PORT: the destination port number on the VPS, in the form of [:], where is optional and is one of TCP or UDP, TCP being the default if none is specified. For example: $ #{command 'vps:firewall:open'} PORT=443 Is equivalent to: $ #{command 'vps:firewall:open'} PORT=443:TCP (optional) $FROM: the origin to grant access to. It can be either a VPS identified by its hostname, or the Internet, identified by #{q 'internet'}. Valid values include: FROM=internet # default Or: FROM=foo # VPS whose hostname is `foo' (optional) $ID: the ID or hostname of the destination VPS. Default: the newest VPS. DESC task :open do vps = top.vps.fetch_current port = ENV["PORT"] or error! <<-MSG The destination port must be specified in the $PORT environment variable, in the form of [:]. Examples: PORT=443, PORT=443:TCP, PORT=53:UDP MSG sources = (ENV['FROM'] || 'internet').split(',') number, protocol = port.to_s.split(':') protocol ||= 'TCP' fwd = vps.port_forwardings.build :sources => sources, :to => number, :protocol => protocol try_save fwd do puts_title "Request sent" puts "#{fwd.protocol.to_s.upcase} port #{fwd.to} has been scheduled for opening on VPS #{vps}." end end desc <<-DESC List all firewall rules defined for a given VPS. DESC task :rules do vps = top.vps.fetch_current puts_title "Firewall rules for VPS #{q vps}" puts_list vps.port_forwardings.all, :table => true do |t| t.col("Service") { |f| f.service_name || "(#{f.protocol})" } t.col("Sources") { |f| "{#{f.simplified_sources * ', '}}:#{f.from}" } t.col("Destination") { |f| "#{f.target}:#{f.to}" } end end end end