SiamCafe.net Blog
Technology

IS-IS Protocol Production Setup Guide — ตั้งค่า IS-IS สำหรับ ISP และ Data Center

is is protocol production setup guide
IS-IS Protocol Production Setup Guide | SiamCafe Blog
2025-11-24· อ. บอม — SiamCafe.net· 1,215 คำ

IS-IS Protocol คืออะไรและใช้ที่ไหน

IS-IS (Intermediate System to Intermediate System) เป็น link-state routing protocol ที่ใช้ SPF (Shortest Path First) algorithm เหมือน OSPF แต่ทำงานบน OSI Layer 2 โดยตรง (CLNP) ไม่ต้องพึ่ง IP IS-IS ถูกออกแบบมาตาม ISO 10589 standard และถูกขยายให้รองรับ IPv4/IPv6 ผ่าน Multi-Topology extensions

IS-IS ถูกใช้อย่างแพร่หลายใน ISP (Internet Service Providers) และ large-scale data center networks เนื่องจากข้อดีหลายประการ รองรับ MPLS และ Segment Routing ได้ดี Convergence เร็ว Scale ได้ดีกว่า OSPF ใน large networks เพราะไม่มี area 0 backbone requirement และมี TLV (Type-Length-Value) extensible format ที่เพิ่ม features ใหม่ได้ง่าย

บริษัทที่ใช้ IS-IS ได้แก่ Google, Facebook (Meta), Amazon, Microsoft สำหรับ data center fabrics และ ISPs ขนาดใหญ่เช่น Level 3, NTT, Telia สำหรับ backbone networks

IS-IS แบ่ง routing domain เป็น Level 1 (intra-area) และ Level 2 (inter-area) routers สามารถเป็น L1, L2 หรือ L1/L2 โดย L2 routers สร้าง backbone ที่เชื่อม areas เข้าด้วยกัน ต่างจาก OSPF ที่ต้องมี Area 0

สถาปัตยกรรมและหลักการทำงานของ IS-IS

รายละเอียดทางเทคนิคของ IS-IS architecture

# IS-IS Architecture Overview
#
# === IS-IS Levels ===
# Level 1 (L1): Intra-area routing
#   - Routers ภายใน area เดียวกัน
#   - คล้าย OSPF non-backbone areas
#   - มี L1 LSDB (Link State Database) แยกกัน
#
# Level 2 (L2): Inter-area routing (backbone)
#   - เชื่อม areas เข้าด้วยกัน
#   - คล้าย OSPF Area 0
#   - มี L2 LSDB แยกจาก L1
#
# L1/L2 Router: ทำหน้าที่ทั้ง L1 และ L2
#   - เป็น border router ระหว่าง areas
#   - มีทั้ง L1 และ L2 LSDB
#
# === Network Entity Title (NET) ===
# Format: AFI.Area-ID.System-ID.SEL
# ตัวอย่าง: 49.0001.1921.6800.1001.00
#   49       = AFI (Authority and Format Identifier)
#   0001     = Area ID
#   1921.6800.1001 = System ID (unique per router)
#   00       = SEL (N-Selector, always 00 for routers)
#
# System ID มาจาก Loopback IP:
#   192.168.1.1 -> 1921.6800.1001
#   10.0.0.1    -> 0100.0000.0001
#
# === PDU Types ===
# IIH (IS-IS Hello): neighbor discovery
#   - L1 LAN IIH, L2 LAN IIH, P2P IIH
# LSP (Link State PDU): routing information
#   - L1 LSP, L2 LSP
# CSNP (Complete Sequence Number PDU): database sync
# PSNP (Partial Sequence Number PDU): request/acknowledge LSPs
#
# === Metrics ===
# Default metric: 10 per interface (range 1-63 for narrow, 1-16777215 for wide)
# Wide metrics: ใช้ 24-bit metric (extended IS reachability TLV 22)
# แนะนำใช้ wide metrics เสมอใน production
#
# === DIS (Designated IS) ===
# คล้าย DR ใน OSPF แต่:
# - ไม่มี BDR (Backup DIS)
# - DIS election ทำใหม่ได้ทันทีเมื่อ priority เปลี่ยน (preemptive)
# - DIS ส่ง CSNP ทุก 10 วินาที
# - ทุก router มี adjacency กับทุก router (full mesh)
#
# === Adjacency Formation ===
# 1. Router ส่ง IIH packets
# 2. Neighbor ตอบ IIH กลับ
# 3. Three-way handshake (P2P) หรือ two-way (LAN)
# 4. Exchange LSPs ผ่าน CSNP/PSNP
# 5. SPF calculation
# 6. Routing table update

ตั้งค่า IS-IS บน Cisco IOS Router

Configuration สำหรับ production IS-IS deployment

! === Cisco IOS IS-IS Configuration ===
! Router R1 (L1/L2, Area 49.0001)

! Enable IS-IS process
router isis CORE
 net 49.0001.1921.6800.1001.00
 is-type level-1-2
 metric-style wide
 log-adjacency-changes
 !
 ! Authentication (recommended for production)
 authentication mode md5 level-1
 authentication mode md5 level-2
 authentication key-chain ISIS-KEY level-1
 authentication key-chain ISIS-KEY level-2
 !
 ! Fast convergence
 spf-interval 5 50 200
 prc-interval 5 50 200
 lsp-gen-interval 5 50 200
 !
 ! Overload bit (use during maintenance)
 ! set-overload-bit on-startup wait-for-bgp
 !
 ! Address family for IPv4
 address-family ipv4 unicast
  metric-style wide
  segment-routing mpls
 exit-address-family
 !
 ! Address family for IPv6
 address-family ipv6 unicast
  multi-topology
 exit-address-family

! Interface configuration
interface Loopback0
 ip address 192.168.1.1 255.255.255.255
 ip router isis CORE
 isis circuit-type level-2-only

interface GigabitEthernet0/0
 description To R2 - P2P Link
 ip address 10.0.12.1 255.255.255.252
 ip router isis CORE
 isis circuit-type level-2-only
 isis network point-to-point
 isis metric 100
 ! BFD for fast failure detection
 bfd interval 100 min_rx 100 multiplier 3
 isis bfd

interface GigabitEthernet0/1
 description To LAN Segment
 ip address 10.0.1.1 255.255.255.0
 ip router isis CORE
 isis circuit-type level-1
 isis priority 127
 isis metric 1000

! Key chain for authentication
key chain ISIS-KEY
 key 1
  key-string MySecretISISKey2024!
  accept-lifetime 00:00:00 Jan 1 2024 infinite
  send-lifetime 00:00:00 Jan 1 2024 infinite

! === Router R2 (L2 only, Area 49.0002) ===
router isis CORE
 net 49.0002.1921.6800.2001.00
 is-type level-2-only
 metric-style wide
 log-adjacency-changes
 authentication mode md5 level-2
 authentication key-chain ISIS-KEY level-2

interface Loopback0
 ip address 192.168.2.1 255.255.255.255
 ip router isis CORE

interface GigabitEthernet0/0
 description To R1 - P2P Link
 ip address 10.0.12.2 255.255.255.252
 ip router isis CORE
 isis network point-to-point
 isis metric 100
 isis bfd

! Verification commands
! show isis neighbors
! show isis database
! show isis topology
! show isis route
! show isis interface
! show isis spf-log

IS-IS บน Linux ด้วย FRRouting

ตั้งค่า IS-IS บน Linux server ด้วย FRRouting

# ติดตั้ง FRRouting บน Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y frr frr-pythontools

# เปิด IS-IS daemon
sudo sed -i 's/isisd=no/isisd=yes/' /etc/frr/daemons
sudo systemctl restart frr

# ตั้งค่า IS-IS ผ่าน vtysh
sudo vtysh

# IS-IS Configuration
configure terminal

! Router configuration
router isis FABRIC
 net 49.0001.0100.0000.0001.00
 is-type level-1
 metric-style wide
 log-adjacency-changes
 lsp-gen-interval 5
 spf-interval 50
 !
 ! Segment Routing
 segment-routing on
 segment-routing prefix 10.0.0.1/32 index 1001

! Interface configuration
interface eth0
 ip router isis FABRIC
 isis circuit-type level-1
 isis network point-to-point
 isis metric 100
 isis hello-interval 1
 isis hello-multiplier 3

interface lo
 ip router isis FABRIC
 isis passive

end
write memory

# === FRRouting Configuration File ===
# /etc/frr/isisd.conf
#
# router isis FABRIC
#  net 49.0001.0100.0000.0001.00
#  is-type level-1
#  metric-style wide
#  log-adjacency-changes
# !
# interface eth0
#  ip router isis FABRIC
#  isis circuit-type level-1
#  isis network point-to-point
#  isis metric 100
# !
# interface lo
#  ip router isis FABRIC
#  isis passive

# Verification
sudo vtysh -c "show isis neighbor"
sudo vtysh -c "show isis database"
sudo vtysh -c "show isis route"
sudo vtysh -c "show isis topology"
sudo vtysh -c "show isis interface"

# sysctl settings สำหรับ routing
# /etc/sysctl.d/99-frr.conf
# net.ipv4.ip_forward = 1
# net.ipv6.conf.all.forwarding = 1
# net.ipv4.conf.all.rp_filter = 0
sudo sysctl -p /etc/sysctl.d/99-frr.conf

Monitoring และ Troubleshooting IS-IS

วิธีตรวจสอบและแก้ปัญหา IS-IS

#!/bin/bash
# isis_monitor.sh — IS-IS Health Monitor
set -euo pipefail

VTYSH="sudo vtysh -c"
LOG="/var/log/isis_monitor.log"
ALERT_WEBHOOK=""

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG"; }
alert() {
    log "ALERT: $1"
    [ -n "$ALERT_WEBHOOK" ] && curl -s -X POST "$ALERT_WEBHOOK" \
        -H "Content-Type: application/json" \
        -d "{\"text\":\"[IS-IS] $1\"}" > /dev/null 2>&1 || true
}

ISSUES=0

# 1. Check IS-IS Process
log "Checking IS-IS process..."
if ! $VTYSH "show isis summary" > /dev/null 2>&1; then
    alert "IS-IS process is NOT running"
    ISSUES=$((ISSUES + 1))
fi

# 2. Check Neighbors
log "Checking IS-IS neighbors..."
EXPECTED_NEIGHBORS=""
NEIGHBOR_COUNT=$($VTYSH "show isis neighbor" | grep -c "Up" || echo 0)

if [ "$NEIGHBOR_COUNT" -lt "$EXPECTED_NEIGHBORS" ]; then
    alert "IS-IS neighbors: $NEIGHBOR_COUNT/$EXPECTED_NEIGHBORS (some DOWN)"
    
    # Show which neighbors are down
    $VTYSH "show isis neighbor" | while read -r line; do
        if echo "$line" | grep -q "Down\|Init"; then
            alert "Neighbor issue: $line"
        fi
    done
    ISSUES=$((ISSUES + 1))
fi

# 3. Check LSDB
log "Checking IS-IS database..."
LSP_COUNT=$($VTYSH "show isis database" | grep -c "LSP" || echo 0)
if [ "$LSP_COUNT" -eq 0 ]; then
    alert "IS-IS database is EMPTY"
    ISSUES=$((ISSUES + 1))
fi

# Check for LSP overload bit
if $VTYSH "show isis database detail" | grep -q "Overload bit set"; then
    alert "IS-IS: Overload bit is SET on some LSPs"
fi

# 4. Check SPF runs
log "Checking SPF statistics..."
SPF_RUNS=$($VTYSH "show isis spf-log" | tail -5)
# Check if SPF is running too frequently (possible flapping)
RECENT_SPF=$($VTYSH "show isis spf-log" | grep "$(date '+%H:%M')" | wc -l)
if [ "$RECENT_SPF" -gt 10 ]; then
    alert "IS-IS: Excessive SPF runs ($RECENT_SPF in last minute) — possible flapping"
    ISSUES=$((ISSUES + 1))
fi

# 5. Check interface status
log "Checking IS-IS interfaces..."
$VTYSH "show isis interface" | while read -r line; do
    if echo "$line" | grep -q "Down"; then
        IFACE=$(echo "$line" | awk '{print $1}')
        alert "IS-IS interface DOWN: $IFACE"
        ISSUES=$((ISSUES + 1))
    fi
done

# 6. Check route count
log "Checking IS-IS routes..."
ROUTE_COUNT=$($VTYSH "show isis route" | grep -c "^[0-9]" || echo 0)
EXPECTED_ROUTES=""
if [ "$ROUTE_COUNT" -lt "$EXPECTED_ROUTES" ]; then
    alert "IS-IS routes: $ROUTE_COUNT (expected >= $EXPECTED_ROUTES)"
    ISSUES=$((ISSUES + 1))
fi

# Summary
if [ "$ISSUES" -eq 0 ]; then
    log "IS-IS health: OK (neighbors=$NEIGHBOR_COUNT, LSPs=$LSP_COUNT, routes=$ROUTE_COUNT)"
else
    log "IS-IS health: $ISSUES issue(s) found"
fi

# Cron: ทุก 2 นาที
# */2 * * * * /opt/scripts/isis_monitor.sh

IS-IS Automation ด้วย Python และ Netmiko

Automate IS-IS configuration และ monitoring

#!/usr/bin/env python3
# isis_automation.py — IS-IS Network Automation
from netmiko import ConnectHandler
import json
import re
from datetime import datetime

class ISISAutomation:
    def __init__(self, devices_file="devices.json"):
        with open(devices_file) as f:
            self.devices = json.load(f)
    
    def connect(self, device_name):
        device = self.devices[device_name]
        return ConnectHandler(**device)
    
    def get_isis_neighbors(self, device_name):
        conn = self.connect(device_name)
        output = conn.send_command("show isis neighbors", use_textfsm=True)
        conn.disconnect()
        return output
    
    def get_isis_database(self, device_name):
        conn = self.connect(device_name)
        output = conn.send_command("show isis database")
        conn.disconnect()
        return output
    
    def deploy_isis_config(self, device_name, config_commands):
        conn = self.connect(device_name)
        output = conn.send_config_set(config_commands)
        conn.save_config()
        conn.disconnect()
        return output
    
    def check_all_neighbors(self):
        results = {}
        for name in self.devices:
            try:
                neighbors = self.get_isis_neighbors(name)
                up_count = sum(1 for n in neighbors if n.get("state") == "Up")
                results[name] = {
                    "status": "OK" if up_count > 0 else "WARN",
                    "neighbors_up": up_count,
                    "total": len(neighbors),
                    "details": neighbors,
                }
            except Exception as e:
                results[name] = {"status": "ERROR", "error": str(e)}
        return results
    
    def rolling_metric_change(self, interface, new_metric):
        """Change IS-IS metric with rolling update to avoid traffic black-holes"""
        for name in self.devices:
            config = [
                f"interface {interface}",
                f" isis metric {new_metric}",
            ]
            print(f"Updating {name}: {interface} metric={new_metric}")
            self.deploy_isis_config(name, config)
            
            # Wait for convergence
            import time
            time.sleep(10)
            
            # Verify neighbors still up
            neighbors = self.get_isis_neighbors(name)
            up = sum(1 for n in neighbors if n.get("state") == "Up")
            if up == 0:
                print(f"WARNING: No neighbors up on {name} after metric change!")
                # Rollback
                config = [f"interface {interface}", f" no isis metric"]
                self.deploy_isis_config(name, config)
                return False
        
        print("Rolling metric change complete")
        return True
    
    def generate_report(self):
        report = {
            "timestamp": datetime.now().isoformat(),
            "devices": {},
        }
        
        for name in self.devices:
            try:
                neighbors = self.get_isis_neighbors(name)
                report["devices"][name] = {
                    "neighbors": len(neighbors),
                    "neighbors_up": sum(1 for n in neighbors if n.get("state") == "Up"),
                }
            except Exception as e:
                report["devices"][name] = {"error": str(e)}
        
        with open(f"isis_report_{datetime.now().strftime('%Y%m%d')}.json", "w") as f:
            json.dump(report, f, indent=2)
        
        return report

# devices.json example:
# {
#   "r1": {
#     "device_type": "cisco_ios",
#     "host": "10.0.0.1",
#     "username": "admin",
#     "password": "secure_pass",
#     "secret": "enable_pass"
#   },
#   "r2": {
#     "device_type": "cisco_ios",
#     "host": "10.0.0.2",
#     "username": "admin",
#     "password": "secure_pass"
#   }
# }

if __name__ == "__main__":
    auto = ISISAutomation()
    results = auto.check_all_neighbors()
    for device, status in results.items():
        print(f"{device}: {status['status']} ({status.get('neighbors_up', 0)} neighbors up)")

FAQ คำถามที่พบบ่อย

Q: IS-IS กับ OSPF ใช้อันไหนดีกว่า?

A: สำหรับ enterprise networks ขนาดเล็กถึงกลาง OSPF เหมาะกว่าเพราะผู้ดูแลส่วนใหญ่คุ้นเคย สำหรับ ISP, large data centers หรือ networks ที่ต้องการ Segment Routing IS-IS เหมาะกว่าเพราะ scale ได้ดีกว่า extensible ผ่าน TLV และไม่มี area 0 constraint Google, Meta, Amazon ใช้ IS-IS สำหรับ data center fabrics

Q: NET address ตั้งยังไง?

A: NET format คือ AFI.AreaID.SystemID.SEL โดย AFI ใช้ 49 สำหรับ private addressing, Area ID ใช้เลขที่ไม่ซ้ำกันต่อ area (เช่น 0001, 0002), System ID ใช้ 6 bytes ที่ unique ต่อ router (แปลงจาก loopback IP เช่น 192.168.1.1 เป็น 1921.6800.1001) และ SEL ใช้ 00 สำหรับ router เสมอ

Q: IS-IS convergence เร็วแค่ไหน?

A: ด้วย tuning ที่เหมาะสม IS-IS convergence อยู่ที่ 50-200ms โดยใช้ BFD สำหรับ fast failure detection (50ms), IS-IS hello interval 1 วินาที, SPF delay 50ms และ wide metrics การใช้ Prefix-SID (Segment Routing) ช่วยให้ traffic สลับเส้นทางได้เร็วยิ่งขึ้นผ่าน TI-LFA (Topology Independent Loop-Free Alternate)

Q: IS-IS รองรับ IPv6 อย่างไร?

A: IS-IS รองรับ IPv6 ผ่าน Multi-Topology IS-IS (RFC 5120) ที่แยก topology สำหรับ IPv4 และ IPv6 หรือใช้ Single Topology ที่ IPv4 และ IPv6 ใช้ topology เดียวกัน Multi-Topology ยืดหยุ่นกว่าเพราะ IPv6 routes สามารถใช้เส้นทางต่างจาก IPv4 ได้ แต่ใช้ memory มากกว่า

📖 บทความที่เกี่ยวข้อง

Helm Chart Template Production Setup Guideอ่านบทความ → Elasticsearch OpenSearch Production Setup Guideอ่านบทความ → CDK Construct Production Setup Guideอ่านบทความ → Astro Content Collections Production Setup Guideอ่านบทความ → Svelte 5 Runes Production Setup Guideอ่านบทความ →

📚 ดูบทความทั้งหมด →