diff options
Diffstat (limited to 'tasks/openvpn_simple_smb/task.py')
-rw-r--r-- | tasks/openvpn_simple_smb/task.py | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/tasks/openvpn_simple_smb/task.py b/tasks/openvpn_simple_smb/task.py new file mode 100644 index 0000000..5d7c22f --- /dev/null +++ b/tasks/openvpn_simple_smb/task.py @@ -0,0 +1,261 @@ +# kpov_util should be imported by add_assignment.py + +instructions = { + 'si': '''\ +<p> +Postavi dva navidezna računalnika: <em>SimpleArbiter</em> in <em>VPNClient1</em>. Poskrbite, da bosta povezana med seboj in v internet. Na <em>VPNClient1</em> namestite OpenVPN in program za nadzor nad virtualnimi napravami (s katerim kreirate napravo <code>tap</code>). + +<p> +Na strežniku <em>SimpleArbiter</em> že teče strežnik in uporablja skrivnost, ki jo najdete tudi na <em>VPNClient1</em> v domačem imeniku uporabnika <code>student</code>. Na <em>VPNClient1</em> vzpostavite VPN tako, da napišete primerno datoteko z nastavitvami. Računalniku <em>VPNClient1</em> na navideznem lokalnem omrežju nastavite naslov +<code>{{IP_VPNClient1}}</code>. + +<p> +Nato poskrbite, da bo na <em>VPNClient1</em> na navideznem omrežju prek NFS omogočen +dostop do imenika <code>/home/test/{{DIRNAME}}</code>. V ta imenik skopirajte datoteke, ki so prek SMB dostopne na <em>SimpleArbiter</em>. +''', + 'en': '''\ +<p> +Setup two virtual machines: <em>SimpleArbiter</em> and <em>VPNClient1</em>. Set the client's network up so that it has access to the internal network and the internet. On <em>VPNClient1</em>, install OpenVPN and a program for supervising virtual devices +(which you will use to create a <code>tap</code> device). On the VPN, set the IP for +<em>VPNClient1</em> to <code>{{IP_VPNClient1}}</code>. + +<p> +An OpenVPN server is already running on <em>SimpleArbiter</em>. Use the secret +available on <em>VPNClient1</em> in the home directory of user <code>student</code> to connect to the VPN server on <em>SimpleArbiter</em>. To do that, you will have to write your +own OpenVPN configuration file. + +<p> +After you have set up the VPN, make the directory <code>/home/test/{{DIRNAME}}</code> on <em>VPNClient1</em> available over NFS from <em>SimpleArbiter</em> over +your VPN. Copy files that are available from <em>SimpleArbiter</em> over SMB to <code>/home/test/{{DIRNAME}}</code>. +''' +} + +computers = { + 'SimpleArbiter': { + 'disks': [ + { + 'name': 'simpleArbiterDhcpGWVPN', + }, + ], + 'network_interfaces': [ + { + 'network': 'test-net' + }, + { + 'network': 'net1' + } + ], + 'flavor': 'm1.tiny', + 'config_drive': False + }, + 'VPNClient1': { + 'disks': [ + { 'name': 'student-VPNClient1', + }, + ], + 'network_interfaces': [ + { + 'network': 'net1' + } + ], + 'flavor': 'm1.tiny', + 'config_drive': False + }, +} + +networks = { + 'test-net': { + 'public': True + }, + # Used for the VPN tunnel + 'net1': { + 'public': False + } +} + +#Tukaj sem generiral tri parametre, prosil bi če se upoštevajo pri Tasku. +params_meta = { + 'IP_SimpleArbiterVPN': {'descriptions':{'si':'IP za SimpleArbiter na VPN'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True}, + 'IP_VPNClient1': {'descriptions':{'si':'IP klienta na VPN'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True}, + 'IP_LANClient1': {'descriptions':{'si':'IP klienta na LAN'}, 'w': True, 'public': True, 'type': 'IP', 'generated': False}, + 'DIRNAME': {'descriptions':{'si':'Imenik, dostopen prek NFS'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True}, + 'secret_random_seed': {'descriptions':{'si':'Seme za skrivnost'}, 'w': False, 'public': False, 'type': None, 'generated': True}, +} + +def task(IP_SimpleArbiterVPN, IP_VPNClient1, IP_LANClient1, DIRNAME): + import collections + from pexpect import pxssh # Used to set up an SSH connection to a remote machine + import pexpect # Allows the script to spawn a child application and control it as if a human were typing commands + + # The necessary things we need to check if the task was performed correctly + results = collections.defaultdict(str) + + # VPNClient1 + sC1 = pxssh.pxssh(encoding='utf-8') + sC1.login(IP_LANClient1, 'student', 'vaje') + + # sA + results['SimpleArbiter_ifconfig'] = pexpect.run( + 'ifconfig -a', encoding='utf-8', env={'PATH': '/bin:/sbin'}) + results['SimpleArbiter_route'] = pexpect.run( + 'route -n', encoding='utf-8', env={'PATH': '/bin:/sbin'}) + + # Pings each of the clients + # 10.8.0.6 and 10.8.0.10 are the first two default addresses distributed by OpenVPN + # Will output everything ping outputs (set to ping 3 times) + results['SimpleArbiter_ping_C1'] = pexpect.run( + 'ping -c 3 {}'.format(IP_VPNClient1), encoding='utf-8') + results['SimpleArbiter_traceroute'] = pexpect.run( + 'traceroute {}'.format(IP_VPNClient1), encoding='utf-8') + sC1.sendline('cat /etc/exports') + sC1.prompt() + output = sC1.before + results['VPNClient1_nfs_access_control_list'] = output + results['SimpleArbiter_mount'] = pexpect.run( + 'sudo mount {}:/home/test/{} /mnt'.format(IP_VPNClient1, DIRNAME), encoding='utf-8') + results['SimpleArbiter_mount_result'] = pexpect.run( + 'sudo mount', encoding='utf-8') + results['SimpleArbiter_ls'] = pexpect.run( + 'ls /mnt', encoding='utf-8') + pexpect.run( + 'sudo umount /mnt', encoding='utf-8') + + # Ping the VPN server + sC1.sendline('ping -c 3 {0}'.format( IP_SimpleArbiterVPN )) + sC1.prompt() + results['VPNClient1_ping_VPN_server'] = sC1.before + + sC1.sendline('/sbin/ifconfig -a') + sC1.prompt() + results['VPNClient1_ifconfig'] = sC1.before + + sC1.sendline('ps xa') + sC1.prompt() + results['VPNClient1_ps'] = sC1.before + sC1.logout() + + return results + +def gen_params(user_id, params_meta): + params = dict() + #Tukaj sem generiral te tri parametre (ime skupne skrivnosti je heidi ) + #(ime imenika kjer naj bo shranjena skupna skrivnost naj bo openvpn) + #(HASH bo naključno generiran niz iz user_id s katerim se bo preverjalo plagiatorstvo) + import random + r = random.Random(user_id) + net = kpov_util.IPv4_subnet_gen(r, '10.168.0.0/16', 24) + params['IP_VPNClient1'], params['IP_SimpleArbiterVPN'] = kpov_util.IPv4_addr_gen(r, net, 2) + params['DIRNAME'] = kpov_util.fname_gen(r, extension=False) + params['secret_random_seed']=str(r.random()) + return params + + +def task_check(results, params): + import re + score = 0 + hints = [] + + IP_SA = params['IP_SimpleArbiterVPN'].replace('.', '\.') + IP_C1 = params['IP_VPNClient1'].replace('.', '\.') + rs = r"tap0: flags=.* mtu 1500\r\n +inet {}".format(IP_SA) + if re.search(rs, + results['SimpleArbiter_ifconfig']): + score += 1 + else: + hints.append("ifconfig on SimpleArbiter not OK") + + if re.search( + "PING.*\r\n64 bytes from {}: icmp_seq=[0-9]+ ttl=64 time=[0-9.]* ms".format(IP_C1), + results['SimpleArbiter_ping_C1']): + score += 1 + else: + hints.append("ping from server not OK") + rs = "1 +{0} \({0}\)".format(IP_C1) + if re.search(rs, results['SimpleArbiter_traceroute']): + score += 1 + else: + hints.append("traceroute not OK") + if results['VPNClient1_nfs_access_control_list'].find( + '/home/test/' + params['DIRNAME'] + ' ') >= 0: + score += 1 + if results['SimpleArbiter_mount_result'].find( + '{}:/home/test/{} on /mnt type nfs'.format( + params['IP_VPNClient1'], params['DIRNAME'])): + score += 1 + else: + hints.append("mount not OK") + + # get r into the correct state + r = random.Random(params['secret_random_seed']) + s = "\n".join(["".join([r.choice("0123456789abcdef") for i in range(32)]) + for i in range(16)]) + keyfile = kpov_util.fname_gen(r, extension=False) + + # now check the filenames + fnames_ok = True + for i in range(3): + fname = kpov_util.fname_gen(r, False) + foo = kpov_util.fortune(r, 4096) + pos = results['SimpleArbiter_ls'].find(fname + '.txt') + fnames_ok = fnames_ok and pos >= 0 + if fnames_ok: + score += 2 + else: + hints.append("shared filenames not OK:") + + # Ping the VPN server + if re.search( + "PING.*\r\n64 bytes from {}: icmp_seq=[0-9]+ ttl=64 time=[0-9.]* ms".format(IP_SA), + results['VPNClient1_ping_VPN_server']): + score += 1 + else: + hints.append("ping from client not OK") + + rs = r"tap0: flags=.* mtu 1500\r\n +inet {}".format(IP_C1) + if re.search(rs, results['VPNClient1_ifconfig']): + score += 1 + else: + hints.append("ifconfig on VPNClient1 not OK") + + if results['VPNClient1_ps'].find('openvpn') > 0: + score += 1 + else: + hints.append("openvpn not found running on VPNClient") + return score, hints + +def prepare_disks(templates, task_params, global_params): + #guestmount -a d -m /dev/VG/LV -m /dev/sda1:/boot --ro /mnt + #asistent je pocasnela :) + import random + r = random.Random(task_params['secret_random_seed']) + s = "\n".join([ + "".join([r.choice("0123456789abcdef") for i in range(32)]) + for i in range(16)]) + s = """# +# 2048 bit OpenVPN static key +# +-----BEGIN OpenVPN Static key V1----- +{} +-----END OpenVPN Static key V1----- +""".format(s) + keyfile = kpov_util.fname_gen(r, extension=False) + ".key" + templates['simpleArbiterDhcpGWVPN'].write("/etc/openvpn/secret.key", s) + netaddr_s = """auto tap0 +iface tap0 inet static + openvpn server + pre-up tunctl -t tap0 + address {} + netmask 255.255.255.0 +""".format(task_params['IP_SimpleArbiterVPN']) + templates['simpleArbiterDhcpGWVPN'].write_append("/etc/network/interfaces", netaddr_s) + for i in range(3): + fname = kpov_util.fname_gen(r, False) + templates['simpleArbiterDhcpGWVPN'].write( + "/srv/smb/" + fname + '.txt', + kpov_util.fortune(r, 4096)) + write_default_config(templates['simpleArbiterDhcpGWVPN'], global_params) + templates['student-VPNClient1'].write("/home/student/" + keyfile, s) + # uid, gid (student = ) + templates['student-VPNClient1'].chown(1000, 1000, "/home/student/" + keyfile) + + write_default_config(templates['simpleArbiterDhcpGWVPN'], global_params) |