
GNS3 Cheatsheet
Overview
GNS3 (Graphical Network Simulator 3) is a powerful network simulation platform that allows network engineers to design, build, and test complex network topologies using real and virtual devices. It provides a comprehensive environment for network training, certification preparation, and production network testing without requiring physical hardware.
Installation
Windows Installation
# Download GNS3 all-in-one installer
# Visit https://gns3.com/software/download and download the Windows installer
# Install with PowerShell (if using Chocolatey)
choco install gns3
# Verify installation
gns3 --version
# Install additional components
# - VMware Workstation/Player (recommended)
# - VirtualBox (alternative)
# - QEMU (included with GNS3)
Linux Installation (Ubuntu/Debian)
# Add GNS3 repository
sudo add-apt-repository ppa:gns3/ppa
sudo apt update
# Install GNS3 GUI and server
sudo apt install gns3-gui gns3-server
# Install additional dependencies
sudo apt install qemu-kvm qemu-utils libvirt-daemon-system libvirt-clients bridge-utils
# Add user to required groups
sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER
sudo usermod -aG ubridge $USER
# Install Docker (optional but recommended)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
# Logout and login again for group changes to take effect
macOS Installation
# Install using Homebrew
brew install --cask gns3
# Or download from official website
# Visit https://gns3.com/software/download
# Install additional components
# - VMware Fusion (recommended)
# - VirtualBox (alternative)
# - Docker Desktop
# Verify installation
gns3 --version
Docker Installation
# Pull GNS3 server image
docker pull gns3/gns3server
# Run GNS3 server in container
docker run -d \
--name gns3-server \
--privileged \
-p 3080:3080 \
-v /var/lib/gns3:/opt/gns3/projects \
-v /etc/gns3:/etc/gns3 \
gns3/gns3server
# Access GNS3 web interface
# http://localhost:3080
Basic Configuration
Initial Setup
# First-time setup wizard
gns3 --setup
# Configure server settings
# File > Preferences > Server
# - Local server: 127.0.0.1:3080
# - Remote server: Configure if using remote GNS3 server
# Configure virtualization
# Edit > Preferences > VirtualBox/VMware/QEMU
# - Set paths to virtualization software
# - Configure resource allocation
Project Management
# Create new project
# File > New Project
# - Project name: MyNetworkLab
# - Location: /home/user/GNS3/projects/
# - Type: Blank project
# Open existing project
# File > Open Project
# Browse to .gns3 project file
# Save project
# File > Save Project (Ctrl+S)
# Export project
# File > Export Project
# Creates portable .gns3project file
# Import project
# File > Import Project
# Select .gns3project file
Device Management
Adding Cisco IOS Images
# Add IOS router image
# Edit > Preferences > Dynamips > IOS routers
# Click "New" and browse to IOS image file
# Configure router template
# - Platform: c7200 (for Cisco 7200 series)
# - Image: Browse to IOS file
# - RAM: 512 MB (recommended)
# - Idle-PC: Calculate for CPU optimization
# Calculate Idle-PC value
# Right-click router in topology
# Select "Idle-PC" > "Calculate"
# Wait for calculation to complete
Adding Virtual Appliances
# Download appliances from GNS3 marketplace
# File > Import Appliance
# Browse to .gns3a appliance file
# Popular appliances:
# - Cisco IOSv (virtual IOS)
# - Cisco IOSvL2 (virtual switch)
# - Cisco ASAv (virtual firewall)
# - Arista vEOS
# - Juniper vSRX
# - pfSense
# - Ubuntu Server
# - Windows Server
# Configure appliance settings
# Edit > Preferences > QEMU VMs
# Select appliance and configure:
# - RAM allocation
# - CPU cores
# - Network adapters
Docker Containers
# Add Docker container
# Edit > Preferences > Docker containers
# Click "New" to add container
# Popular network containers:
# - Alpine Linux: alpine:latest
# - Ubuntu: ubuntu:latest
# - Network tools: nicolaka/netshoot
# - Web server: nginx:alpine
# Configure container
# - Image name: alpine:latest
# - Start command: /bin/sh
# - Console type: telnet
# - Environment variables: as needed
Topology Design
Basic Network Topology
# Create simple router topology
# 1. Drag routers from device panel
# 2. Connect with cables
# 3. Configure interfaces
# Example: Three-router topology
# R1 --- R2 --- R3
# | |
# PC1 PC2
# Add devices:
# - 3x Cisco 7200 routers
# - 2x VPCS (Virtual PC Simulator)
# - Ethernet switches as needed
# Connect devices:
# - Click cable tool
# - Select source device/interface
# - Select destination device/interface
Advanced Topology Features
# Add text annotations
# Insert > Text
# Add descriptive labels for network segments
# Add shapes and drawings
# Insert > Rectangle/Ellipse
# Create network diagrams and documentation
# Group devices
# Select multiple devices
# Right-click > Group
# Useful for organizing complex topologies
# Create network segments
# Use Ethernet switches to create broadcast domains
# Configure VLANs for network segmentation
Topology Templates
# Save topology as template
# File > Export Project
# Save in templates directory
# Common topology templates:
# - CCNA lab setup
# - OSPF network
# - BGP routing lab
# - Security lab with firewalls
# - Data center topology
# Load template
# File > New Project
# Select "From template"
# Choose saved template
Device Configuration
Router Configuration
# Access router console
# Right-click router > Console
# Or double-click router
# Basic router configuration
Router> enable
Router# configure terminal
Router(config)# hostname R1
R1(config)# interface fastethernet0/0
R1(config-if)# ip address 192.168.1.1 255.255.255.0
R1(config-if)# no shutdown
R1(config-if)# exit
# Configure routing
R1(config)# router ospf 1
R1(config-router)# network 192.168.1.0 0.0.0.255 area 0
R1(config-router)# exit
# Save configuration
R1# copy running-config startup-config
Switch Configuration
# Access switch console
# Right-click switch > Console
# Basic switch configuration
Switch> enable
Switch# configure terminal
Switch(config)# hostname SW1
SW1(config)# vlan 10
SW1(config-vlan)# name SALES
SW1(config-vlan)# exit
# Configure access port
SW1(config)# interface fastethernet0/1
SW1(config-if)# switchport mode access
SW1(config-if)# switchport access vlan 10
SW1(config-if)# exit
# Configure trunk port
SW1(config)# interface fastethernet0/24
SW1(config-if)# switchport mode trunk
SW1(config-if)# switchport trunk allowed vlan all
SW1(config-if)# exit
Virtual PC Configuration
# Access VPCS console
# Right-click VPCS > Console
# Configure IP address
VPCS> ip 192.168.1.10 255.255.255.0 192.168.1.1
# Test connectivity
VPCS> ping 192.168.1.1
VPCS> trace 8.8.8.8
# Show configuration
VPCS> show ip
VPCS> show
# Save configuration
VPCS> save
Network Protocols and Services
OSPF Configuration
# Configure OSPF on multiple routers
# Router R1
R1(config)# router ospf 1
R1(config-router)# router-id 1.1.1.1
R1(config-router)# network 192.168.1.0 0.0.0.255 area 0
R1(config-router)# network 10.1.1.0 0.0.0.255 area 0
# Router R2
R2(config)# router ospf 1
R2(config-router)# router-id 2.2.2.2
R2(config-router)# network 10.1.1.0 0.0.0.255 area 0
R2(config-router)# network 10.2.2.0 0.0.0.255 area 0
# Verify OSPF
R1# show ip ospf neighbor
R1# show ip ospf database
R1# show ip route ospf
BGP Configuration
# Configure eBGP between autonomous systems
# Router R1 (AS 100)
R1(config)# router bgp 100
R1(config-router)# bgp router-id 1.1.1.1
R1(config-router)# neighbor 10.1.1.2 remote-as 200
R1(config-router)# network 192.168.1.0 mask 255.255.255.0
# Router R2 (AS 200)
R2(config)# router bgp 200
R2(config-router)# bgp router-id 2.2.2.2
R2(config-router)# neighbor 10.1.1.1 remote-as 100
R2(config-router)# network 192.168.2.0 mask 255.255.255.0
# Verify BGP
R1# show ip bgp summary
R1# show ip bgp
R1# show ip route bgp
VLAN and Trunking
# Configure VLANs on switch
SW1(config)# vlan 10
SW1(config-vlan)# name SALES
SW1(config-vlan)# vlan 20
SW1(config-vlan)# name ENGINEERING
SW1(config-vlan)# exit
# Configure access ports
SW1(config)# interface range fastethernet0/1-10
SW1(config-if-range)# switchport mode access
SW1(config-if-range)# switchport access vlan 10
SW1(config)# interface range fastethernet0/11-20
SW1(config-if-range)# switchport mode access
SW1(config-if-range)# switchport access vlan 20
# Configure trunk port
SW1(config)# interface fastethernet0/24
SW1(config-if)# switchport mode trunk
SW1(config-if)# switchport trunk allowed vlan 10,20
# Verify VLAN configuration
SW1# show vlan brief
SW1# show interfaces trunk
Advanced Features
Packet Capture
# Start packet capture on link
# Right-click on network link
# Select "Start capture"
# Choose capture file location
# View captured packets
# Right-click on link with active capture
# Select "Stop capture"
# Wireshark opens automatically
# Capture filters
# Before starting capture, set filters:
# - Protocol: tcp, udp, icmp
# - Host: host 192.168.1.1
# - Port: port 80 or port 443
Network Automation
# Python script for device configuration
#!/usr/bin/env python3
import telnetlib
import time
def configure_router(host, commands):
"""Configure router via telnet"""
try:
tn = telnetlib.Telnet(host, 23, timeout=10)
# Wait for prompt and enter enable mode
tn.read_until(b">")
tn.write(b"enable\n")
tn.read_until(b"#")
# Enter configuration mode
tn.write(b"configure terminal\n")
tn.read_until(b"(config)#")
# Execute commands
for command in commands:
tn.write(command.encode() + b"\n")
time.sleep(1)
# Exit configuration mode
tn.write(b"exit\n")
tn.write(b"copy running-config startup-config\n")
tn.write(b"\n") # Confirm save
tn.close()
print(f"Configuration completed for {host}")
except Exception as e:
print(f"Error configuring {host}: {e}")
# Configuration commands
router_commands = [
"hostname R1",
"interface fastethernet0/0",
"ip address 192.168.1.1 255.255.255.0",
"no shutdown",
"exit",
"router ospf 1",
"network 192.168.1.0 0.0.0.255 area 0"
]
# Configure router
configure_router("192.168.1.1", router_commands)
Bulk Configuration Script
#!/usr/bin/env python3
import concurrent.futures
import telnetlib
import time
import json
class GNS3Configurator:
def __init__(self, config_file):
"""Initialize with configuration file"""
with open(config_file, 'r') as f:
self.config = json.load(f)
def configure_device(self, device):
"""Configure individual device"""
host = device['host']
commands = device['commands']
device_type = device.get('type', 'router')
try:
tn = telnetlib.Telnet(host, 23, timeout=10)
if device_type == 'router':
self._configure_router(tn, commands)
elif device_type == 'switch':
self._configure_switch(tn, commands)
tn.close()
return f"✓ {host} configured successfully"
except Exception as e:
return f"✗ {host} failed: {e}"
def _configure_router(self, tn, commands):
"""Configure router device"""
tn.read_until(b">")
tn.write(b"enable\n")
tn.read_until(b"#")
tn.write(b"configure terminal\n")
tn.read_until(b"(config)#")
for command in commands:
tn.write(command.encode() + b"\n")
time.sleep(0.5)
tn.write(b"exit\n")
tn.write(b"copy running-config startup-config\n")
tn.write(b"\n")
def _configure_switch(self, tn, commands):
"""Configure switch device"""
tn.read_until(b">")
tn.write(b"enable\n")
tn.read_until(b"#")
tn.write(b"configure terminal\n")
tn.read_until(b"(config)#")
for command in commands:
tn.write(command.encode() + b"\n")
time.sleep(0.5)
tn.write(b"exit\n")
tn.write(b"copy running-config startup-config\n")
tn.write(b"\n")
def configure_all(self, max_workers=5):
"""Configure all devices concurrently"""
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = [executor.submit(self.configure_device, device)
for device in self.config['devices']]
for future in concurrent.futures.as_completed(futures):
print(future.result())
# Example configuration file (config.json)
config_example = {
"devices": [
{
"host": "192.168.1.1",
"type": "router",
"commands": [
"hostname R1",
"interface fastethernet0/0",
"ip address 192.168.1.1 255.255.255.0",
"no shutdown"
]
},
{
"host": "192.168.1.2",
"type": "switch",
"commands": [
"hostname SW1",
"vlan 10",
"name SALES",
"exit"
]
}
]
}
# Usage
if __name__ == "__main__":
configurator = GNS3Configurator("config.json")
configurator.configure_all()
Testing and Validation
Connectivity Testing
# Basic connectivity tests
# From VPCS or router
ping 192.168.1.1
ping 8.8.8.8
# Traceroute testing
trace 192.168.1.1
trace 8.8.8.8
# Extended ping from router
R1# ping
Protocol [ip]:
Target IP address: 192.168.1.2
Repeat count [5]: 100
Datagram size [100]: 1500
Timeout in seconds [2]: 5
Extended commands [n]: y
Source address or interface: 192.168.1.1
Type of service [0]:
Set DF bit in IP header? [no]:
Validate reply data? [no]:
Data pattern [0xABCD]:
Loose, Strict, Record, Timestamp, Verbose[none]:
Sweep range of sizes [n]:
Network Validation Script
#!/usr/bin/env python3
import subprocess
import json
import time
from datetime import datetime
class NetworkValidator:
def __init__(self, test_config):
"""Initialize with test configuration"""
self.tests = test_config
self.results = []
def ping_test(self, source, target, count=5):
"""Perform ping test"""
try:
# Use system ping command
result = subprocess.run(
['ping', '-c', str(count), target],
capture_output=True,
text=True,
timeout=30
)
success = result.returncode == 0
output = result.stdout if success else result.stderr
return {
'test': 'ping',
'source': source,
'target': target,
'success': success,
'output': output,
'timestamp': datetime.now().isoformat()
}
except Exception as e:
return {
'test': 'ping',
'source': source,
'target': target,
'success': False,
'error': str(e),
'timestamp': datetime.now().isoformat()
}
def traceroute_test(self, source, target):
"""Perform traceroute test"""
try:
result = subprocess.run(
['traceroute', target],
capture_output=True,
text=True,
timeout=60
)
success = result.returncode == 0
output = result.stdout if success else result.stderr
return {
'test': 'traceroute',
'source': source,
'target': target,
'success': success,
'output': output,
'timestamp': datetime.now().isoformat()
}
except Exception as e:
return {
'test': 'traceroute',
'source': source,
'target': target,
'success': False,
'error': str(e),
'timestamp': datetime.now().isoformat()
}
def run_all_tests(self):
"""Run all configured tests"""
print("Starting network validation tests...")
for test in self.tests:
test_type = test['type']
source = test['source']
target = test['target']
print(f"Running {test_type} from {source} to {target}")
if test_type == 'ping':
result = self.ping_test(source, target, test.get('count', 5))
elif test_type == 'traceroute':
result = self.traceroute_test(source, target)
self.results.append(result)
# Wait between tests
time.sleep(test.get('delay', 1))
def generate_report(self, output_file='network_test_report.json'):
"""Generate test report"""
report = {
'test_run': datetime.now().isoformat(),
'total_tests': len(self.results),
'passed': sum(1 for r in self.results if r['success']),
'failed': sum(1 for r in self.results if not r['success']),
'results': self.results
}
with open(output_file, 'w') as f:
json.dump(report, f, indent=2)
print(f"Test report saved to {output_file}")
return report
# Example test configuration
test_config = [
{
'type': 'ping',
'source': 'local',
'target': '192.168.1.1',
'count': 10,
'delay': 2
},
{
'type': 'ping',
'source': 'local',
'target': '192.168.1.2',
'count': 5,
'delay': 1
},
{
'type': 'traceroute',
'source': 'local',
'target': '8.8.8.8',
'delay': 3
}
]
# Usage
if __name__ == "__main__":
validator = NetworkValidator(test_config)
validator.run_all_tests()
report = validator.generate_report()
print(f"\nTest Summary:")
print(f"Total tests: {report['total_tests']}")
print(f"Passed: {report['passed']}")
print(f"Failed: {report['failed']}")
Performance Optimization
Resource Management
# Optimize GNS3 performance
# Edit > Preferences > General
# - Check "Use local server"
# - Adjust "Console delay" to 500ms
# - Enable "Auto start console applications"
# Memory optimization
# Edit > Preferences > QEMU
# - Reduce RAM allocation for devices
# - Use linked clones when possible
# - Enable KVM acceleration (Linux)
# CPU optimization
# Edit > Preferences > General
# - Limit CPU usage per device
# - Use multi-core allocation wisely
# - Calculate Idle-PC for Cisco routers
Performance Monitoring Script
#!/usr/bin/env python3
import psutil
import time
import json
from datetime import datetime
class GNS3Monitor:
def __init__(self, interval=5):
"""Initialize performance monitor"""
self.interval = interval
self.data = []
def get_system_stats(self):
"""Get current system statistics"""
return {
'timestamp': datetime.now().isoformat(),
'cpu_percent': psutil.cpu_percent(interval=1),
'memory_percent': psutil.virtual_memory().percent,
'memory_used_gb': psutil.virtual_memory().used / (1024**3),
'memory_total_gb': psutil.virtual_memory().total / (1024**3),
'disk_usage_percent': psutil.disk_usage('/').percent,
'network_io': dict(psutil.net_io_counters()._asdict())
}
def get_gns3_processes(self):
"""Get GNS3-related process information"""
gns3_processes = []
for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
try:
if 'gns3' in proc.info['name'].lower() or 'qemu' in proc.info['name'].lower():
gns3_processes.append(proc.info)
except (psutil.NoSuchProcess, psutil.AccessDenied):
pass
return gns3_processes
def monitor(self, duration_minutes=10):
"""Monitor system for specified duration"""
end_time = time.time() + (duration_minutes * 60)
print(f"Starting {duration_minutes}-minute monitoring session...")
while time.time() < end_time:
stats = self.get_system_stats()
stats['gns3_processes'] = self.get_gns3_processes()
self.data.append(stats)
print(f"CPU: {stats['cpu_percent']:.1f}% | "
f"Memory: {stats['memory_percent']:.1f}% | "
f"GNS3 Processes: {len(stats['gns3_processes'])}")
time.sleep(self.interval)
def save_report(self, filename='gns3_performance_report.json'):
"""Save monitoring data to file"""
with open(filename, 'w') as f:
json.dump(self.data, f, indent=2)
print(f"Performance report saved to {filename}")
def analyze_performance(self):
"""Analyze performance data"""
if not self.data:
print("No data to analyze")
return
cpu_values = [d['cpu_percent'] for d in self.data]
memory_values = [d['memory_percent'] for d in self.data]
analysis = {
'duration_minutes': len(self.data) * self.interval / 60,
'cpu_stats': {
'average': sum(cpu_values) / len(cpu_values),
'max': max(cpu_values),
'min': min(cpu_values)
},
'memory_stats': {
'average': sum(memory_values) / len(memory_values),
'max': max(memory_values),
'min': min(memory_values)
},
'recommendations': []
}
# Generate recommendations
if analysis['cpu_stats']['average'] > 80:
analysis['recommendations'].append("High CPU usage detected. Consider reducing device count or optimizing configurations.")
if analysis['memory_stats']['average'] > 80:
analysis['recommendations'].append("High memory usage detected. Consider reducing RAM allocation for devices.")
return analysis
# Usage
if __name__ == "__main__":
monitor = GNS3Monitor(interval=5)
monitor.monitor(duration_minutes=10)
monitor.save_report()
analysis = monitor.analyze_performance()
print("\nPerformance Analysis:")
print(f"Average CPU: {analysis['cpu_stats']['average']:.1f}%")
print(f"Average Memory: {analysis['memory_stats']['average']:.1f}%")
if analysis['recommendations']:
print("\nRecommendations:")
for rec in analysis['recommendations']:
print(f"- {rec}")
Troubleshooting
Common Issues and Solutions
# Issue: Devices won't start
# Solution: Check virtualization settings
# 1. Verify VMware/VirtualBox installation
# 2. Check hardware virtualization in BIOS
# 3. Ensure sufficient system resources
# Issue: Console connection fails
# Solution: Check console settings
# Edit > Preferences > General > Console applications
# - Telnet: Use built-in terminal
# - SSH: Configure SSH client path
# Issue: High CPU usage
# Solution: Calculate Idle-PC for Cisco routers
# Right-click router > Idle-PC > Calculate
# Apply calculated value to reduce CPU usage
# Issue: Network connectivity problems
# Solution: Check interface status
show ip interface brief
show interfaces
show ip route
# Issue: GNS3 server connection problems
# Solution: Restart GNS3 server
sudo systemctl restart gns3-server
# Or manually:
gns3server --host 0.0.0.0 --port 3080
Diagnostic Script
#!/usr/bin/env python3
import subprocess
import platform
import psutil
import socket
import json
from datetime import datetime
class GNS3Diagnostics:
def __init__(self):
"""Initialize diagnostics"""
self.results = {}
def check_system_requirements(self):
"""Check system requirements"""
system_info = {
'platform': platform.platform(),
'processor': platform.processor(),
'architecture': platform.architecture(),
'cpu_count': psutil.cpu_count(),
'memory_gb': psutil.virtual_memory().total / (1024**3),
'disk_space_gb': psutil.disk_usage('/').free / (1024**3)
}
# Check minimum requirements
requirements_met = {
'cpu_cores': system_info['cpu_count'] >= 2,
'memory': system_info['memory_gb'] >= 4,
'disk_space': system_info['disk_space_gb'] >= 10
}
self.results['system_requirements'] = {
'info': system_info,
'requirements_met': requirements_met,
'all_requirements_met': all(requirements_met.values())
}
def check_virtualization(self):
"""Check virtualization support"""
virt_support = {}
try:
# Check for hardware virtualization
if platform.system() == "Linux":
result = subprocess.run(['grep', '-E', '(vmx|svm)', '/proc/cpuinfo'],
capture_output=True, text=True)
virt_support['hardware_virt'] = result.returncode == 0
# Check KVM
result = subprocess.run(['lsmod'], capture_output=True, text=True)
virt_support['kvm_loaded'] = 'kvm' in result.stdout
elif platform.system() == "Windows":
# Check Hyper-V capability
result = subprocess.run(['systeminfo'], capture_output=True, text=True)
virt_support['hyper_v'] = 'Hyper-V' in result.stdout
except Exception as e:
virt_support['error'] = str(e)
self.results['virtualization'] = virt_support
def check_network_connectivity(self):
"""Check network connectivity"""
connectivity = {}
# Test internet connectivity
try:
socket.create_connection(("8.8.8.8", 53), timeout=5)
connectivity['internet'] = True
except:
connectivity['internet'] = False
# Test GNS3 server port
try:
socket.create_connection(("127.0.0.1", 3080), timeout=5)
connectivity['gns3_server'] = True
except:
connectivity['gns3_server'] = False
self.results['network'] = connectivity
def check_gns3_installation(self):
"""Check GNS3 installation"""
installation = {}
try:
# Check GNS3 version
result = subprocess.run(['gns3', '--version'],
capture_output=True, text=True)
installation['gns3_installed'] = result.returncode == 0
installation['gns3_version'] = result.stdout.strip() if result.returncode == 0 else None
except FileNotFoundError:
installation['gns3_installed'] = False
try:
# Check GNS3 server
result = subprocess.run(['gns3server', '--version'],
capture_output=True, text=True)
installation['gns3server_installed'] = result.returncode == 0
installation['gns3server_version'] = result.stdout.strip() if result.returncode == 0 else None
except FileNotFoundError:
installation['gns3server_installed'] = False
self.results['installation'] = installation
def check_processes(self):
"""Check running GNS3 processes"""
processes = []
for proc in psutil.process_iter(['pid', 'name', 'status', 'cpu_percent', 'memory_percent']):
try:
if any(keyword in proc.info['name'].lower() for keyword in ['gns3', 'qemu', 'vmware', 'virtualbox']):
processes.append(proc.info)
except (psutil.NoSuchProcess, psutil.AccessDenied):
pass
self.results['processes'] = processes
def run_all_checks(self):
"""Run all diagnostic checks"""
print("Running GNS3 diagnostics...")
self.check_system_requirements()
print("✓ System requirements checked")
self.check_virtualization()
print("✓ Virtualization support checked")
self.check_network_connectivity()
print("✓ Network connectivity checked")
self.check_gns3_installation()
print("✓ GNS3 installation checked")
self.check_processes()
print("✓ Running processes checked")
self.results['timestamp'] = datetime.now().isoformat()
def generate_report(self, filename='gns3_diagnostics.json'):
"""Generate diagnostic report"""
with open(filename, 'w') as f:
json.dump(self.results, f, indent=2)
print(f"\nDiagnostic report saved to {filename}")
# Print summary
print("\n=== DIAGNOSTIC SUMMARY ===")
# System requirements
req = self.results['system_requirements']
print(f"System Requirements: {'✓ PASS' if req['all_requirements_met'] else '✗ FAIL'}")
# Network
net = self.results['network']
print(f"Internet Connectivity: {'✓ PASS' if net['internet'] else '✗ FAIL'}")
print(f"GNS3 Server: {'✓ RUNNING' if net['gns3_server'] else '✗ NOT RUNNING'}")
# Installation
inst = self.results['installation']
print(f"GNS3 GUI: {'✓ INSTALLED' if inst['gns3_installed'] else '✗ NOT FOUND'}")
print(f"GNS3 Server: {'✓ INSTALLED' if inst['gns3server_installed'] else '✗ NOT FOUND'}")
# Processes
proc_count = len(self.results['processes'])
print(f"Related Processes: {proc_count} found")
# Usage
if __name__ == "__main__":
diagnostics = GNS3Diagnostics()
diagnostics.run_all_checks()
diagnostics.generate_report()
Integration and Automation
CI/CD Integration
# GitHub Actions workflow for GNS3 testing
name: Network Testing with GNS3
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
network-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install GNS3
run: |
sudo add-apt-repository ppa:gns3/ppa
sudo apt update
sudo apt install -y gns3-server gns3-gui
sudo apt install -y qemu-kvm qemu-utils libvirt-daemon-system
- name: Start GNS3 Server
run: |
gns3server --host 0.0.0.0 --port 3080 &
sleep 10
- name: Import Test Project
run: |
# Import GNS3 project from repository
gns3 --import test-topology.gns3project
- name: Run Network Tests
run: |
python3 network_tests.py
- name: Generate Test Report
run: |
python3 generate_report.py
- name: Upload Test Results
uses: actions/upload-artifact@v2
with:
name: test-results
path: test-results/
Jenkins Pipeline
pipeline {
agent any
stages {
stage('Setup GNS3') {
steps {
script {
// Start GNS3 server
sh 'docker run -d --name gns3-server --privileged -p 3080:3080 gns3/gns3server'
// Wait for server to start
sh 'sleep 30'
}
}
}
stage('Deploy Network') {
steps {
script {
// Import and start network topology
sh 'python3 deploy_network.py'
}
}
}
stage('Run Tests') {
steps {
script {
// Execute network tests
sh 'python3 run_network_tests.py'
}
}
}
stage('Generate Report') {
steps {
script {
// Generate test report
sh 'python3 generate_test_report.py'
}
// Archive test results
archiveArtifacts artifacts: 'test-results/**/*', fingerprint: true
// Publish test results
publishTestResults testResultsPattern: 'test-results/*.xml'
}
}
}
post {
always {
// Cleanup
sh 'docker stop gns3-server || true'
sh 'docker rm gns3-server || true'
}
failure {
// Send notification on failure
emailext (
subject: "Network Test Failed: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
body: "Network testing failed. Check console output for details.",
to: "${env.CHANGE_AUTHOR_EMAIL}"
)
}
}
}
REST API Integration
#!/usr/bin/env python3
import requests
import json
import time
class GNS3API:
def __init__(self, server_url="http://localhost:3080"):
"""Initialize GNS3 API client"""
self.base_url = server_url
self.session = requests.Session()
def get_projects(self):
"""Get list of projects"""
response = self.session.get(f"{self.base_url}/v2/projects")
return response.json()
def create_project(self, name, path=None):
"""Create new project"""
data = {"name": name}
if path:
data["path"] = path
response = self.session.post(f"{self.base_url}/v2/projects", json=data)
return response.json()
def get_project_nodes(self, project_id):
"""Get nodes in project"""
response = self.session.get(f"{self.base_url}/v2/projects/{project_id}/nodes")
return response.json()
def start_node(self, project_id, node_id):
"""Start a node"""
response = self.session.post(f"{self.base_url}/v2/projects/{project_id}/nodes/{node_id}/start")
return response.status_code == 200
def stop_node(self, project_id, node_id):
"""Stop a node"""
response = self.session.post(f"{self.base_url}/v2/projects/{project_id}/nodes/{node_id}/stop")
return response.status_code == 200
def get_node_status(self, project_id, node_id):
"""Get node status"""
response = self.session.get(f"{self.base_url}/v2/projects/{project_id}/nodes/{node_id}")
return response.json().get('status')
def start_all_nodes(self, project_id):
"""Start all nodes in project"""
nodes = self.get_project_nodes(project_id)
for node in nodes:
node_id = node['node_id']
print(f"Starting node: {node['name']}")
self.start_node(project_id, node_id)
time.sleep(2) # Wait between starts
def stop_all_nodes(self, project_id):
"""Stop all nodes in project"""
nodes = self.get_project_nodes(project_id)
for node in nodes:
node_id = node['node_id']
print(f"Stopping node: {node['name']}")
self.stop_node(project_id, node_id)
def wait_for_nodes_ready(self, project_id, timeout=300):
"""Wait for all nodes to be ready"""
start_time = time.time()
while time.time() - start_time < timeout:
nodes = self.get_project_nodes(project_id)
all_started = True
for node in nodes:
status = self.get_node_status(project_id, node['node_id'])
if status != 'started':
all_started = False
break
if all_started:
print("All nodes are ready")
return True
print("Waiting for nodes to start...")
time.sleep(10)
print("Timeout waiting for nodes to start")
return False
# Example usage
def automated_network_test():
"""Automated network testing workflow"""
api = GNS3API()
# Get projects
projects = api.get_projects()
print(f"Found {len(projects)} projects")
# Use first project or create new one
if projects:
project_id = projects[0]['project_id']
project_name = projects[0]['name']
else:
project = api.create_project("Automated Test Network")
project_id = project['project_id']
project_name = project['name']
print(f"Using project: {project_name}")
# Start all nodes
print("Starting all nodes...")
api.start_all_nodes(project_id)
# Wait for nodes to be ready
if api.wait_for_nodes_ready(project_id):
print("Network is ready for testing")
# Run your network tests here
# test_network_connectivity()
# test_routing_protocols()
# etc.
else:
print("Failed to start network")
# Stop all nodes
print("Stopping all nodes...")
api.stop_all_nodes(project_id)
if __name__ == "__main__":
automated_network_test()
Best Practices
Project Organization
# Organize projects by purpose
/GNS3/Projects/
├── CCNA-Labs/
│ ├── Basic-Routing/
│ ├── VLAN-Configuration/
│ └── OSPF-Lab/
├── Security-Labs/
│ ├── Firewall-Configuration/
│ └── VPN-Setup/
└── Production-Testing/
├── Network-Migration/
└── Performance-Testing/
# Use descriptive naming conventions
# Project: CCNA-OSPF-Lab-v2.1
# Devices: R1-Core, R2-Distribution, SW1-Access
# Links: R1-R2-WAN, SW1-R2-LAN
Configuration Management
# Save device configurations regularly
# Router configuration backup
R1# copy running-config tftp://192.168.1.100/R1-config-backup.txt
# Automated backup script
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backup/gns3-configs/$DATE"
mkdir -p $BACKUP_DIR
# List of device IPs
DEVICES=("192.168.1.1" "192.168.1.2" "192.168.1.3")
for device in "${DEVICES[@]}"; do
echo "Backing up $device..."
# Use expect or similar tool for automated backup
expect backup_device.exp $device $BACKUP_DIR
done
Security Considerations
# Secure GNS3 server access
# Bind to specific interface
gns3server --host 192.168.1.100 --port 3080
# Use authentication (if available)
# Configure in ~/.config/GNS3/2.2/gns3_server.conf
[Server]
auth = true
user = admin
password = secure_password
# Network isolation
# Use separate network segments for lab traffic
# Avoid bridging lab networks to production
Performance Optimization
# Optimize device settings
# Reduce unnecessary services on routers
R1(config)# no ip http server
R1(config)# no ip http secure-server
R1(config)# no cdp run
R1(config)# no service pad
# Use efficient topologies
# Minimize unnecessary connections
# Use switches instead of hubs
# Implement proper network segmentation
# Resource allocation
# Allocate RAM based on actual needs
# Use linked clones for similar devices
# Enable hardware acceleration when available
Advanced Scripting and Automation
Network Discovery Script
#!/usr/bin/env python3
import subprocess
import ipaddress
import concurrent.futures
import json
from datetime import datetime
class NetworkDiscovery:
def __init__(self, network_range):
"""Initialize network discovery"""
self.network = ipaddress.IPv4Network(network_range)
self.discovered_hosts = []
def ping_host(self, ip):
"""Ping individual host"""
try:
result = subprocess.run(
['ping', '-c', '1', '-W', '1', str(ip)],
capture_output=True,
text=True
)
if result.returncode == 0:
return {
'ip': str(ip),
'status': 'up',
'response_time': self._extract_ping_time(result.stdout)
}
except Exception:
pass
return None
def _extract_ping_time(self, ping_output):
"""Extract ping response time from output"""
try:
for line in ping_output.split('\n'):
if 'time=' in line:
time_part = line.split('time=')[1].split()[0]
return float(time_part)
except:
pass
return None
def discover_network(self, max_workers=50):
"""Discover all hosts in network"""
print(f"Discovering hosts in {self.network}...")
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = [executor.submit(self.ping_host, ip) for ip in self.network.hosts()]
for future in concurrent.futures.as_completed(futures):
result = future.result()
if result:
self.discovered_hosts.append(result)
print(f"Found host: {result['ip']} ({result['response_time']}ms)")
def port_scan(self, ip, ports=[22, 23, 80, 443, 3080]):
"""Scan common ports on discovered host"""
open_ports = []
for port in ports:
try:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
result = sock.connect_ex((ip, port))
sock.close()
if result == 0:
open_ports.append(port)
except:
pass
return open_ports
def detailed_scan(self):
"""Perform detailed scan on discovered hosts"""
print("Performing detailed scan...")
for host in self.discovered_hosts:
ip = host['ip']
print(f"Scanning {ip}...")
# Port scan
open_ports = self.port_scan(ip)
host['open_ports'] = open_ports
# Try to identify device type
if 23 in open_ports: # Telnet
host['device_type'] = 'network_device'
elif 3080 in open_ports: # GNS3 server
host['device_type'] = 'gns3_server'
elif 80 in open_ports or 443 in open_ports:
host['device_type'] = 'web_server'
else:
host['device_type'] = 'unknown'
def generate_report(self, filename='network_discovery.json'):
"""Generate discovery report"""
report = {
'scan_time': datetime.now().isoformat(),
'network_range': str(self.network),
'total_hosts': len(self.discovered_hosts),
'hosts': self.discovered_hosts
}
with open(filename, 'w') as f:
json.dump(report, f, indent=2)
print(f"Discovery report saved to {filename}")
return report
# Usage
if __name__ == "__main__":
# Discover GNS3 lab network
discovery = NetworkDiscovery("192.168.1.0/24")
discovery.discover_network()
discovery.detailed_scan()
report = discovery.generate_report()
print(f"\nDiscovery Summary:")
print(f"Network: {report['network_range']}")
print(f"Hosts found: {report['total_hosts']}")
for host in report['hosts']:
print(f" {host['ip']} - {host['device_type']} - Ports: {host['open_ports']}")
Configuration Compliance Checker
#!/usr/bin/env python3
import telnetlib
import re
import json
from datetime import datetime
class ComplianceChecker:
def __init__(self, compliance_rules):
"""Initialize with compliance rules"""
self.rules = compliance_rules
self.results = []
def connect_device(self, host, username="", password=""):
"""Connect to network device"""
try:
tn = telnetlib.Telnet(host, 23, timeout=10)
if username:
tn.read_until(b"Username:")
tn.write(username.encode() + b"\n")
tn.read_until(b"Password:")
tn.write(password.encode() + b"\n")
tn.read_until(b">")
tn.write(b"enable\n")
tn.read_until(b"#")
return tn
except Exception as e:
print(f"Failed to connect to {host}: {e}")
return None
def get_running_config(self, tn):
"""Get running configuration"""
tn.write(b"show running-config\n")
tn.write(b" ") # Space to continue
config = ""
while True:
output = tn.read_until(b"#", timeout=5).decode()
config += output
if "#" in output and "More" not in output:
break
tn.write(b" ") # Continue reading
return config
def check_rule(self, config, rule):
"""Check individual compliance rule"""
rule_type = rule['type']
pattern = rule['pattern']
description = rule['description']
severity = rule.get('severity', 'medium')
if rule_type == 'required':
# Pattern must be present
match = re.search(pattern, config, re.MULTILINE | re.IGNORECASE)
compliant = match is not None
elif rule_type == 'forbidden':
# Pattern must not be present
match = re.search(pattern, config, re.MULTILINE | re.IGNORECASE)
compliant = match is None
else:
compliant = False
return {
'rule': description,
'type': rule_type,
'pattern': pattern,
'severity': severity,
'compliant': compliant,
'match': match.group() if match else None
}
def check_device_compliance(self, host, username="", password=""):
"""Check compliance for single device"""
print(f"Checking compliance for {host}...")
tn = self.connect_device(host, username, password)
if not tn:
return None
try:
config = self.get_running_config(tn)
tn.close()
device_results = {
'host': host,
'timestamp': datetime.now().isoformat(),
'rules_checked': len(self.rules),
'compliant_rules': 0,
'non_compliant_rules': 0,
'rule_results': []
}
for rule in self.rules:
result = self.check_rule(config, rule)
device_results['rule_results'].append(result)
if result['compliant']:
device_results['compliant_rules'] += 1
else:
device_results['non_compliant_rules'] += 1
device_results['compliance_percentage'] = (
device_results['compliant_rules'] / device_results['rules_checked'] * 100
)
self.results.append(device_results)
return device_results
except Exception as e:
print(f"Error checking {host}: {e}")
tn.close()
return None
def generate_compliance_report(self, filename='compliance_report.json'):
"""Generate compliance report"""
if not self.results:
print("No compliance data to report")
return
# Calculate overall statistics
total_devices = len(self.results)
total_rules = sum(r['rules_checked'] for r in self.results)
total_compliant = sum(r['compliant_rules'] for r in self.results)
report = {
'report_time': datetime.now().isoformat(),
'summary': {
'total_devices': total_devices,
'total_rules_checked': total_rules,
'total_compliant_rules': total_compliant,
'overall_compliance_percentage': (total_compliant / total_rules * 100) if total_rules > 0 else 0
},
'device_results': self.results
}
with open(filename, 'w') as f:
json.dump(report, f, indent=2)
print(f"Compliance report saved to {filename}")
# Print summary
print(f"\nCompliance Summary:")
print(f"Devices checked: {total_devices}")
print(f"Overall compliance: {report['summary']['overall_compliance_percentage']:.1f}%")
# Show non-compliant devices
for device in self.results:
if device['compliance_percentage'] < 100:
print(f" {device['host']}: {device['compliance_percentage']:.1f}% compliant")
return report
# Example compliance rules
compliance_rules = [
{
'type': 'required',
'pattern': r'service password-encryption',
'description': 'Password encryption must be enabled',
'severity': 'high'
},
{
'type': 'required',
'pattern': r'no ip http server',
'description': 'HTTP server must be disabled',
'severity': 'medium'
},
{
'type': 'required',
'pattern': r'banner motd',
'description': 'Login banner must be configured',
'severity': 'low'
},
{
'type': 'forbidden',
'pattern': r'username.*password 0',
'description': 'Plain text passwords are forbidden',
'severity': 'high'
},
{
'type': 'required',
'pattern': r'logging \d+\.\d+\.\d+\.\d+',
'description': 'Syslog server must be configured',
'severity': 'medium'
}
]
# Usage
if __name__ == "__main__":
checker = ComplianceChecker(compliance_rules)
# Check multiple devices
devices = ["192.168.1.1", "192.168.1.2", "192.168.1.3"]
for device in devices:
checker.check_device_compliance(device)
# Generate report
checker.generate_compliance_report()
This comprehensive GNS3 cheatsheet provides extensive coverage of network simulation, device configuration, automation, and professional network testing workflows. The included scripts and examples enable advanced network engineering tasks and integration with modern DevOps practices.