-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathDeployREMnux.py
148 lines (117 loc) · 6.37 KB
/
DeployREMnux.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/python
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver
from libcloud.compute.deployment import ScriptDeployment
from libcloud.compute.base import NodeAuthSSHKey
from libcloud.compute.ssh import ParamikoSSHClient
import datetime, json, argparse, time, string, random
from distutils.util import strtobool
parser = argparse.ArgumentParser(description='DeployREMnux is a Python script that will deploy a cloud instance of the public REMnux distribution in the Amazon cloud (AWS). The REMnux distribution itself is maintained by Lenny Zeltser with extensive help from David Westcott and is available from https://remnux.org. This script was created by Carrie Roberts (@OrOneEqualsOne).')
parser.add_argument('-p','--password',help='The password for the remnux user that will be used to RDP into the instace', required=False)
parser.add_argument('-t','--terminate',help='Terminate the specified node id and associated resources. e.g. -t i-0cf26edddf5c39b6a', required=False)
parser.add_argument('-u','--update',help='Issue the "update-remnux full" command on deploy to have the REMnux distro update itself', default=False, required=False, action='store_true')
args = parser.parse_args()
# read config file
with open('DeployREMnux-config.txt') as json_data_file:
config = json.load(json_data_file)
ACCESS_ID = config["AmazonConfig"]["aws_access_key_id"]
SECRET_KEY = config["AmazonConfig"]["aws_secret_access_key"]
private_key_file = config["SshConfig"]["private_key_file"]
public_key_file = config["SshConfig"]["public_key_file"]
myregion = 'us-east-1'
IMAGE_ID = 'ami-79cff703'
SIZE_ID = config["AmazonConfig"]["aws_instance_size"]
cls = get_driver(Provider.EC2)
driver = cls(ACCESS_ID, SECRET_KEY, region=myregion)
def cleanup_and_exit(node):
print ("Terminating node and associated resources.")
nodeName = node.name
driver.destroy_node(node)
start_time = time.time()
retry_timeout = 60*2 # retry time in seconds
while(True):
try:
driver.ex_delete_security_group(nodeName)
except Exception:
if(time.time() - start_time > retry_timeout):
print "Failed to delete associated Security Group"
break
time.sleep(3)
continue
break
kp = driver.get_key_pair(nodeName)
driver.delete_key_pair(kp)
print("REMnux Instance Shutdown")
exit()
if args.terminate:
node = driver.list_nodes([args.terminate])[0]
cleanup_and_exit(node)
print("Spinning up REMnux Instance, this will take a minute or two. . .")
nodeName = datetime.datetime.utcnow().strftime("REMnux-%Y-%m-%dt%H-%M-%S-%f")
sizes = driver.list_sizes()
images = driver.list_images(location=myregion, ex_image_ids=[IMAGE_ID])
size = [s for s in sizes if s.id == SIZE_ID][0]
image = [i for i in images if i.id == IMAGE_ID][0]
#read in public key in order to deploy to new node
with file(public_key_file) as f:
pub_key = f.read()
pk = NodeAuthSSHKey(pub_key)
# create this ssh key in the cloud
driver.import_key_pair_from_string(nodeName, pub_key)
# create the security group, only allowing ssh at first
sg = driver.ex_create_security_group(nodeName, "allows ssh and rdp from anywhere", vpc_id=None)
sg = driver.ex_authorize_security_group_ingress(sg["group_id"], 22, 22, cidr_ips=['0.0.0.0/0'], group_pairs=None, protocol='tcp')
# a deployment to change the remnux user password that will be used for RDP access
# Generate a random password if a blank password was provided in the configuration file, Random string generator from https://stackoverflow.com/questions/2257441/random-string-generation-with-upper-case-letters-and-digits-in-python
newPass = config["RemnuxConfig"]["remnux_user_password"]
if args.password:
newPass = args.password
if newPass == "":
newPass = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(20))
passwd_change_cmd = ('echo -e "malware\n%s\n%s\n\" | passwd' % (newPass,newPass)).encode('utf-8')
sd = ScriptDeployment(passwd_change_cmd, args=None, name="change_passwd.sh",delete=True)
my_mapping = [{'VirtualName': None, 'Ebs': {'DeleteOnTermination': 'true'}, 'DeviceName': '/dev/sda1'}]
# create and provision node
node = driver.deploy_node(name=nodeName, ex_blockdevicemappings=my_mapping, image=image, size=size, ex_security_groups=[nodeName] ,auth=pk, ssh_username="remnux",ssh_key=private_key_file,deploy=sd)
# on Windows, libcloud doesn't run the deploy script to change the password, so we try it manually here
sshclient = ParamikoSSHClient(node.public_ips[0],username="remnux",key=private_key_file,timeout=300)
res1 = sshclient.connect()
res2 = sshclient.run(passwd_change_cmd)
# allow remote access (RDP) by modifying the security group
driver.ex_authorize_security_group(nodeName, 3389, 3389, cidr_ip='0.0.0.0/0', protocol='tcp')
print("REMnux Instance Ready to use, IP address: %s RDP password for the 'remnux' user is %s" % (node.public_ips[0], newPass))
print("For SSH access use this command: ssh -i %s remnux@%s" % (private_key_file, node.public_ips[0]))
#update REMnux
if args.update:
print("Go ahead and use it while it is updating itself, this will take ... quite a while. (~35 minutes)")
res3 = sshclient.run("update-remnux full")
print("Done! Whew, that was a lot of work!. A reboot is necessary for the update to take full effect.")
# prompt before instance terminate
print 'Would you like to reboot the instance now? [Y/n]'
while True:
try:
response = raw_input().lower()
if ((response is "") or (strtobool(response))):
print("Rebooting now to complete update process.")
node.reboot()
time.sleep(60) #a hack because the node reports "running" even when it is rebooting
print("Rebooted and ready to go. Enjoy!")
break
else:
print ("OK, you can reboot it later at your own convenience.")
break
except ValueError:
print "Please respond with y or n"
# prompt before instance terminate
print 'Would you like to terminate (premanently destroy) the instance now? [Y/n]'
while True:
try:
response = raw_input().lower()
if ((response is "") or (strtobool(response))):
cleanup_and_exit(node)
break
else:
print ("You can terminate this instance in the future by running this command:\npython DeployREMnux.py -t %s" % node.id)
break
except ValueError:
print "Please respond with y or n"