NAS EMULATOR + WOL Proxy

This commit is contained in:
2025-08-31 15:01:12 +09:00
parent bb37f75a0a
commit 147f1dec22
5 changed files with 179 additions and 11 deletions

7
Dockerfile.nas Normal file
View 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
View 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"]

View File

@@ -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
View 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
View 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)