목차

소개

배경 정보

Linux 서버 구성

DHCP 구성

HTTP 서버 요구 사항

문제 해결 정보

라우터가 DHCP를 사용하여 IP 주소를 가져오도록 활성화

HTTP 서버가 작동하는지 확인

ZTP를 시작하는 방법

수동으로 ZTP 시작

iPXE로 라우터 부팅

설치 후 자동화

관련 정보

소개

이 문서에서는 ZTP(Zero Touch Provisioning)의 최초 구축에 대한 문제 해결 팁을 설명합니다.

ZTP는 XR 디바이스 프로비저닝에서 사람의 상호 작용을 줄이기 위해 도입되었습니다.ZTP는 iPXE(Preboot eXecution Environment)의 구현을 사용합니다.

배경 정보

ZTP는 다음을 수행할 수 있습니다.

- 자동 구성 업데이트:이미지 설치 후 XR 구성 다운로드 및 적용

- 스크립트 실행:사용자 정의 스크립트 파일을 다운로드하고 실행합니다.다양한 메서드/함수를 스크립트 실행의 일부로 구현할 수 있습니다.

- 여러 패키지 업데이트

- SMU 설치

- 확인

- eXR에서는 파일의 첫 번째 행의 내용을 기준으로 수행할 작업 중 하나를 결정합니다.

- 파일이 다음으로 시작하는 경우!!!IOS XR은 구성 파일을 나타내며 apply_config를 수행합니다.

- 마찬가지로, #으로 시작하는 파일!/bin/bash 또는 #!/bin/sh 또는 #!/usr/bin/python은 스크립트 파일을 나타내며 스크립트 실행을 수행합니다.

- eXR 6.2.2에서 Python 지원 소개

- eXR iPXE는 TFTP(Trivial File Transfer Protocol), FTP(File Transfer Protocol) 및 HTTP(Hypertext Transfer Protocol)를 지원합니다.

- 확인할 시그니처를 예측할 수 없으므로 HTTPS(Hypertext Transfer Protocol Secure)가 지원되지 않습니다.

Linux 서버 구성

iPXE는 이미지/컨피그레이션 다운로드에 TFTP/FTP/HTTP가 필요하고 이미지 및 컨피그레이션에 대한 정보를 가져오거나 제공하기 위해 DHCP(Dynamic Host Configuration Protocol)를 사용하는 PXE를 통한 개선입니다.

DHCP 구성

다음 예에서는 패킷 캡처를 검토하여 DHCP 작업을 확인합니다.

HTTP 서버 요구 사항

관리 이더넷 인터페이스에서 HTTP 서버에 연결할 수 있어야 합니다.

문제 해결 정보

Linux 서버가 설정되면 DHCP/HTTP 서버 연결성 및 기능 확인 을 수행합니다.

이 설정에서는 단일 Linux 서버가 DHCP/HTTP 서버로 사용됩니다.이러한 기능에 별도의 서버가 있는 경우 필요한 경우 모든 서버에서 이 단계를 확인하십시오.

[root@xxxxxxxxxx]# service dhcpd status

Redirecting to /bin/systemctl status  dhcpd.service

dhcpd.service - DHCPv4 Server Daemon

Loaded: loaded (/usr/lib/systemd/system/dhcpd.service; disabled; vendor preset: disabled)

Active: active (running) since Mon 2017-05-29 10:30:59 PDT; 15h ago

Docs: man:dhcpd(8)

man:dhcpd.conf(5)

Main PID: 26913 (dhcpd)

Status: "Dispatching packets..."

CGroup: /system.slice/dhcpd.service

└─26913 /usr/sbin/dhcpd -f -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --no-pid

<SNIP>

힌트:일부 줄은 줄임표 크기이며, 전체 줄을 표시하려면 -l을 사용합니다.

[root@xxxxxxxx]# service httpd status

Redirecting to /bin/systemctl status  httpd.service

httpd.service - The Apache HTTP Server

Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)

Active: active (running) since Fri 2017-05-26 05:50:30 PDT; 3 days ago

Docs: man:httpd(8)

man:apachectl(8)

Process: 28088 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=0/SUCCESS)

Process: 11036 ExecReload=/usr/sbin/httpd $OPTIONS -k graceful (code=exited, status=0/SUCCESS)

Main PID: 28095 (httpd)

Status: "Total requests: 0; Current requests/sec: 0; Current traffic:   0 B/sec"

CGroup: /system.slice/httpd.service

├─11037 /usr/sbin/httpd -DFOREGROUND

├─11038 /usr/sbin/httpd -DFOREGROUND

├─11039 /usr/sbin/httpd -DFOREGROUND

├─11040 /usr/sbin/httpd -DFOREGROUND

├─11041 /usr/sbin/httpd -DFOREGROUND

├─26998 /usr/sbin/httpd -DFOREGROUND

├─27426 /usr/sbin/httpd -DFOREGROUND

├─27427 /usr/sbin/httpd -DFOREGROUND

├─27428 /usr/sbin/httpd -DFOREGROUND

├─27889 /usr/sbin/httpd -DFOREGROUND

└─28095 /usr/sbin/httpd -DFOREGROUND

May 26 05:50:30 xxxxx systemd[1]: Starting The Apache HTTP Server...

May 26 05:50:30 xxxxx systemd[1]: Started The Apache HTTP Server.

May 27 03:16:01 xxxxx systemd[1]: Reloaded The Apache HTTP Server.

May 28 03:37:01 xxxxx systemd[1]: Reloaded The Apache HTTP Server.

라우터가 DHCP를 사용하여 IP 주소를 가져오도록 활성화

Interface MgmtEth 0/RP0/CPU0/0

Ipv4 address dhcp

Shut/no shut

HTTP 서버가 작동하는지 확인

- http:// <ip-servername>이 작동하는지 테스트합니다.

- IP 주소/서버 이름에 대한 브라우저를 엽니다.

DHCP 또는 HTTP가 작동하지 않으면 방화벽 문제 또는 연결 가능성 문제가 발생할 수 있습니다.

서버에서 방화벽 속성을 확인하려면 다음 명령을 수행하거나 특정 프로토콜을 추가합니다.

IP tables 명령을 사용하여 방화벽 규칙을 확인합니다.

Iptables –L –n

Chain IN_public_allow (1 references)

target     prot opt source               destination

ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:67 ctstate NEW

ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 ctstate NEW

ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 ctstate NEW

다음 방화벽 명령을 사용하여 허용되는 항목을 나열합니다.

[root@xxxxxxxxx ~]# firewall-cmd --list-all

public (active)

target: default

icmp-block-inversion: no

interfaces: enp2s0f0

sources:

services: dhcp dhcpv6-client http ssh

ports:

protocols:

masquerade: no

forward-ports:

sourceports:

icmp-blocks:

rich rules:

다음 명령을 사용하여 포트를 영구적으로 허용합니다.

firewall-cmd --permanent --add-service=http

firewall-cmd --permanent --add-service=dhcp

DHCP 서버에서 패킷 캡처를 활성화합니다.

tcpdump –i <interface id> port (bootpc & bootps & port http) –s 0(buffer size) –w <dest. File name>

ex: tcpdump -i enp2s0f0 port 67 or port 68 or port 80 -s 0 -w iPXEboot.pcap

ZTP를 시작하는 방법

수동으로 ZTP 시작

ZTP를 호출하려면 ZTP initiate exec CLI 명령을 사용합니다.  기본적으로 ZTP에 사용되는 인터페이스는 MGMTEth입니다.다른 인터페이스에서 이 프로세스를 시작하려면 다음 옵션을 사용합니다.

ZTP initiate interface <type> <number> <cr>

또는

Ztp initiate <cr>

iPXE로 라우터 부팅

1. Calvados에서 reload CLI 명령을 시작합니다.

이 명령을 사용하면 라우터가 다시 로드되어 iPXE 부팅이 시작됩니다.

참고:사용자 클래스 정보는 Wireshark의 버그 때문에 Malformed 옵션으로 해석됩니다.

2. 라우터가 DHCP 검색을 시작합니다. 사용자 클래스가 iPXE 옵션으로 채워져 있음을 확인합니다.

3. 서버의 DHCP 오퍼에는 옵션 67에 부트 파일 이름이 포함됩니다.

4. 라우터가 이미지 다운로드를 시작합니다.

5. 이미지가 성공적으로 다운로드되면 디바이스에 이미지 설치가 시작됩니다.

6. 라우터가 다운로드된 이미지로 성공적으로 부팅되면 다른 DHCP 요청을 시작합니다.

이 검색에서 사용자 클래스 정보에는 *.exr-config가 포함되어 있습니다.DHCP는 구성 파일 또는 스크립트(예:Else 문(etc/dhcp/dhcpd.conf).

7. DHCP 서버는 옵션 67에서 필요한 파일 정보를 반환합니다.

8. 라우터가 컨피그레이션을 다운로드합니다.

스크립트는 DHCP 서버의 응답으로 포함되고 이미지/컨피그레이션을 복사하도록 할 수 있습니다.  아래 예와 같이 설치 후 스크립트로 사용할 수도 있습니다.

설치 후 자동화

eXR 소프트웨어에서 설치 후 다양한 자동화를 수행할 수 있습니다.

이 예에서 이 스크립트는 모든 필수 패키지를 설치하고 구성을 적용합니다. 이 버전은 약간 수정된 ztp_helper.sh 버전입니다. 이 스크립트는 xr-linux-shell에서 호출됩니다.

RP/0/RP0/CPU0:NCS-5502-A#more disk0:/ztp/ztp_helper_file.sh

Wed May 31 00:55:54.529 UTC

#!/bin/bash

################################################################################

# Install config and additional packages

################################################################################

source /disk0:/ztp/ztp_helper.sh

export HTTP_SERVER=http://10.10.10.10

export RPM_PATH=images

export CONFIG_PATH=images

#Config

export INITIAL_CONFIG=NCS-5502-A.cfg

export FINAL_CONFIG=NCS-5502-A.cfg

#Packages

K9SEC_RPM=ncs5500-k9sec-2.2.0.0-r612.x86_64.rpm

MCAST_RPM=ncs5500-mcast-2.0.0.0-r612.x86_64.rpm

ISIS_RPM=ncs5500-isis-1.1.0.0-r612.x86_64.rpm

OSPF_RPM=ncs5500-ospf-1.1.0.0-r612.x86_64.rpm

MGBL_RPM=ncs5500-mgbl-3.0.0.0-r612.x86_64.rpm

MPLS_RPM=ncs5500-mpls-2.1.0.0-r612.x86_64.rpm

MPLSTE_RPM=ncs5500-mpls-te-rsvp-2.2.0.0-r612.x86_64.rpm

function download_config(){

ip netns exec tpnns /usr/bin/wget ${HTTP_SERVER}/${CONFIG_PATH}/${FINAL_CONFIG} -O /harddisk:/new-config 2>&1

if [[ "$?" != 0 ]]; then

printf "### Error downloading system configuration ###"

else

printf "### Downloading system configuration complete ###";

fi

}

function apply_config(){

# Applies initial configuration

printf "### Applying initial system configuration ###";

xrapply_with_reason "Initial ZTP configuration" /harddisk:/new-config 2>&1;

printf "### Checking for errors ###";

local config_status=$(xrcmd "show configuration failed");

if [[ $config_status ]]; then

echo $config_status

printf "!!! Error encounter applying configuration file, review the log !!!!";

fi

printf "### Applying system configuration complete ###";

}

function install_pkg(){

#Download packages

printf "Downloading Packages"

ip netns exec tpnns /usr/bin/wget ${HTTP_SERVER}/${RPM_PATH}/${K9SEC_RPM} -O /harddisk:/$K9SEC_RPM 2>&1

if [[ "$?" != 0 ]]; then

printf "### Error downloading $K9SEC_RPM ###"

else

printf "### Downloading $K9SEC_PKG complete ###";

fi

printf "Downloading Packages"

ip netns exec tpnns /usr/bin/wget ${HTTP_SERVER}/${RPM_PATH}/${MCAST_RPM} -O /harddisk:/$MCAST_RPM 2>&1

if [[ "$?" != 0 ]]; then

printf "### Error downloading $MCAST_RPM ###"

else

printf "### Downloading $MCAST_RPM complete ###";

fi

printf "Downloading Packages"

ip netns exec tpnns /usr/bin/wget ${HTTP_SERVER}/${RPM_PATH}/${ISIS_RPM} -O /harddisk:/$ISIS_RPM 2>&1

if [[ "$?" != 0 ]]; then

printf "### Error downloading $ISIS_RPM ###"

else

printf "### Downloading $ISIS_RPM complete ###";

fi

printf "Downloading Packages"

ip netns exec tpnns /usr/bin/wget ${HTTP_SERVER}/${RPM_PATH}/${OSPF_RPM} -O /harddisk:/$OSPF_RPM 2>&1

if [[ "$?" != 0 ]]; then

printf "### Error downloading $OSPF_RPM ###"

else

printf "### Downloading $OSPF_RPM complete ###";

fi

printf "Downloading Packages"

ip netns exec tpnns /usr/bin/wget ${HTTP_SERVER}/${RPM_PATH}/${MGBL_RPM} -O /harddisk:/$MGBL_RPM 2>&1

if [[ "$?" != 0 ]]; then

printf "### Error downloading $MGBL_RPM ###"

else

printf "### Downloading $MGBL_RPM complete ###";

fi

printf "Downloading Packages"

ip netns exec tpnns /usr/bin/wget ${HTTP_SERVER}/${RPM_PATH}/${MPLS_RPM} -O /harddisk:/$MPLS_RPM 2>&1

if [[ "$?" != 0 ]]; then

printf "### Error downloading $MPLS_RPM ###"

else

printf "### Downloading $MPLS_RPM complete ###";

fi

printf "Downloading Packages"

ip netns exec tpnns /usr/bin/wget ${HTTP_SERVER}/${RPM_PATH}/${MPLSTE_RPM} -O /harddisk:/$MPLSTE_RPM 2>&1

if [[ "$?" != 0 ]]; then

printf "### Error downloading $MPLSTE_RPM ###"

else

printf "### Downloading $MPLSTE_RPM complete ###";

fi

xrcmd "install update source /harddisk:/ $K9SEC_RPM $MCAST_RPM $ISIS_RPM $OSPF_RPM $MGBL_RPM $MPLS_RPM $MPLSTE_RPM" 2>&1

local complete=0

while [ "$complete" = 0 ]; do

complete=`xrcmd "show install active" | grep k9sec | head -n1 | wc -l`

printf "Waiting for k9sec package to be activated"

sleep 5

done

rm -f /harddisk:/$K9SEC_RPM /harddisk:/$MCAST_RPM /harddisk:/$MCAST_RPM /harddisk:/$ISIS_RPM /harddisk:/$OSPF_RPM /harddisk:/$MGBL_RPM /harddisk:/$MPLSTE_RPM /harddisk:/$MPLS_RPM

printf "### XR PACKAGE INSTALL COMPLETE ###"

}

printf "Start Auto provision"

install_pkg;

download_config;

apply_config;

관련 정보

- https://xrdocs.github.io/software-management/tutorials/2016-08-26-working-with-ztp/

- https://xrdocs.github.io/software-management/tutorials/2016-07-27-ipxe-deep-dive/

- https://xrdocs.github.io/software-management/blogs/2016-10-14-ios-xr-packages-and-security/