NAS EMULATOR + WOL Proxy
This commit is contained in:
7
Dockerfile.nas
Normal file
7
Dockerfile.nas
Normal file
@@ -0,0 +1,7 @@
|
||||
# Dockerfile для эмулятора NAS
|
||||
FROM python:3.11-slim
|
||||
WORKDIR /app
|
||||
COPY src/nas_emulator.py ./
|
||||
RUN pip install flask
|
||||
EXPOSE 5050
|
||||
CMD ["python", "nas_emulator.py"]
|
||||
7
Dockerfile.wol
Normal file
7
Dockerfile.wol
Normal file
@@ -0,0 +1,7 @@
|
||||
# Dockerfile для WOL-прокси
|
||||
FROM python:3.11-slim
|
||||
WORKDIR /app
|
||||
COPY src/wol_proxy.py ./
|
||||
RUN pip install flask
|
||||
EXPOSE 5000
|
||||
CMD ["python", "wol_proxy.py"]
|
||||
@@ -1,5 +1,3 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
synology-bot:
|
||||
build:
|
||||
@@ -23,16 +21,22 @@ services:
|
||||
start_period: 20s
|
||||
networks:
|
||||
- bot-network
|
||||
# Для ограничения ресурсов (раскомментируйте и настройте при необходимости):
|
||||
# deploy:
|
||||
# resources:
|
||||
# limits:
|
||||
# cpus: '0.50'
|
||||
# memory: 512M
|
||||
# reservations:
|
||||
# cpus: '0.25'
|
||||
# memory: 256M
|
||||
|
||||
wol-proxy:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.wol
|
||||
container_name: wol-proxy
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
|
||||
nas-emulator:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.nas
|
||||
container_name: nas-emulator
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
networks:
|
||||
bot-network:
|
||||
driver: bridge
|
||||
|
||||
91
src/nas_emulator.py
Normal file
91
src/nas_emulator.py
Normal file
@@ -0,0 +1,91 @@
|
||||
from flask import Flask, request, jsonify
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# Заглушки для команд NAS
|
||||
@app.route('/login', methods=['POST'])
|
||||
def login():
|
||||
return jsonify({'status': 'success', 'message': 'login received'})
|
||||
|
||||
@app.route('/logout', methods=['POST'])
|
||||
def logout():
|
||||
return jsonify({'status': 'success', 'message': 'logout received'})
|
||||
|
||||
@app.route('/wake_on_lan', methods=['POST'])
|
||||
def wake_on_lan():
|
||||
return jsonify({'status': 'success', 'message': 'wake_on_lan received'})
|
||||
|
||||
@app.route('/power_on', methods=['POST'])
|
||||
def power_on():
|
||||
return jsonify({'status': 'success', 'message': 'power_on received'})
|
||||
|
||||
@app.route('/power_off', methods=['POST'])
|
||||
def power_off():
|
||||
return jsonify({'status': 'success', 'message': 'power_off received'})
|
||||
|
||||
@app.route('/reboot_system', methods=['POST'])
|
||||
def reboot_system():
|
||||
return jsonify({'status': 'success', 'message': 'reboot_system received'})
|
||||
|
||||
@app.route('/get_system_status', methods=['GET'])
|
||||
def get_system_status():
|
||||
return jsonify({'status': 'success', 'message': 'get_system_status received', 'data': {}})
|
||||
|
||||
@app.route('/get_shared_folders', methods=['GET'])
|
||||
def get_shared_folders():
|
||||
return jsonify({'status': 'success', 'message': 'get_shared_folders received', 'folders': []})
|
||||
|
||||
@app.route('/get_system_load', methods=['GET'])
|
||||
def get_system_load():
|
||||
return jsonify({'status': 'success', 'message': 'get_system_load received', 'load': {}})
|
||||
|
||||
@app.route('/get_storage_status', methods=['GET'])
|
||||
def get_storage_status():
|
||||
return jsonify({'status': 'success', 'message': 'get_storage_status received', 'storage': {}})
|
||||
|
||||
@app.route('/get_security_status', methods=['GET'])
|
||||
def get_security_status():
|
||||
return jsonify({'status': 'success', 'message': 'get_security_status received', 'security': {}})
|
||||
|
||||
@app.route('/get_processes', methods=['GET'])
|
||||
def get_processes():
|
||||
return jsonify({'status': 'success', 'message': 'get_processes received', 'processes': []})
|
||||
|
||||
@app.route('/is_online', methods=['GET'])
|
||||
def is_online():
|
||||
return jsonify({'status': 'success', 'message': 'is_online received', 'online': True})
|
||||
|
||||
@app.route('/wait_for_boot', methods=['POST'])
|
||||
def wait_for_boot():
|
||||
return jsonify({'status': 'success', 'message': 'wait_for_boot received'})
|
||||
|
||||
@app.route('/file/list', methods=['GET'])
|
||||
def list_files():
|
||||
return jsonify({'status': 'success', 'message': 'list_files received', 'files': []})
|
||||
|
||||
@app.route('/file/info', methods=['GET'])
|
||||
def get_file_info():
|
||||
return jsonify({'status': 'success', 'message': 'get_file_info received', 'info': {}})
|
||||
|
||||
@app.route('/file/download', methods=['POST'])
|
||||
def download_file():
|
||||
return jsonify({'status': 'success', 'message': 'download_file received'})
|
||||
|
||||
@app.route('/file/upload', methods=['POST'])
|
||||
def upload_file():
|
||||
return jsonify({'status': 'success', 'message': 'upload_file received'})
|
||||
|
||||
@app.route('/file/delete', methods=['POST'])
|
||||
def delete_file():
|
||||
return jsonify({'status': 'success', 'message': 'delete_file received'})
|
||||
|
||||
@app.route('/folder/create', methods=['POST'])
|
||||
def create_folder():
|
||||
return jsonify({'status': 'success', 'message': 'create_folder received'})
|
||||
|
||||
@app.route('/file/rename', methods=['POST'])
|
||||
def rename_file():
|
||||
return jsonify({'status': 'success', 'message': 'rename_file received'})
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=5050)
|
||||
59
src/wol_proxy.py
Normal file
59
src/wol_proxy.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from flask import Flask, request, jsonify
|
||||
import socket
|
||||
import struct
|
||||
import os
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# Функция отправки WOL-пакета
|
||||
def send_wol(mac_address):
|
||||
# Проверка формата MAC
|
||||
mac_address = mac_address.replace(':', '').replace('-', '')
|
||||
if len(mac_address) != 12:
|
||||
raise ValueError('Неверный формат MAC-адреса')
|
||||
# Формирование magic packet
|
||||
data = b'FF' * 6 + (mac_address * 16).encode()
|
||||
send_data = b''
|
||||
for i in range(0, len(data), 2):
|
||||
send_data += struct.pack('B', int(data[i:i+2], 16))
|
||||
# Отправка пакета
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
||||
sock.sendto(send_data, ('<broadcast>', 9))
|
||||
sock.close()
|
||||
|
||||
@app.route('/wol', methods=['POST'])
|
||||
def wol():
|
||||
data = request.get_json()
|
||||
mac = data.get('mac')
|
||||
if not mac:
|
||||
return jsonify({'error': 'MAC-адрес обязателен'}), 400
|
||||
try:
|
||||
send_wol(mac)
|
||||
return jsonify({'status': 'WOL sent', 'mac': mac})
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
# Пример получения IP по MAC через парсинг DHCP lease-файла
|
||||
@app.route('/ip', methods=['GET'])
|
||||
def get_ip():
|
||||
mac = request.args.get('mac')
|
||||
lease_file = '/var/lib/dhcp/dhcpd.leases' # путь к lease-файлу
|
||||
if not mac:
|
||||
return jsonify({'error': 'MAC-адрес обязателен'}), 400
|
||||
if not os.path.exists(lease_file):
|
||||
return jsonify({'error': 'Lease-файл не найден'}), 500
|
||||
ip = None
|
||||
with open(lease_file, 'r') as f:
|
||||
for line in f:
|
||||
if mac.lower() in line.lower():
|
||||
# Пример: lease 192.168.1.100 { ... hardware ethernet 00:11:22:33:44:55; ... }
|
||||
if 'lease' in line:
|
||||
ip = line.split()[1]
|
||||
if ip:
|
||||
return jsonify({'ip': ip, 'mac': mac})
|
||||
else:
|
||||
return jsonify({'error': 'IP не найден для MAC'}), 404
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=5000)
|
||||
Reference in New Issue
Block a user