commit f9662c488e3c61676ab80b1a536b2bf03d324007 Author: Sebastian Serfling Date: Tue Feb 11 12:39:12 2025 +0100 first Upload diff --git a/Firmen-Logo.png b/Firmen-Logo.png new file mode 100644 index 0000000..af919a8 Binary files /dev/null and b/Firmen-Logo.png differ diff --git a/docker_sync.py b/docker_sync.py new file mode 100644 index 0000000..0a2bdad --- /dev/null +++ b/docker_sync.py @@ -0,0 +1,2 @@ +import os +os.system(f"docker exec -u www-data app-server /bin/bash -c 'php occ files:scan --path=karstenstoecker/files/Stines\ GmbH/1.\ Verwaltung/4.\ Verträge/2.\ Zulieferer\ -\ Dienstleister/MS\ -\ SPLA/Insight/Reports/'") \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..e18903f --- /dev/null +++ b/main.py @@ -0,0 +1,362 @@ +import csv +import os +import mysql.connector +import pandas as pd +from datetime import datetime, timedelta +import openpyxl +import calendar +import http.client, urllib +# from reportlab.lib.pagesizes import letter +# from reportlab.pdfgen import canvas +from openpyxl.styles import Alignment, Font +import subprocess + +date = datetime.now() - timedelta(1) +month = datetime.now().strftime("%m") +year = datetime.now().strftime("%Y") +start_date_00 = date.replace(hour=0, minute=0, second=0, microsecond=0) +start_date_23 = start_date_00.replace(hour=23, minute=59, second=59, microsecond=0) +start_date_str = start_date_00.strftime("01.%m") +last_date_str = start_date_00.strftime(f"{calendar.monthrange(int(year),int(month))[1]}.%m") + +mydb = mysql.connector.connect( + host="172.17.1.21", + port="3306", + user="root", + password="N53yBCswuawzBzS445VNAhWVMs3N59Gb9szEsrzXRBzarDqpdETpQeyt5v5CGe", + database="Stines-GmbH", + auth_plugin='mysql_native_password', +) +mydb.connect() +cursor = mydb.cursor() + +cursor.execute("SELECT Datenbank FROM Kunden GROUP by Datenbank") +kunden = cursor.fetchall() + +main_path = fr"/docker/app_data/data/karstenstoecker/files/Stines GmbH/1. Verwaltung/4. Verträge/2. Zulieferer - Dienstleister/MS - SPLA/Insight/Reports/{year}" +for i in kunden: + kunde = i[0].replace("-"," ").replace("ae","ä") + if os.path.exists(fr"{main_path}/{i}/{start_date_str} - {last_date_str}/RAW"): + next + else: + try: + os.mkdir(fr"{main_path}/{kunde}") + except: + next + try: + os.mkdir(fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}") + except: + next + try: + os.mkdir(fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW") + except: + next + # RAW EXPORT + ## AD - User Export START ## + with open(fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/Active-Directory-User - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv', 'w', newline='', encoding='utf-8') as csvfile: + csv_writer = csv.writer(csvfile,delimiter=";") + cursor.execute(f'SELECT * FROM `{i[0]}`.`Active-Directory-User` where importdate BETWEEN {start_date_00.timestamp()} and {start_date_23.timestamp()}') + csv_writer.writerow([i[0] for i in cursor.description]) + csv_writer.writerows(cursor.fetchall()) + ## AD - User Export ENDE ## + ## SERVER - Export START ## + with open(fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/SERVER - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv', 'w', newline='', encoding='utf-8') as csvfile: + csv_writer = csv.writer(csvfile,delimiter=";") + # print(f"SELECT Kundennummer,Name,`Server-Name`,`IP-Adresse`,CreateDate,`Windows-Key`,CPU,RAM,Speicher,Prozessor FROM `Stines-GmbH`.`Kunden-Server` where Name='{i[0]}' AND `Windows-Key` IS NOT NULL") + cursor.execute(f"SELECT Kundennummer,Name,`Server-Name`,`IP-Adresse`,CreateDate,`Windows-Key`,CPU,RAM,Speicher,Prozessor FROM `Stines-GmbH`.`Kunden-Server` where Name='{i[0]}' AND `Windows-Key` IS NOT NULL") + csv_writer.writerow([i[0] for i in cursor.description]) + csv_writer.writerows(cursor.fetchall()) + ## SERVER - Export ENDE ## + ## RDS - User Export START ## + with open(fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/RDS-User - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv', 'w', newline='', encoding='utf-8') as csvfile: + csv_writer = csv.writer(csvfile,delimiter=";") + try: + cursor.execute(f"SELECT id FROM `{i[0]}`.`Exchange-User` LIMIT 1") + except: + next + table_exists = cursor.fetchone() is not None + if table_exists: + cursor.execute(f'SELECT db1.importdate as "time",db1.CreateTimeStamp,db1.SamAccountName,db1.DisplayName, db1.EmailAddress, db1.extensionAttribute1 AS "RDS Deaktviert am", db1.extensionAttribute2 AS "Exchange Deaktviert am", db1.Description,db1.Deleted,db1.LastLogonDate,db1.City FROM `{i[0]}`.`Active-Directory-User` db1 INNER JOIN `{i[0]}`.`Active-Directory-RDS-User` db2 ON db1.SamAccountName = db2.SamAccountName WHERE db1.importdate BETWEEN {start_date_00.timestamp()} and {start_date_23.timestamp()} AND db2.SamAccountName NOT LIKE "%test%" AND db2.SamAccountName NOT LIKE "%admin%"') + else: + cursor.execute(f'SELECT db1.importdate as "time",db1.CreateTimeStamp,db1.SamAccountName,db1.DisplayName, db1.EmailAddress, db1.extensionAttribute1 AS "RDS Deaktviert am", db1.Description,db1.Deleted,db1.LastLogonDate,db1.City FROM `{i[0]}`.`Active-Directory-User` db1 INNER JOIN `{i[0]}`.`Active-Directory-RDS-User` db2 ON db1.SamAccountName = db2.SamAccountName WHERE db1.importdate BETWEEN {start_date_00.timestamp()} and {start_date_23.timestamp()} AND db2.SamAccountName NOT LIKE "%test%" AND db2.SamAccountName NOT LIKE "%admin%"') + csv_writer.writerow([i[0] for i in cursor.description]) + csv_writer.writerows(cursor.fetchall()) + if table_exists: + with open(fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/Exchange-User - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv', 'w', newline='', encoding='utf-8') as csvfile: + csv_writer = csv.writer(csvfile,delimiter=";") + cursor.execute(f'SELECT importdate as "time",SamAccountName,WindowsEmailAddress,CustomAttribute2 as "Description",WhenCreated FROM `{i[0]}`.`Exchange-User` WHERE RecipientTypeDetails = "UserMailbox" AND importdate BETWEEN {start_date_00.timestamp()} and {start_date_23.timestamp()} AND SamAccountName NOT LIKE "%test%" AND SamAccountName NOT LIKE "%admin%" AND SamAccountName NOT LIKE "%journal%" ') + csv_writer.writerow([i[0] for i in cursor.description]) + csv_writer.writerows(cursor.fetchall()) + ## RDS - User Export ENDE ## + ## RAW EXPORT ENDE ## + ## CREATE Excel Sheet from csv Export ## + ## EXPORT to AD- User Excel-Sheet ## + csv_datei = fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/RDS-User - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv' + df = pd.read_csv(csv_datei, sep=";", encoding="utf-8") + # Leere Felder mit "-" füllen + df = df.fillna("-") + df["time"] = pd.to_datetime(df["time"], unit='s') + # Excel-Datei erstellen und Daten schreiben + excel_datei = fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}/{kunde}_User_Export Stand({last_date_str}).xlsx" + if os.path.exists(excel_datei): + mode = 'a' + else: + mode = 'w' + with pd.ExcelWriter(excel_datei, engine='openpyxl', mode=f'{mode}') as writer: + df.to_excel(writer, index=False, sheet_name=f'{start_date_00.strftime("%d-%m")}') + workbook = writer.book + worksheet = writer.sheets[f'{start_date_00.strftime("%d-%m")}'] + worksheet.auto_filter.ref = "A1:J1" + # Spaltenbreite festlegen + for column in worksheet.columns: + max_length = 0 + column_letter = column[0].column_letter + for cell in column: + try: + if len(str(cell.value)) > max_length: + max_length = len(cell.value) + except: + pass + adjusted_width = (max_length + 2) * 1.2 + worksheet.column_dimensions[column_letter].width = adjusted_width + ## EXPORT to AD- User Excel-Sheet ## + csv_datei = fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/SERVER - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv' + df = pd.read_csv(csv_datei, sep=";", encoding="utf-8") + # Leere Felder mit "-" füllen + df = df.fillna("-") + # df["time"] = pd.to_datetime(df["time"], unit='s') + # Excel-Datei erstellen und Daten schreiben + excel_datei = fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}/{kunde}_Server_Export Stand({last_date_str}).xlsx" + if os.path.exists(excel_datei): + mode = 'a' + else: + mode = 'w' + with pd.ExcelWriter(excel_datei, engine='openpyxl', mode=f'{mode}') as writer: + df.to_excel(writer, index=False, sheet_name=f'{start_date_00.strftime("%d-%m")}') + workbook = writer.book + worksheet = writer.sheets[f'{start_date_00.strftime("%d-%m")}'] + worksheet.auto_filter.ref = "A1:J1" + # Spaltenbreite festlegen + for column in worksheet.columns: + max_length = 0 + column_letter = column[0].column_letter + for cell in column: + try: + if len(str(cell.value)) > max_length: + max_length = len(cell.value) + except: + pass + adjusted_width = (max_length + 2) * 1.2 + worksheet.column_dimensions[column_letter].width = adjusted_width + if table_exists: + csv_datei = fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/Exchange-User - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv' + df = pd.read_csv(csv_datei, sep=";", encoding="utf-8") + # Leere Felder mit "-" füllen + df = df.fillna("-") + df["time"] = pd.to_datetime(df["time"], unit='s') + # Excel-Datei erstellen und Daten schreiben + excel_datei = fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}/{kunde}_Mailbox_Export Stand({last_date_str}).xlsx" + if os.path.exists(excel_datei): + mode = 'a' + else: + mode = 'w' + with pd.ExcelWriter(excel_datei, engine='openpyxl', mode=f'{mode}') as writer: + df.to_excel(writer, index=False, sheet_name=f'{start_date_00.strftime("%d-%m")}') + workbook = writer.book + worksheet = writer.sheets[f'{start_date_00.strftime("%d-%m")}'] + worksheet.auto_filter.ref = "A1:E1" + # Spaltenbreite festlegen + for column in worksheet.columns: + max_length = 0 + column_letter = column[0].column_letter + for cell in column: + try: + if len(str(cell.value)) > max_length: + max_length = len(cell.value) + except: + pass + adjusted_width = (max_length + 2) * 1.2 + worksheet.column_dimensions[column_letter].width = adjusted_width + + ## CREATE Worksheet first Page + try: + os.remove(fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}/{kunde}_Komplett.xlsx") + except: + next + excel_datei = fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}/{kunde}_Komplett.xlsx" + + workbook = openpyxl.Workbook() + worksheet = workbook.active + worksheet.title = "Übersicht" + font = Font(size=20) + + font_small = Font(size=16) + + + worksheet.merge_cells('C5:G6') + worksheet.merge_cells('C7:G7') + worksheet.merge_cells('C8:E8') + worksheet.merge_cells('C10:E10') + worksheet.merge_cells('C12:E12') + worksheet.merge_cells('C14:E14') + + worksheet['C5'] = "Übersicht" + worksheet['C5'].font = font + + worksheet['C7'] = f"{start_date_str} - {last_date_str}" + worksheet['C7'].font = font_small + + worksheet['C10'] = "RDS-User" + worksheet['C10'].font = font_small + worksheet['G10'] = "=COUNTIF('RDS - User'!G2:G50;\"-\")" + + if table_exists: + worksheet['C12'] = "Exchange-User" + worksheet['C12'].font = font_small + worksheet['G12'] = "=COUNTIF('Exchange - User'!D2:D50;\"<>\"&\"*Exchange - Deaktiviert*\")+1" + else: + next + + worksheet['C14'] = "Server-Cores" + worksheet['C14'].font = font_small + worksheet['G14'] = "=COUNTIF('Server'!J2:J50)*8/2" + + workbook.save(excel_datei) + + csv_datei = fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/RDS-User - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv' + df = pd.read_csv(csv_datei, sep=";", encoding="utf-8") + # Leere Felder mit "-" füllen + df = df.fillna("-") + df["time"] = pd.to_datetime(df["time"], unit='s') + # Excel-Datei erstellen und Daten schreiben + excel_datei = fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}/{kunde}_Komplett.xlsx" + if os.path.exists(excel_datei): + mode = 'a' + else: + mode = 'w' + with pd.ExcelWriter(excel_datei, engine='openpyxl', mode=f'{mode}') as writer: + df.to_excel(writer, index=False, sheet_name=f'RDS - User') + workbook = writer.book + worksheet = writer.sheets[f'RDS - User'] + worksheet.auto_filter.ref = "A1:J1" + # Spaltenbreite festlegen + for column in worksheet.columns: + max_length = 0 + column_letter = column[0].column_letter + for cell in column: + try: + if len(str(cell.value)) > max_length: + max_length = len(cell.value) + except: + pass + adjusted_width = (max_length + 2) * 1.2 + worksheet.column_dimensions[column_letter].width = adjusted_width + + if table_exists: + csv_datei = fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/Exchange-User - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv' + df = pd.read_csv(csv_datei, sep=";", encoding="utf-8") + # Leere Felder mit "-" füllen + df = df.fillna("-") + df["time"] = pd.to_datetime(df["time"], unit='s') + # Excel-Datei erstellen und Daten schreiben + excel_datei = fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}/{kunde}_Komplett.xlsx" + if os.path.exists(excel_datei): + mode = 'a' + else: + mode = 'w' + with pd.ExcelWriter(excel_datei, engine='openpyxl', mode=f'{mode}') as writer: + df.to_excel(writer, index=False, sheet_name=f'Exchange - User') + workbook = writer.book + worksheet = writer.sheets[f'Exchange - User'] + worksheet.auto_filter.ref = "A1:E1" + # Spaltenbreite festlegen + for column in worksheet.columns: + max_length = 0 + column_letter = column[0].column_letter + for cell in column: + try: + if len(str(cell.value)) > max_length: + max_length = len(cell.value) + except: + pass + adjusted_width = (max_length + 2) * 1.2 + worksheet.column_dimensions[column_letter].width = adjusted_width + csv_datei = fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/SERVER - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv' + df = pd.read_csv(csv_datei, sep=";", encoding="utf-8") + # Leere Felder mit "-" füllen + df = df.fillna("-") + # df["time"] = pd.to_datetime(df["time"], unit='s') + # Excel-Datei erstellen und Daten schreiben + excel_datei = fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}/{kunde}_Komplett.xlsx" + if os.path.exists(excel_datei): + mode = 'a' + else: + mode = 'w' + with pd.ExcelWriter(excel_datei, engine='openpyxl', mode=f'{mode}') as writer: + df.to_excel(writer, index=False, sheet_name=f'Server') + workbook = writer.book + worksheet = writer.sheets[f'Server'] + worksheet.auto_filter.ref = "A1:J1" + # Spaltenbreite festlegen + for column in worksheet.columns: + max_length = 0 + column_letter = column[0].column_letter + for cell in column: + try: + if len(str(cell.value)) > max_length: + max_length = len(cell.value) + except: + pass + adjusted_width = (max_length + 2) * 1.2 + worksheet.column_dimensions[column_letter].width = adjusted_width +# # os.mkdir("") +# # +# # print(table_exists) +# # +# # c = canvas.Canvas(fr"{i}/{start_date_str} - {last_date_str}/PDF_Export Stand({last_date_str}).pdf", pagesize=letter) +# # # Hier können Sie IhrenCode zum Hinzufügen von Daten zur PDF einfügen +# # c.setFont("Helvetica", 10) +# # c.drawString(50, 750, f"Create Date - {datetime.now().strftime("%d-%M-%Y")}") +# # c.drawImage("Firmen-Logo.png", x=450, y=730, width=150, height=40) +# # c.setFont("Helvetica", 12) +# # c.drawString(100, 680, "REPORT der RDP / Exchange User der Firma bla") +# # +# # k = 10 +# # n = 650 +# # x = 100 +# # t = 0 +# # if n < 50: +# # if t == 1: +# # x = 400 +# # n = 650 +# # print(x) +# # print("insede") +# # else: +# # x = 250 +# # n = 650 +# # t += 1 +# # c.setFont("Helvetica", 8) +# # c.drawString(x, n, f"Zeitraum: {i}") +# # c.drawString(x, n - 10, f"Aktive RDS-User: {i}") +# # c.drawString(x, n - 20, f"Deaktivierte RDS-User: {i}") +# # if table_exists: +# # c.drawString(x, n - 30, f"Aktive EX-User: {i}") +# # c.drawString(x, n - 40, f"Deaktivierte EX-User: {i}") +# # n = n - 60 +# # c.save() +# # subprocess.Popen(["start", "output.pdf"], shell=True) +cursor.close() +mydb.close() +os.system(f'chmod 777 -R "/docker/app_data/data/karstenstoecker/files/Stines GmbH/1. Verwaltung/4. Verträge/2. Zulieferer - Dienstleister/MS - SPLA/Insight/Reports/{year}"') +os.system(f"/bin/bash -c 'docker exec -u www-data app-server /bin/bash -c 'php occ files:scan --path=karstenstoecker/files/Stines\ GmbH/1.\ Verwaltung/4.\ Verträge/2.\ Zulieferer\ -\ Dienstleister/MS\ -\ SPLA/Insight/Reports/''") + +## SEND Pushover ## +conn = http.client.HTTPSConnection("api.pushover.net:443") +conn.request("POST", "/1/messages.json", + urllib.parse.urlencode({ + "token": "avzcexyjeu7y71pcskwshyx8ytmq8i", + "user": "uo2sf2pmrtjvt8auu786fviabimimr", + "message": "Reporting was running!", + }), { "Content-type": "application/x-www-form-urlencoded" }) +conn.getresponse() + diff --git a/main.py_old b/main.py_old new file mode 100644 index 0000000..91005e4 --- /dev/null +++ b/main.py_old @@ -0,0 +1,229 @@ +import csv +import os +import mysql.connector +import pandas as pd +from datetime import datetime, timedelta +import openpyxl +# from reportlab.lib.pagesizes import letter +# from reportlab.pdfgen import canvas +import subprocess + +mydb = mysql.connector.connect( + host="172.17.1.21", + port="3306", + user="root", + password="N53yBCswuawzBzS445VNAhWVMs3N59Gb9szEsrzXRBzarDqpdETpQeyt5v5CGe", + database="Stines-GmbH", + auth_plugin='mysql_native_password', +) +mydb.connect() +cursor = mydb.cursor() + +lastdate_month=29 +month=2 + +for k in range(0,lastdate_month): + heute = datetime.now() + start_date = datetime(2024, month, 1).replace(hour=0, minute=0, second=0, microsecond=0) + start_date_00 = start_date + timedelta(days=k) + start_date_23 = start_date_00.replace(hour=23, minute=59, second=59, microsecond=0) + last_date = datetime(2024, month, lastdate_month) + year = last_date.strftime("%Y") + + cursor.execute("SELECT Datenbank FROM Kunden GROUP by Datenbank") + kunden = cursor.fetchall() + start_date_str = start_date.strftime("%d.%m") + last_date_str = last_date.strftime("%d.%m") + + main_path = fr"/docker/app_data/data/karstenstoecker/files/Stines GmbH/1. Verwaltung/4. Verträge/2. Zulieferer - Dienstleister/Microsoft Service Provider License Agreement/Insight Technology Solutions GmbH/Reports/{year}" + + for i in kunden: + kunde = i[0].replace("-"," ").replace("ae","ä") + if os.path.exists(fr"{main_path}/{i}/{start_date_str} - {last_date_str}/RAW"): + next + else: + try: + os.mkdir(fr"{main_path}/{kunde}") + except: + next + try: + os.mkdir(fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}") + except: + next + try: + os.mkdir(fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW") + except: + next + # RAW EXPORT + ## AD - User Export START ## + with open(fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/Active-Directory-User - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv', 'w', newline='', encoding='utf-8') as csvfile: + csv_writer = csv.writer(csvfile,delimiter=";") + cursor.execute(f'SELECT * FROM `{i[0]}`.`Active-Directory-User` where importdate BETWEEN {start_date_00.timestamp()} and {start_date_23.timestamp()}') + csv_writer.writerow([i[0] for i in cursor.description]) + csv_writer.writerows(cursor.fetchall()) + + ## AD - User Export ENDE ## + ## SERVER - Export START ## + with open(fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/SERVER - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv', 'w', newline='', encoding='utf-8') as csvfile: + csv_writer = csv.writer(csvfile,delimiter=";") + # print(f"SELECT Kundennummer,Name,`Server-Name`,`IP-Adresse`,CreateDate,`Windows-Key`,CPU,RAM,Speicher,Prozessor FROM `Stines-GmbH`.`Kunden-Server` where Name='{i[0]}' AND `Windows-Key` IS NOT NULL") + cursor.execute(f"SELECT Kundennummer,Name,`Server-Name`,`IP-Adresse`,CreateDate,`Windows-Key`,CPU,RAM,Speicher,Prozessor FROM `Stines-GmbH`.`Kunden-Server` where Name='{i[0]}' AND `Windows-Key` IS NOT NULL") + csv_writer.writerow([i[0] for i in cursor.description]) + csv_writer.writerows(cursor.fetchall()) + ## SERVER - Export ENDE ## + ## RDS - User Export START ## + with open(fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/RDS-User - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv', 'w', newline='', encoding='utf-8') as csvfile: + csv_writer = csv.writer(csvfile,delimiter=";") + try: + cursor.execute(f"SELECT id FROM `{i[0]}`.`Exchange-User` LIMIT 1") + except: + next + table_exists = cursor.fetchone() is not None + if table_exists: + cursor.execute(f'SELECT db1.importdate as "time",db1.CreateTimeStamp,db1.SamAccountName,db1.DisplayName, db1.EmailAddress, db1.extensionAttribute1 AS "RDS Deaktviert am", db1.extensionAttribute2 AS "Exchange Deaktviert am", db1.Description,db1.Deleted,db1.LastLogonDate,db1.City FROM `{i[0]}`.`Active-Directory-User` db1 INNER JOIN `{i[0]}`.`Active-Directory-RDS-User` db2 ON db1.SamAccountName = db2.SamAccountName WHERE db1.importdate BETWEEN {start_date_00.timestamp()} and {start_date_23.timestamp()} AND db2.SamAccountName NOT LIKE "%test%" AND db2.SamAccountName NOT LIKE "%admin%"') + else: + cursor.execute(f'SELECT db1.importdate as "time",db1.CreateTimeStamp,db1.SamAccountName,db1.DisplayName, db1.EmailAddress, db1.extensionAttribute1 AS "RDS Deaktviert am", db1.Description,db1.Deleted,db1.LastLogonDate,db1.City FROM `{i[0]}`.`Active-Directory-User` db1 INNER JOIN `{i[0]}`.`Active-Directory-RDS-User` db2 ON db1.SamAccountName = db2.SamAccountName WHERE db1.importdate BETWEEN {start_date_00.timestamp()} and {start_date_23.timestamp()} AND db2.SamAccountName NOT LIKE "%test%" AND db2.SamAccountName NOT LIKE "%admin%"') + csv_writer.writerow([i[0] for i in cursor.description]) + csv_writer.writerows(cursor.fetchall()) + if table_exists: + with open(fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/Exchange-User - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv', 'w', newline='', encoding='utf-8') as csvfile: + csv_writer = csv.writer(csvfile,delimiter=";") + cursor.execute(f'SELECT importdate as "time",SamAccountName,WindowsEmailAddress,CustomAttribute2 as "Description",WhenCreated FROM `{i[0]}`.`Exchange-User` WHERE RecipientTypeDetails = "UserMailbox" AND importdate BETWEEN {start_date_00.timestamp()} and {start_date_23.timestamp()} AND SamAccountName NOT LIKE "%test%" AND SamAccountName NOT LIKE "%admin%" AND SamAccountName NOT LIKE "%journal%" ') + csv_writer.writerow([i[0] for i in cursor.description]) + csv_writer.writerows(cursor.fetchall()) + ## RDS - User Export ENDE ## + ## RAW EXPORT ENDE ## + ## CREATE Excel Sheet from csv Export ## + ## EXPORT to AD- User Excel-Sheet ## + csv_datei = fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/RDS-User - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv' + df = pd.read_csv(csv_datei, sep=";", encoding="utf-8") + # Leere Felder mit "-" füllen + df = df.fillna("-") + df["time"] = pd.to_datetime(df["time"], unit='s') + # Excel-Datei erstellen und Daten schreiben + excel_datei = fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}/{kunde}_User_Export Stand({last_date_str}).xlsx" + if os.path.exists(excel_datei): + mode = 'a' + else: + mode = 'w' + with pd.ExcelWriter(excel_datei, engine='openpyxl', mode=f'{mode}') as writer: + df.to_excel(writer, index=False, sheet_name=f'{start_date_00.strftime("%d-%m")}') + workbook = writer.book + worksheet = writer.sheets[f'{start_date_00.strftime("%d-%m")}'] + + worksheet.auto_filter.ref = "A1:J1" + # Spaltenbreite festlegen + for column in worksheet.columns: + max_length = 0 + column_letter = column[0].column_letter + for cell in column: + try: + if len(str(cell.value)) > max_length: + max_length = len(cell.value) + except: + pass + adjusted_width = (max_length + 2) * 1.2 + worksheet.column_dimensions[column_letter].width = adjusted_width + + ## EXPORT to AD- User Excel-Sheet ## + csv_datei = fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/SERVER - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv' + df = pd.read_csv(csv_datei, sep=";", encoding="utf-8") + # Leere Felder mit "-" füllen + df = df.fillna("-") + # df["time"] = pd.to_datetime(df["time"], unit='s') + # Excel-Datei erstellen und Daten schreiben + excel_datei = fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}/{kunde}_Server_Export Stand({last_date_str}).xlsx" + if os.path.exists(excel_datei): + mode = 'a' + else: + mode = 'w' + with pd.ExcelWriter(excel_datei, engine='openpyxl', mode=f'{mode}') as writer: + df.to_excel(writer, index=False, sheet_name=f'{start_date_00.strftime("%d-%m")}') + workbook = writer.book + worksheet = writer.sheets[f'{start_date_00.strftime("%d-%m")}'] + + worksheet.auto_filter.ref = "A1:J1" + # Spaltenbreite festlegen + for column in worksheet.columns: + max_length = 0 + column_letter = column[0].column_letter + for cell in column: + try: + if len(str(cell.value)) > max_length: + max_length = len(cell.value) + except: + pass + adjusted_width = (max_length + 2) * 1.2 + worksheet.column_dimensions[column_letter].width = adjusted_width + + if table_exists: + csv_datei = fr'{main_path}/{kunde}/{start_date_str} - {last_date_str}/RAW/Exchange-User - {kunde} - {start_date_00.strftime("%Y-%m-%d")}.csv' + df = pd.read_csv(csv_datei, sep=";", encoding="utf-8") + # Leere Felder mit "-" füllen + df = df.fillna("-") + df["time"] = pd.to_datetime(df["time"], unit='s') + # Excel-Datei erstellen und Daten schreiben + excel_datei = fr"{main_path}/{kunde}/{start_date_str} - {last_date_str}/{kunde}_Mailbox_Export Stand({last_date_str}).xlsx" + if os.path.exists(excel_datei): + mode = 'a' + else: + mode = 'w' + with pd.ExcelWriter(excel_datei, engine='openpyxl', mode=f'{mode}') as writer: + df.to_excel(writer, index=False, sheet_name=f'{start_date_00.strftime("%d-%m")}') + workbook = writer.book + worksheet = writer.sheets[f'{start_date_00.strftime("%d-%m")}'] + + worksheet.auto_filter.ref = "A1:E1" + # Spaltenbreite festlegen + for column in worksheet.columns: + max_length = 0 + column_letter = column[0].column_letter + for cell in column: + try: + if len(str(cell.value)) > max_length: + max_length = len(cell.value) + except: + pass + adjusted_width = (max_length + 2) * 1.2 + worksheet.column_dimensions[column_letter].width = adjusted_width + + # os.mkdir("") + # + # print(table_exists) + # + # c = canvas.Canvas(fr"{i}/{start_date_str} - {last_date_str}/PDF_Export Stand({last_date_str}).pdf", pagesize=letter) + # # Hier können Sie IhrenCode zum Hinzufügen von Daten zur PDF einfügen + # c.setFont("Helvetica", 10) + # c.drawString(50, 750, f"Create Date - {datetime.now().strftime("%d-%M-%Y")}") + # c.drawImage("Firmen-Logo.png", x=450, y=730, width=150, height=40) + # c.setFont("Helvetica", 12) + # c.drawString(100, 680, "REPORT der RDP / Exchange User der Firma bla") + # + # k = 10 + # n = 650 + # x = 100 + # t = 0 + # if n < 50: + # if t == 1: + # x = 400 + # n = 650 + # print(x) + # print("insede") + # else: + # x = 250 + # n = 650 + # t += 1 + # c.setFont("Helvetica", 8) + # c.drawString(x, n, f"Zeitraum: {i}") + # c.drawString(x, n - 10, f"Aktive RDS-User: {i}") + # c.drawString(x, n - 20, f"Deaktivierte RDS-User: {i}") + # if table_exists: + # c.drawString(x, n - 30, f"Aktive EX-User: {i}") + # c.drawString(x, n - 40, f"Deaktivierte EX-User: {i}") + # n = n - 60 + # c.save() + # subprocess.Popen(["start", "output.pdf"], shell=True) + +cursor.close() +mydb.close() + diff --git a/pdf.py b/pdf.py new file mode 100644 index 0000000..1ec6b75 --- /dev/null +++ b/pdf.py @@ -0,0 +1,64 @@ +import openpyxl +from reportlab.pdfgen import canvas +from reportlab.pdfbase import pdfmetrics +from reportlab.pdfbase.pdfmetrics import stringWidth +from reportlab.pdfbase.ttfonts import TTFont +import os +from PyPDF2 import PdfFileReader, PdfFileMerger + +pdfmetrics.registerFont(TTFont('Arial', 'Arial.ttf')) +wb = openpyxl.load_workbook('Excel_Export Stand(31.08).xlsx') +sheet = wb.get_sheet_by_name("01-08") + +# print(sheet.cell(2,2).value) + +page_width = 2156 +page_height = 3050 +start = 200 +start_2 = 700 +spread = 80 +categories = ["Roll Number: ", "Name: ", "Gender: ", "Age: ", "Board: ", "City: ", "Email: "] + +university = "NED University Of Engineering And Technology" + + +def create_data(): + for i in range(2, 14): + std_id = sheet.cell(row=i, column=1).value + std_name = sheet.cell(row=i, column=2).value + std_gender = sheet.cell(row=i, column=3).value + std_age = sheet.cell(row=i, column=4).value + std_board = sheet.cell(row=i, column=5).value + std_city = sheet.cell(row=i, column=6).value + std_email = sheet.cell(row=i, column=8).value + + data = [std_id, std_name, std_gender, std_age, std_board, std_city, std_email] + + c = canvas.Canvas(str(std_name) + '.pdf') + c.setPageSize((page_width, page_height)) + c.setFont('Arial', 80) + text_width = stringWidth(university, 'Arial', 80) + c.drawString((page_width - text_width) / 2, 2900, university) + + y = 2500 + + for x in range(0, 7): + c.setFont('Arial', 40) + c.drawString(start, y, categories[x]) + c.drawString(start_2, y, str(data[x])) + y -= spread + + c.save() + + +def merge_data(): + files_dir = 'pytopdf' + pdf_files = [f for f in os.listdir(files_dir) if f.endswith('.pdf')] + merger = PdfFileMerger() + for filename in pdf_files: + merger.append(PdfFileReader(os.path.join(files_dir, filename, 'rb'))) + merger.write(os.path.join(files_dir, 'merged_data.pdf')) + + +create_data() +merge_data() \ No newline at end of file diff --git a/rport-installer.sh b/rport-installer.sh new file mode 100644 index 0000000..f66aa10 --- /dev/null +++ b/rport-installer.sh @@ -0,0 +1,1348 @@ +#!/bin/sh -e +MY_COMMAND="$0 $*" +exit_trap() { + # shellcheck disable=SC2181 + if [ $? -eq 0 ]; then + return 0 + fi + echo "" + echo "An error occurred." + echo "Try running in debug mode with 'sh -x ${MY_COMMAND}'" + echo "Ask for help on https://github.com/openrport/openrport-pairing/discussions/categories/help-needed " + echo "" +} +trap exit_trap EXIT + +# BEGINNING of templates/header.txt ----------------------------------------------------------------------------------| + +## +## This is the RPort client installer script. +## It helps you to quickly install the rport client on a variety of Linux distributions. +## The scripts creates a initial configuration and connects the client to your server. +## +## For any inquiries use our GitHub forum on +## https://github.com/openrport/rport-pairing/discussions/ +## +## Copyright cloudradar GmbH, Potsdam Germany, 2022 +## Maintainer openrport, Lille, France, 2023 +## Released under the MIT open-source license. +## https://github.com/openrport/rport-pairing/blob/main/LICENSE +## +# END of templates/header.txt ----------------------------------------------------------------------------------------| + +## BEGINNING of rendered template templates/linux/installer_vars.sh +# +# Dynamically inserted variables +# +FINGERPRINT="05:7f:44:a8:62:02:72:e6:e0:ab:56:f3:42:01:0a:8f" +CONNECT_URL="http://rport.stines.de:8000" +CLIENT_ID="stines" +PASSWORD="WdwCpNJGcnsuriu" + +# +# Global static installer vars +# +TMP_FOLDER=/tmp/rport-install +FORCE=1 +USE_ALTERNATIVE_MACHINEID=0 +LOG_DIR=/var/log/rport +LOG_FILE=${LOG_DIR}/rport.log +## END of rendered template templates/linux/installer_vars.sh + + +# BEGINNING of templates/linux/vars.sh -------------------------------------------------------------------------------| + +# +# Global Variables for installation and update +# +CONF_DIR=/etc/rport +CONFIG_FILE=${CONF_DIR}/rport.conf +USER=rport +ARCH=$(uname -m | sed s/"armv\(6\|7\)l"/'armv\1'/ | sed s/aarch64/arm64/) +# END of templates/linux/vars.sh -------------------------------------------------------------------------------------| + + +# BEGINNING of templates/linux/functions.sh --------------------------------------------------------------------------| + +set -e +if which tput >/dev/null 2>&1; then + true +else + alias tput=true +fi + +throw_fatal() { + echo 2>&1 "[!] $1" + echo "[=] Fatal Exit. Don't give up. Good luck with the next try." + false +} + +throw_hint() { + echo "[>] $1" +} + +throw_info() { + echo "$(tput setab 2 2>/dev/null)$(tput setaf 7 2>/dev/null)[*]$(tput sgr 0 2>/dev/null) $1" +} + +throw_warning() { + echo "[:] $1" +} + +throw_debug() { + echo "$(tput setab 4 2>/dev/null)$(tput setaf 7 2>/dev/null)[-]$(tput sgr 0 2>/dev/null) $1" +} + +wait_for_rport() { + i=0 + while [ "$i" -lt 40 ]; do + pidof rport >/dev/null 2>&1 && return 0 + echo "$i waiting for rport process to come up ..." + sleep 0.2 + i=$((i + 1)) + done + return 1 +} + +is_rport_subprocess() { + if [ -n "$1" ]; then + SEARCH_PID=$1 + else + SEARCH_PID=$$ + fi + PARENT_PID=$(ps -o ppid= -p "$SEARCH_PID" | tr -d ' ') + PARENT_NAME=$(ps -p "$PARENT_PID" -o comm=) + if [ "$PARENT_NAME" = "rport" ]; then + return 0 + elif [ "$PARENT_PID" -eq 1 ]; then + return 1 + fi + is_rport_subprocess "$PARENT_PID" +} +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: is_available +# DESCRIPTION: Check if a command is available on the system. +# PARAMETERS: command name +# RETURNS: 0 if available, 1 otherwise +#---------------------------------------------------------------------------------------------------------------------- +is_available() { + if command -v "$1" >/dev/null 2>&1; then + return 0 + else + return 1 + fi +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: uninstall +# DESCRIPTION: Uninstall everything and remove the user +#---------------------------------------------------------------------------------------------------------------------- +uninstall() { + if pgrep rportd >/dev/null; then + echo 1>&2 "You are running the rportd server on this machine. Uninstall manually." + exit 0 + fi + stop_rport >/dev/null 2>&1 || true + rc-service rport stop >/dev/null 2>&1 || true + pkill -9 rport >/dev/null 2>&1 || true + rport --service uninstall >/dev/null 2>&1 || true + FILES="/usr/local/bin/rport + /usr/local/bin/rport + /etc/systemd/system/rport.service + /etc/sudoers.d/rport-update-status + /etc/sudoers.d/rport-all-cmd + /usr/local/bin/tacoscript + /etc/init.d/rport + /var/run/rport.pid + /etc/runlevels/default/rport + /etc/apt/sources.list.d/rport.list" + for FILE in $FILES; do + if [ -e "$FILE" ]; then + rm -f "$FILE" && echo " [ DELETED ] File $FILE" + fi + done + if id rport >/dev/null 2>&1; then + if is_available deluser; then + deluser --remove-home rport >/dev/null 2>&1 || true + deluser --only-if-empty --group rport >/dev/null 2>&1 || true + elif is_available userdel; then + userdel -r -f rport >/dev/null 2>&1 + fi + if is_available groupdel; then + groupdel -f rport >/dev/null 2>&1 || true + fi + echo " [ DELETED ] User rport" + fi + FOLDERS="/etc/rport + /var/log/rport + /var/lib/rport" + for FOLDER in $FOLDERS; do + if [ -e "$FOLDER" ]; then + rm -rf "$FOLDER" && echo " [ DELETED ] Folder $FOLDER" + fi + done + if dpkg -l 2>&1 | grep -q "rport.*Remote access"; then + apt-get -y remove --purge rport + fi + echo "RPort client successfully uninstalled." +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: print_distro +# DESCRIPTION: print name of the distro +#---------------------------------------------------------------------------------------------------------------------- +print_distro() { + if [ -e /etc/os-release ]; then + # shellcheck source=/dev/null + . /etc/os-release 2>/dev/null || true + echo "Detected Linux Distribution: ${PRETTY_NAME}" + fi +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: has_sudo +# DESCRIPTION: Check if sudo is installed and sudo rules can be managed as separated files +# RETURNS: 0 (success, sudo os present), 1 (fail, sudo can't be used by rport) +#---------------------------------------------------------------------------------------------------------------------- +has_sudo() { + if ! which sudo >/dev/null 2>&1; then + return 1 + fi + if [ -e /etc/sudoers.d/ ]; then + return 0 + fi + return 1 +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: create_sudoers_all +# DESCRIPTION: create a sudoers file to grant full sudo right to the rport user +#---------------------------------------------------------------------------------------------------------------------- +create_sudoers_all() { + SUDOERS_FILE=/etc/sudoers.d/rport-all-cmd + if [ -e "$SUDOERS_FILE" ]; then + throw_info "You already have a $SUDOERS_FILE. Not changing." + return 1 + fi + + if has_sudo; then + echo "# +# This file has been auto-generated during the installation of the rport client. +# Change to your needs or delete. +# +${USER} ALL=(ALL) NOPASSWD:ALL +" >$SUDOERS_FILE + echo "A $SUDOERS_FILE has been created. Please review and change to your needs." + else + echo "You don't have sudo installed. No sudo rules created. RPort will not be able to get elevated right." + fi +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: create_sudoers_updates +# DESCRIPTION: create a sudoers file to allow rport supervise the update status +#---------------------------------------------------------------------------------------------------------------------- +create_sudoers_updates() { + SUDOERS_FILE=/etc/sudoers.d/rport-update-status + if [ -e "$SUDOERS_FILE" ]; then + throw_info "You already have a $SUDOERS_FILE. Not changing." + return 0 + fi + + if has_sudo; then + echo '# +# This file has been auto-generated during the installation of the rport client. +# Change to your needs. +#' >$SUDOERS_FILE + if is_available apt-get; then + echo "${USER} ALL=NOPASSWD: SETENV: /usr/bin/apt-get update -o Debug\:\:NoLocking=true" >>$SUDOERS_FILE + fi + #if is_available yum;then + # echo 'rport ALL=NOPASSWD: SETENV: /usr/bin/yum *'>>$SUDOERS_FILE + #fi + #if is_available dnf;then + # echo 'rport ALL=NOPASSWD: SETENV: /usr/bin/dnf *'>>$SUDOERS_FILE + #fi + if is_available zypper; then + echo "${USER} ALL=NOPASSWD: SETENV: /usr/bin/zypper refresh *" >>$SUDOERS_FILE + fi + #if is_available apk;then + # echo 'rport ALL=NOPASSWD: SETENV: /sbin/apk *'>>$SUDOERS_FILE + #fi + echo "A $SUDOERS_FILE has been created. Please review and change to your needs." + fi +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: abort +# DESCRIPTION: Exit the script with an error message. +#---------------------------------------------------------------------------------------------------------------------- +abort() { + echo >&2 "$1 Exit!" + clean_up + exit 1 +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: confirm +# DESCRIPTION: Print a success message. +#---------------------------------------------------------------------------------------------------------------------- +confirm() { + echo "Success: $1" +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: check_prerequisites +# DESCRIPTION: Check if prerequisites are fulfilled. +#---------------------------------------------------------------------------------------------------------------------- + +check_prerequisites() { + if [ "$(id -u)" -ne 0 ]; then + abort "Execute as root or use sudo." + fi + + if command -v sed >/dev/null 2>&1; then + true + else + abort "sed command missing. Make sure sed is in your path." + fi + + if command -v tar >/dev/null 2>&1; then + true + else + abort "tar command missing. Make sure tar is in your path." + fi +} + +is_terminal() { + if echo "$TERM" | grep -q "^xterm"; then + return 0 + else + echo 1>&2 "You are not on a terminal. Please use command line switches to avoid interactive questions." + return 1 + fi +} + +update_tacoscript() { + TACO_VERSION=$(/usr/local/bin/tacoscript --version | grep -o "Version:.*" | awk '{print $2}') + cd /tmp + test -e tacoscript.tar.gz && rm -f tacoscript.tar.gz + curl -LSso tacoscript.tar.gz "https://download.rport.io/tacoscript/${RELEASE}/?arch=Linux_${ARCH}>=$TACO_VERSION" + if tar xzf tacoscript.tar.gz 2>/dev/null; then + echo "" + throw_info "Updating Tacoscript from ${TACO_VERSION} to latest ${RELEASE} $(./tacoscript --version | grep -o "Version:.*")" + mv -f /tmp/tacoscript /usr/local/bin/tacoscript + else + throw_info "Nothing to do. Tacoscript is on the latest version ${TACO_VERSION}." + fi +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: install_tacoscript +# DESCRIPTION: install Tacoscript on Linux +#---------------------------------------------------------------------------------------------------------------------- +install_tacoscript() { + if [ -e /usr/local/bin/tacoscript ]; then + throw_info "Tacoscript already installed. Checking for updates ..." + update_tacoscript + return 0 + fi + cd /tmp + test -e tacoscript.tar.gz && rm -f tacoscript.tar.gz + curl -Ls "https://download.rport.io/tacoscript/${RELEASE}/?arch=Linux_${ARCH}" -o tacoscript.tar.gz + tar xvzf tacoscript.tar.gz -C /usr/local/bin/ tacoscript + rm -f tacoscript.tar.gz + echo "Tacoscript installed $(/usr/local/bin/tacoscript --version)" +} + +version_to_int() { + echo "$1" | + awk -v 'maxsections=3' -F'.' 'NF < maxsections {printf("%s",$0);for(i=NF;i= maxsections {print}' | + awk -v 'maxdigits=3' -F'.' '{print $1*10^(maxdigits*2)+$2*10^(maxdigits)+$3}' +} + +runs_with_selinux() { + if command -v getenforce >/dev/null 2>&1 && getenforce | grep -q Enforcing; then + return 0 + else + return 1 + fi +} + +enable_file_reception() { + if [ "$(version_to_int "$TARGET_VERSION")" -lt 6005 ]; then + # Version does not handle file reception yet. + return 0 + fi + if [ "$ENABLE_FILEREC" -eq 0 ]; then + echo "File reception disabled." + FILEREC_CONF="false" + else + echo "File reception enabled." + FILEREC_CONF="true" + fi + if grep -q '\[file-reception\]' "$CONFIG_FILE"; then + echo "File reception already configured" + else + cat <>"$CONFIG_FILE" + + +[file-reception] + ## Receive files pushed by the server, enabled by default + # enabled = true + ## The rport client will reject writing files to any of the following folders and its subfolders. + ## https://oss.rport.io/docs/no18-file-reception.html + ## Wildcards (glob) are supported. + ## Linux defaults + # protected = ['/bin', '/sbin', '/boot', '/usr/bin', '/usr/sbin', '/dev', '/lib*', '/run'] + ## Windows defaults + # protected = ['C:\Windows\', 'C:\ProgramData'] + +EOF + fi + toml_set "$CONFIG_FILE" file-reception enabled $FILEREC_CONF + # Clean up from pre-releases + test -e /etc/sudoers.d/rport-filepush && rm -f /etc/sudoers.d/rport-filepush + if [ "$ENABLE_FILEREC_SUDO" -eq 0 ]; then + # File receptions sudo rules not desired, end this function here + return 0 + fi + # Create a sudoers file + FILERCV_SUDO="/etc/sudoers.d/rport-filereception" + if [ -e $FILERCV_SUDO ]; then + echo "Sudo rule $FILERCV_SUDO already exists" + else + cat <$FILERCV_SUDO +# The following rule allows the rport client to change the ownership of any file retrieved from the rport server +rport ALL=NOPASSWD: /usr/bin/chown * /var/lib/rport/filepush/*_rport_filepush + +# The following rules allows the rport client to move copied files to any folder +rport ALL=NOPASSWD: /usr/bin/mv /var/lib/rport/filepush/*_rport_filepush * + +EOF + fi +} + +enable_lan_monitoring() { + if [ "$(version_to_int "$TARGET_VERSION")" -lt 5008 ]; then + # Version does not handle network interfaces yet. + return 0 + fi + if grep "^\s*net_[wl]" "$CONFIG_FILE"; then + # Network interfaces already configured + return 0 + fi + echo "Enabling Network monitoring" + for IFACE in /sys/class/net/*; do + IFACE=$(basename "${IFACE}") + [ "$IFACE" = 'lo' ] && continue + if ip addr show "$IFACE" | grep -E -q "inet (10|192\.168|172\.16)\."; then + # Private IP + NET_LAN="$IFACE" + else + # Public IP + NET_WAN="$IFACE" + fi + done + if [ -n "$NET_LAN" ]; then + sed -i "/^\[monitoring\]/a \ \ net_lan = ['${NET_LAN}' , '1000' ]" "$CONFIG_FILE" + fi + if [ -n "$NET_WAN" ]; then + sed -i "/^\[monitoring\]/a \ \ net_wan = ['${NET_WAN}' , '1000' ]" "$CONFIG_FILE" + fi +} + +detect_interpreters() { + if [ "$(version_to_int "$TARGET_VERSION")" -lt 5008 ]; then + # Version does not handle interpreters yet. + return 0 + fi + if grep -q "\[interpreter\-aliases\]" "$CONFIG_FILE"; then + # Config already updated + true + else + echo "Updating config with new interpreter-aliases ..." + echo '[interpreter-aliases]' >>"$CONFIG_FILE" + fi + SEARCH="bash zsh ksh csh python3 python2 perl pwsh fish" + for ITEM in $SEARCH; do + FOUND=$(command -v "$ITEM" 2>/dev/null || true) + if [ -z "$FOUND" ]; then + continue + fi + echo "Interpreter '$ITEM' found in '$FOUND'" + if grep -q -E "^\s*$ITEM =" "$CONFIG_FILE"; then + echo "Interpreter '$ITEM' already registered." + continue + fi + # Append the found interpreter to the config + sed -i "/^\[interpreter-aliases\]/a \ \ $ITEM = \"$FOUND\"" "${CONFIG_FILE}" + done +} + +toml_set() { + TOML_FILE="$1" + BLOCK="$2" + KEY="$3" + VALUE="$4" + if [ -w "$TOML_FILE" ]; then + true + else + echo 2>&1 "$TOML_FILE does not exist or is not writable." + return 1 + fi + if grep -q "\[$BLOCK\]" "$TOML_FILE"; then + true + else + echo 2>&1 "$TOML_FILE has no block [$BLOCK]" + return 1 + fi + LINE=$(grep -n -A100 "\[$BLOCK\]" "$TOML_FILE" | grep "${KEY} = ") + if [ -z "$LINE" ]; then + echo 2>&1 "Key $KEY not found in block $BLOCK" + return 1 + fi + LINE_NO=$(echo "$LINE" | cut -d'-' -f1) + sed -i "${LINE_NO}s/.*/ ${KEY} = ${VALUE}/" "$TOML_FILE" +} + +gen_uuid() { + if [ -e /proc/sys/kernel/random/uuid ]; then + cat /proc/sys/kernel/random/uuid + return 0 + fi + if which uuidgen >/dev/null 2>&1; then + uuidgen + return 0 + fi + if which dbus-uuidgen >/dev/null 2>&1; then + dbus-uuidgen + return 0 + fi + # Use a internet-based fallback + curl -s https://www.uuidtools.com/api/generate/v4 | tr -d '"[]' +} + +get_ip_from_fqdn() { + if which getent >/dev/null; then + getent hosts "$1" | awk '{ print $1 }' + return 0 + fi + ping "$1" -c 1 -q 2>&1 | grep -Po "(\d{1,3}\.){3}\d{1,3}" +} + +start_rport() { + if is_available systemctl; then + systemctl daemon-reload + systemctl start rport + systemctl enable rport + elif [ -e /etc/init/rport.conf ]; then + # We are on an upstart system + start rport + elif is_available service; then + service rport start + fi + if pidof rport >/dev/null 2>&1; then + return 0 + else + return 1 + fi +} + +stop_rport() { + if is_available systemctl; then + systemctl stop rport + elif [ -e /etc/init/rport.conf ]; then + # We are on an upstart system + stop rport + elif is_available service; then + service rport stop + fi +} + +backup_config() { + if [ -z "$CONFIG_FILE" ]; then + throw_fatal "backup_config() \$CONFIG_FILE undefined." + fi + CONFIG_BACKUP="/tmp/.rport-conf.$(date +%s)" + cp "$CONFIG_FILE" "$CONFIG_BACKUP" + throw_debug "Configuration file copied to $CONFIG_BACKUP" +} + +clean_up_legacy_installation() { + # If this is a migration from the old none deb-based installation, clean up + if [ -e /etc/systemd/system/rport.service ]; then + throw_info "Removing old systemd service /etc/systemd/system/rport.service" + rm -f /etc/systemd/system/rport.service + systemctl daemon-reload + fi + if [ -e /usr/local/bin/rport ]; then + throw_info "Removing old version /usr/local/bin/rport" + rm -f /usr/local/bin/rport + fi +} + +install_via_deb_repo() { + if [ -z "$RELEASE" ]; then + throw_fatal "install_via_deb_repo() \$RELEASE undefined" + fi + validate_custom_user + if [ -e /etc/apt/trusted.gpg.d/rport.gpg ] && dpkg -l | grep -q rport; then + throw_info "System is already using the rport deb repo." + else + throw_info "RPort will use Debian package ..." + # shellcheck source=/dev/null + . /etc/os-release + if [ -n "$UBUNTU_CODENAME" ]; then + CODENAME=$UBUNTU_CODENAME + else + CODENAME=$VERSION_CODENAME + fi + curl -sf https://repo.openrport.io/dearmor.gpg >/etc/apt/trusted.gpg.d/openrport.gpg + echo "deb [signed-by=/etc/apt/trusted.gpg.d/openrport.gpg] https://repo.openrport.io/deb ${CODENAME} ${RELEASE}" >/etc/apt/sources.list.d/rport.list + fi + apt-get update + if dpkg -s rport >/dev/null 2>&1 && ! [ -e /etc/rport/rport.conf ]; then + throw_warning "Broken DEB package installation found." + throw_debug "Will remove old package first." + apt-get -y --purge remove rport + fi + DEBIAN_FRONTEND=noninteractive apt-get --yes -o Dpkg::Options::="--force-confold" install rport + TARGET_VERSION=$(rport --version | cut -d" " -f2) + clean_up_legacy_installation +} + +install_via_rpm_repo() { + if [ -z "$RELEASE" ]; then + throw_fatal "install_via_rpm_repo() \$RELEASE undefined" + fi + validate_custom_user + if [ -e /etc/yum.repos.d/openrport.repo ] && rpm -qa | grep -q rport; then + throw_info "System is already using the rport yum repo." + else + throw_info "RPort will use RPM package ..." + rpm --import https://repo.openrport.io/key.gpg + cat </etc/yum.repos.d/rport.repo +[rport-stable] +name=RPort $RELEASE +baseurl=https://repo.openrport.io/rpm/$RELEASE/ +enabled=1 +gpgcheck=1 +gpgkey=https://repo.openrport.io/key.gpg +EOF + fi + dnf -y install rport --refresh + TARGET_VERSION=$(rport --version | cut -d" " -f2) + clean_up_legacy_installation +} + +validate_custom_user() { + if [ "$USER" != "rport" ]; then + throw_fatal "RPM/DEB packages cannot be used with a custom user. Try '-p'" + fi +} + +# Check if it's a supported debian system +is_debian() { + if [ "$NO_REPO" -eq 1 ]; then + return 1 + fi + if which apt-get >/dev/null 2>&1 && test -e /etc/apt/sources.list.d/; then + true + else + return 1 + fi + DIST_SUPPORTED="jammy focal bionic bullseye buster bookworm" + for DIST in $DIST_SUPPORTED; do + if grep -qi "CODENAME.*$DIST" /etc/os-release; then + return 0 + fi + done + return 1 +} + +is_rhel() { + if [ "$NO_REPO" -eq 1 ]; then + return 1 + fi + if grep -q "VERSION=.[6-7]" /etc/os-release; then + throw_info "RHEL/CentOS too old for RPM installation. Switching to tar.gz package." + return 1 + fi + + if which rpm >/dev/null 2>&1 && test -e /etc/yum.repos.d; then + return 0 + fi + return 1 +} + +validate_pkg_url() { + if echo "${PKG_URL}" | grep -q -E "https*:\/\/.*_linux_$(uname -m)\.(tar\.gz|deb|rpm)$"; then + true + else + throw_fatal "Invalid PKG_URL '$PKG_URL'." + fi +} + +download_pkg_url() { + DL_AUTH="" + if [ -n "$RPORT_INSTALLER_DL_USERNAME" ] && [ -n "$RPORT_INSTALLER_DL_PASSWORD" ]; then + DL_AUTH="-u ${RPORT_INSTALLER_DL_USERNAME}:${RPORT_INSTALLER_DL_PASSWORD}" + throw_info "Download will use HTTP basic authentication" + fi + throw_info "Downloading from ${PKG_URL} ..." + PKG_DOWNLOAD=$(mktemp) + # shellcheck disable=SC2086 + curl -LSs "${PKG_URL}" ${DL_AUTH} >${PKG_DOWNLOAD} + if [ -n "$(find "${PKG_DOWNLOAD}" -empty)" ]; then + rm -f "${PKG_DOWNLOAD}" + throw_fatal "Download to ${PKG_DOWNLOAD} failed" + fi + throw_info "Download to ${PKG_DOWNLOAD} completed" +} + +install_from_deb_download() { + validate_pkg_url + if echo "${PKG_URL}" | grep -q "deb$"; then + true + else + throw_fatal "URL not pointing to a debian package" + fi + download_pkg_url + mv "${PKG_DOWNLOAD}" "${PKG_DOWNLOAD}".deb + PKG_DOWNLOAD=${PKG_DOWNLOAD}.deb + chmod 0644 "${PKG_DOWNLOAD}" + throw_info "Installing debian package ${PKG_DOWNLOAD}" + DEBIAN_FRONTEND=noninteractive apt-get --yes -o Dpkg::Options::="--force-confold" install "${PKG_DOWNLOAD}" + rm -f "${PKG_DOWNLOAD}" + clean_up_legacy_installation +} + +install_from_rpm_download() { + validate_pkg_url + if echo "${PKG_URL}" | grep -q "rpm$"; then + true + else + throw_fatal "URL not pointing to an rpm package" + fi + download_pkg_url + throw_info "Installing rpm package" + rpm -U "${PKG_DOWNLOAD}" + rm -f "${PKG_DOWNLOAD}" + clean_up_legacy_installation +} + +abort_on_rport_subprocess() { + if is_rport_subprocess; then + throw_hint "Execute the rport update in a process decoupled from its parent, e.g." + throw_hint ' nohup sh -c "curl -s https://pairing.openrport.io/update|sh" >/tmp/rport-update.log 2>&1 &' + throw_fatal "You cannot update rport from an rport subprocess." + fi +} + +# END of templates/linux/functions.sh --------------------------------------------------------------------------------| + + +# BEGINNING of templates/linux/install.sh ----------------------------------------------------------------------------| + +set -e +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: prepare +# DESCRIPTION: Create a temporary folder and prepare the system to execute the installation +#---------------------------------------------------------------------------------------------------------------------- +prepare() { + test -e "${TMP_FOLDER}" && rm -rf "${TMP_FOLDER}" + mkdir "${TMP_FOLDER}" + cd "${TMP_FOLDER}" +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: cleanup +# DESCRIPTION: Remove the temporary folder and cleanup any leftovers after script has ended +#---------------------------------------------------------------------------------------------------------------------- +clean_up() { + cd /tmp + rm -rf "${TMP_FOLDER}" +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: test_connection +# DESCRIPTION: Check if the RPort server is reachable or abort. +#---------------------------------------------------------------------------------------------------------------------- +test_connection() { + CONN_TEST=$(curl -vIs -m5 "${CONNECT_URL}" 2>&1 || true) + if echo "${CONN_TEST}" | grep -q "Connected to"; then + confirm "${CONNECT_URL} is reachable. All good." + else + echo "$CONN_TEST" + echo "" + echo "Testing the connection to the RPort server on ${CONNECT_URL} failed." + echo "* Check your internet connection and firewall rules." + echo "* Check if a transparent HTTP proxy is sniffing and blocking connections." + echo "* Check if a virus scanner is inspecting HTTP connections." + abort "FATAL: No connection to the RPort server." + fi +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: download_and_extract +# DESCRIPTION: Download the package from Github and unpack to the temp folder +# https://downloads.openrport.io/ acts a redirector service +# returning the real download URL of GitHub in a more handy fashion +#---------------------------------------------------------------------------------------------------------------------- +download_and_extract() { + cd "${TMP_FOLDER}" + # Download the tar.gz package + if is_available curl; then + curl -LSs "https://downloads.openrport.io/rport/${RELEASE}/latest.php?arch=Linux_${ARCH}" -o rport.tar.gz + elif is_available wget; then + wget -q "https://downloads.openrport.io/rport/${RELEASE}/latest.php?arch=Linux_${ARCH}" -O rport.tar.gz + else + abort "No download tool found. Install curl or wget." + fi + # Unpack + tar xzf rport.tar.gz +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: download_and_extract_from_url +# DESCRIPTION: Download the package from any URL and unpack to the temp folder +#---------------------------------------------------------------------------------------------------------------------- +download_and_extract_from_url() { + cd "${TMP_FOLDER}" + ARCH=$(uname -m) + DL_AUTH="" + DL="rport.tar.gz" + # Use a specific version + if echo "$PKG_URL" | grep -q -E "^https?:\/\/.*\_linux_${ARCH}.tar.gz"; then + DOWNLOAD_URL="$PKG_URL" + else + echo "PKG_URL does not match 'http(s)://... _linux_${ARCH}.tar.gz'" + abort "Invalid download URL." + fi + if [ -n "$RPORT_INSTALLER_DL_USERNAME" ] && [ -n "$RPORT_INSTALLER_DL_PASSWORD" ]; then + DL_AUTH="-u ${RPORT_INSTALLER_DL_USERNAME}:${RPORT_INSTALLER_DL_PASSWORD}" + confirm "Download will use HTTP basic authentication" + fi + echo "Downloading from ${DOWNLOAD_URL}" + [ -e "${DL}" ] && rm -f "${DL}" + # shellcheck disable=SC2086 + curl -LSs "${DOWNLOAD_URL}" -o "${DL}" ${DL_AUTH} + echo "Verifying download" + FILES_IN_TAR=$(tar tzf "${DL}") + confirm "Package contains $(echo "$FILES_IN_TAR" | wc -w) files" + tar xzf "${DL}" rport + tar xzf "${DL}" rport.example.conf + rm -f "${DL}" +} +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: install_bin +# DESCRIPTION: Install a binary located in the temp folder to /usr/local/bin +# PARAMETERS: binary name relative to the temp folder +#---------------------------------------------------------------------------------------------------------------------- +install_bin() { + EXEC_BIN=/usr/local/bin/${1} + if [ -e "$EXEC_BIN" ]; then + if [ "$FORCE" -eq 0 ]; then + abort "${EXEC_BIN} already exists. Use -f to overwrite." + fi + fi + mv "${TMP_FOLDER}/${1}" "${EXEC_BIN}" + confirm "${1} installed to ${EXEC_BIN}" + TARGET_VERSION=$(${EXEC_BIN} --version | awk '{print $2}') + confirm "RPort $TARGET_VERSION installed to $EXEC_BIN" +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: install_config +# DESCRIPTION: Install an example config located in the temp folder to /etc/rport +# PARAMETERS: config name relative to the temp folder without suffix .example.conf +#---------------------------------------------------------------------------------------------------------------------- +install_config() { + test -e "$CONF_DIR" || mkdir "$CONF_DIR" + CONFIG_FILE=${CONF_DIR}/${1}.conf + if [ -e "${CONFIG_FILE}" ]; then + true + elif [ -e "${TMP_FOLDER}/rport.example.conf" ]; then + mv "${TMP_FOLDER}/rport.example.conf" "${CONFIG_FILE}" + else + throw_hint "If you have used the RPort RPM or DEB package previously, remove it first using the package manager." + throw_fatal "No rport.conf file found." + fi + confirm "${CONFIG_FILE} created." +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: create_user +# DESCRIPTION: Create a system user "rport" +#---------------------------------------------------------------------------------------------------------------------- +create_user() { + confirm "RPort will run as user ${USER}" + if id "${USER}" >/dev/null 2>&1; then + confirm "User ${USER} already exist." + else + if is_available useradd; then + useradd -r -d /var/lib/rport -m -s /bin/false -U -c "System user for rport client" $USER + elif is_available adduser; then + addgroup rport + adduser -h /var/lib/rport -s /bin/false -G rport -S -D $USER + else + abort "No command found to add a user" + fi + fi +# test -e "$LOG_DIR" || mkdir -p "$LOG_DIR" +# test -e /var/lib/rport/scripts || mkdir -p /var/lib/rport/scripts +# chown "${USER}":root "$LOG_DIR" +# chown "${USER}":root /var/lib/rport/scripts +# chmod 0700 /var/lib/rport/scripts +# chown "${USER}":root "$CONFIG_FILE" +# chmod 0640 "$CONFIG_FILE" +# chown root:root /usr/local/bin/rport +# chmod 0755 /usr/local/bin/rport +} + +set_file_and_dir_owner() { + test -e "$LOG_DIR" || mkdir -p "$LOG_DIR" + test -e /var/lib/rport/scripts || mkdir -p /var/lib/rport/scripts + chown "${USER}":root "$LOG_DIR" + chown "${USER}":root /var/lib/rport/scripts + chmod 0700 /var/lib/rport/scripts + chown "${USER}":root "$CONFIG_FILE" + chmod 0640 "$CONFIG_FILE" + if [ -e /usr/local/bin/rport ]; then + chown root:root /usr/local/bin/rport + chmod 0755 /usr/local/bin/rport + fi +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: create_systemd_service +# DESCRIPTION: Install a systemd service file +#---------------------------------------------------------------------------------------------------------------------- +create_systemd_service() { + if [ -e /lib/systemd/system/rport.service ]; then + echo "Systemd service already present." + else + echo "Installing systemd service for rport" + test -e /etc/systemd/system/rport.service && rm -f /etc/systemd/system/rport.service + /usr/local/bin/rport --service install --service-user "${USER}" --config /etc/rport/rport.conf + fi + start_rport +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: create_openrc_service +# DESCRIPTION: Install a oprnrc service file +#---------------------------------------------------------------------------------------------------------------------- +create_openrc_service() { + echo "Installing openrc service for rport" + cat </etc/init.d/rport +#!/sbin/openrc-run +command="/usr/local/bin/rport" +command_args="-c /etc/rport/rport.conf" +command_user="${USER}" +command_background=true +pidfile=/var/run/rport.pid +EOF + chmod 0755 /etc/init.d/rport + rc-service rport start + rc-update add rport default +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: prepare_server_cofnig +# DESCRIPTION: Make changes to the example config to give the user a better starting point +#---------------------------------------------------------------------------------------------------------------------- +prepare_config() { + echo "Preparing $CONFIG_FILE" + sed -i "s|#*server = .*|server = \"${CONNECT_URL}\"|g" "$CONFIG_FILE" + sed -i "s/#*auth = .*/auth = \"${CLIENT_ID}:${PASSWORD}\"/g" "$CONFIG_FILE" + sed -i "s/#*fingerprint = .*/fingerprint = \"${FINGERPRINT}\"/g" "$CONFIG_FILE" + sed -i "s/#*log_file = .*C.*Program Files.*/""/g" "$CONFIG_FILE" + sed -i "s/#*log_file = /log_file = /g" "$CONFIG_FILE" + sed -i "s|#updates_interval = '4h'|updates_interval = '4h'|g" "$CONFIG_FILE" + if [ "$ENABLE_COMMANDS" -eq 1 ]; then + sed -i "s/#allow = .*/allow = ['.*']/g" "$CONFIG_FILE" + sed -i "s/#deny = .*/deny = []/g" "$CONFIG_FILE" + sed -i '/^\[remote-scripts\]/a \ \ enabled = true' "$CONFIG_FILE" + sed -i "s|# script_dir = '/var/lib/rport/scripts'|script_dir = '/var/lib/rport/scripts'|g" "$CONFIG_FILE" + else + sed -i '/^\[remote-commands\]/a \ \ enabled = false' "$CONFIG_FILE" + fi + + # Set the hostname. + if grep -Eq "\s+use_hostname = true" "$CONFIG_FILE"; then + # For versions >= 0.5.9 + # Just insert an example. + sed -i "s/#name = .*/#name = \"$(get_hostname)\"/g" "$CONFIG_FILE" + else + # Older versions + # Insert a hardcoded name + sed -i "s/#*name = .*/name = \"$(get_hostname)\"/g" "$CONFIG_FILE" + fi + + # Set the machine_id + if [ -n "$MACHINE_ID" ]; then + #User wants a hard-coded client id + sed -i "s/.*use_system_id = .*/ use_system_id = false/g" "$CONFIG_FILE" + sed -i "s/#id = .*/id = \"$MACHINE_ID\"/g" "$CONFIG_FILE" + echo "Using a random hard-coded client id not based on /etc/machine-id" + else + if grep -Eq "\s+use_system_id = true" "$CONFIG_FILE" && [ -e /etc/machine-id ]; then + # Versions >= 0.5.9 read it dynamically, nothing to do here + echo "Using /etc/machine-id as rport client id" + else + # Older versions need a hard-coded id in the rport.conf, preferably based on /etc/machine-id + sed -i "s/#id = .*/id = \"$(machine_id)\"/g" "$CONFIG_FILE" + fi + fi + + # Activate client attributes + if get_geodata; then + LABELS="\"city\":\"${CITY}\", \"country\":\"${COUNTRY}\"" + fi + if [ -n "$XTAG" ]; then + XTAG="\"$XTAG\"" + fi + CLIENT_ATTRIBUTES="/var/lib/rport/client_attributes.json" + if [ -e /var/lib/rport ]; then + true + else + mkdir /var/lib/rport + chown "${USER}":root /var/lib/rport + fi + cat <$CLIENT_ATTRIBUTES +{ + "tags": [${TAGS}], + "labels": { ${LABELS} } +} +EOF + sed -i "s|#attributes_file_path = \"/var/.*|attributes_file_path = \"${CLIENT_ATTRIBUTES}\"|g" "$CONFIG_FILE" + chown "${USER}" "${CLIENT_ATTRIBUTES}" +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: get_hostname +# DESCRIPTION: Try to get the hostname from various sources +#---------------------------------------------------------------------------------------------------------------------- +get_hostname() { + hostname -f 2>/dev/null && return 0 + hostname 2>/dev/null && return 0 + cat /etc/hostname 2>/dev/null && return 0 + LANG=en hostnamectl | grep hostname | grep -v 'n/a' | cut -d':' -f2 | tr -d ' ' +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: machine_id +# DESCRIPTION: Try to get a unique machine id form different locations. +# Generate one based on the hostname as a fallback. +#---------------------------------------------------------------------------------------------------------------------- +machine_id() { + if [ -e /etc/machine-id ]; then + cat /etc/machine-id + return 0 + fi + + if [ -e /var/lib/dbus/machine-id ]; then + cat /var/lib/dbus/machine-id + return 0 + fi + + alt_machine_id +} + +alt_machine_id() { + ip a | grep ether | md5sum | awk '{print $1}' +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: install_client +# DESCRIPTION: Execute all needed steps to install the rport client +#---------------------------------------------------------------------------------------------------------------------- +install_client() { + echo "Installing rport client" + print_distro + if runs_with_selinux && [ "$SELINUX_FORCE" -ne 1 ]; then + echo "" + echo "Your system has SELinux enabled. This installer will not create the needed policies." + echo "Rport will not connect with out the right policies." + echo "Read more https://kb.openrport.io/digging-deeper/advanced-client-management/run-with-selinux" + echo "Excute '$0 ${RAW_ARGS} -l' to skip this warning and install anyways. You must create the polcies later." + exit 1 + fi + test_connection + if [ -n "$PKG_URL" ]; then + if is_debian; then + install_from_deb_download + elif is_rhel; then + install_from_rpm_download + else + download_and_extract_from_url + install_bin rport + fi + elif is_debian; then + install_via_deb_repo + elif is_rhel; then + install_via_rpm_repo + else + download_and_extract + install_bin rport + fi +# install_bin rport + create_user + install_config rport + prepare_config + enable_lan_monitoring + detect_interpreters + set_file_and_dir_owner + if is_available openrc; then + create_openrc_service + else + create_systemd_service + fi + create_sudoers_updates + [ "$ENABLE_SUDO" -eq 1 ] && create_sudoers_all + [ "$INSTALL_TACO" -eq 1 ] && install_tacoscript + verify_and_terminate +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: verify_and_terminate +# DESCRIPTION: Verify the installation has succeeded +#---------------------------------------------------------------------------------------------------------------------- +verify_and_terminate() { + sleep 1 + if pgrep rport >/dev/null 2>&1; then + if check_log; then + finish + return 0 + elif [ $? -eq 1 ] && [ "$USE_ALTERNATIVE_MACHINEID" -ne 1 ]; then + USE_ALTERNATIVE_MACHINEID=1 + use_alternative_machineid + verify_and_terminate + return 0 + fi + fi + fail +} + +use_alternative_machineid() { + # If the /etc/machine-id is already used, use an alternative unique id + stop_rport + rm -f "$LOG_FILE" + echo "Creating a unique id based on the mac addresses of the network cards." + sed -i "s/^id = .*/id = \"$(alt_machine_id)\"/g" "$CONFIG_FILE" + start_rport +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: get_geodata +# DESCRIPTION: Retrieve the Country and the city of the currently used public IP address +#---------------------------------------------------------------------------------------------------------------------- +get_geodata() { + GEODATA="" + GEOSERVICE_URL="http://ip-api.com/line/?fields=status,country,city" + if is_available curl; then + GEODATA=$(curl -m2 -Ss "${GEOSERVICE_URL}" 2>/dev/null) + else + GEODATA=$(wget --timeout=2 -O - -q "${GEOSERVICE_URL}" 2>/dev/null) + fi + if echo "$GEODATA" | grep -q "^success"; then + CITY="$(echo "$GEODATA" | head -n3 | tail -n1)" + COUNTRY="$(echo "$GEODATA" | head -n2 | tail -n1)" + GEODATA="1" + return 0 + else + return 1 + fi +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: check_log +# DESCRIPTION: Check the log file for proper operation or common errors +#---------------------------------------------------------------------------------------------------------------------- +check_log() { + if [ -e "$LOG_FILE" ]; then + true + else + echo 2>&1 "[!] Logfile $LOG_FILE does not exist." + echo 2>&1 "[!] RPOrt very likely failed to start." + return 4 + fi + if grep -q "client id .* is already in use" "$LOG_FILE"; then + echo "" + echo 2>&1 "[!] Configuration error: client id is already in use." + echo 2>&1 "[!] Likely you have systems with an duplicated machine-id in your network." + echo "" + return 1 + elif grep -q "Connection error: websocket: bad handshake" "$LOG_FILE"; then + echo "" + echo 2>&1 "[!] Connection error: websocket: bad handshake" + echo "Check if transparent proxies are interfering outgoing http connections." + return 2 + elif tac "$LOG_FILE" | grep error; then + return 3 + fi + + return 0 +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: help +# DESCRIPTION: print a help message and exit +#---------------------------------------------------------------------------------------------------------------------- +help() { + cat < Use a different user account than 'rport'. Will be created if not present. +-i Install Tacoscript along with the RPort client. +-l Install with SELinux enabled. +-g Add an extra tag to the client. +-d Do not use /etc/machine-id to identify this machine. A random UUID will be used instead. +-p Do not use the RPM/DEB repository. Forces tar.gz installation. +-z Download the rport client tar.gz from the given URL instead of using GitHub releases. See environment variables. + +Environment variables: + If RPORT_INSTALLER_DL_USERNAME and RPORT_INSTALLER_DL_PASSWORD are set, downloads of custom packages triggered with + '-z' are initiated with HTTP basic authentication. + +Learn more https://kb.openrport.io/connecting-clients#advanced-pairing-options +EOF + exit 0 +} + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: finish +# DESCRIPTION: print some information +#---------------------------------------------------------------------------------------------------------------------- +finish() { + echo " +# +# Installation of rport finished. +# +# This client is now connected to $SERVER +# +# Look at $CONFIG_FILE and explore all options. +# Logs are written to /var/log/rport/rport.log. +# +# READ THE DOCS ON https://kb.openrport.io/ +# +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# Give us a star on https://github.com/openrport/openrport +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# + +Thanks for using + ____ _____ _____ _ + / __ \ | __ \| __ \ | | + | | | |_ __ ___ _ __ | |__) | |__) |__ _ __| |_ + | | | | '_ \ / _ \ '_ \| _ /| ___/ _ \| '__| __| + | |__| | |_) | __/ | | | | \ \| | | (_) | | | |_ + \____/| .__/ \___|_| |_|_| \_\_| \___/|_| \__| + | | + |_| + +" +} + +fail() { + echo " +# +# -------------!! ERROR !!------------- +# +# Installation of openrport finished with errors. +# + +Try the following to investigate: +1) systemctl rport status + +2) tail /var/log/rport/rport.log + +3) Ask for help on https://kb.openrport.io/need-help/request-support +" + if runs_with_selinux; then + echo " +4) Check your SELinux settings and create a policy for rport." + fi +} + +#---------------------------------------------------------------------------------------------------------------------- +# END OF FUNCTION DECLARATION +#---------------------------------------------------------------------------------------------------------------------- + +# +# Check for prerequisites +# +check_prerequisites + +MANDATORY="SERVER FINGERPRINT CLIENT_ID PASSWORD" +for VAR in $MANDATORY; do + if eval "[ -z $${VAR} ]"; then + abort "Variable \$${VAR} not set." + fi +done + +# +# Read the command line options and map to a function call +# +RAW_ARGS=$* +ACTION=install_client +ENABLE_COMMANDS=0 +ENABLE_SUDO=0 +RELEASE=stable +INSTALL_TACO=0 +SELINUX_FORCE=0 +ENABLE_FILEREC=0 +ENABLE_FILEREC_SUDO=0 +XTAG="" +NO_REPO=0 +while getopts 'phvfcsuxstildrba:g:z:' opt; do + case "${opt}" in + + h) + help + exit 0 + ;; + f) FORCE=1 ;; + v) + echo "$0 -- Version $VERSION" + exit 0 + ;; + c) ACTION=install_client ;; + u) ACTION=uninstall ;; + x) ENABLE_COMMANDS=1 ;; + s) ENABLE_SUDO=1 ;; + t) RELEASE=unstable ;; + i) INSTALL_TACO=1 ;; + l) SELINUX_FORCE=1 ;; + r) ENABLE_FILEREC=1 ;; + b) ENABLE_FILEREC_SUDO=1 ;; + a) USER=${OPTARG} ;; + g) XTAG=${OPTARG} ;; + z) export PKG_URL="${OPTARG}" ;; + d) MACHINE_ID=$(gen_uuid) ;; + p) NO_REPO=1 ;; + + \?) + echo "Option does not exist." + exit 1 + ;; + esac # --- end of case --- +done +shift $((OPTIND - 1)) +prepare # Prepare the system +$ACTION # Execute the function according to the users decision +clean_up # Clean up the system + +# END of templates/linux/install.sh ----------------------------------------------------------------------------------| + diff --git a/run.py b/run.py new file mode 100644 index 0000000..14981a8 --- /dev/null +++ b/run.py @@ -0,0 +1,10 @@ +import http.client, urllib + +conn = http.client.HTTPSConnection("api.pushover.net:443") +conn.request("POST", "/1/messages.json", + urllib.parse.urlencode({ + "token": "avzcexyjeu7y71pcskwshyx8ytmq8i", + "user": "uo2sf2pmrtjvt8auu786fviabimimr", + "message": "Reporting was running!", + }), { "Content-type": "application/x-www-form-urlencoded" }) +conn.getresponse()