From charlesreid1

Line 52: Line 52:


==Infrastructure as Code (IaC) Setup==
==Infrastructure as Code (IaC) Setup==
===Vagrant (for VMs and Network Orchestration)===
Use a Vagrantfile to define your base "attacker" machine (e.g., a lightweight Linux VM with nmap and other tools pre-installed) and any specific target VMs that require a full OS (e.g., a Windows Server trial, or an older Linux distribution).
Vagrant can define private networks that your VMs and Docker containers will share. For example:
<pre>
# Vagrantfile (example snippet)
Vagrant.configure("2") do |config|
  config.vm.define "attacker" do |attacker|
    attacker.vm.box = "generic/ubuntu2004" # Or your preferred minimal box
    attacker.vm.network "private_network", ip: "192.168.50.10"
    attacker.vm.provision "ansible" do |ansible|
      ansible.playbook = "playbooks/attacker_setup.yml"
    end
  end
  config.vm.define "target-linux-vm" do |targetvm|
    targetvm.vm.box = "generic/ubuntu1804"
    targetvm.vm.network "private_network", ip: "192.168.50.20"
    targetvm.vm.provision "ansible" do |ansible|
      ansible.playbook = "playbooks/target_linux_vm_setup.yml"
    end
  end
end
</pre>
===Docker Compose (for Containerized Services/Targets)===
Use docker-compose.yml files to define various target "machines" (containers). Each container can run a specific service (web server, FTP, database, custom vulnerable app) on a defined IP address within the Docker network.
You can create custom Docker networks that can be linked to or exist on the same subnet as the Vagrant private network, or be routed.
<pre>
# docker-compose.yml (example snippet)
version: '3.8'
services:
  webserver_vulnerable:
    image: vulnerables/web-dvwa # Example vulnerable web app
    container_name: target_web_dvwa
    networks:
      lab_network:
        ipv4_address: 192.168.50.100 # Assign static IP within the lab network
    ports: # Only expose internally or not at all for nmap scanning
      # - "80:80" # Avoid exposing to EC2 host's public IP unless intended
    restart: unless-stopped
  ftp_server:
    image: fdelbia/vsftpd # Example FTP server
    container_name: target_ftp
    environment:
      FTP_USER: ftpuser
      FTP_PASS: ftppass
    networks:
      lab_network:
        ipv4_address: 192.168.50.101
    # By default, vsftpd in this image might expose 20, 21. Control with Ansible/container config.
    restart: unless-stopped
networks:
  lab_network:
    driver: bridge
    ipam:
      config:
        - subnet: 192.168.50.0/24
          gateway: 192.168.50.1
</pre>


=Flags=
=Flags=


{{NmapShortCourseFlag}}
{{NmapShortCourseFlag}}

Revision as of 22:38, 26 May 2025

This page describes how to run the labs for this nmap short course. Notes for myself, but also for anyone who might be interested.

TODO: GitHub repo link

Overview

The aim is to provide students with a laboratory environment to supplement lectures about nmap and allow them the freedom to explore and learn in a structured and well-defined environment, so that they can focus on learning how to use their tools.

The environment we define will be entirely virtual, so that we can define 1 host or 10 or 50, all of them will run as virtual machines on one single server. We will use infrastructure as code to define the virtual network and the virtual hosts living on it, their software, their configuration, etc. All of this virtual infra will run on a large EC2 instance. (As large as budget allows.)

Students will be logging into a (virtual) bastion host inside the (virtual) network they will be exploring, all of which are hosted on the main EC2 instance (which must be accessible to students so that they can log into the bastion host).

The core idea is to use a single, reasonably powerful EC2 instance as the hypervisor and host for your entire virtual network. Inside this EC2 instance, we'll use a combination of Vagrant (with libvirt/KVM) for managing any full virtual machines (like an attacker machine or specific OS targets) and Docker/Docker Compose for deploying a variety of lightweight target services and "machines" (containers). Ansible will be the glue for configuring everything consistently.

Core Lab Infrastructure on EC2

EC2 Instance Choice:

  • Operating System: Use a Linux distribution that supports KVM, such as Ubuntu Server LTS or Amazon Linux 2. Ubuntu Server often has more readily available documentation for tools like Vagrant with libvirt.
  • Instance Type: You'll need an instance with sufficient vCPUs and RAM to run multiple VMs/containers. Start with something like a t3.xlarge (4 vCPUs, 16 GiB RAM) or m5.large/m5.xlarge (2-4 vCPUs, 8-16 GiB RAM). Monitor resource usage and adjust as needed. Ensure your chosen instance type supports nested virtualization if you plan to run VMs within VMs (though for this setup, KVM on the EC2 host is primary).
  • Storage: Allocate sufficient EBS storage (SSD, e.g., gp3 for balanced performance and cost) for the OS, VM images, Docker images, and student data.
  • Security Group:
    • Allow SSH (port 22) from your IP and your students' IPs (or a bastion/VPN exit IP).
    • If using a VPN hosted on this EC2, allow the VPN port (e.g., UDP 1194 for OpenVPN).
    • Other ports should generally not be exposed directly to the internet; students will access target services from within the lab environment.

Virtualization Software Setup:

  • KVM/QEMU & Libvirt: Install these on your EC2 host instance to enable running full virtual machines.
sudo apt update
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager
sudo systemctl enable --now libvirtd
sudo usermod -aG libvirt $(whoami) # Add your user to the libvirt group
  • Vagrant: Install Vagrant. This will orchestrate your VMs.
    • Install the vagrant-libvirt plugin: vagrant plugin install vagrant-libvirt
  • Docker & Docker Compose: Install Docker Engine and Docker Compose. This will run your containerized targets.
sudo apt install docker.io
sudo systemctl enable --now docker
sudo usermod -aG docker $(whoami) # Add your user to the docker group
# Install Docker Compose (check official docs for latest version/method)
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

(Note: You'll need to log out and log back in for group changes to take effect, or use newgrp libvirt and newgrp docker in your current session.)

Infrastructure as Code (IaC) Setup

Vagrant (for VMs and Network Orchestration)

Use a Vagrantfile to define your base "attacker" machine (e.g., a lightweight Linux VM with nmap and other tools pre-installed) and any specific target VMs that require a full OS (e.g., a Windows Server trial, or an older Linux distribution).

Vagrant can define private networks that your VMs and Docker containers will share. For example:

# Vagrantfile (example snippet)
Vagrant.configure("2") do |config|
  config.vm.define "attacker" do |attacker|
    attacker.vm.box = "generic/ubuntu2004" # Or your preferred minimal box
    attacker.vm.network "private_network", ip: "192.168.50.10"
    attacker.vm.provision "ansible" do |ansible|
      ansible.playbook = "playbooks/attacker_setup.yml"
    end
  end

  config.vm.define "target-linux-vm" do |targetvm|
    targetvm.vm.box = "generic/ubuntu1804"
    targetvm.vm.network "private_network", ip: "192.168.50.20"
    targetvm.vm.provision "ansible" do |ansible|
      ansible.playbook = "playbooks/target_linux_vm_setup.yml"
    end
  end
end

Docker Compose (for Containerized Services/Targets)

Use docker-compose.yml files to define various target "machines" (containers). Each container can run a specific service (web server, FTP, database, custom vulnerable app) on a defined IP address within the Docker network.

You can create custom Docker networks that can be linked to or exist on the same subnet as the Vagrant private network, or be routed.

# docker-compose.yml (example snippet)
version: '3.8'
services:
  webserver_vulnerable:
    image: vulnerables/web-dvwa # Example vulnerable web app
    container_name: target_web_dvwa
    networks:
      lab_network:
        ipv4_address: 192.168.50.100 # Assign static IP within the lab network
    ports: # Only expose internally or not at all for nmap scanning
      # - "80:80" # Avoid exposing to EC2 host's public IP unless intended
    restart: unless-stopped

  ftp_server:
    image: fdelbia/vsftpd # Example FTP server
    container_name: target_ftp
    environment:
      FTP_USER: ftpuser
      FTP_PASS: ftppass
    networks:
      lab_network:
        ipv4_address: 192.168.50.101
    # By default, vsftpd in this image might expose 20, 21. Control with Ansible/container config.
    restart: unless-stopped

networks:
  lab_network:
    driver: bridge
    ipam:
      config:
        - subnet: 192.168.50.0/24
          gateway: 192.168.50.1

Flags