Fortigate-lab.yaml
lab:
description: |
FortiGate Practice Lab — clean canvas for FortiGate config practice.
Topology: EXT-USER -- INET-R1 -- FortiGate(port1/2/3) -- SW1 -- PC1/PC2,
with DMZ-SRV on port3.
Interfaces:
port1 outside 203.0.113.2/28 gw 203.0.113.1
port2 inside 192.168.1.1/24
port3 dmz 172.16.10.1/24
Hosts:
PC1 192.168.1.10 PC2 192.168.1.11
DMZ-SRV 172.16.10.10 (HTTP/HTTPS listeners)
EXT-USER 198.51.100.10
Public destinations: 8.8.8.8, 1.1.1.1 (INET-R1 loopbacks)
Public VIP target: 203.0.113.10 (you create this)
Credentials: FortiGate admin/(blank, set on first login). PCs cisco/cisco.
See companion file fortigate-practice-exercises.md for the 10 exercises
and stretch goals.
notes: ''
timestamp: 1714780800.0
title: FortiGate-Practice-Lab
version: 0.3.0
nodes:
# ──────────────────────────────────────────────────────────────────
# INET-R1 — Simulated ISP / internet edge router
# Provides "public" destinations (Lo0=8.8.8.8, Lo1=1.1.1.1) and the
# 203.0.113.0/28 outside link toward FortiGate. EXT-USER hangs off Gi0/1.
# ──────────────────────────────────────────────────────────────────
- id: n0
label: INET-R1
node_definition: iosv
x: -400
y: 0
ram: 512
configuration: |
hostname INET-R1
no ip domain lookup
!
interface Loopback0
description Simulated 8.8.8.8
ip address 8.8.8.8 255.255.255.255
!
interface Loopback1
description Simulated 1.1.1.1
ip address 1.1.1.1 255.255.255.255
!
interface GigabitEthernet0/0
description To FortiGate port1
ip address 203.0.113.1 255.255.255.240
no shutdown
!
interface GigabitEthernet0/1
description To EXT-USER LAN
ip address 198.51.100.1 255.255.255.0
no shutdown
!
! VIP 203.0.113.10 sits in the connected /28 — FortiGate replies to ARP.
! No extra route needed.
!
line con 0
logging synchronous
!
end
interfaces:
- id: i0
label: Loopback0
type: loopback
- id: i1
slot: 0
label: GigabitEthernet0/0
type: physical
- id: i2
slot: 1
label: GigabitEthernet0/1
type: physical
# ──────────────────────────────────────────────────────────────────
# FortiGate — uses your custom node definition (id: fortigate)
# Boots with a near-default config. You configure everything from here.
# ──────────────────────────────────────────────────────────────────
- id: n1
label: FortiGate
node_definition: fortigate
x: -150
y: 0
# No configuration block — the FortiGate boots with its default config
# so you can practice the full setup from scratch.
interfaces:
- id: i0
slot: 0
label: p1
type: physical
- id: i1
slot: 1
label: p2
type: physical
- id: i2
slot: 2
label: p3
type: physical
- id: i3
slot: 3
label: p4
type: physical
# ──────────────────────────────────────────────────────────────────
# SW1 — Inside L2 access switch
# ──────────────────────────────────────────────────────────────────
- id: n2
label: SW1
node_definition: iosvl2
x: 100
y: 100
ram: 768
configuration: |
hostname SW1
no ip domain lookup
!
vlan 10
name USERS
!
interface GigabitEthernet0/0
description To FortiGate port2 (inside)
switchport access vlan 10
switchport mode access
spanning-tree portfast
!
interface GigabitEthernet0/1
description PC1
switchport access vlan 10
switchport mode access
spanning-tree portfast
!
interface GigabitEthernet0/2
description PC2
switchport access vlan 10
switchport mode access
spanning-tree portfast
!
interface range GigabitEthernet1/0 - 3
shutdown
!
line con 0
logging synchronous
!
end
interfaces:
- id: i0
label: Loopback0
type: loopback
- id: i1
slot: 0
label: GigabitEthernet0/0
type: physical
- id: i2
slot: 1
label: GigabitEthernet0/1
type: physical
- id: i3
slot: 2
label: GigabitEthernet0/2
type: physical
# ──────────────────────────────────────────────────────────────────
# EXT-USER — External "internet" host
# Use to test inbound to public services (VIP at 203.0.113.10):
# ping 203.0.113.10
# nc -zv 203.0.113.10 80
# nc -zv 203.0.113.10 443
# ──────────────────────────────────────────────────────────────────
- id: n3
label: EXT-USER
node_definition: alpine
x: -550
y: 100
configuration: |
# Sourced as root at boot
hostname ext-user
USERNAME=cisco
PASSWORD=cisco
ip link show eth1 >/dev/null 2>&1 && IF=eth1 || IF=eth0
ip address add 198.51.100.10/24 dev $IF
ip link set dev $IF up
ip route add default via 198.51.100.1
interfaces:
- id: i0
slot: 0
label: eth0
type: physical
# ──────────────────────────────────────────────────────────────────
# DMZ-SRV — DMZ web/host server
# Pre-launches HTTP listeners on 80 and 443 so VIP testing has
# something to hit. Real IP 172.16.10.10 — you'll NAT to 203.0.113.10.
# ──────────────────────────────────────────────────────────────────
- id: n4
label: DMZ-SRV
node_definition: alpine
x: 100
y: -150
configuration: |
# Sourced as root at boot
hostname dmz-srv
USERNAME=cisco
PASSWORD=cisco
ip link show eth1 >/dev/null 2>&1 && IF=eth1 || IF=eth0
ip address add 172.16.10.10/24 dev $IF
ip link set dev $IF up
ip route add default via 172.16.10.1
# Tiny HTTP listeners — respawn after each connection so you can hit
# them repeatedly while testing VIPs.
( while true; do echo -e "HTTP/1.0 200 OK\r\n\r\nDMZ-SRV port 80" | nc -l -p 80 -q 1; done ) &
( while true; do echo -e "HTTP/1.0 200 OK\r\n\r\nDMZ-SRV port 443" | nc -l -p 443 -q 1; done ) &
interfaces:
- id: i0
slot: 0
label: eth0
type: physical
# ──────────────────────────────────────────────────────────────────
# PC1 — Inside user
# ──────────────────────────────────────────────────────────────────
- id: n5
label: PC1
node_definition: alpine
x: 280
y: 50
configuration: |
# Sourced as root at boot
hostname pc1
USERNAME=cisco
PASSWORD=cisco
ip link show eth1 >/dev/null 2>&1 && IF=eth1 || IF=eth0
ip address add 192.168.1.10/24 dev $IF
ip link set dev $IF up
ip route add default via 192.168.1.1
interfaces:
- id: i0
slot: 0
label: eth0
type: physical
# ──────────────────────────────────────────────────────────────────
# PC2 — Inside user
# ──────────────────────────────────────────────────────────────────
- id: n6
label: PC2
node_definition: alpine
x: 280
y: 150
configuration: |
# Sourced as root at boot
hostname pc2
USERNAME=cisco
PASSWORD=cisco
ip link show eth1 >/dev/null 2>&1 && IF=eth1 || IF=eth0
ip address add 192.168.1.11/24 dev $IF
ip link set dev $IF up
ip route add default via 192.168.1.1
interfaces:
- id: i0
slot: 0
label: eth0
type: physical
links:
# INET-R1 Gi0/0 <-> FortiGate port1 (outside / WAN)
- id: l0
n1: n0
i1: i1
n2: n1
i2: i0
label: "INET-R1 to FGT-port1"
# INET-R1 Gi0/1 <-> EXT-USER
- id: l1
n1: n0
i1: i2
n2: n3
i2: i0
label: "INET-R1 to EXT-USER"
# FortiGate port2 <-> SW1 Gi0/0 (inside)
- id: l2
n1: n1
i1: i1
n2: n2
i2: i1
label: "FGT-port2 to SW1"
# FortiGate port3 <-> DMZ-SRV (dmz)
- id: l3
n1: n1
i1: i2
n2: n4
i2: i0
label: "FGT-port3 to DMZ-SRV"
# SW1 Gi0/1 <-> PC1
- id: l4
n1: n2
i1: i2
n2: n5
i2: i0
label: "SW1 to PC1"
# SW1 Gi0/2 <-> PC2
- id: l5
n1: n2
i1: i3
n2: n6
i2: i0
label: "SW1 to PC2"