├── LICENSE
├── README.md
├── Topology.png
├── ppp_script_on_up.txt
├── requirement
└── ztp_mikrotik.py
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Ahmad Rosid Komarudin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ztp-mikrotik
2 | Zero Touch Provisioning on Mikrotik
3 |
4 | This repository contain python script to doing Zero Touch Provisioning on Mikrotik
5 |
6 |
Topology
7 | This repository is tested using this Topology
8 |
9 |
10 | Requirement
11 | To run this repository, you need some python library installed on your computer.
12 |
13 | - Python 3.6.5
14 | - flask
15 | - paramiko
16 | - telepot
17 | - python-mysqldb
18 |
19 |
20 |
21 | Setup
22 |
23 | - Create Telegram bot, this telegram bot will used to notify us if the provisioning on Mikrotik completed. You can follow tutorial on https://docs.microsoft.com/en-us/azure/bot-service/bot-service-channel-connect-telegram?view=azure-bot-service-4.0
24 | - Clone this repository
25 |
26 | - git clone https://github.com/arrosid/ztp-mikrotik.git
27 | - cd ztp-mikrotik
28 |
29 | - Install requirement library
30 |
31 | - virtualenv -p python3 venv
32 | - source venv/bin/activate
33 | - pip install -r requirement
34 | - sudo apt-get install python-mysqldb
35 |
36 | - Edit ztp_mikrotik.py. Fill the 'your_token' and 'your_chat_id'
37 | - Run the python script
38 |
39 | - python3 ztp_mikrotik.py
40 |
41 | - Configure PPPoE Server on ISP
42 | - Add ppp_script_on_up.txt to the on UP script in the PPP Server Profile. Modify the 'your_flask_server_ip_address'. Make sure your flask server can reach PPPoE Client. May be you need to add static route to the PPPoE Client via PPPoE Server
43 | - Configure PPPoE Client on Customer, and see that you will reciev Telegram notification and the customer is provisioned automatically
44 |
45 |
--------------------------------------------------------------------------------
/Topology.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ArRosid/ztp-mikrotik/47f3a98855ae2d8b36d64119ab2ae745b5867981/Topology.png
--------------------------------------------------------------------------------
/ppp_script_on_up.txt:
--------------------------------------------------------------------------------
1 | foreach i in=[/ppp active find where uptime <1m ] do={
2 | local name [ppp active get value-name=name $i];
3 | local ipaddr [ppp active get value-name=address $i];
4 | tool fetch url="http://:5000/configure" http-method=post http-content-type="application/json" http-data="{\"ip_router\":\"$ipaddr\"}"
5 | }
6 |
--------------------------------------------------------------------------------
/requirement:
--------------------------------------------------------------------------------
1 | flask
2 | paramiko
3 | telepot
4 | librouteros
5 |
--------------------------------------------------------------------------------
/ztp_mikrotik.py:
--------------------------------------------------------------------------------
1 | from flask import Flask, request, jsonify
2 | import paramiko
3 | import time
4 | import telepot
5 | from librouteros import connect
6 | import MySQLdb as mdb
7 |
8 | app = Flask(__name__)
9 |
10 |
11 | @app.route('/configure', methods=['POST'])
12 | def configure():
13 | dats = request.get_json()
14 | ip = dats['ip_router']
15 | username = 'admin'
16 | password = ''
17 |
18 | # get info from router
19 | api = connect(username=username, password=password, host=ip)
20 | router_board_info = api(cmd="/system/routerboard/print")
21 | identity_info = api(cmd="/system/identity/print")
22 |
23 | identity = identity_info[0]['name']
24 | serial_number = router_board_info[0]['serial-number']
25 | model = router_board_info[0]['model']
26 | version = router_board_info[0]['upgrade-firmware']
27 |
28 | # connect to router using ssh
29 | ssh_client = paramiko.SSHClient()
30 | ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
31 | ssh_client.connect(hostname=ip, username=username, password=password, allow_agent=False, look_for_keys=False)
32 |
33 | config_list = [
34 | 'ip dns set servers=8.8.8.8',
35 | 'ip address add address=192.168.1.1/24 interface=ether2',
36 | 'ip pool add name=dhcp-server ranges=192.168.1.2-192.168.1.254',
37 | 'ip dhcp-server add name=dhcp-server interface=ether2 address-pool=dhcp-server disabled=no',
38 | 'ip dhcp-server network add address=192.168.1.0/24 gateway=192.168.1.1 dns-server=8.8.8.8',
39 | 'ip service disable telnet,ftp,www,api-ssl',
40 | 'ip firewall nat add chain=srcnat out-interface=pppoe-client action=masquerade',
41 | 'ip firewall address-list add address=192.168.1.2-192.168.1.10 list=allowed_to_router',
42 | 'ip firewall address-list add address=10.10.10.1 list=allowed_to_router',
43 | 'ip firewall filter add action=accept chain=input src-address-list=allowed_to_router',
44 | 'ip firewall filter add action=accept chain=input protocol=icmp',
45 | 'ip firewall filter add action=drop chain=input',
46 | 'ip firewall filter add action=drop chain=forward comment="Drop new connections from internet which are not dst-natted" connection-nat-state=!dstnat connection-state=new in-interface=pppoe-client',
47 | 'password old-password="" new-password="idnmantab" confirm-new-password="idnmantab"',
48 | 'user add name=noc password=noc123 disabled=no group=read',
49 | 'tool bandwidth-server set enabled=no',
50 | 'system clock set time-zone-name=Asia/Jakarta',
51 | 'system ntp client set enabled=yes primary-ntp=202.162.32.12',
52 | 'tool mac-server set allowed-interface-list=none',
53 | 'tool mac-server mac-winbox set allowed-interface-list=none',
54 | 'tool mac-server ping set enabled=no',
55 | 'ip neighbor discovery-settings set discover-interface-list=none',
56 | ]
57 |
58 | # configure router
59 | for config in config_list:
60 | ssh_client.exec_command(config)
61 | time.sleep(0.2)
62 |
63 | # add info to the database
64 | sql_host = 'localhost'
65 | sql_username = 'root'
66 | sql_password = '***'
67 | sql_database = 'ztp_mikrotik'
68 |
69 | sql_conn = mdb.connect(sql_host, sql_username, sql_password, sql_database)
70 | cursor = sql_conn.cursor()
71 |
72 | cursor.execute("Use {}".format(sql_database))
73 |
74 | cursor.execute("INSERT INTO customer ({}, {}, {}, {}, {}) VALUES('{}', '{}', '{}', '{}', '{}')".format('identity', 'ip_address', 'serial_number', 'model', 'version', identity, ip, serial_number, model, version))
75 |
76 | sql_conn.commit()
77 |
78 | # send notification to telegram
79 | telegram_token = ''
80 | chat_id = ''
81 | bot = telepot.Bot(telegram_token)
82 | bot.sendMessage(chat_id, 'Client Baru UP!\nIdentity: {}\nIP: {}\nSerial Number: {}\nModel: {}\nVersion: {}'.format(identity, ip, serial_number, model, version))
83 |
84 | data = {'status': 'ok'}
85 |
86 | return jsonify(data)
87 |
88 |
89 | if __name__ == '__main__':
90 | app.run(host='0.0.0.0', debug=True)
91 |
--------------------------------------------------------------------------------