Yealink T19 Penyediaan otomatis + Buku Alamat Dinamis

Ketika saya mulai bekerja di perusahaan ini, saya sudah memiliki beberapa basis pada perangkat ip, beberapa server dengan asterisk dan splash dalam bentuk FreeBPX. Selain itu, pertukaran telepon analog Samsung IDCS500 bekerja secara paralel dan, secara umum, adalah sistem komunikasi utama di perusahaan, ip telephony hanya bekerja untuk bagian penjualan. Dan semuanya akan mendidih berulang kali, tetapi suatu hari suatu keputusan diberikan untuk mentransfer semua orang ke telepon IP, tanggal disepakati, peralatan dibeli dan rencana untuk memindahkan perusahaan ke abad ke-21 mulai dilaksanakan.
Hal pertama yang mulai mengganggu dalam situasi ini adalah meningkatnya jumlah telepon yang perlu dikelola, dan hal kedua yang sangat mengkhawatirkan adalah buku telepon. Jika Endpoint Manager (yang, kebetulan, dikeluarkan dari versi terbaru FreePBX) dapat membantu kami dengan yang pertama, maka berikut adalah beberapa pertanyaan dengan buku:

  • Pertama, bagaimana memastikan keakuratannya dengan perubahan terus-menerus dari perpindahan / pergantian pengguna?
  • Kedua, bagaimana cara sepenuhnya menghilangkan identitas ponsel. Dan jangan mengisi nama kontak setiap saat?

Tugas itu menarik, solusinya tidak lama datang. Sekarang saya akan memberikan daftar lengkap, dan kemudian kami akan menganalisis secara berurutan.

from scapy.all import sniff from scapy.layers.inet import IP import mysql.connector import ldap import getpass import tftpy import requests import os import time from string import replace def conn_ldap(login): ad = ldap.initialize('ldap://***.local') ad.simple_bind_s('voip@***.local', 'password') basedn = 'OU=IT,DC=***,DC=LOCAL' basedn_user = 'OU=***,OU=***,DC=***,DC=LOCAL' scope = ldap.SCOPE_SUBTREE filterexp = "(&(sAMAccountName=" + login + ")(ObjectClass=person))" filterexp2 = "(&(ObjectClass=organizationUnit))" attrlist = ['cn'] attrlist2 = ['OU'] search = ad.search_s(basedn, scope, filterexp, attrlist) adname = search[0][1]['cn'][0].decode('utf-8') if adname == ' ': search = ad.search_s(basedn_user, scope, filterexp2, attrlist2) for i in range(1, len(search)+1): group = search[i][1]['ou'][0] basedn_user2 = 'OU='+group+','+basedn_user search = ad.search_s(basedn_user2, scope, filterexp, attrlist) adname = search[0][1]['cn'][0].decode('utf-8') if adname != ' ': return adname adname = search[0][1]['cn'][0].decode('utf-8') ad.unbind_s() return adname def tftp_file_change(config,place,adname,current_account,current_account_password): client = tftpy.TftpClient("192.168.0.3", 69) client.download('template.cfg', place) fileread = open(place, 'r') line = fileread.readlines() fileread.close() line[5] = (('account.1.label = ').encode('utf-8') + adname.encode('utf-8') + '\n') line[2] = (('account.1.auth_name = ').encode('utf-8') + current_account.encode('utf-8') + '\n') line[3] = (('account.1.display_name = ').encode('utf-8') + current_account.encode('utf-8') + '\n') line[6] = (('account.1.password = ').encode('utf-8') + current_account_password[0][0] + '\n') filewrite = open(place, 'w') for i in line: filewrite.write(i) filewrite.close() print place print config client.upload(config,place) def get_phone_inform(ipaddr): fileconf = requests.get('http://admin:admin@'+ipaddr+'/servlet?phonecfg=get[&accounts=1]') conf = fileconf.text.split('|') current_account = conf[2] return current_account def sniff_frame(): pcapf = sniff(count=1, timeout=70, filter="dst host 192.168.0.3 and port 5060") if len(pcapf) == 0: exit() frame = pcapf[0] macaddr = frame.src print macaddr[:8] if macaddr[:8] != '80:5e:c0': exit() ipaddr = frame[0][IP].src return macaddr, ipaddr def conn_mysql(query,fquery,macaddr,qwery2): connect = mysql.connector.connect(host='192.168.0.3', database='voip', user='voip_wr', password='***') cursor = connect.cursor() cursor.execute(fquery) state = cursor.fetchall() state = bool(state[0][0]) if state == True: cursor.execute(qwery2) connect.commit() connect.close() else: cursor.execute(query) connect.commit() connect.close() def check_account(current_account): connect = mysql.connector.connect(host='192.168.0.3', database='asterisk', user='voip_wr', password='***') cursor = connect.cursor() qwery = 'select data from sip where id=' + current_account + ' and keyword="secret";' cursor.execute(qwery) password = cursor.fetchall() if password == ' ': exit() else: return password if __name__ == '__main__': macaddr, ipaddr = sniff_frame() current_account = get_phone_inform(ipaddr) current_account_password = check_account(current_account) macaddr = macaddr.replace(':', '') ipaddr = ipaddr.decode('utf-8') adname = conn_ldap(getpass.getuser()) query = 'INSERT INTO station (mac, ip, name, number) VALUES (' + '"' + macaddr + '",' + '"' + ipaddr + '",' + '"' + adname + '",' + '"' + get_phone_inform(ipaddr) + '"' + ')' qwery2 = 'UPDATE station SET ip=' + '"' + ipaddr + '"' + ', name=' + '"' + adname + '"' + ', number=' + '"' + get_phone_inform(ipaddr) + '"' + ' WHERE mac=' + '"' + macaddr + '"' fquery = 'SELECT EXISTS(SELECT mac FROM voip.station WHERE mac=' + '"' + macaddr + '")' query = query.encode('utf-8') fquery = fquery.encode('utf-8') config = macaddr + '.cfg' place = os.path.expanduser("~") + "\\" + "AppData\\Local\\" + config conn_mysql(query,fquery,macaddr,qwery2) tftp_file_change(config,place,adname,current_account,current_account_password) requests.get('http://admin:admin@'+ipaddr+'/cgi-bin/ConfigManApp.com?key=AutoP') requests.get('http://admin:admin@'+ipaddr+'/cgi-bin/ConfigManApp.com?key=Reboot') 

Program ini berjalan pada komputer pengguna dan bekerja di bawah kondisi bahwa komputer terhubung ke jaringan melalui telepon, karena Yealink T19 tidak dapat berfungsi sebagai gateway.

Pertama kita perlu memahami apakah itu terhubung? dan mac dan ip mana yang memiliki telepon kita.

 def sniff_frame(): pcapf = sniff(count=1, timeout=70, filter="dst host 192.168.0.3 and port 5060") if len(pcapf) == 0: exit() frame = pcapf[0] macaddr = frame.src print macaddr[:8] if macaddr[:8] != '80:5e:c0': exit() ipaddr = frame[0][IP].src return macaddr, ipaddr 

Di sini kita menggunakan fungsi sniff dari kerangka scapy, dengan menggunakannya kita mendapatkan paket udp yang telah ditentukan, tunggu 70 detik dan jika kita tidak menangkap apa-apa, keluar.

 count=1, timeout=70, filter="dst host 192.168.0.3 and port 5060" 

Selanjutnya, kami memastikan bahwa perangkat tersebut benar-benar Yealink dan mengembalikan nilai yang diperlukan (ip dan mac).

Dengan menggunakan permintaan khusus, kami mengetahui akun saat ini di telepon. Untuk melakukan ini, konfigurasi saat ini diunduh dari ponsel dan diuraikan.

 def get_phone_inform(ipaddr): fileconf = requests.get('http://admin:admin@'+ipaddr+'/servlet?phonecfg=get[&accounts=1]') conf = fileconf.text.split('|') current_account = conf[2] return current_account 

Kami mengetahui kata sandi untuk akun ini. Untuk melakukan ini, kita beralih ke tabel asterisk.sip dan di dalamnya ke bidang data.

 def check_account(current_account): connect = mysql.connector.connect(host='192.168.0.3', database='asterisk', user='voip_wr', password='***') cursor = connect.cursor() qwery = 'select data from sip where id=' + current_account + ' and keyword="secret";' cursor.execute(qwery) password = cursor.fetchall() if password == ' ': exit() else: return password 

Nah, untuk tahap terakhir, kita terhubung ke ldap AD dan menggunakan sAMAccountName yang diperoleh melalui fungsi getpass.getuser () untuk mengambil cn dari pengguna saat ini (yang biasanya berisi nama pengguna).

 def conn_ldap(login): ad = ldap.initialize('ldap://***.local') ad.simple_bind_s('voip@***.local', 'password') basedn = 'OU=***,DC=***,DC=LOCAL' basedn_user = 'OU=***,OU=***,DC=***,DC=LOCAL' scope = ldap.SCOPE_SUBTREE filterexp = "(&(sAMAccountName=" + login + ")(ObjectClass=person))" filterexp2 = "(&(ObjectClass=organizationUnit))" attrlist = ['cn'] attrlist2 = ['OU'] search = ad.search_s(basedn, scope, filterexp, attrlist) adname = search[0][1]['cn'][0].decode('utf-8') if adname == ' ': search = ad.search_s(basedn_user, scope, filterexp2, attrlist2) for i in range(1, len(search)+1): group = search[i][1]['ou'][0] basedn_user2 = 'OU='+group+','+basedn_user search = ad.search_s(basedn_user2, scope, filterexp, attrlist) adname = search[0][1]['cn'][0].decode('utf-8') if adname != ' ': return adname adname = search[0][1]['cn'][0].decode('utf-8') ad.unbind_s() return adname 

Kami terhubung ke tabel yang sebelumnya dibuat dalam database (saya membuatnya di tempat yang sama) dan menambahkan semua yang kami pelajari, yaitu: ip, mac, nama pengguna.

 def conn_mysql(query,fquery,macaddr,qwery2): connect = mysql.connector.connect(host='192.168.0.3', database='voip', user='voip_wr', password='***') cursor = connect.cursor() cursor.execute(fquery) state = cursor.fetchall() state = bool(state[0][0]) if state == True: cursor.execute(qwery2) connect.commit() connect.close() else: cursor.execute(query) connect.commit() connect.close() 

Kita bisa berhenti pada ini, karena kami telah membuat buku alamat dinamis, Anda bertanya, tetapi saya melangkah lebih jauh dan mengacaukan perangkat autoprovisioning di sini.

Untuk melakukan ini, konfigurasi templat diunduh dari server tftp yang sudah dikonfigurasi sebelumnya, ke dalamnya kami melakukan perubahan dan menyimpannya dengan mac.cfg. Yaitu, untuk Yealink ada dua jenis konfigurasi, satu global, dan yang kedua diterapkan pada telepon tertentu dan harus dalam bentuk mac_phone.cfg

Setelah semua perubahan dalam file dan menyimpannya kembali ke server tftp, kami memberikan perintah ke telepon untuk penyediaan dan reboot perangkat.

 def tftp_file_change(config,place,adname,current_account,current_account_password): client = tftpy.TftpClient("192.168.0.3", 69) client.download('template.cfg', place) fileread = open(place, 'r') line = fileread.readlines() fileread.close() line[5] = (('account.1.label = ').encode('utf-8') + adname.encode('utf-8') + '\n') line[2] = (('account.1.auth_name = ').encode('utf-8') + current_account.encode('utf-8') + '\n') line[3] = (('account.1.display_name = ').encode('utf-8') + current_account.encode('utf-8') + '\n') line[6] = (('account.1.password = ').encode('utf-8') + current_account_password[0][0] + '\n') filewrite = open(place, 'w') for i in line: filewrite.write(i) filewrite.close() print place print config client.upload(config,place) 

 requests.get('http://admin:admin@'+ipaddr+'/cgi-bin/ConfigManApp.com?key=AutoP') requests.get('http://admin:admin@'+ipaddr+'/cgi-bin/ConfigManApp.com?key=Reboot') 

Setelah me-reboot perangkat, kita mendapatkan nama lengkap di layar ponsel + selalu dengan benar mengisi buku alamat di hadapan basis data, maka kita hanya perlu mengacaukan XML dan sedikit PHP untuk menampilkan konten secara dinamis. Ada banyak contoh seperti itu, bahkan YEALINK sendiri memilikinya.

PS: Untuk skalabilitas yang lebih besar, Anda dapat memindahkan pengaturan utama (variabel) ke file terpisah.

Source: https://habr.com/ru/post/id465779/


All Articles