DEV Community

Tarık Anafarta
Tarık Anafarta

Posted on

GNS3 Üzerinde OpenLDAP, FreeRADIUS, TACACS+, Keycloak ve Elastic ile Merkezi Cisco Switch AAA Kurulumu

Bu doküman, GNS3 üzerinde Cisco switch'lerin merkezi kullanıcı veritabanı üzerinden kimlik doğrulaması yapmasını, grup bazlı yetki almasını, komut bazlı TACACS+ authorization uygulanmasını ve TACACS accounting loglarının Elastic/Kibana üzerinde görüntülenmesini özetler.

Kurulumda Active Directory yerine açık kaynak bir LDAP sunucusu olan OpenLDAP kullanıldı. Keycloak, OpenLDAP ile user federation yapacak şekilde eklendi. SW1 üzerinde RADIUS + OpenLDAP login doğrulandı. SW2 üzerinde final durumda TACACS+ + OpenLDAP kullanıldı; admin, operator ve readonly roller için komut bazlı yetkilendirme yapıldı.

Not: IP adresleri, parolalar ve bazı isimler dokümantasyon amacıyla maskelenmiştir. Kendi ortamınıza göre değiştirmeniz gerekir.


1. Amaç

Amaç, Cisco switch'lere lokal kullanıcılarla değil, merkezi dizindeki hesaplarla giriş yapılmasını sağlamaktır.

Hedef akış:

SW1 kullanıcı login -> FreeRADIUS -> OpenLDAP -> Grup kontrolü -> Yetki seviyesi
SW2 kullanıcı login -> TACACS+    -> OpenLDAP -> Grup kontrolü -> Yetki seviyesi + komut yetkilendirme + accounting log
Enter fullscreen mode Exit fullscreen mode

Final yetkilendirme modeli:

network-admins     -> admin profile    -> privilege 15, tüm shell komutları izinli
network-operators  -> operator profile -> privilege 15, sınırlı operasyon komutları izinli
network-readonly   -> readonly profile -> privilege 1, sadece show/exit/logout izinli
Enter fullscreen mode Exit fullscreen mode

Bu yapı sayesinde çok sayıda kullanıcı için TACACS config dosyasına tek tek kullanıcı yazılmaz. Kullanıcı hangi LDAP grubundaysa o profile uygulanır.


2. Kullanılan bileşenler

Bileşen Rolü
Ubuntu Docker servislerinin ve local GNS3 server'ın çalıştığı makine
GNS3 Ağ topolojisinin oluşturulduğu lab ortamı
OpenLDAP Kullanıcı ve grup veritabanı
phpLDAPadmin OpenLDAP için web yönetim arayüzü
Keycloak OpenLDAP user federation ve IAM/SSO katmanı
FreeRADIUS SW1 için RADIUS AAA sunucusu
tac_plus-ng SW2 için TACACS+ sunucusu
Logstash TACACS accounting loglarını parse eder
Elasticsearch Parse edilen logları indeksler
Kibana Logları arama, filtreleme ve dashboard için kullanılır
Cisco vIOS-L2 Lab switch imajı
GNS3 Cloud + TAP Switch'leri Ubuntu üzerindeki AAA servislerine bağlayan sanal ağ

3. Lab IP planı

Gerçek IP adresleri dokümantasyon amacıyla maskelenmiştir.

Ubuntu AAA Server       : <AAA_SERVER_IP>
GNS3 TAP Interface      : <TAP_GATEWAY_IP>/24
SW1 Management IP       : <SW1_MGMT_IP>/24
SW2 Management IP       : <SW2_MGMT_IP>/24
OpenLDAP Docker IP      : <LDAP_CONTAINER_IP>
FreeRADIUS Docker IP    : <RADIUS_CONTAINER_IP>
TACACS+ Docker IP       : <TACACS_CONTAINER_IP>
Keycloak Docker IP      : <KEYCLOAK_CONTAINER_IP>
Elasticsearch Docker IP : <ELASTICSEARCH_CONTAINER_IP>
Kibana Docker IP        : <KIBANA_CONTAINER_IP>
Logstash Docker IP      : <LOGSTASH_CONTAINER_IP>
Enter fullscreen mode Exit fullscreen mode

Lab içinde kullanılan örnek TAP ağı:

TAP Gateway             : <TAP_GATEWAY_IP>
SW1                     : <SW1_MGMT_IP>
SW2                     : <SW2_MGMT_IP>
Enter fullscreen mode Exit fullscreen mode

4. Klasör yapısı

Ana dizin:

/opt/aaa-stack
Enter fullscreen mode Exit fullscreen mode

Klasör yapısı:

/opt/aaa-stack
├── docker-compose.yml
├── freeradius
│   ├── Dockerfile
│   ├── clients.conf
│   ├── mods-enabled
│   │   └── ldap
│   └── sites-enabled
│       └── default
├── tacacs
│   ├── tac_plus-ng.cfg
│   └── logs
│       └── accounting.log
├── logstash
│   ├── pipeline
│   │   └── tacacs-accounting.conf
│   └── data
├── elasticsearch
│   └── data
└── keycloak
    └── data
Enter fullscreen mode Exit fullscreen mode

5. Docker Compose servisleri

Aşağıdaki compose örneği labda kullanılan servislerin genel yapısını gösterir. Parolalar, IP adresleri ve subnet değerleri maskelenmiştir.

services:
  openldap:
    image: osixia/openldap:1.5.0
    container_name: openldap
    hostname: openldap
    environment:
      LDAP_ORGANISATION: "Lab"
      LDAP_DOMAIN: "lab.local"
      LDAP_ADMIN_PASSWORD: "<LDAP_ADMIN_PASSWORD>"
      LDAP_CONFIG_PASSWORD: "<LDAP_CONFIG_PASSWORD>"
      LDAP_TLS: "false"
    volumes:
      - openldap_data:/var/lib/ldap
      - openldap_config:/etc/ldap/slapd.d
    ports:
      - "389:389"
    restart: unless-stopped
    networks:
      aaa_net:
        ipv4_address: <LDAP_CONTAINER_IP>

  phpldapadmin:
    image: osixia/phpldapadmin:0.9.0
    container_name: phpldapadmin
    environment:
      PHPLDAPADMIN_LDAP_HOSTS: openldap
      PHPLDAPADMIN_HTTPS: "false"
    ports:
      - "8080:80"
    depends_on:
      - openldap
    restart: unless-stopped
    networks:
      aaa_net:
        ipv4_address: <PHPLDAPADMIN_CONTAINER_IP>

  freeradius:
    build:
      context: ./freeradius
    container_name: freeradius
    depends_on:
      - openldap
    ports:
      - "1812:1812/udp"
      - "1813:1813/udp"
    volumes:
      - ./freeradius/clients.conf:/etc/freeradius/3.0/clients.conf:ro
      - ./freeradius/mods-enabled/ldap:/etc/freeradius/3.0/mods-enabled/ldap:ro
      - ./freeradius/sites-enabled/default:/etc/freeradius/3.0/sites-enabled/default:ro
    command: freeradius -X
    restart: unless-stopped
    networks:
      aaa_net:
        ipv4_address: <RADIUS_CONTAINER_IP>

  tacacs:
    image: christianbecker/tac_plus-ng:latest
    container_name: tacacs
    depends_on:
      - openldap
    ports:
      - "49:49/tcp"
    volumes:
      - ./tacacs/tac_plus-ng.cfg:/etc/tac_plus-ng.cfg:ro
      - ./tacacs/logs:/var/log/tac_plus-ng
    command: tac_plus-ng /etc/tac_plus-ng.cfg
    restart: unless-stopped
    networks:
      aaa_net:
        ipv4_address: <TACACS_CONTAINER_IP>

  keycloak:
    image: quay.io/keycloak/keycloak:26.6.1
    container_name: keycloak
    command:
      - start-dev
    environment:
      KC_BOOTSTRAP_ADMIN_USERNAME: <KEYCLOAK_ADMIN_USER>
      KC_BOOTSTRAP_ADMIN_PASSWORD: <KEYCLOAK_ADMIN_PASSWORD>
    ports:
      - "8081:8080"
    volumes:
      - ./keycloak/data:/opt/keycloak/data
    restart: unless-stopped
    networks:
      aaa_net:
        ipv4_address: <KEYCLOAK_CONTAINER_IP>

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.15.3
    container_name: elasticsearch
    environment:
      discovery.type: single-node
      xpack.security.enabled: "false"
      ES_JAVA_OPTS: "-Xms1g -Xmx1g"
    ports:
      - "9200:9200"
    volumes:
      - ./elasticsearch/data:/usr/share/elasticsearch/data
    restart: unless-stopped
    networks:
      aaa_net:
        ipv4_address: <ELASTICSEARCH_CONTAINER_IP>

  kibana:
    image: docker.elastic.co/kibana/kibana:8.15.3
    container_name: kibana
    depends_on:
      - elasticsearch
    environment:
      ELASTICSEARCH_HOSTS: "http://elasticsearch:9200"
    ports:
      - "5601:5601"
    restart: unless-stopped
    networks:
      aaa_net:
        ipv4_address: <KIBANA_CONTAINER_IP>

  logstash:
    image: docker.elastic.co/logstash/logstash:8.15.3
    container_name: logstash-tacacs
    depends_on:
      - elasticsearch
      - tacacs
    volumes:
      - ./logstash/pipeline:/usr/share/logstash/pipeline:ro
      - ./logstash/data:/usr/share/logstash/data
      - ./tacacs/logs:/var/log/tacacs:ro
    restart: unless-stopped
    networks:
      aaa_net:
        ipv4_address: <LOGSTASH_CONTAINER_IP>

networks:
  aaa_net:
    driver: bridge
    ipam:
      config:
        - subnet: <DOCKER_AAA_SUBNET>

volumes:
  openldap_data:
  openldap_config:
Enter fullscreen mode Exit fullscreen mode

Not: Keycloak bu labda start-dev ile çalıştırıldı. Production ortamda dev mode yerine kalıcı veritabanı, TLS, reverse proxy/hostname ve HA planı yapılmalıdır.


6. OpenLDAP kullanıcı ve grup verisi

Bu labda ilk kullanıcı ve grup kayıtları phpLDAPadmin web arayüzü üzerinden oluşturuldu.

phpLDAPadmin arayüzüne tarayıcıdan erişildi:

http://<AAA_SERVER_IP>:8080
Enter fullscreen mode Exit fullscreen mode

Login bilgileri:

Login DN : cn=admin,dc=lab,dc=local
Password : <LDAP_ADMIN_PASSWORD>
Enter fullscreen mode Exit fullscreen mode

OpenLDAP içinde temel dizin yapısı:

dc=lab,dc=local
├── ou=people
└── ou=groups
Enter fullscreen mode Exit fullscreen mode

Başlangıç kullanıcıları:

uid=netadmin,ou=people,dc=lab,dc=local
uid=readonly,ou=people,dc=lab,dc=local
Enter fullscreen mode Exit fullscreen mode

Sonradan PBİK formatına uygun 6 haneli kullanıcılar da eklendi:

uid=100001,ou=people,dc=lab,dc=local
uid=100002,ou=people,dc=lab,dc=local
Enter fullscreen mode Exit fullscreen mode

Bu kullanıcı adları switch login username olarak kullanılır:

Username: 100001
Username: 100002
Enter fullscreen mode Exit fullscreen mode

Gruplar:

cn=network-admins,ou=groups,dc=lab,dc=local
cn=network-operators,ou=groups,dc=lab,dc=local
cn=network-readonly,ou=groups,dc=lab,dc=local
Enter fullscreen mode Exit fullscreen mode

Grup üyelikleri member attribute'u ile tanımlandı:

network-admins:
member: uid=netadmin,ou=people,dc=lab,dc=local

network-operators:
member: uid=100001,ou=people,dc=lab,dc=local

network-readonly:
member: uid=readonly,ou=people,dc=lab,dc=local
member: uid=100002,ou=people,dc=lab,dc=local
Enter fullscreen mode Exit fullscreen mode

Özet yetkilendirme:

netadmin -> network-admins    -> admin profile
100001   -> network-operators -> operator profile
readonly -> network-readonly  -> readonly profile
100002   -> network-readonly  -> readonly profile
Enter fullscreen mode Exit fullscreen mode

Not: groupOfNames objectClass'i en az bir member attribute'u ister. Bu yüzden gruptaki son kullanıcı silinmeye çalışılırsa LDAP object class violation hatası alınabilir.


7. Keycloak ve OpenLDAP federation

Keycloak bu labda TACACS+ server'ın yerine geçmedi. Switch tarafında cihazlar TACACS+ konuştuğu için enforcement noktası tac_plus-ng olarak kaldı.

Keycloak'un bu labdaki rolü:

OpenLDAP kullanıcı ve gruplarını görmek
OpenLDAP ile user federation yapmak
Writable modda Keycloak UI üzerinden OpenLDAP'a kullanıcı/grup/membership yazabilmek
İleride SSO/OIDC/SAML/MFA gibi IAM ihtiyaçları için zemin sağlamak
Enter fullscreen mode Exit fullscreen mode

Gerçek AAA flow şu şekildedir:

SW2 -> TACACS+ -> tac_plus-ng -> OpenLDAP
Enter fullscreen mode Exit fullscreen mode

Keycloak doğrudan switch login isteğini karşılamaz. Cisco switch Keycloak token okumaz; switch TACACS+ konuşur.

7.1 Keycloak erişimi

Keycloak host üzerinde şu porttan yayınlandı:

http://<AAA_SERVER_IP>:8081
Enter fullscreen mode Exit fullscreen mode

Admin login:

Username: <KEYCLOAK_ADMIN_USER>
Password: <KEYCLOAK_ADMIN_PASSWORD>
Enter fullscreen mode Exit fullscreen mode

Realm:

network-aaa
Enter fullscreen mode Exit fullscreen mode

7.2 LDAP User Federation ayarı

Keycloak içinde:

User federation -> Add provider -> ldap
Enter fullscreen mode Exit fullscreen mode

Örnek ayarlar:

UI display name       : openldap
Vendor                : Other
Connection URL        : ldap://openldap:389
Enable StartTLS       : Off
Bind type             : simple
Bind DN               : cn=admin,dc=lab,dc=local
Bind credentials      : <LDAP_ADMIN_PASSWORD>
Users DN              : ou=people,dc=lab,dc=local
Username LDAP attr    : uid
RDN LDAP attr         : uid
UUID LDAP attr        : entryUUID
Search scope          : Subtree
Import users          : On
Edit mode             : WRITABLE
Sync registrations    : On
Enter fullscreen mode Exit fullscreen mode

Kullanıcı object class ayarı writable kullanım için sade tutuldu:

inetOrgPerson, organizationalPerson, person
Enter fullscreen mode Exit fullscreen mode

Bu nedenle TACACS LDAP filter da inetOrgPerson ile uyumlu olacak şekilde güncellendi.

7.3 LDAP group mapper

Keycloak LDAP provider altında group mapper eklendi:

Mapper type                   : group-ldap-mapper
LDAP Groups DN                : ou=groups,dc=lab,dc=local
Group Name LDAP Attribute     : cn
Group Object Classes          : groupOfNames
Membership LDAP Attribute     : member
Membership Attribute Type     : DN
Membership User LDAP Attribute: uid
User Groups Retrieve Strategy : LOAD_GROUPS_BY_MEMBER_ATTRIBUTE
Mode                          : LDAP_ONLY
Enter fullscreen mode Exit fullscreen mode

Bu ayar ile Keycloak'ta kullanıcıyı bir gruba eklemek OpenLDAP'taki groupOfNames/member attribute'unu günceller.

7.4 Keycloak'tan oluşturulan kullanıcıların OpenLDAP'a yazılması

Keycloak üzerinden PBİK formatında kullanıcı oluşturuldu:

Username: 100002
Enter fullscreen mode Exit fullscreen mode

OpenLDAP üzerinde kontrol:

docker exec -it openldap ldapsearch \
  -x \
  -H ldap://localhost:389 \
  -D "cn=admin,dc=lab,dc=local" \
  -w '<LDAP_ADMIN_PASSWORD>' \
  -b "ou=people,dc=lab,dc=local" \
  "(uid=100002)"
Enter fullscreen mode Exit fullscreen mode

Örnek beklenen çıktı:

dn: uid=100002,ou=people,dc=lab,dc=local
uid: 100002
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
cn: 100002
sn: 100002
userPassword: <PASSWORD_HASH_OR_VALUE>
Enter fullscreen mode Exit fullscreen mode

Keycloak üzerinden 100002 kullanıcısı network-readonly grubuna eklendi. LDAP grup üyeliği şu komutla doğrulandı:

docker exec -it openldap ldapsearch \
  -x \
  -H ldap://localhost:389 \
  -D "cn=admin,dc=lab,dc=local" \
  -w '<LDAP_ADMIN_PASSWORD>' \
  -b "ou=groups,dc=lab,dc=local" \
  "(cn=network-readonly)" member
Enter fullscreen mode Exit fullscreen mode

Beklenen:

member: uid=100002,ou=people,dc=lab,dc=local
Enter fullscreen mode Exit fullscreen mode

Bu test ile şu doğrulandı:

Keycloak UI üzerinden kullanıcı oluşturuldu.
Kullanıcı OpenLDAP'a yazıldı.
Keycloak üzerinden grup üyeliği verildi.
Bu üyelik OpenLDAP groupOfNames/member attribute'una yazıldı.
TACACS+ aynı OpenLDAP grup üyeliğini okuyarak yetki verdi.
Enter fullscreen mode Exit fullscreen mode

7.5 Keycloak token konusu

Keycloak üzerinden kullanıcı token'ı alınabilir ve token içinde roller görülebilir. Ancak Cisco IOS switch bu token'ı kullanmaz.

Önemli ayrım:

Keycloak token -> OIDC/SAML/web uygulamaları için anlamlıdır.
Cisco switch   -> TACACS+ konuşur, OIDC token okumaz.
Enter fullscreen mode Exit fullscreen mode

Bu nedenle bu labda Keycloak token'ı üzerinden doğrudan command authorization yapılmadı. Token/role bazlı doğrudan TACACS karar modeli istenirse ek bir MAVIS adapter, policy service veya bunu native destekleyen kurumsal AAA ürünü gerekir.


8. FreeRADIUS Dockerfile

Dosya:

/opt/aaa-stack/freeradius/Dockerfile
Enter fullscreen mode Exit fullscreen mode
FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
    apt-get install -y freeradius freeradius-ldap ldap-utils && \
    rm -rf /var/lib/apt/lists/*

EXPOSE 1812/udp 1813/udp

CMD ["freeradius", "-X"]
Enter fullscreen mode Exit fullscreen mode

9. FreeRADIUS client tanımları

Dosya:

/opt/aaa-stack/freeradius/clients.conf
Enter fullscreen mode Exit fullscreen mode
client localhost {
    ipaddr = 127.0.0.1
    secret = <RADIUS_SHARED_SECRET>
    require_message_authenticator = no
    nas_type = other
}

client docker_bridge {
    ipaddr = <DOCKER_AAA_SUBNET>
    secret = <RADIUS_SHARED_SECRET>
    require_message_authenticator = no
    nas_type = other
}

client gns3_tap_lab {
    ipaddr = <GNS3_TAP_SUBNET>
    secret = <RADIUS_SHARED_SECRET>
    require_message_authenticator = no
    nas_type = cisco
}
Enter fullscreen mode Exit fullscreen mode

10. FreeRADIUS LDAP modülü

Dosya:

/opt/aaa-stack/freeradius/mods-enabled/ldap
Enter fullscreen mode Exit fullscreen mode
ldap {
    server = "openldap"
    port = 389

    identity = "cn=admin,dc=lab,dc=local"
    password = "<LDAP_ADMIN_PASSWORD>"

    base_dn = "dc=lab,dc=local"

    user {
        base_dn = "ou=people,dc=lab,dc=local"
        filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
    }

    group {
        base_dn = "ou=groups,dc=lab,dc=local"
        filter = "(objectClass=groupOfNames)"
        membership_filter = "(&(objectClass=groupOfNames)(member=%{control:Ldap-UserDn}))"
        name_attribute = cn
    }

    options {
        chase_referrals = yes
        rebind = yes
        res_timeout = 10
        srv_timelimit = 3
        net_timeout = 1
        idle = 60
        probes = 3
        interval = 3
    }

    tls {
        start_tls = no
    }
}
Enter fullscreen mode Exit fullscreen mode

11. FreeRADIUS default site

Dosya:

/opt/aaa-stack/freeradius/sites-enabled/default
Enter fullscreen mode Exit fullscreen mode
server default {
    listen {
        type = auth
        ipaddr = *
        port = 1812
    }

    listen {
        type = acct
        ipaddr = *
        port = 1813
    }

    authorize {
        ldap

        if (ok) {
            update control {
                Auth-Type := LDAP
            }
        }
    }

    authenticate {
        Auth-Type LDAP {
            ldap
        }
    }

    post-auth {
        if (&LDAP-Group == "network-admins") {
            update reply {
                Service-Type := Administrative-User
                Cisco-AVPair := "shell:priv-lvl=15"
                Reply-Message := "LDAP RADIUS Admin Login OK"
            }
        }
        elsif (&LDAP-Group == "network-readonly") {
            update reply {
                Service-Type := NAS-Prompt-User
                Cisco-AVPair := "shell:priv-lvl=1"
                Reply-Message := "LDAP RADIUS Readonly Login OK"
            }
        }
        else {
            reject
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

12. TACACS+ config

TACACS+ tarafında tac_plus-ng kullanıldı. Bu servis, MAVIS LDAP backend üzerinden OpenLDAP'a bağlanır.

Final model:

network-admins     -> admin_profile
network-operators  -> operator_profile
network-readonly   -> readonly_profile
Enter fullscreen mode Exit fullscreen mode

Dosya:

/opt/aaa-stack/tacacs/tac_plus-ng.cfg
Enter fullscreen mode Exit fullscreen mode
id = spawnd {
    listen { port = 49 }
    spawn {
        instances min = 1
        instances max = 16
    }
}

id = tac_plus-ng {
    log acctlog {
        destination = /var/log/tac_plus-ng/accounting.log
    }

    accounting log = acctlog

    mavis module = external {
        setenv LDAP_HOSTS = "ldap://openldap:389"
        setenv LDAP_BASE = "ou=people,dc=lab,dc=local"
        setenv LDAP_BASE_GROUP = "ou=groups,dc=lab,dc=local"
        setenv LDAP_SCOPE = sub
        setenv LDAP_SCOPE_GROUP = sub
        setenv LDAP_FILTER = "(&(objectClass=inetOrgPerson)(uid=%s))"
        setenv LDAP_FILTER_GROUP = "(&(objectClass=groupOfNames)(member=%s))"
        setenv LDAP_USER = "cn=admin,dc=lab,dc=local"
        setenv LDAP_PASSWD = "<LDAP_ADMIN_PASSWORD>"
        exec = /usr/local/lib/mavis/mavis_tacplus-ng_ldap.pl
    }

    user backend = mavis
    login backend = mavis
    pap backend = mavis

    device gns3_tap_switches {
        address = <GNS3_TAP_SUBNET>
        key = <TACACS_SHARED_SECRET>
    }

    profile admin_profile {
        script {
            if (service == shell) {
                if (cmd == "") {
                    set priv-lvl = 15
                    permit
                }
                permit
            }
        }
    }

    profile operator_profile {
        script {
            if (service == shell) {
                if (cmd == "") {
                    set priv-lvl = 15
                    permit
                }

                if (cmd =~ /^show(\s|$)/) {
                    permit
                }

                if (cmd =~ /^configure\s+terminal(\s|$)/) {
                    permit
                }

                if (cmd =~ /^interface\s+/) {
                    permit
                }

                if (cmd =~ /^ip\s+address\s+/) {
                    permit
                }

                if (cmd =~ /^no\s+shutdown(\s|$)/) {
                    permit
                }

                if (cmd =~ /^exit(\s|$)/) {
                    permit
                }

                if (cmd =~ /^end(\s|$)/) {
                    permit
                }

                if (cmd =~ /^logout(\s|$)/) {
                    permit
                }

                deny
            }
        }
    }

    profile readonly_profile {
        script {
            if (service == shell) {
                if (cmd == "") {
                    set priv-lvl = 1
                    permit
                }

                if (cmd =~ /^show(\s|$)/) {
                    permit
                }

                if (cmd =~ /^exit(\s|$)/) {
                    permit
                }

                if (cmd =~ /^logout(\s|$)/) {
                    permit
                }

                deny
            }
        }
    }

    ruleset {
        rule admin_rule {
            enabled = yes
            script {
                if (memberof =~ /^cn=network-admins,ou=groups,dc=lab,dc=local$/) {
                    profile = admin_profile
                    permit
                }
            }
        }

        rule operator_rule {
            enabled = yes
            script {
                if (memberof =~ /^cn=network-operators,ou=groups,dc=lab,dc=local$/) {
                    profile = operator_profile
                    permit
                }
            }
        }

        rule readonly_rule {
            enabled = yes
            script {
                if (memberof =~ /^cn=network-readonly,ou=groups,dc=lab,dc=local$/) {
                    profile = readonly_profile
                    permit
                }
            }
        }

        rule deny_all {
            enabled = yes
            script {
                deny
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Syntax test:

docker run --rm -it \
  --network aaa-stack_aaa_net \
  -v /opt/aaa-stack/tacacs/tac_plus-ng.cfg:/etc/tac_plus-ng.cfg:ro \
  -v /opt/aaa-stack/tacacs/logs:/var/log/tac_plus-ng \
  christianbecker/tac_plus-ng:latest \
  tac_plus-ng /etc/tac_plus-ng.cfg
Enter fullscreen mode Exit fullscreen mode

Restart:

cd /opt/aaa-stack
docker compose restart tacacs
Enter fullscreen mode Exit fullscreen mode

13. Servisleri başlatma

cd /opt/aaa-stack

docker compose up -d --build
Enter fullscreen mode Exit fullscreen mode

Kontrol:

docker ps
Enter fullscreen mode Exit fullscreen mode

Beklenen container'lar:

openldap
phpldapadmin
freeradius
tacacs
keycloak
elasticsearch
kibana
logstash-tacacs
Enter fullscreen mode Exit fullscreen mode

Port kontrolü:

sudo ss -lntup | egrep ':389|:8080|:8081|:1812|:1813|:49|:9200|:5601'
Enter fullscreen mode Exit fullscreen mode

Beklenen portlar:

389/tcp    OpenLDAP
8080/tcp   phpLDAPadmin
8081/tcp   Keycloak
1812/udp   RADIUS authentication
1813/udp   RADIUS accounting
49/tcp     TACACS+
9200/tcp   Elasticsearch
5601/tcp   Kibana
Enter fullscreen mode Exit fullscreen mode

14. GNS3 tarafında yapılanlar

Local Ubuntu üzerindeki GNS3 server kullanıldı.

TAP interface oluşturuldu:

sudo ip tuntap add dev tap-gns3 mode tap user $USER
sudo ip addr add <TAP_GATEWAY_IP>/24 dev tap-gns3
sudo ip link set tap-gns3 up
Enter fullscreen mode Exit fullscreen mode

GNS3 Cloud node içinde tap-gns3 seçildi.

Neden ESW1 kullanıldı?

Cloud üzerindeki TAP port tek bağlantı kabul ettiği için, birden fazla switch'i aynı TAP ağına bağlamak amacıyla araya GNS3 built-in Ethernet switch eklendi.

14.1 TAP interface'i kalıcı hale getirme

TAP interface reboot sonrasında kaybolmasın diye systemd service oluşturuldu.

Script:

sudo tee /usr/local/sbin/gns3-tap-up.sh > /dev/null <<'EOF'
#!/usr/bin/env bash
set -e

TAP_NAME="tap-gns3"
TAP_USER="<LINUX_USER>"
TAP_IP="<TAP_GATEWAY_IP>/24"

if ! ip link show "$TAP_NAME" >/dev/null 2>&1; then
    ip tuntap add dev "$TAP_NAME" mode tap user "$TAP_USER"
fi

ip addr flush dev "$TAP_NAME" || true
ip addr add "$TAP_IP" dev "$TAP_NAME"
ip link set "$TAP_NAME" up
EOF

sudo chmod +x /usr/local/sbin/gns3-tap-up.sh
Enter fullscreen mode Exit fullscreen mode

Stop script:

sudo tee /usr/local/sbin/gns3-tap-down.sh > /dev/null <<'EOF'
#!/usr/bin/env bash
set -e

TAP_NAME="tap-gns3"

if ip link show "$TAP_NAME" >/dev/null 2>&1; then
    ip link set "$TAP_NAME" down || true
    ip tuntap del dev "$TAP_NAME" mode tap || true
fi
EOF

sudo chmod +x /usr/local/sbin/gns3-tap-down.sh
Enter fullscreen mode Exit fullscreen mode

Systemd service:

sudo tee /etc/systemd/system/gns3-tap.service > /dev/null <<'EOF'
[Unit]
Description=Create persistent TAP interface for GNS3 lab
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/gns3-tap-up.sh
ExecStop=/usr/local/sbin/gns3-tap-down.sh

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable gns3-tap.service
sudo systemctl start gns3-tap.service
Enter fullscreen mode Exit fullscreen mode

Kontrol:

systemctl status gns3-tap.service --no-pager
ip -br addr show tap-gns3
Enter fullscreen mode Exit fullscreen mode

Beklenen:

tap-gns3 UP <TAP_GATEWAY_IP>/24
Enter fullscreen mode Exit fullscreen mode

15. SW1 temel IP config

enable
conf t
hostname SW1

interface vlan 1
 ip address <SW1_MGMT_IP> 255.255.255.0
 no shutdown
exit

ip default-gateway <TAP_GATEWAY_IP>

end
write memory
Enter fullscreen mode Exit fullscreen mode

Test:

show ip interface brief
ping <TAP_GATEWAY_IP>
Enter fullscreen mode Exit fullscreen mode

16. SW2 temel IP config

enable
conf t
hostname SW2

interface vlan 1
 ip address <SW2_MGMT_IP> 255.255.255.0
 no shutdown
exit

ip default-gateway <TAP_GATEWAY_IP>

end
write memory
Enter fullscreen mode Exit fullscreen mode

Test:

show ip interface brief
ping <TAP_GATEWAY_IP>
Enter fullscreen mode Exit fullscreen mode

17. SW1 için Cisco RADIUS AAA config

SW1 final durumda RADIUS örneği olarak bırakıldı.

conf t

aaa new-model

radius server AAA-RADIUS
 address ipv4 <TAP_GATEWAY_IP> auth-port 1812 acct-port 1813
 key <RADIUS_SHARED_SECRET>

aaa group server radius RADIUS-GRP
 server name AAA-RADIUS

aaa authentication login default group RADIUS-GRP local
aaa authorization exec default group RADIUS-GRP local

username localadmin privilege 15 secret <LOCAL_FALLBACK_PASSWORD>

line vty 0 15
 login authentication default
 authorization exec default
 transport input telnet ssh

end
write memory
Enter fullscreen mode Exit fullscreen mode

Kontrol:

show aaa servers
show running-config | section radius
show running-config | section aaa
Enter fullscreen mode Exit fullscreen mode

SW1 login testi:

telnet <SW1_MGMT_IP>
Enter fullscreen mode Exit fullscreen mode

Admin kullanıcı:

Username: netadmin
Password: <NETADMIN_PASSWORD>
Enter fullscreen mode Exit fullscreen mode

Beklenen:

SW1#
Current privilege level is 15
Enter fullscreen mode Exit fullscreen mode

Readonly kullanıcı:

Username: readonly
Password: <READONLY_PASSWORD>
Enter fullscreen mode Exit fullscreen mode

Beklenen:

SW1>
Current privilege level is 1
Enter fullscreen mode Exit fullscreen mode

18. SW2 için Cisco TACACS+ AAA config

SW2 final durumda TACACS+ kullanacak şekilde bırakıldı.

Lab imajı eski IOS syntax'ını kabul ettiği için TACACS server şu formatla tanımlandı:

conf t

aaa new-model

tacacs-server host <TAP_GATEWAY_IP> key <TACACS_SHARED_SECRET>

aaa group server tacacs+ TACACS-GRP
 server <TAP_GATEWAY_IP>

username localadmin privilege 15 secret <LOCAL_FALLBACK_PASSWORD>

aaa authentication login default group TACACS-GRP local
aaa authorization exec default group TACACS-GRP local

aaa authorization commands 1 default group TACACS-GRP local
aaa authorization commands 15 default group TACACS-GRP local
aaa authorization config-commands

aaa accounting exec default start-stop group TACACS-GRP
aaa accounting commands 1 default start-stop group TACACS-GRP
aaa accounting commands 15 default start-stop group TACACS-GRP

line vty 0 15
 login authentication default
 authorization exec default
 transport input ssh

end
write memory
Enter fullscreen mode Exit fullscreen mode

Komutların anlamı:

aaa authentication login default group TACACS-GRP local
  Login authentication için önce TACACS+, sonra local fallback.

aaa authorization exec default group TACACS-GRP local
  Kullanıcı login sonrası shell/exec açabilir mi ve privilege seviyesi ne olacak?

aaa authorization commands 1/15 default group TACACS-GRP local
  Privilege 1 ve 15 komutları için command authorization yap.

aaa authorization config-commands
  Config mode içindeki komutları da authorization kapsamına al.

aaa accounting exec default start-stop group TACACS-GRP
  Oturum başlangıç/bitiş accounting kaydı üret.

aaa accounting commands 1/15 default start-stop group TACACS-GRP
  Privilege 1 ve 15 komutlarını accounting'e gönder.
Enter fullscreen mode Exit fullscreen mode

Not: local fallback labda kilitlenmemek için kullanıldı. Production ortamda fallback davranışı güvenlik politikasına göre ayrıca değerlendirilmelidir.

TACACS+ test komutları:

test aaa group TACACS-GRP netadmin <NETADMIN_PASSWORD> legacy
test aaa group TACACS-GRP netadmin <WRONG_PASSWORD> legacy
Enter fullscreen mode Exit fullscreen mode

Beklenen:

Doğru şifre  -> User was successfully authenticated
Yanlış şifre -> User authentication request was rejected by server
Enter fullscreen mode Exit fullscreen mode

19. SW2 SSH config

Telnet yerine SSH kullanılması için SW2 üzerinde RSA key ve SSH v2 açıldı.

conf t

ip domain-name lab.local
crypto key generate rsa modulus 2048

ip ssh version 2
ip ssh time-out 60
ip ssh authentication-retries 3

line vty 0 15
 login authentication default
 authorization exec default
 transport input ssh

end
write memory
Enter fullscreen mode Exit fullscreen mode

Kontrol:

show ip ssh
show running-config | section line vty
Enter fullscreen mode Exit fullscreen mode

Beklenen:

SSH Enabled - version 2.0
transport input ssh
Enter fullscreen mode Exit fullscreen mode

Labdaki vIOS-L2 imajı eski SSH algoritmaları sunduğu için Ubuntu'dan bağlantıda legacy OpenSSH seçenekleri kullanıldı:

ssh \
  -oKexAlgorithms=+diffie-hellman-group14-sha1 \
  -oHostKeyAlgorithms=+ssh-rsa \
  -oPubkeyAcceptedAlgorithms=+ssh-rsa \
  <USERNAME>@<SW2_MGMT_IP>
Enter fullscreen mode Exit fullscreen mode

Örnek:

ssh \
  -oKexAlgorithms=+diffie-hellman-group14-sha1 \
  -oHostKeyAlgorithms=+ssh-rsa \
  -oPubkeyAcceptedAlgorithms=+ssh-rsa \
  100001@<SW2_MGMT_IP>
Enter fullscreen mode Exit fullscreen mode

Production ortamda güncel IOS-XE veya güncel SSH algoritmaları destekleyen cihazlarda normal SSH komutu yeterli olabilir.


20. SW2 TACACS+ komut bazlı yetkilendirme testleri

Admin test

Kullanıcı:

netadmin -> network-admins
Enter fullscreen mode Exit fullscreen mode

Beklenen:

SW2#show privilege
Current privilege level is 15

SW2#write memory
# çalışır
Enter fullscreen mode Exit fullscreen mode

Operator test

Kullanıcı:

100001 -> network-operators
Enter fullscreen mode Exit fullscreen mode

Beklenen:

SW2#show privilege
Current privilege level is 15

SW2#conf t
SW2(config)#interface vlan 1
SW2(config-if)#no shutdown
# çalışır

SW2#write memory
Command authorization failed.

SW2#reload
Command authorization failed.
Enter fullscreen mode Exit fullscreen mode

Operator kullanıcının privilege seviyesi 15 olsa bile tüm komutları çalıştıramaz. Çünkü command authorization açık olduğu için switch her yetkilendirilen komutta TACACS+ server'a sorar.

Readonly test

Kullanıcı:

100002 -> network-readonly
Enter fullscreen mode Exit fullscreen mode

Beklenen:

SW2>show privilege
Current privilege level is 1

SW2>show ip interface brief
# çalışır

SW2>conf t
Command authorization failed.
Enter fullscreen mode Exit fullscreen mode

21. TACACS accounting loglama

SW2 üzerinde accounting açıldığı için login/logout ve komut kayıtları TACACS+ server tarafında tutulur. Bu loglar switch diskine yazılmaz.

TACACS config içinde accounting log dosyası tanımı:

log acctlog {
    destination = /var/log/tac_plus-ng/accounting.log
}

accounting log = acctlog
Enter fullscreen mode Exit fullscreen mode

Docker volume sayesinde container içindeki log dosyası host üzerinde şu path'e yazılır:

/opt/aaa-stack/tacacs/logs/accounting.log
Enter fullscreen mode Exit fullscreen mode

Canlı izleme:

tail -f /opt/aaa-stack/tacacs/logs/accounting.log
Enter fullscreen mode Exit fullscreen mode

Örnek log satırları:

<TIMESTAMP> <SWITCH_IP>    100001    tty2    <SOURCE_IP>    start    shell
<TIMESTAMP> <SWITCH_IP>    100001    tty2    <SOURCE_IP>    stop     shell    show privilege <cr>
<TIMESTAMP> <SWITCH_IP>    100001    tty2    <SOURCE_IP>    stop     shell    write memory <cr>
Enter fullscreen mode Exit fullscreen mode

Alanların anlamı:

timestamp       -> olay zamanı
switch IP       -> observer.ip, işlem yapılan switch
username        -> user.name
tty             -> terminal/session hattı
source IP       -> switch'e bağlanan kaynak IP
start/stop      -> accounting action
shell           -> servis tipi
command         -> çalıştırılan komut
Enter fullscreen mode Exit fullscreen mode

source.ip labda genelde TAP gateway IP olarak görünür. Çünkü SSH bağlantıları Ubuntu host/TAP üzerinden yapılmaktadır. Gerçek ortamda bu alan admin bilgisayarı veya jump server IP'si olabilir.


22. Logstash pipeline

Logstash, TACACS accounting log dosyasını okuyup alanlara ayırır ve Elasticsearch'e gönderir.

Dosya:

/opt/aaa-stack/logstash/pipeline/tacacs-accounting.conf
Enter fullscreen mode Exit fullscreen mode
input {
  file {
    path => "/var/log/tacacs/accounting.log"
    start_position => "beginning"
    sincedb_path => "/usr/share/logstash/data/tacacs-accounting.sincedb"
    mode => "tail"
    codec => "plain"
  }
}

filter {
  if [message] =~ /^\s*$/ {
    drop { }
  }

  mutate {
    replace => {
      "[event][original]" => "%{message}"
    }
    add_field => {
      "[event][dataset]" => "tacacs.accounting"
      "[event][module]" => "tacacs"
    }
  }

  grok {
    match => {
      "message" => "^%{YEAR:[tacacs][year]}-%{MONTHNUM:[tacacs][month]}-%{MONTHDAY:[tacacs][day]} %{TIME:[tacacs][time]} %{ISO8601_TIMEZONE:[tacacs][timezone]} %{IP:[observer][ip]}\t%{DATA:[user][name]}\t%{DATA:[tacacs][tty]}\t%{IP:[source][ip]}\t%{WORD:[event][action]}\t%{WORD:[service][name]}(?:\t%{GREEDYDATA:[tacacs][command]})?$"
    }
    tag_on_failure => [ "tacacs_parse_failed" ]
  }

  mutate {
    add_field => {
      "[tacacs][timestamp_raw]" => "%{[tacacs][year]}-%{[tacacs][month]}-%{[tacacs][day]} %{[tacacs][time]} %{[tacacs][timezone]}"
    }
    strip => [
      "[tacacs][command]",
      "[user][name]",
      "[observer][ip]",
      "[source][ip]",
      "[event][action]",
      "[service][name]"
    ]
  }

  date {
    match => [ "[tacacs][timestamp_raw]", "yyyy-MM-dd HH:mm:ss Z" ]
    target => "@timestamp"
    tag_on_failure => [ "tacacs_dateparse_failed" ]
  }

  if ![tacacs][command] or [tacacs][command] == "" {
    mutate {
      add_field => {
        "[tacacs][command_type]" => "session"
      }
    }
  } else {
    mutate {
      add_field => {
        "[tacacs][command_type]" => "command"
      }
    }

    ruby {
      code => '
        cmd = event.get("[tacacs][command]")
        if cmd && cmd.strip != ""
          event.set("[tacacs][command_prefix]", cmd.strip.split(/\s+/)[0])
        end
      '
    }
  }

  if [tacacs][command_prefix] == "no" {
    mutate {
      add_field => {
        "[event][risk_score]" => "50"
        "[tacacs][command_category]" => "negative_config"
      }
    }
  } else if [tacacs][command_prefix] == "configure" {
    mutate {
      add_field => {
        "[event][risk_score]" => "40"
        "[tacacs][command_category]" => "configuration_mode"
      }
    }
  } else if [tacacs][command_prefix] == "write" {
    mutate {
      add_field => {
        "[event][risk_score]" => "30"
        "[tacacs][command_category]" => "save_config"
      }
    }
  } else if [tacacs][command_prefix] == "show" {
    mutate {
      add_field => {
        "[event][risk_score]" => "10"
        "[tacacs][command_category]" => "read_only"
      }
    }
  }

  mutate {
    remove_field => [
      "[tacacs][year]",
      "[tacacs][month]",
      "[tacacs][day]",
      "[tacacs][time]",
      "[tacacs][timezone]"
    ]
  }
}

output {
  elasticsearch {
    hosts => ["http://elasticsearch:9200"]
    index => "tacacs-accounting-%{+YYYY.MM.dd}"
  }

  stdout {
    codec => rubydebug
  }
}
Enter fullscreen mode Exit fullscreen mode

Logstash restart:

cd /opt/aaa-stack
docker compose restart logstash
Enter fullscreen mode Exit fullscreen mode

Index kontrolü:

curl "http://localhost:9200/_cat/indices/tacacs-accounting-*?v"
Enter fullscreen mode Exit fullscreen mode

23. Kibana kullanımı

Kibana erişimi:

http://<AAA_SERVER_IP>:5601
Enter fullscreen mode Exit fullscreen mode

Data view:

Name          : tacacs-accounting
Index pattern : tacacs-accounting-*
Timestamp     : @timestamp
Enter fullscreen mode Exit fullscreen mode

Discover ekranında önerilen kolonlar:

@timestamp
observer.ip
source.ip
user.name
event.action
tacacs.command_type
tacacs.command_prefix
tacacs.command_category
tacacs.command
tacacs.tty
Enter fullscreen mode Exit fullscreen mode

Örnek filtreler:

user.name : "100001"
Enter fullscreen mode Exit fullscreen mode
observer.ip : "<SW2_MGMT_IP>"
Enter fullscreen mode Exit fullscreen mode
tacacs.command_type : "command"
Enter fullscreen mode Exit fullscreen mode
tacacs.command_prefix : "no"
Enter fullscreen mode Exit fullscreen mode
tacacs.command : "write memory <cr>"
Enter fullscreen mode Exit fullscreen mode
user.name : "100001" and tacacs.command_prefix : "configure"
Enter fullscreen mode Exit fullscreen mode
user.name : "100002" and tacacs.command_type : "command"
Enter fullscreen mode Exit fullscreen mode

Bu şekilde şu sorular yanıtlanabilir:

Kim switch'e login oldu?
Kim hangi switch üzerinde işlem yaptı?
Kim hangi komutu çalıştırdı?
Kim configure terminal yaptı?
Kim no ile başlayan komut çalıştırdı?
Kim write memory denedi?
Readonly kullanıcı hangi komutları çalıştırdı?
Operator kullanıcı hangi komutlarda deny aldı?
Enter fullscreen mode Exit fullscreen mode

Not: TACACS accounting bazı IOS davranışlarında deny edilen her komutu loglamayabilir. Çalıştırılan/işlenen komutlar accounting tarafında daha net görünür. Deny eventlerinin ayrıca saklanması gerekiyorsa switch syslog veya TACACS authorization debug/log seçenekleri ayrıca değerlendirilmelidir.


24. Log retention ve disk konusu

TACACS accounting logları switch diskine yazılmaz. Loglar AAA sunucusu tarafında tutulur:

/opt/aaa-stack/tacacs/logs/accounting.log
Enter fullscreen mode Exit fullscreen mode

Bu yüzden switch diskini şişirmez. Disk büyümesi Ubuntu/Elastic tarafında olur.

Raw accounting log için logrotate örneği:

sudo tee /etc/logrotate.d/tacacs-accounting > /dev/null <<'EOF'
/opt/aaa-stack/tacacs/logs/accounting.log {
    daily
    rotate 30
    compress
    missingok
    notifempty
    copytruncate
}
EOF
Enter fullscreen mode Exit fullscreen mode

Test:

sudo logrotate -d /etc/logrotate.d/tacacs-accounting
Enter fullscreen mode Exit fullscreen mode

Elasticsearch tarafında production için ILM/retention policy planlanmalıdır.


25. 5651 ve log bütünlüğü notu

Bu yapı TACACS+ command accounting loglarını merkezi olarak saklar ve Kibana üzerinden aranabilir hale getirir.

Ancak tek başına tam bir 5651 uyumlu loglama sistemi olarak değerlendirilmemelidir. 5651 benzeri uyumluluk ihtiyaçları için genellikle şu ek konular gerekir:

NTP ile doğru zaman senkronizasyonu
Log bütünlüğü için hash/imza/zaman damgası
Yetkisiz değişikliğe karşı koruma
Retention policy
Erişim kontrolü
Gerekirse WORM/değiştirilemez saklama
Merkezi SIEM veya 5651 uyumlu loglama ürünü
Enter fullscreen mode Exit fullscreen mode

Bu labdaki yapı network cihaz yönetimi açısından şu audit sorularını karşılar:

Kim login oldu?
Hangi cihazda işlem yaptı?
Hangi komutu çalıştırdı?
Ne zaman çalıştırdı?
Enter fullscreen mode Exit fullscreen mode

26. Güncel final flow

Final durumda lab akışı şöyledir:

Keycloak UI
   |
   | LDAP federation / writable user & group management
   v
OpenLDAP
   |
   | LDAP user + group membership
   v
TACACS+ Server - tac_plus-ng
   |
   | permit / deny / priv-lvl
   v
Cisco SW2
   |
   | TACACS accounting
   v
accounting.log
   |
   v
Logstash -> Elasticsearch -> Kibana
Enter fullscreen mode Exit fullscreen mode

Switch login/authorization akışı:

1. Kullanıcı SSH ile SW2'ye bağlanır.
2. SW2, username/password bilgisini TACACS+ server'a gönderir.
3. tac_plus-ng, MAVIS LDAP backend ile OpenLDAP'a sorar.
4. OpenLDAP kullanıcıyı doğrular.
5. tac_plus-ng kullanıcının LDAP grup üyeliğini okur.
6. Grup üyeliğine göre admin/operator/readonly profile seçilir.
7. Kullanıcı komut çalıştırdığında SW2 yine TACACS+ server'a command authorization sorar.
8. tac_plus-ng ilgili profile göre permit/deny döner.
9. Accounting logları Logstash üzerinden Elasticsearch'e gider.
Enter fullscreen mode Exit fullscreen mode

Keycloak'un rolü:

Keycloak doğrudan switch authentication server'ı değildir.
Switch Keycloak token okumaz.
Switch TACACS+ konuşur.
Keycloak bu labda OpenLDAP kullanıcı/grup yönetimi ve IAM/federation katmanıdır.
Enter fullscreen mode Exit fullscreen mode

Bu nedenle doğru teknik anlatım:

Keycloak, OpenLDAP/AD ile entegre edildi. Kullanıcı ve grup yönetimi Keycloak üzerinden yapılabiliyor ve LDAP'a yazılıyor. TACACS+ ise switch CLI enforcement noktası olarak kalıyor. tac_plus-ng, LDAP grup üyeliklerine göre admin/operator/readonly profillerini uyguluyor. Tüm login ve komut kayıtları TACACS accounting ile Elastic/Kibana'ya aktarılıyor.
Enter fullscreen mode Exit fullscreen mode

27. Sonuç

Bu lab ile Cisco switch login ve yönetim işlemleri merkezi hale getirildi.

Final mimari:

SW1 -> FreeRADIUS -> OpenLDAP -> LDAP Group -> Cisco privilege level
SW2 -> TACACS+    -> OpenLDAP -> LDAP Group -> Cisco privilege level + command authorization + accounting
Keycloak -> OpenLDAP federation/writable user-group management
TACACS accounting -> Logstash -> Elasticsearch -> Kibana
Enter fullscreen mode Exit fullscreen mode

RADIUS tarafı merkezi login ve privilege atamasını göstermek için kullanıldı.

TACACS+ tarafı network cihaz yönetiminde daha ileri seviye kontrol sağlamak için kullanıldı:

Kullanıcı doğrulama
Exec authorization
Komut bazlı authorization
Komut accounting
Merkezi loglama
Enter fullscreen mode Exit fullscreen mode

Keycloak bu yapıda kullanıcı/grup yönetimini ve IAM katmanını sağlar. Switch tarafındaki gerçek CLI enforcement ise TACACS+ ile yapılır.

Bu yapı gerçek ortamda Active Directory ile benzer mantıkta uygulanabilir:

Cisco Switch -> TACACS+/RADIUS -> AD/OpenLDAP -> Grup üyeliği -> Yetki profili
Enter fullscreen mode Exit fullscreen mode

Top comments (0)