Dies ist eine Fortsetzung von Letztes Mal. Das möchte ich vorerst tun.
Diesmal endlich "Erstellen Sie ein Python-Skript für Wake on LAN".
Annahme: Ubuntu 18.04. Richten Sie es zunächst so ein, dass Wake on LAN ausgeführt werden kann.
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
~~
Auslassen. WOL-Einstellung (1/3) des gebooteten PCs: BIOS / UEFI-Einstellung wo siehe.
Ü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
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
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.
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.
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.
Stellen Sie ein Kanalgeheimnis aus und notieren Sie es.
Stellen Sie ein Channel Access Token aus und notieren Sie es.
Stellen Sie die automatische Antwort usw. in den Antworteinstellungen entsprechend ein.
Geben Sie die Webhook-URL über die Nachrichten-API ein. Diesmal ist es "https: // {Domain Name} / wake-on-lan".
Damit sind die LINE Bot-Einstellungen abgeschlossen.
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'
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