Juniper ZTP/Homer

From ppwiki
Jump to navigation Jump to search

Goal

In this Tutorial, we are going to setup a ZTP environment to be able to run the basic configuration on a new Juniper switch. Once the basic configuration is done, we will run homer to deploy the switch configuration. If you want to know more about homer please check: https://wikitech.wikimedia.org/wiki/Homer

Prerequisites

For this tutorial I will be using :

- EVE-NG 2.0.3-112

- VQFX model: vqfx-10000 running JUNOS 19.4R1.10

- DHPC/TFTP VM (IP:10.192.16.5/install1001.dfw.labnet)

- Homer VM(IP:10.192.32.17/homer1001.dfw.labnet)

- Netbox VM(IP:10.192.32.3/netbox1001.dfw.labnet)

- DNS server(IP:10.192.16.2/ns0.dfw.labnet)

All the VM's are running on Proxmox 7.3.4

Diagram

Setup and Configuration

The section is the just the section needed to make ztp work.

Note: We will generate the juniper_ztp file using later on a python script

DHCP configuration

#######################################################################
# ZTP Sample Config begins here:
#######################################################################
option option-150 code 150 = ip-address;
set vendor-string = option vendor-class-identifier;
option space ZTP;
option ZTP.image-file-name         code 0 = text;
option ZTP.config-file-name        code 1 = text;
option ZTP.image-file-type         code 2 = text;
option ZTP.transfer-mode           code 3 = text;
option ZTP.alt-imagefile-name      code 4 = text;
option ZTP-encapsulation           code 43 = encapsulate ZTP;
# mgmt nework
subnet 10.193.0.0 netmask 255.255.255.0 {
         authoritative;
         option subnet-mask             255.255.255.0;
         option option-150              10.192.16.5;  #TFTP server
         option routers                 10.193.0.1;
         option broadcast-address       10.193.0.255;
         option domain-name             "mgmt.dfw.labnet";
         default-lease-time             600;
         max-lease-time                 7200;
}
group {
        vendor-option-space ZTP;
        include "/etc/dhcp/juniper_ztp";   
}

DNS entries for the 4 switches

$ORIGIN 0.193.10.in-addr.arpa.
---
101     1H      IN      PTR     lsw1-a1-dfw.mgmt.dfw.labnet.
102     1H      IN      PTR     lsw1-a2-dfw.mgmt.dfw.labnet.
103     1H      IN      PTR     lsw1-a3-dfw.mgmt.dfw.labnet.
104     1H      IN      PTR     lsw1-a4-dfw.mgmt.dfw.labnet.

$ORIGIN mgmt.dfw.labnet.
---
lsw1-a1-dfw      1H      IN      A       10.193.0.101
lsw1-a2-dfw      1H      IN      A       10.193.0.102
lsw1-a3-dfw      1H      IN      A       10.193.0.103
lsw1-a4-dfw      1H      IN      A       10.193.0.104

Script

This Python scrip will read data from a csv file and generate the dhcp_hosts = juniper_ztp file using a template. I am running the script on my homer VM in a NFS directory (see below). The reason i am running it in a NFS directory is to create a symbolic link from the directory to the "/etc/dhcp/juniper_ztp" file mentioned in the dhcpd.conf file.

ppaul@homer1001:/nfs/general/ztp$ ls -l
total 12
-rw-r--r-- 1 nobody nogroup 281 Feb  5 21:34 dhcp_template
-rw-r--r-- 1 nobody nogroup 738 Feb  5 21:36 generate_host.py
-rw-r--r-- 1 nobody nogroup 224 Feb  5 23:31 ztp_host.csv
ppaul@homer1001:/nfs/general/ztp$ 
ppaul@install1001:/etc/dhcp$ ls -la
total 72
drwxr-xr-x  5 root root  4096 Feb  5 23:13 .
drwxr-xr-x 82 root root  4096 Feb  5 23:05 ..
-rw-r--r--  1 root root  1426 May 26  2021 debug
-rw-r--r--  1 root root  1735 May 26  2021 dhclient.conf
drwxr-xr-x  2 root root  4096 Nov  3 23:31 dhclient-enter-hooks.d
drwxr-xr-x  2 root root  4096 Nov  3 23:32 dhclient-exit-hooks.d
-rw-r--r--  1 root root  3331 Oct  4 15:52 dhcpd6.conf
-rw-r--r--  1 root root  6088 Feb  5 01:07 dhcpd.conf
lrwxrwxrwx  1 root root    27 Feb  5 23:13 juniper_ztp -> /nfs/general/ztp/dhcp_hosts 
-rw-r--r--  1 root root 18869 Jan 28 14:29 linux-host-entries
-rw-r--r--  1 root root   794 Nov  3 23:38 linux-vm-entries
 
  • cvs file :ztp_host.csv

In a real world, working with real switches you can get the mgmt interface MAC directly from the sticker on the box the switch came in. You don't have to power on and connect to the switch before getting the information like I did with the VQFX. For the mgmt IP address and the host name you can get those information once the switch is already in Netbox and has an IP.

hostname,mgmt_ip,cidr_bits,mac_address
lsw1-a1-dfw,10.193.0.101,24,50:00:00:0e:00:00
lsw1-a2-dfw,10.193.0.102,24,50:00:00:16:00:00
lsw1-a3-dfw,10.193.0.103,24,50:00:00:17:00:00
lsw1-a4-dfw,10.193.0.104,24,50:00:00:18:00:00
  • template: dhcp_template
 host {{ hostname }} {
         hardware ethernet {{ mac_address }};
         fixed-address {{ mgmt_ip }};
         option option-150 10.192.16.5;
         option host-name "{{ hostname }}";
         option ZTP.config-file-name "junos_script.sh";
 }
 
  • python script
#!/usr/bin/python3
# Import  modules
import csv
import sys
from jinja2 import Template
# Set variable to your host file path. 
dhcp_file="/nfs/general/ztp/dhcp_hosts"
# Set this variable to the configuration folder
conf_path="/nfs/general/ztp/"
#  csv file name
csv_file="/nfs/general/ztp/ztp_host.csv"
# Read the cvs file and stores the colum headings as a keys
device_data = csv.DictReader(open(csv_file))
# Loops through the device_data csv so we can perform actions for each row
for row in device_data:
 data = row
 with open("dhcp_template") as t_dhcp:
           t_format = t_dhcp.read()
 template = Template(t_format)
 open_t = open(dhcp_file, 'a')
 print (open_t)
 open_t.write((template.render(data)))
 open_t.close()

Running the script

In the ztp directory on the homer VM we have just three(3) files. Now we are going to run the "generate_host.py" script; this should have a fourth file called "dhch_hosts"

ppaul@homer1001:/nfs/general/ztp$ sudo python3 generate_host.py 
<_io.TextIOWrapper name='/nfs/general/ztp/dhcp_hosts' mode='a' encoding='UTF-8'>
<_io.TextIOWrapper name='/nfs/general/ztp/dhcp_hosts' mode='a' encoding='UTF-8'>
<_io.TextIOWrapper name='/nfs/general/ztp/dhcp_hosts' mode='a' encoding='UTF-8'>
<_io.TextIOWrapper name='/nfs/general/ztp/dhcp_hosts' mode='a' encoding='UTF-8'>
ppaul@homer1001:/nfs/general/ztp$

dhcp_hosts contents

# Host lsw1-a1-dfw added by ztp script
host lsw1-a1-dfw {
       hardware ethernet 50:00:00:0e:00:00;
       fixed-address 10.193.0.101;
       option option-150 "10.192.16.5";
       option host-name "lsw1-a1-dfw";
       option ZTP.config-file-name "junos_script.sh";
}
# End lsw1-a1-dfw section# Host lsw1-a2-dfw added by ztp script
host lsw1-a2-dfw {
       hardware ethernet 50:00:00:16:00:00;
       fixed-address 10.193.0.102;
       option option-150 "10.192.16.5";
       option host-name "lsw1-a2-dfw";
       option ZTP.config-file-name "junos_script.sh";
}
# End lsw1-a2-dfw section# Host lsw1-a3-dfw added by ztp script
host lsw1-a3-dfw {
       hardware ethernet 50:00:00:17:00:00;
       fixed-address 10.193.0.103;
       option option-150 "10.192.16.5";
       option host-name "lsw1-a3-dfw";
       option ZTP.config-file-name "junos_script.sh";
}
# End lsw1-a3-dfw section# Host lsw1-a4-dfw added by ztp script
host lsw1-a4-dfw {
       hardware ethernet 50:00:00:18:00:00;
       fixed-address 10.193.0.104;
       option option-150 "10.192.16.5";
       option host-name "lsw1-a4-dfw";
       option ZTP.config-file-name "junos_script.sh";
}
# End lsw1-a4-dfw section

Switch script

We can see in the DHCP file we have the "option ZTP.config-file-name" pointing to the script "junos_script.sh". You can fin the scirpt below

#!/bin/sh
# Define some variables
KEY='"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4xpjWJoQhCf176i77ni9//mcYO3bBWu7necWZwJNVkFsvvT6XuWfkKVMUFnTjTMr1erv8WRDze7le9Jl2a/xMIgo9Cf71SU9faPbd /ukvaLl5VUeGvHKFg9d+7GUGx1z9K1qKY2VOBO5EQCht8+4o4mMaizoXoxHvkNolswAa5Jv/EPwnfCeDyV7TsG+Se1k7/1h1VFOwW7Dbxno1aCnMDYbcfiBnzGnLSZQGjehok6cqYTjsNIIdAiZYSpH77pnAGglFhxNUSlqj0qRIJZdG3nhPlvIRPjn7fouq3BJEmiWPP8ru67H1J2mdSkix4xOxdUWfGB9eJlENfnobJjBr ppaul@U18"' 
root_passwd='"$6$qspxq1Js$f0UFEnzRo7oFEOZ3URiSBVBinJvwYSv4qlZpQ9eKlhc1YlRG3RCCVyqtXN.92mB8P3ilTUK1h.7WOSRjY1z9i."'
em0_IP=$(cli -c "show interfaces em0 brief | match inet | trim 10 ")
# Mgmt interface
cli -c "configure; \
        set interfaces em0 unit 0 family inet address $em0_IP ; \
        delete interfaces em0 unit 0 family inet dhcp ; \
        commit and-quit "
# Routing options
cli -c "configure; \
        set routing-options static route 0.0.0.0/0 next-hop 10.193.0.1 ; \
        commit and-quit "
# Edit system
cli -c "configure; \
        set system root-authentication encrypted-password $root_passwd ; \
        set system login user homer uid 2002 ; \
        set system login user homer class super-user ; \
        set system login user homer authentication ssh-rsa $KEY ; \
        set system services ssh ; \
        set system services netconf ; \
        commit and-quit "

How it works?

Part 1

Steps 1 is not needed if you are working on a real switch. On the VQFX, you need to manually setup ztp

1- setup ztp (set chassis auto-image-upgrade) commit

2- switch starts the ztp process

3- switch send a dhcp request to the dhcp server

4- switch receive an IP address from the dhcp server

5- switch check if there is a configuration file and an image file

6- if file(s) exist switch download the file(s)

In our case, the switch will only download the script. We are using a script here and not a configuration file because a configuration file will over write the existing switch configuration which we don't want to.

7- Execution of the script

Part 2

1- The script setup the mgmt interface(em0) IP address and delete the dhcp option on the interface

2- The script setup the net-hop for the mgmt netowrk

3- The script setup the root password

4- The script setup the homer user and add the the ssh-key (needed to run homer)

5- The script setup the ssh and netconf service

6- END

At this point we can use now homer to perform the other switch configuration.

ZTP in action

- Set up ztp on the swith

{master:0}[edit]
root@vqfx-re# set chassis auto-image-upgrade 
root@vqfx-re# show | compare 
[edit]
+  chassis {
+      auto-image-upgrade;
+  }
{master:0}[edit]
root@vqfx-re# show interfaces                                                                                
Auto Image Upgrade: DHCP Client Bound interfaces:                                                                                                                                                              
Auto Image Upgrade: DHCP Client Unbound interfaces: xe-0/0/0.0 xe-0/0/1.0      
xe-0/0/2.0 xe-0/0/3.0 xe-0/0/4.0 xe-0/0/5.0 xe-0/0/6.0 xe-0/0/7.0 xe-0/0/8.0  
xe-0/0/9.0 xe-0/0/10.0 xe-0/0/11.0 em0.0                                                                                                                                                               
Auto Image Upgrade: To stop, on CLI apply                                      
"delete chassis auto-image-upgrade"  and commit                                                                                                                                                              
Auto Image Upgrade: No DHCP Client in bound state, reset all DHCP clients                                                                                                                                                              
Auto Image Upgrade: DHCP Client State Reset: xe-0/0/0.0 xe-0/0/1.0 xe-0/0/2.0  
xe-0/0/3.0 xe-0/0/4.0 xe-0/0/5.0 xe-0/0/6.0 xe-0/0/7.0 xe-0/0/8.0 xe-0/0/9.0  
xe-0/0/10.0 xe-0/0/11.0 em0.0
Auto Image Upgrade: DHCP Options for client interface em0.0 ConfigFile:        
junos_script.sh Gateway: 10.193.0.1 DHCP Server: 10.192.16.5 File Server:     
10.192.16.5 Options state:                                                    
Partial Options::Config File set,Image File not set,File Server set                                                                                 
Auto Image Upgrade: Active on client interface: em0.0                                                                               
error: remote side unexpectedly closed connection
root@vqfx-re:RE:0%                                                                                 
Auto Image Upgrade: Interface::   "em0"                                        
Auto Image Upgrade: Server::      "10.192.16.5"                                
Auto Image Upgrade: Image File::  "NOT SPECIFIED"                              
Auto Image Upgrade: Config File:: "junos_script.sh"                            
Auto Image Upgrade: Gateway::     "10.193.0.1"                                 
Auto Image Upgrade: Protocol::    "tftp"                                                                                                                                                                                                     
Auto Image Upgrade: Start fetching junos_script.sh file from server 10.192.16.5
through em0 using tftp                                                                                                                                                                                                                     
Auto Image Upgrade: File junos_script.sh fetched from server 10.192.16.5 throug
h em0                                                                                                                                                                                                                                       
Auto Image Upgrade: Executing script junos_script.sh     
Auto Image Upgrade: junos_script.sh executed successfully. See /var/log/script_
output                                                                                                                                                                                                                                      
Broadcast Message from root@lsw1-a2-dfw                                        
       (no tty) at 16:19 UTC...                                                                                                                             
Auto image Upgrade: Stopped

Please see below for the script log

root@vqfx-re:RE:0% cat /var/log/script_output 
Entering configuration mode
configuration check succeeds
commit complete
Exiting configuration mode
Entering configuration mode
configuration check succeeds
commit complete
Exiting configuration mode
Entering configuration mode
configuration check succeeds
commit complete
Exiting configuration mode

We see in the output below that the homer user, the mgmt interface and the ssh and netconf services are set.

{master:0}[edit]
root@lsw1-a2-dfw# show system login user homer                  
uid 2002;
class super-user;
authentication {
    ssh-rsa "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4xpjWJoQhCf176i77ni9//mcYO3bBWu7necWZwJNVkFsvvT6XuWfkKVMUFnTjTMr1erv8WRDze7le9Jl2a/xMIgo9Cf71SU9faPbd /ukvaLl5VUeGvHKFg9d+7GUGx1z9K1qKY2VOBO5EQCht8+4o4mMaizoXoxHvkNolswAa5Jv/EPwnfCeDyV7TsG+Se1k7/1h1VFOwW7Dbxno1aCnMDYbcfiBnzGnLSZQGjehok6cqYTjsNIIdAiZYSpH77pnAGglFhxNUSlqj0qRIJZdG3nhPlvIRPjn7fouq3BJEmiWPP8ru67H1J2mdSkix4xOxdUWfGB9eJlENfnobJjBr papaul@U18"; ##   SECRET-DATA
}
{master:0}[edit]
root@lsw1-a2-dfw# show interfaces em0             
unit 0 {
    family inet {
        address 10.193.0.102/24;
    }
}
{master:0}[edit]
root@lsw1-a2-dfw# show system services 
ssh {
    root-login allow;
}
netconf {
    ssh;
}

Now the switch is ready.We can run homer on it

Running homer

Before running homer make sure that the switch is in Netbox and that it has it's DNS Name set.

Below is the output of the changes after running homer with diff


ppaul@homer1001:~$ homer lsw1-a2* diff
/usr/local/lib/python3.9/dist-packages/paramiko/transport.py:219: CryptographyDeprecationWarning: Blowfish has been deprecated
  "class": algorithms.Blowfish,
INFO:homer.devices:Initialized 46 devices
INFO:homer:Generating diff for query lsw1-a2*
INFO:homer:Gathering global Netbox data
INFO:homer.devices:Matched 1 device(s) for query 'lsw1-a2*'
INFO:homer:Generating configuration for lsw1-a2-dfw.mgmt.dfw.labnet
INFO:homer.transports.junos:Running commit check on lsw1-a2-dfw.mgmt.dfw.labnet
Changes for 1 devices: ['lsw1-a2-dfw.mgmt.dfw.labnet']
[edit system root-authentication]
-   encrypted-password "$6$qspxq1Js$f0UFEnzRo7oFEOZ3URiSBVBinJvwYSv4qlZpQ9eKlhc1YlRG3RCCVyqtXN.92mB8P3ilTUK1h.7WOSRjY1z9i."; ## SECRET-DATA
+   encrypted-password "$5$bSgF2gnxBS/rA$sYP/f1pWJhl5d1VN0hHzjxd0jZhmnwGLCiwVm3hE8Z."; ## SECRET-DATA
[edit system root-authentication]
-    ssh-rsa "ssh-rsa  AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key"; ## SECRET-DATA
[edit system login]
+    class operations {
+        permissions [ admin-control clear configure field interface-control maintenance network rollback secret shell trace-control view view-configuration ];
+    }
+    class rancid {
+        permissions [ view view-configuration ];
+    }
[edit system login]
+    user ppaul {
+        uid 2001;
+        class super-user;
+        authentication {
+            ssh-rsa "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCry+y+fh4Yjz/yu+wfUtWl80z0Cd2bHcjEbGSg3kf0bkjmZK9uDRrHrxP /bmMjhqHNQCPwSIi6eRrvddPJxi8yP5Qmr9T2rnE8UxacmjXhGPTL+2GpoDYp5ybGuRhZdJG07EyiXiAFu6jSe9okZdhapRaAbhy/wMr1weZ/rrJwOGar7AKk+XCi4fwahh6vw9b++EEtGqRNzIDMw10nBl/kCc0141hHQ8ZhmvFdzNh2LQt2tvYwu0T/YmENcDs3tb7Us2hd4fw6KXIsqNLqxWLRjWgWj5J5zQpOzHgP/TM1X25ZxUlRh6jttcBsGSfaddzFwISK2qNbP+XvqJkR0g5J tpapaul@Macbooks-MacBook-Air.local"; ## SECRET-DATA
+        }
+    }
-    user vagrant {
-        uid 2000;
-        class super-user;
-        authentication {
-            ssh-rsa "ssh-rsa  AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key"; ## SECRET-DATA
-        }
-    }
[edit system]
+  domain-name mgmt.dfw.labnet;
+  backup-router 10.193.0.1;
+  time-zone UTC;
+  /* Prefer the primary (loopback) address for locally generated packets causing issue on vqfx between fpc and RE  */
+  no-redirects;
[edit interfaces]
-   et-0/0/0 {
-       unit 0 {
-           family inet {
-               dhcp {
-                   vendor-id Juniper-qfx10002-72q;
-               }
-           }
-       }
-   }
-   xe-0/0/0 {
-       unit 0 {
-           family inet {
-               dhcp {
-                   vendor-id Juniper-qfx10002-72q;
-               }
-----------
-----------
[edit]
+  snmp {
+      location dfw;
+      filter-interfaces {
+          interfaces {
+              "^.*\.0$";
+          }
+      }
+      community passwordnotGood {
+          authorization read-only;
+      }

[edit routing-options static route 0.0.0.0/0]
+    no-readvertise;
[edit protocols]
+   lldp {
+       port-id-subtype interface-name;
+       interface all;
+   }
[edit vlans]
-   default {
-       vlan-id 1;
-   }
+   private1-a-dfw {
+       vlan-id 20;
+   }
+   private1-b-dfw {
+       vlan-id 30;
+   }
+   private1-c-dfw {
+       vlan-id 40;
+   }
+   private1-d-dfw {
+       vlan-id 50;
+   }

tcpdump on dhcp server

ppaul@install1001:~$ sudo tcpdump -vvv 'udp and (src port 67 or src port 68 or src port 69)'
tcpdump: listening on ens18, link-type EN10MB (Ethernet), snapshot length 262144 bytes
19:59:25.102231 IP (tos 0x0, ttl 64, id 30167, offset 0, flags [none], proto UDP (17), length 293)
    10.193.0.1.bootps > install1001.dfw.labnet.bootps: [udp sum ok] BOOTP/DHCP, Request from 50:00:00:17:00:00 (oui Unknown), length 265, hops 1, xid 0x2d895b7c, Flags [Broadcast] (0x8000)
 	  Gateway-IP 10.193.0.1
	  Client-Ethernet-Address 50:00:00:17:00:00 (oui Unknown)
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: Discover
	    Lease-Time (51), length 4: 86400
	    Hostname (12), length 12: "VM5F3D5FF6E7"
	    END (255), length 0
	    PAD (0), length 0
19:59:25.122924 IP (tos 0x0, ttl 64, id 14907, offset 0, flags [DF], proto UDP (17), length 367)
     install1001.dfw.labnet.bootps > 10.193.0.1.bootps: [bad udp cksum 0x26f3 -> 0xb12a!] BOOTP/DHCP, Reply, length 339, hops 1, xid 0x2d895b7c, Flags [Broadcast] (0x8000)
	  Your-IP lsw1-a3-dfw.mgmt.dfw.labnet
	  Gateway-IP 10.193.0.1
	  Client-Ethernet-Address 50:00:00:17:00:00 (oui Unknown)
	  file "nonexistent-file"
	  Vendor-rfc1048 Extensions
	    Magic Cookie 0x63825363
	    DHCP-Message (53), length 1: Offer
	    Server-ID (54), length 4: install1001.dfw.labnet
	    Lease-Time (51), length 4: 7200
	    Subnet-Mask (1), length 4: 255.255.255.0
	    Default-Gateway (3), length 4: 10.193.0.1
	    Domain-Name-Server (6), length 8: ns0.dfw.labnet,ns1.tx.labnet
	    Hostname (12), length 11: "lsw1-a3-dfw"
	    TFTP-Server-Address (150), length 4: install1001.dfw.labnet
	    BR (28), length 4: 10.193.0.255
	    Domain-Name (15), length 15: "mgmt.dfw.labnet"
	    Vendor-Option (43), length 17: 1.15.106.117.110.111.115.95.115.99.114.105.112.116.46.115.104
	    END (255), length 0