Coder Social home page Coder Social logo

nchekwa / python-ztp Goto Github PK

View Code? Open in Web Editor NEW
21.0 2.0 6.0 195 KB

Python ZTP server which support simple DHCP reponse, TFTP, HTTP file service

Shell 59.72% Python 39.07% Dockerfile 1.21%
ztp dhcp-discovery tftp python-ztp docker dhcp-server tftp-server http-server dhcp dhcpd

python-ztp's Introduction

Zero touch provisioning (ZTP) (include DHCP/TFTP/HTTP)

Python3 script which using YAML file as host config to offer DHCP/IP for device.
System sniff DHCP packets and answer using own build DHCP responses (based on scapy library)
Built-in TFTP/HTTP servers allow host download config/firmware which was pointed in dhcp option.

No more installing Isc/Kea DHCP and configuring DHCP scopes/TFTP/HTTP...

Syntax:

[root@server ztp]# ./ztp.py -h
usage: ztp.py [-h] [-i INTERFACE] [-l LIMIT] [-p PATH] [--port_tftp PORT_TFTP]
              [--port_http PORT_HTTP] [-d PCAP]

optional arguments:
  -h, --help            show this help message and exit
  -i INTERFACE, --interface INTERFACE
                        Interface to service requests
  -p PATH, --path PATH  TFTP folder path. Set `None` to disable TFTP
  --port_tftp PORT_TFTP
                        TFTP port
  --port_http PORT_HTTP
                        HTTP port
  -d PCAP, --pcap PCAP  collect PCAP file name for debug

Memory consumption:

[root@server ztp]# pmap 3068 | grep total
 total           410900K

Example:

Screenshot

Config Yaml file example:

VM0021210000:
  mac: 50:00:21:21:00:00
  hostname: Spine-21
  domain: juniper.lab
  ip: 10.240.40.21
  subnet_mask: 255.255.252.0
  router: 10.240.40.1
  name_server: 8.8.8.8       // (only SINGLE server supported)
  lease_time: 60
  tftp_server_name: 10.240.40.254
  boot-file-name: juniper.config
  tftp_server_address: 10.240.40.254
  vendor_specific: 0:junos.tgz,1:VM0021210000/juniper.sh,3:http

Config needs to be store in tftp folder in single / or multiple yaml files.
Configs are checked/read everytime when new dhcp Discovery pacet would be capture.
This consuming some resorces (utlize disk) but allow you 'in fly' modyfie config without restarting ztp instance.
YAML Config format:
<hostname/name>:
  mac: <mac - allow format with seperators like .:->
  <parameter>: <value>

In some cases new unboxed device report as hostname their serial number so in this situation, if script discovery that hostname inside Discovery message match this <hostname/name> - it will use this config section to send Offer.

DHCP_Discovery

If hostname/name will not be found in config files - it will check in 2nd step - mac match - for DHCP request in all configs.

parameters are related to scapy dhcp layer lib which can be found under this Link -> DHCPOptions
Please note that parameters tftp_server_name (option 66) and tftp_server_address (option 150) are missing in scapy layer lib so it needs to be added manually:

sed -i 's/    67: StrField/    66: "tftp_server_name",\n    67: StrField/g' /usr/local/lib/python3.6/site-packages/scapy/layers/dhcp.py
sed -i 's/    255: "end"/    150: IPField("tftp_server_address", "0.0.0.0"),\n    255: "end"/g' /usr/local/lib/python3.6/site-packages/scapy/layers/dhcp.py

Scapy issie 2747

Please remember that this docker need to be exposed to net=host as we need to get access to broadcast packages (scapy promisc mode). Use IFACE env on which interface docker should be listening.

Download docker image:

Download from docker.hub

[user@localhost ~]# docker pull nchekwa/python_ztp

Run in interactive mode:

[user@localhost ~]# docker run --name ztp --net=host -e IFACE="eth1" -v /tftp:/opt/ztp/tftp --rm -ti nchekwa/python_ztp

Docker registration:

[user@localhost ~]# docker create \
  --name=ztp \
  --net=host \
  -e IFACE="eth1" \
  -v /tftp:/opt/ztp/tftp \
  --restart unless-stopped \
  nchekwa/python_ztp:latest

[user@localhost ~]# docker ps -a
CONTAINER ID        IMAGE                       COMMAND                   CREATED              STATUS              PORTS               NAMES
22cf97689207        nchekwa/python_ztp:latest   "/bin/sh -c '\"python…"   About a minute ago   Created                                 ztp

[user@localhost ~]# docker start ztp
ztp
[user@localhost ~]#  docker logs -f --tail 10 ztp
Running. Press CTRL-C to exit.
[facts]    DHCP/TFTP interface: eth1
[facts]    eth1 IP: 10.240.40.254
[facts]    eth1 MAC: 50:00:00:33:00:01
[facts]    File folder status: exist
[facts]    File Path: /opt/ztp/tftp
[OK]       TFTP starting on 10.240.40.254 - port 69
[Warning]  HTTP 10.240.40.254:80 port in use
[OK]       DHCP starting sniffer eth1 - udp and (port 67 or 68)
eth1|<- [Rcv][Discover][0x61ec0f9e] Host VM0033330000 (50:00:33:33:00:00) asked for an IP
eth1|<- [Rcv][Discover][0x7c78d728] Host VM0033330000 (50:00:33:33:00:00) asked for an IP

Docker Composer:

Install:

curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

docker-compose --version
docker-compose version 1.26.2, build eefe0d31

Run:

docker-compose.yaml

---
version: "3"
services:
  python_ztp:
    image: nchekwa/python_ztp
    container_name: ztp
    network_mode: host
    environment:
      - IFACE=eth1
    volumes:
      - /tftp:/opt/ztp/tftp
    restart: unless-stopped
[user@localhost ~]# docker-compose -f docker-compose.yaml up -d
[user@localhost ~]# docker-compose -f docker-compose.yaml down

python-ztp's People

Contributors

azdolinski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

python-ztp's Issues

Portnumbers for ACK and OFFER are not correct

The source and destination port on these two packets are swapped.
To fix it I changed the following lines:
OLD lines:
236 sport = packet[UDP].sport
237 dport = packet[UDP].dport
279 sport = packet[UDP].sport
280 dport = packet[UDP].dport
NEW lines:
236 sport = packet[UDP].dport
237 dport = packet[UDP].sport
279 sport = packet[UDP].dport
280 dport = packet[UDP].sport

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.