[LINUX] Erstellen Sie ein Python-Skript für Wake on LAN (Wake on LAN über NAT [5])

Einführung

Dies ist eine Fortsetzung von Letztes Mal. Das möchte ich vorerst tun.

network_detail.png

Diesmal endlich "Erstellen Sie ein Python-Skript für Wake on LAN".

Desktop-PC-Einstellungen

Annahme: Ubuntu 18.04. Richten Sie es zunächst so ein, dass Wake on LAN ausgeführt werden kann.

Feste IP-Zuweisung

sudo vi /etc/netplan/~~.yaml

Füllen Sie Folgendes aus:

/etc/netplan/~~.yaml


# Let NetworkManager manage all devices on this system
network:
  version: 2
  renderer: NetworkManager

  ethernets:
    eno1:
       dhcp4: no
       wakeonlan: true # enable wake on lan
       addresses: [192.168.1.**/24] # assign arbitrary address
       gateway4: 192.168.1.1  # your router(raspi)'s address
       nameservers:
         addresses: [8.8.8.8,8.8.4.4] # google's public dns

Neustart.

sudo netplan apply
sudo reboot

Installieren Sie "ethtool", um sicherzustellen, dass "Wake on LAN" aktiviert ist.

sudo apt-get install -y ethtool

Notieren Sie sich den Ethernet-Namen. Überprüfen Sie als Nächstes, ob die IP festgelegt ist.

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eno1<<<<copy<<<<: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether **:**:**:**:**:** brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.**/24 brd 192.168.1.255 scope global noprefixroute eno1
       valid_lft forever preferred_lft forever
    inet6 fe80::2d8:61ff:fe56:242d/64 scope link
       valid_lft forever preferred_lft forever

Stellen Sie sicher, dass Wake on LAN aktiviert ist. Es ist in Ordnung, wenn es "Wake-on: g" ist.

$ sudo ethtool eno1
~~
Supports Wake-on: pumbg
Wake-on: g # if it's d, your wake on lan setting may be wrong
~~

BIOS-Einstellungen

Auslassen. WOL-Einstellung (1/3) des gebooteten PCs: BIOS / UEFI-Einstellung wo siehe.

Bestätigung

Überprüfen Sie "ip a" mit Raspeye und es ist in Ordnung, wenn ip dem mit Desktop verbundenen Ethernet zugewiesen ist. (Es muss "UP, LOWER_UP" sein. [Danke telcomM](https://unix.stackexchange.com/questions/588973/wake-on-lan-from-custom-router-raspberry-pi/588983 # 588883)))

$ ip a
4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether **:**:**:**:**:** brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 brd 192.168.1.255 scope global noprefixroute eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::83fa:6dee:9799:9a6e/64 scope link 
       valid_lft forever preferred_lft forever

Bestätigung (Bestätigung, dass Wakeonlan installiert und gestartet werden kann)

Installieren Sie wake onlan auf Raspai.

sudo apt install wakeonlan
wakeonlan -i 192.168.1.255 -p 7 **:**:**:**:**:**

Wenn Sie damit beginnen können, ist es OK.

mod_wsgi Installieren Sie zuerst mod_wsgi und verschiedene Dinge, die Python-Skripte mit Apache ausführen können.

sudo apt install python3-dev python3-pip apache2 libapache2-mod-wsgi-py3
sudo apt-get -y install python3 ipython3 python3-flask curl

Python-Skript-Erstellung

Erstellen Sie ein Python-Skript, das vorerst funktioniert. Dieses Mal werden wir Flask verwenden.

cd ~
mkdir flask && cd flask
vi app.py

~/flask/app.py


from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
    return 'This is vpn server for wake on lan!\n\n'
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Überprüfen Sie vorerst, ob mod_wsgi funktioniert.

$ python3 app.py
$ curl http://localhost:5000 #In einer anderen Registerkarte
This is vpn server for wake on lan!

Wenn Sie "Dies ist ein VPN-Server für Wake on LAN!" Sehen, ist dies in Ordnung.

Apache- und mod_wsgi-Einstellungen

Erstellen Sie eine neue Einstellungsdatei für den Kolben.

sudo vi /etc/apache2/sites-available/flask.conf

Dieses Mal versuche ich, von GCP zu Port 80 umzuleiten. Geben Sie also Folgendes ein.

/etc/apache2/sites-available/flask.conf


<VirtualHost *:80>
    ServerName kado.example.com
    WSGIDaemonProcess flask user={username} group={username} threads=5
    WSGIScriptAlias / /home/{username}/flask/adapter.wsgi
    <Directory /home/{username}/flask/>
        WSGIProcessGroup flask
        WSGIApplicationGroup %{GLOBAL}
        WSGIScriptReloading On
        Require all granted
    </Directory>
</VirtualHost>

Aktivieren Sie flask.conf.

sudo a2dissite 000-default.conf
sudo a2ensite flask.conf
sudo service apache2 restart

Erstellen Sie eine adapter.wsgi-Datei.

vi ~/flask/adapter.wsgi

~/flask/adapter.wsgi


import sys
if sys.version_info[0]<3:       # require python3
    raise Exception("Python3 required! Current (wrong) version: '%s'" % sys.version_info)
sys.path.insert(0, '/home/kadorpi/flask/')
from app import app as application # <- app means app of app.py

Starten Sie Apache neu.

sudo service apache2 restart

Überprüfen Sie, ob es funktioniert.

$ curl localhost
This is vpn server for wake on lan!

Das Python-Skript läuft jetzt auf Apache.

Aktivieren Sie die LAN-Skripterstellung für den Line-Bot

Es wird etwas später sein, wenn wir hier ankommen. Sendet eine HTTP-Anfrage von Line an GCP und leitet die empfangene Anfrage an Port 80 von Raspai weiter. Anschließend wird die von Raspeye empfangene Anforderung von Python verarbeitet.

Registrieren Sie zunächst ein Konto in Line Developer. Erstellen Sie als Nächstes einen Kanal.

1.png 2.png

3.png

Stellen Sie ein Kanalgeheimnis aus und notieren Sie es.

4.png

Stellen Sie ein Channel Access Token aus und notieren Sie es.

5.png

Stellen Sie die automatische Antwort usw. in den Antworteinstellungen entsprechend ein.

6.png

Geben Sie die Webhook-URL über die Nachrichten-API ein. Diesmal ist es "https: // {Domain Name} / wake-on-lan".

7.png

Damit sind die LINE Bot-Einstellungen abgeschlossen.

Konfigurieren Sie mod_wsgi neu

Legen Sie das Kanalgeheimnis und das Kanalzugriffstoken fest, die Sie zuvor als Umgebungsvariablen notiert haben.

vi ~/flask/adapter.wsgi

Fügen Sie Folgendes hinzu.

~/flask/adapter.wsgi


import os
os.environ['LINE_CHANNEL_SECRET'] = 'fuga'
os.environ['LINE_CHANNEL_ACCESS_TOKEN'] = 'hogehoge'

Python-Skript

Installieren Sie die erforderlichen Module.

pip3 install line-bot-sdk flask

Der Python-Code sieht folgendermaßen aus:

python


import os, sys
from flask import Flask, request, abort
app = Flask(__name__)

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    TextMessage, TextSendMessage, MessageEvent
)

# get channel_secret and channel_access_token from your environment variable
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)
if channel_secret is None:
    print('Specify LINE_CHANNEL_SECRET as environment variable.')
    sys.exit(1)
if channel_access_token is None:
    print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
    sys.exit(1)

line_bot_api = LineBotApi(channel_access_token)
handler = WebhookHandler(channel_secret)

@app.route('/')
def show_web():
    return 'This is vpn server for wake on lan!\n\n'

@app.route('/wake-on-lan', methods=['POST'])
def wake_on_lan():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'ok'

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    message = event.message.text

    replies = []
    if re.compile("\s*(check)\s*", re.IGNORECASE).search(message):
        result = confirm()
        replies += [TextSendMessage(result)]

    elif re.compile("\s*(kick)\s*", re.IGNORECASE).search(message):
        if confirm() == 'Awake':
            replies += [TextSendMessage('Already awake')]
        else:
            result = kick()
            replies += [TextSendMessage(result)]

    buttons_template = ButtonsTemplate(
        title='usage', text='Tap below buttons', actions=[
            MessageAction(label=m, text=m) for m in message_list
        ])

    template_message = TemplateSendMessage(alt_text='Usage', template=buttons_template)
    replies += [template_message]

    line_bot_api.reply_message(event.reply_token, replies)


def confirm():
    hostname = "192.168.1.**"
    response = os.system("ping -c 1 " + hostname)
    # and then check the response...
    if response == 0:
        pingstatus = "Awake"
    else:
        pingstatus = "Sleeping"

    return pingstatus

def kick():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    s.sendto(b'\xFF' * 6 + b'\x**\x**\x**\x**\x**\x**' * 16, ('192.168.1.255', 7))
    s.close()

    return 'kicked'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Um eine kleine Erklärung zu geben, laden Sie zuerst das Kanalgeheimnis und das Kanalzugriffstoken für LINE unten.

# get channel_secret and channel_access_token from your environment variable
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)
if channel_secret is None:
    print('Specify LINE_CHANNEL_SECRET as environment variable.')
    sys.exit(1)
if channel_access_token is None:
    print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
    sys.exit(1)

line_bot_api = LineBotApi(channel_access_token)
handler = WebhookHandler(channel_secret)

Für die Webanzeige wurde Folgendes hinzugefügt.

@app.route('/')
def show_web():
    return 'This is vpn server for wake on lan!\n\n'

Schreiben Sie hier die oben festgelegte Webhook-Anforderungsverarbeitung.

@app.route('/wake-on-lan', methods=['POST'])
def wake_on_lan():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'ok'

Und schließlich, wenn "kick" in die Nachricht kommt, senden Sie MagicPacket, und wenn "check" kommt, wird hier der Prozess geschrieben, um zu überprüfen, ob es von Ping gestartet werden kann.

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    message = event.message.text

    replies = []
    if re.compile("\s*(check)\s*", re.IGNORECASE).search(message):
        result = confirm()
        replies += [TextSendMessage(result)]

    elif re.compile("\s*(kick)\s*", re.IGNORECASE).search(message):
        if confirm() == 'Awake':
            replies += [TextSendMessage('Already awake')]
        else:
            result = kick()
            replies += [TextSendMessage(result)]

    buttons_template = ButtonsTemplate(
        title='usage', text='Tap below buttons', actions=[
            MessageAction(label=m, text=m) for m in message_list
        ])

    template_message = TemplateSendMessage(alt_text='Usage', template=buttons_template)
    replies += [template_message]

    line_bot_api.reply_message(event.reply_token, replies)


def confirm():
    hostname = "192.168.1.**"
    response = os.system("ping -c 1 " + hostname)
    # and then check the response...
    if response == 0:
        pingstatus = "Awake"
    else:
        pingstatus = "Sleeping"

    return pingstatus

def kick():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    s.sendto(b'\xFF' * 6 + b'\x**\x**\x**\x**\x**\x**' * 16, ('192.168.1.255', 7))
    s.close()

    return 'kicked'
sudo service apache2 restart

動画

How To Use Apache HTTP Server As Reverse-Proxy Using mod_proxy Extension

Recommended Posts

Erstellen Sie ein Python-Skript für Wake on LAN (Wake on LAN über NAT [5])
Erhalten Sie eine Domain mit GCP und MyDNS (Wake on LAN over NAT [1])
Erstellen Sie eine Python-Umgebung auf dem Mac (2017/4)
Erstellen Sie eine Python-Umgebung in Centos
Erstellen einer virtuellen Umgebung für Python auf dem Mac [Sehr einfach]
Wettbewerb mit VS-Code Erstellen Sie eine Python-Umgebung für Profis unter Windows
Verwandle Razzpie in einen Router (Wake on LAN over NAT [4])
Erstellen Sie eine Python-Umgebung auf Ihrem Mac
Erstellen wir eine virtuelle Umgebung für Python
Ein Python-Skript für Mac, das unter Windows ohne verstümmelte Zeichen komprimiert wird
Erstellen Sie eine neue Todoist-Aufgabe aus Python Script
[Venv] Erstellen Sie eine virtuelle Python-Umgebung unter Ubuntu
Ein Memorandum zum Berühren von Python Flask mit Heroku
Erstellen Sie eine Python-Ausführungsumgebung unter IBM i
Erstellen Sie ein Python-Modul
Erstellen Sie eine Python-Umgebung
[Python] 2 Erstellen Sie eine Risiko-Rendite-Karte für Ihr Asset-Portfolio
Erstellen Sie unter Linux einen QR-Code für die URL
Erstellen Sie die Python-Erweiterung E-Cell 4 unter Windows 7 (64 Bit).
Erstellen Sie eine komfortable Python 3 (Anaconda) -Entwicklungsumgebung mit Windows
Vorgehensweise zum Erstellen einer CDK-Umgebung unter Windows (Python)
Erstellen Sie in Docker eine Ebene für AWS Lambda Python
Python-Skript, das eine JSON-Datei aus einer CSV-Datei erstellt
Erstellen Sie unter Windows eine anständige Shell- und Python-Umgebung
Erstellen Sie eine Python-Entwicklungsumgebung mit OS X Lion
Reverse Proxy von Apache auf GCP zu lokalem Raspeye Apache (Wake on LAN über NAT [3])
Skript zum einfachen Erstellen einer Clientgeräteumgebung für AWS IoT (Python v2-Version)
Erstellen Sie ein Wox-Plugin (Python)
Erstellen Sie eine Funktion in Python
Erstellen Sie ein Wörterbuch in Python
Erstellen Sie eine Python-Entwicklungsumgebung (pyenv / virtualenv) auf einem Mac (Homebrew).
[Python, Shell-Skript, Teamentwicklung] Erstellen Sie ein geschicktes Git-Repository
Erstellen Sie ein untergeordnetes Konto für die Verbindung mit Stripe in Python
[Python] Erstellen Sie eine Datums- und Zeitliste für einen bestimmten Zeitraum
Richten Sie den Softether-Server auf GCP ein (Verbindung von iPhone / Raspeye herstellen) (Wake on LAN over NAT (2])
Erstellen Sie einen Twitter-BOT mit dem GoogleAppEngine SDK für Python
Erstellen Sie ein Python-Numpy-Array
Erstellen Sie die Python-Erweiterung E-Cell 4 unter Mac OS X (Yosemite).
Erstellen Sie ein Klassenzimmer auf Jupyterhub
Erstellen Sie ein Verzeichnis mit Python
Erstellen Sie unter CentOS 7.7 eine Python-Umgebung für Ihren Heimserver
[Python] Erstellen Sie mit Django einen Bildschirm für den HTTP-Statuscode 403/404/500
Erstellen Sie eine Windows Python-Ausführungsumgebung mit VScode + Remote WSL
Erstellen Sie eine gestreifte Illusion mit Gammakorrektur für Python3 und openCV3
Erstellen Sie ein Shell-Skript, um die Python-Datei mehrmals auszuführen
Erstellen Sie mit Python + Qt (PySide) einen Farbwähler für das Farbrad.
Python vba zum Erstellen einer Datumszeichenfolge zum Erstellen eines Dateinamens
Ein Python-Skript, das auf dem Mac erstellte ._DS_Store- und ._ * -Dateien löscht
Erstellen Sie ein USB-Boot-Ubuntu mit einer Python-Umgebung für die Datenanalyse
Erstellen einer Python-Umgebung auf einem Mac
Python-Skript für die ldapsearch base64-Dekodierung
Erstellen Sie mit tkinter eine Python-GUI
Erstellen Sie einen DI-Container mit Python
Erstellen einer Python-Umgebung unter Ubuntu
Erstellen Sie eine virtuelle Umgebung mit Python!
Erstellen Sie eine Binärdatei in Python
Ein kleines Skript zur Selbstverteidigung von Malware