mirror of
https://github.com/rapid7/metasploitable3.git
synced 2024-09-21 00:01:14 +02:00
136 lines
2.8 KiB
Ruby
136 lines
2.8 KiB
Ruby
|
#!/usr/bin/env ruby
|
||
|
|
||
|
#
|
||
|
# This script will update ProFTPd's DefaultAddress setting in the config file
|
||
|
# when the IP changes.
|
||
|
#
|
||
|
# You should comebine systemd to make sure this things automatically updates
|
||
|
# ProFTPd as soon as it starts. The script:
|
||
|
#
|
||
|
# [Unit]
|
||
|
#Description=Foo
|
||
|
#
|
||
|
# [Service]
|
||
|
# ExecStart=rvm-shell -c /opt/proftpd/proftp_ip_renewer.rb
|
||
|
|
||
|
# [Install]
|
||
|
# WantedBy=multi-user.target
|
||
|
#
|
||
|
|
||
|
require 'socket'
|
||
|
|
||
|
class HostsRenewer
|
||
|
|
||
|
class Error < RuntimeError; end
|
||
|
|
||
|
# The config file to update
|
||
|
CONFIG_PATH = '/etc/hosts'
|
||
|
|
||
|
# Number of seconds to wait before we try to update again
|
||
|
WAIT_TIME = 3
|
||
|
|
||
|
# The kind of private IP prefix we are looking for to update
|
||
|
# The Metasploitable3 private IP always starts with 10-something.
|
||
|
EXPECTED_IP_PREFIX = '10'
|
||
|
|
||
|
def initialize
|
||
|
unless config_exists?
|
||
|
raise ProFTPIPRenewer::Error, "#{CONFIG_PATH} not found"
|
||
|
end
|
||
|
|
||
|
last_known_ip = get_default_address_from_config
|
||
|
@hostname = `hostname`
|
||
|
|
||
|
unless last_known_ip
|
||
|
puts "* The ip/hostname isn't present in /etc/hosts. Adding it."
|
||
|
init_default_address_to_config
|
||
|
last_known_ip = get_default_address_from_config
|
||
|
restart_proftpd
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def read_config
|
||
|
File.read(CONFIG_PATH)
|
||
|
end
|
||
|
|
||
|
def init_default_address_to_config
|
||
|
current_ip = get_private_ip
|
||
|
value = "\n#{current_ip} #{@hostname}\n"
|
||
|
File.open(CONFIG_PATH, 'ab') do |f|
|
||
|
f.write(value)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def get_default_address_from_config
|
||
|
config = read_config
|
||
|
current_ip = get_private_ip
|
||
|
config.scan(/#{current_ip} #{@hostname}/).flatten.first
|
||
|
end
|
||
|
|
||
|
def get_private_ip
|
||
|
ip = Socket.ip_address_list.select { |addr| addr.ip_address =~ /^#{EXPECTED_IP_PREFIX}\./}.first
|
||
|
if ip
|
||
|
ip.ip_address
|
||
|
else
|
||
|
puts "* The desired IP is not found. We are falling back to 127.0.0.1."
|
||
|
'127.0.0.1'
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def config_exists?
|
||
|
File.exists?(CONFIG_PATH)
|
||
|
end
|
||
|
|
||
|
def update_ip_address
|
||
|
config = read_config
|
||
|
new_config = ''
|
||
|
changed = false
|
||
|
current_ip = get_private_ip
|
||
|
|
||
|
config.each_line do |line|
|
||
|
if line =~ /(#{current_ip}) #{@hostname}/
|
||
|
if $1 != current_ip
|
||
|
changed = true
|
||
|
puts "* IP has changed to: #{current_ip}."
|
||
|
new_config << "#{current_ip} #{@hostname}\n"
|
||
|
end
|
||
|
else
|
||
|
new_config << line
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if changed
|
||
|
File.write(CONFIG_PATH, new_config)
|
||
|
puts "* #{CONFIG_PATH} updated"
|
||
|
restart_proftpd
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def restart_proftpd
|
||
|
puts "* Restarting ProFTPd"
|
||
|
puts `service proftpd stop`
|
||
|
puts `service proftpd start`
|
||
|
end
|
||
|
|
||
|
def start
|
||
|
while true
|
||
|
update_ip_address
|
||
|
sleep WAIT_TIME
|
||
|
end
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
def main
|
||
|
begin
|
||
|
ip_renewer = HostsRenewer.new
|
||
|
ip_renewer.start
|
||
|
rescue HostsRenewer::Error => e
|
||
|
puts "* Error: #{e.message}"
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if __FILE__ == $PROGRAM_NAME
|
||
|
main
|
||
|
end
|