Beispiel #1
0
def check_server_vpn(user_id):

    client = get_docker_client(LOCAL_TUNNEL)
    client_low = get_docker_client(LOCAL_TUNNEL, True)

    #print("deleted containers->"+json.dumps(client.containers.prune()))
    #print("\n\ndeleted images->"+json.dumps(client.images.prune(filters={"dangling":False})))
    #client.networks.prune()
    #client.volumes.prune()

    client = get_docker_client(LOCAL_TUNNEL)
    name_VPN = "serverVPN_user_" + str(user_id)
    try:
        #print("CHECK - sto quiii")
        cont_vpn = client.containers.get(name_VPN)
        print("CHECK per vedere lo stato attuale del container vpn:" +
              cont_vpn.status)
        if cont_vpn.status == "running":
            pass
        elif cont_vpn.status == "exited":
            client_low.start(name_VPN)
        else:
            return False
    except docker.errors.APIError as e:
        print("serverVPN per l'utente (ID:" + str(user_id) +
              ") inesistente, dettagli: (" + str(e.args) + ")---- \n \n")
        return False

    return True
Beispiel #2
0
def stop_lab(name_lab, nome, id_user, request):

    client = get_docker_client(LOCAL_TUNNEL)
    try:
        client.containers.get(name_lab).remove(force=True)
        msg_response = "Laboratorio Stoppato !! <br />"
    except:
        msg_response = "Errore nel stoppare il laboratorio (1) !! <br />"

    response_list = {
        "msg_response": msg_response,
        "response_action": "start_container"
    }

    insert_notification("Laboratorio " + nome + " Stoppato!", "#", id_user)

    #Togli il valore dalla sessione
    try:
        del request.session[name_lab]
        del request.session[name_lab + "_start_time"]
        del request.session[name_lab + "_IP"]
        print("Sessione relativa al laboratorio " + name_lab + " eliminata")
    except:
        print("Errore nel cancellare la sessione")

    print("RITORNO")
    return response_list
Beispiel #3
0
def check_if_container_up(nome_container):
    client = get_docker_client(LOCAL_TUNNEL)
    try:
        client.containers.get(nome_container)
        return True
    except:
        return False
Beispiel #4
0
def esercizi(request):
    context = {}
    labs = Lab.objects.all()
    args = Tag_Args.objects.all()
    livelli = Tag_Level.objects.all()

    client = get_docker_client(LOCAL_TUNNEL)

    #request.session[name_lab]
    #request.session[name_lab+"_start_time"]
    #request.session[name_lab+"_IP"]

    try:
        user_id = str(request.session["user_pk"])
    except:
        html_template = loader.get_template('error-403.html')
        context = {}
        return HttpResponse(html_template.render(context, request))

    from .lab_manage import check_if_container_up

    for lab in labs:
        name_lab = "labid_" + str(lab.pk) + "_userid_" + str(
            request.session["user_pk"])
        if name_lab in request.session:
            if check_if_container_up(name_lab) == False:
                print(
                    "\nHo trovato una sessione settata, per un laboratorio inesistente...provvedo a cancellare:\n"
                )
                try:
                    del request.session[name_lab]
                    del request.session[name_lab + "_start_time"]
                    del request.session[name_lab + "_IP"]
                    print("---Sessioni cancellate")
                except:
                    print("---Errore nel cancellare le sessioni associate")

    try:
        cont_vpn = client.containers.get("serverVPN_user_" + user_id)
        stdout = cont_vpn.exec_run(cmd="sh -c 'cat client.ovpn'")

        if "BEGIN PRIVATE KEY" in bytes(stdout.output).decode("utf-8"):
            vpn_status = "on"
        else:
            vpn_status = "off"
    except:
        vpn_status = "off"

    context = {
        'labs': labs,
        'args': args,
        'livelli': livelli,
        'VPN': vpn_status,
    }

    html_template = loader.get_template('esercizi.html')
    return HttpResponse(html_template.render(context, request))
Beispiel #5
0
def prune_networks():

    client = get_docker_client(LOCAL_TUNNEL)

    try:
        client.networks.prune()
    except docker.errors.APIError:
        print(
            "\n \n ---- il server ha ritornato un errore mentre faceva i prune dei networks ---- \n \n"
        )
Beispiel #6
0
def get_ip_by_container(container_name, network_name):

    client = get_docker_client(LOCAL_TUNNEL)

    try:
        net_custom = client.networks.get(network_id=network_name)
    except docker.errors.NotFound:
        return False

    for container in net_custom.attrs["Containers"]:
        if net_custom.attrs["Containers"][str(
                container)]['Name'] == container_name:
            return net_custom.attrs["Containers"][str(
                container)]['IPv4Address']
Beispiel #7
0
def get_client_vpn(request):

    client = get_docker_client(LOCAL_TUNNEL)
    try:
        user_id = str(request.session["user_pk"])
    except:
        html_template = loader.get_template('error-403.html')
        context = {}
        return HttpResponse(html_template.render(context, request))

    cont_vpn = client.containers.get("serverVPN_user_" + user_id)
    stdout = cont_vpn.exec_run(cmd="sh -c 'cat client.ovpn'")

    context = {
        'client': bytes(stdout.output).decode("utf-8"),
    }

    html_template = loader.get_template('client.ovpn')
    return HttpResponse(html_template.render(context, request))
Beispiel #8
0
def manage(request):
    # is_ajax è una funzione già fatta da Django che controlla la presenza dell'header HTTP_X_REQUESTED_WITH nella richiesta HTTP
    if request.is_ajax():

        # L'SDK python per docker ha una versione standard, ed una versione "low" che permette di interagire con docker a più basso livello
        client = get_docker_client(LOCAL_TUNNEL)
        client_low = get_docker_client(LOCAL_TUNNEL, True)

        #creo una data corretta che servirà successivamente (il sistema attuale è 2 ore indietro, quindi qui ne aggiungo 2)
        x = datetime.datetime.now() + datetime.timedelta(hours=2)

        message = ""

        #I messaggi inviati dal frontend vengono concatenati come una stringa JSON
        POST_VALUES = decode_input(json.loads(request.POST.get('data')))

        #prendo dal db il lab che ha come primary key POST_VALUES["lab"]
        try:
            labo = Lab.objects.get(pk=POST_VALUES["lab"])
        except:
            response_list = {"error": "Impossibile trovare il laboratorio"}
            message = json.dumps(response_list)

            return message

        ######################################################################
        #                                                                    #
        #                   INIZIO CONFIGURAZIONI VARIABILI                  #
        #                                                                    #
        ######################################################################

        #Gestore stopping_Thread dei Laboratori
        pool_threads = {}

        #Nome network custom
        network_name_user = "******" + str(request.session["user_pk"])

        # Nome del container Docker per il Laboratorio
        name_lab = "labid_" + str(labo.pk) + "_userid_" + str(
            request.session["user_pk"])

        # Nome Immagine del DockerHub
        image_lab = labo.docker_name

        # - START - Configurazioni per il comando docker.run
        cap_lab = labo.cap_add

        if labo.detach == "True":
            detach_lab = True
        else:
            detach_lab = False

        if labo.auto_remove == "True":
            auto_rm_lab = True
        else:
            auto_rm_lab = False
        # - END -

        ######################################################################
        #                                                                    #
        #                   FINE CONFIGURAZIONI VARIABILI                    #
        #                                                                    #
        ######################################################################

        #Flag che serve più avanti per capire se il container in questione è già in esecuzione
        found = False

        #Fai il check se esiste già una network associata all 'utente
        #Se non esiste crea la network e fai l'attach al server VPN e restituisci il certificato all'utente
        #Poi fai l'attach del container su quella rete, e restituisci l'ip all'utente

        #client.networks.create(name, ARGS)
        #   NAME = nome_utente
        #   DRIVER = bridge
        #   INTERNAL = true ? (Restrict external access to the network.)

        response_list = {"": ""}

        try:
            ######################################################################
            #                                                                    #
            # FACCIAMO UNA SERIE DI CHECK PER VEDERE SE TUTTO L'ENVIROMENT E' OK #
            #                                                                    #
            ######################################################################

            if check_server_vpn(str(request.session["user_pk"])) == False:
                response_list = {"error": "Attendere l'avvio del serverVPN"}
                message = json.dumps(response_list)

                return message

            ######################################################################
            #                                                                    #
            #                           END CHECKS                               #
            #                                                                    #
            ######################################################################

            # I comandi inviati dal frontend tramite AJAX
            if POST_VALUES["action"] == "start_lab" or POST_VALUES[
                    "action"] == "stop_lab":

                for cont in client.containers.list():
                    contain = client.containers.get(cont.short_id)

                    #print (json.dumps(contain.attrs))

                    #message = message + " <br /> imgs: " + contain.attrs['Config']['Image'] + " name:" + contain.attrs['Name']

                    # E' stato trovato il container del Lab
                    if contain.attrs['Config'][
                            'Image'] == image_lab and contain.attrs[
                                'Name'] == "/" + name_lab:
                        found = True
                        break
                    else:
                        pass
                        #print(contain.attrs['Name'] + "!=" + name_lab)

            if POST_VALUES["action"] == "start_lab":
                if (found == True):
                    msg_response = "Questo laboratorio è già in esecuzione <br />"
                    response_list = {
                        "response_action": "stop_container",
                        "msg_response": msg_response,
                        "start_time": x.strftime("%m/%d/%Y, %H:%M:%S"),
                        "show_not": "dontshow",
                        "durata": labo.durata_secondi,
                        "id_timer": labo.pk
                    }

                else:

                    ports_dict = {
                        '80/tcp': 3000
                    }  #will expose port 2222 inside the container as port 3333 on the host.

                    # Avvia il container
                    lab_started = client.containers.run(
                        image_lab,
                        cap_add=[cap_lab],
                        detach=detach_lab,
                        name=name_lab,
                        auto_remove=auto_rm_lab,
                        network=network_name_user)

                    # Prende l'ip del container startato
                    lab_ip = get_ip_by_container(name_lab, network_name_user)

                    msg_response = "Laboratorio Avviato !! <br /> IP Lab: " + str(
                        lab_ip)
                    response_list = {
                        "response_action": "stop_container",
                        "msg_response": msg_response,
                        "start_time": x.strftime("%m/%d/%Y, %H:%M:%S"),
                        "durata": labo.durata_secondi,
                        "id_timer": labo.pk
                    }

                    print(
                        "\n\n\n Starto il thread per stoppare il laboratorio "
                        + name_lab + " tra 60 minuti")
                    #3600 secondi sono 1 ora 300 sono 5 min
                    t = Timer(labo.durata_secondi, stop_lab, [
                        name_lab, labo.nome, request.session["user_pk"],
                        request
                    ])  # per testing metto 15 secondi
                    pool_threads[name_lab] = t
                    t.start(
                    )  # after 30 seconds, "hello, world" will be printed

                    insert_notification(
                        "Laboratorio " + labo.nome + " Avviato!", "#",
                        request.session["user_pk"])

                    try:
                        my_stats = Statistiche.objects.get(
                            user_id=User.objects.get(
                                pk=request.session["user_pk"]))
                        my_stats.lab_avviati = int(my_stats.lab_avviati) + 1
                        my_stats.save()
                    except ObjectDoesNotExist:
                        my_stats = Statistiche(
                            lab_avviati=1,
                            flag_trovate=0,
                            guide_lette=0,
                            punteggio=0,
                            user_id=User.objects.get(
                                pk=request.session["user_pk"]))
                        my_stats.save()

                    # Setta la sessione che serve al frontend
                    request.session[name_lab] = "running"
                    request.session[name_lab + "_start_time"] = x.strftime(
                        "%m/%d/%Y, %H:%M:%S")
                    request.session[name_lab + "_durata"] = labo.durata_secondi
                    request.session[name_lab + "_IP"] = lab_ip

            elif POST_VALUES["action"] == "stop_lab":
                if (found == True):
                    print("INIZIO A STOPPARE")
                    if name_lab in pool_threads:
                        print(
                            "Esiste ancora il thread autostoppante del laboratorio, quindi ora lo killiamo e poi stoppiamo il lab"
                        )
                        pool_threads.get(name_lab).cancel()
                        del pool_threads[name_lab]
                    print("1")
                    try:
                        client.containers.get(name_lab).remove(force=True)
                        msg_response = "Laboratorio Stoppato !! <br />"
                        print("1-1")
                    except:
                        msg_response = "Errore nel stoppare il laboratorio (1) !! <br />"
                        print("1-2")
                    print("2")
                    response_list = {
                        "msg_response": msg_response,
                        "response_action": "start_container"
                    }
                    print("3")
                    insert_notification(
                        "Laboratorio " + labo.nome + " Stoppato!", "#",
                        request.session["user_pk"])
                    print("4")
                    #Togli il valore dalla sessione
                    try:
                        del request.session[name_lab]
                        del request.session[name_lab + "_start_time"]
                        del request.session[name_lab + "_IP"]
                        print("Sessione relativa al laboratorio " + name_lab +
                              " eliminata")
                    except:
                        print("Errore nel cancellare la sessione")

                    print("5")

                else:
                    #fatal error

                    try:
                        del request.session[name_lab]
                        del request.session[name_lab + "_start_time"]
                        del request.session[name_lab + "_IP"]
                    except:
                        print("Errore nel cancellare la sessione")

                    msg_response = "Laboratorio non in esecuzione !! <br />"
                    response_list = {"msg_response": msg_response}

        except docker.errors.NotFound as e:
            print(
                "\n \n ---- il server non è riuscito a trovare il container VPN 1 (Provvedere ad un lancio manuale)  ("
                + str(e.args) + ")---- \n \n")
            response_list = {"error": "error1"}
        except docker.errors.APIError as e:
            print("\n \n ---- Errore nell'api docker 2 (" + str(e.args) +
                  ")---- \n \n")
            response_list = {"error": "error2"}

        message = json.dumps(response_list)

    else:
        message = "Not Ajax"
    return message
Beispiel #9
0
def create_server_vpn(user_id):

    user_id = str(user_id)

    # L'SDK python per docker ha una versione standard, ed una versione "low" che permette di interagire con docker a più basso livello
    client = get_docker_client(LOCAL_TUNNEL)
    client_low = get_docker_client(LOCAL_TUNNEL, True)

    #url sul quale sarà attivo il server VPN
    url_attuale = DNS_NAME_SERVER

    #export ID_UTENTE_ID=Utente1
    nome_certificato_utente = "Utente_" + user_id

    #export PORTA_CLIENT_ID=1001
    #RANGE PORTE NON USATE 34444 - 36962
    porta_client_utente = get_porta(
        user_id)  #PORTA_CLIENT_ID deve essere in un certo range

    #

    #export OVPN_DATA_ID="ovpn-data-$ID_UTENTE"
    nome_volume_utente = "ovpn-data-" + user_id

    # Nome della network custom associata all'utente
    network_name_user = "******" + user_id

    # Nome del container VPN
    name_VPN = "serverVPN_user_" + user_id
    print("ora inizio a creare")
    # Proviamo a fare un get della network Custom dell'utente, nel caso esista già
    try:
        client.networks.get(network_id=network_name_user)
    except docker.errors.NotFound:
        #Nel caso non ci sia (poichè può essere stata eliminata dopo un tot di inutilizzo), la creiamo
        #print("la rete custom dell'utente ancora non esiste, quindi la creiamo")
        client.networks.create(name=network_name_user, driver="bridge")

    #docker volume create --name $OVPN_DATA_ID
    client.volumes.create(name=nome_volume_utente)

    #primo comando
    #docker run -v $OVPN_DATA_ID:/etc/openvpn --log-driver=none --rm kylemanna/openvpn ovpn_genconfig -u udp://vpn.projectwork2.cyberhackademy.it:$PORTA_CLIENT_ID

    #secondo comando
    #docker run -v $OVPN_DATA_ID:/etc/openvpn --log-driver=none --rm -e EASYRSA_BATCH=1 kylemanna/openvpn ovpn_initpki nopass

    #terzo comando
    #docker run -v $OVPN_DATA_ID:/etc/openvpn -d -p $PORTA_CLIENT_ID:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn

    #quarto comando
    #docker run -v $OVPN_DATA_ID:/etc/openvpn --log-driver=none --rm kylemanna/openvpn easyrsa build-client-full $ID_UTENTE_ID nopass

    #quinto comando
    #docker run -v $OVPN_DATA_ID:/etc/openvpn --log-driver=none --rm kylemanna/openvpn ovpn_getclient $ID_UTENTE_ID > $ID_UTENTE_ID.ovpn

    #immagine del serverVPN VECCHIA = "kylemanna/openvpn"
    immagine_server = "giuseppsss/openvpn"

    volumes = ['/host_location']

    volume_bindings = {
        nome_volume_utente: {
            'bind': '/etc/openvpn',
            'mode': 'rw',
        },
    }

    envs = ["EASYRSA_BATCH=1"]

    porte = {
        '1194/udp': porta_client_utente
    }  #will expose port 1194/udp inside the container as port porta_client_utente on the host.

    print("\n- Inizio il primo comando - ")
    try:
        cmd1 = "ovpn_genconfig -u udp://" + url_attuale + ":" + str(
            porta_client_utente)

        cmd_setup_1 = client.containers.run(immagine_server,
                                            volumes=volume_bindings,
                                            command=cmd1,
                                            cap_add=["net_admin"],
                                            network=network_name_user)
    except docker.errors.APIError as e1:
        print("Errore al primo comando (" + str(e1.args) + ")---- \n \n")
        return False

    print("completato")

    print("\n- Inizio il secondo comando - ")
    if True:
        try:
            cmd_setup_2 = client.containers.run(immagine_server,
                                                volumes=volume_bindings,
                                                command="ovpn_initpki nopass",
                                                environment=envs,
                                                cap_add=["net_admin"],
                                                auto_remove=True,
                                                network=network_name_user)
        except docker.errors.APIError as e2:
            print("Errore al secondo comando (" + str(e2.args) + ")---- \n \n")
            return False
    print("completato")

    print("\n- Inizio il terzo comando - ")
    try:
        cmd_setup_3 = client.containers.run(immagine_server,
                                            volumes=volume_bindings,
                                            ports=porte,
                                            cap_add=["net_admin"],
                                            detach=True,
                                            name=name_VPN,
                                            network=network_name_user)
    except docker.errors.APIError as e3:
        print("Errore al terzo comando (" + str(e3.args) + ")---- \n \n")
        return False
    print("completato")

    print("\n- Inizio il quarto comando - ")
    try:

        #se già esiste:
        #vedi se c'è la stringa = Request file already exists
        #rm /etc/openvpn/pki/reqs/"+nome_certificato_utente+".req
        #rm /etc/openvpn/pki/issued/"+nome_certificato_utente+".crt
        #rm /etc/openvpn/pki/private/"+nome_certificato_utente+".key

        cont_vpn = client.containers.get(name_VPN)
        stdout = cont_vpn.exec_run(cmd="easyrsa build-client-full " +
                                   nome_certificato_utente + " nopass")

        if "Request file already exists" in bytes(
                stdout.output).decode("utf-8"):

            cmd_delete_all = "rm /etc/openvpn/pki/reqs/" + nome_certificato_utente + ".req && rm /etc/openvpn/pki/issued/" + nome_certificato_utente + ".crt && rm /etc/openvpn/pki/private/" + nome_certificato_utente + ".key"

            stdout = cont_vpn.exec_run(cmd=cmd_delete_all)

            stdout = cont_vpn.exec_run(cmd="easyrsa build-client-full " +
                                       nome_certificato_utente + " nopass")
            if "Generating a RSA private key" in bytes(
                    stdout.output).decode("utf-8"):
                print("-- Certificato generato")
            else:
                raise docker.errors.APIError("Non ha generato nulla1")

        elif "Generating a RSA private key" in bytes(
                stdout.output).decode("utf-8"):
            print("-- Certificato generato 2")

        stdout = cont_vpn.exec_run(cmd="sh -c 'ovpn_getclient " +
                                   nome_certificato_utente + " > client.ovpn'")
        stdout = cont_vpn.exec_run(cmd="sh -c 'cat client.ovpn'")
        if "BEGIN CERTIFICATE" in bytes(stdout.output).decode("utf-8"):
            print("-- File client.ovpn generato correttamente")
        else:
            raise docker.errors.APIError("Non ha generato nulla2" +
                                         bytes(stdout.output).decode("utf-8"))

        client.containers.prune()
        client.images.prune()
        client.networks.prune()
        client.volumes.prune()

        print("-- Prune completati")

    except docker.errors.APIError as e4:
        print("Errore al quarto comando (" + str(e4.args) + ")---- \n \n")
        return False

    print("completato")

    #se il serverVPN non è connesso alla rete custom, connettilo
    #client_low.connect_container_to_network(container=name_VPN, net_id=network_name_user)

    return True