[PYTHON] Es ist eine Huckepack-Geschichte über den Dienst, der "Nyan" zurückgibt, wenn Sie Ping drücken

Kürzlich habe ich ein kleines Funktionsprinzip für "Ping ASCII Art" ausprobiert, das in der Netzwerkbranche zu einem heißen Thema geworden ist. Es tut mir leid, weil es nur eine Berührung ist, aber es ist nur zum persönlichen Lernen.

Die ursprüngliche Geschichte wird das Präsentationsmaterial von JANOG BoF & LT Night # 2 von @kooshin sein.

Trotzdem ist @kooshin, der die überfüllten Ideen tatsächlich verkörpert hat, wirklich erstaunlich.

■ Ich habe die Ubuntu-Umgebung ausprobiert

Ich habe eine Umgebung mit Ubuntu 16.04.3 LTS erstellt.

root@ubuntu:~# cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.3 LTS"

■ Erstellen Sie eine virtuelle Python-Umgebung für den Root-Benutzer

Ich möchte die Python-Umgebung als Root-Benutzer nicht verschmutzen, daher werde ich eine virtuelle Umgebung mit pyenv pflegen. Es hat nichts mit dem Hauptthema zu tun, daher können Sie die Arbeit hier überspringen.

(1) Installieren Sie verschiedene Pakete im Voraus

tsubo@ubuntu:~$ sudo apt-get install git gcc make openssl libssl-dev libbz2-dev libreadline-dev libsqlite3-dev

(2) Bereiten Sie die Pyenv-Umgebung vor

root@ubuntu:~# git clone https://github.com/yyuu/pyenv.git ~/.pyenv

(3) Fügen Sie dem Root-Benutzer die Umgebungsvariable pyenv hinzu

Fügen Sie .bashrc die folgenden Umgebungsvariablen hinzu

export PYENV_ROOT=$HOME/.pyenv
export PATH=$PYENV_ROOT/bin:$PATH
eval "$(pyenv init -)"

Aktivieren Sie die hinzugefügte Umgebungsvariable

root@ubuntu:~# source .bashrc 

(4) Überprüfen Sie das Installationsergebnis von pyenv

root@ubuntu:~# pyenv --version
pyenv 1.1.3-33-g48aa0c4

(5) Aktivieren Sie Python 3.6.2.

python3.6.2 installieren

root@heat:~# pyenv install 3.6.2
Downloading Python-3.6.2.tar.xz...
-> https://www.python.org/ftp/python/3.6.2/Python-3.6.2.tar.xz
Installing Python-3.6.2...
Installed Python-3.6.2 to /root/.pyenv/versions/3.6.2

Aktivieren Sie python3.6.2

root@ubuntu:~# pyenv global 3.6.2
root@ubuntu:~# pyenv versions
  system
* 3.6.2 (set by /root/.pyenv/version)

■ Installieren Sie verschiedene Python-Bibliotheken im Voraus

Sie benötigen diese Python-Bibliotheksumgebungen.

(1) Installieren Sie NetfilterQueue

root@ubuntu:~# pip install NetfilterQueue
Collecting NetfilterQueue
  Downloading NetfilterQueue-0.8.1.tar.gz (58kB)
    100% |████████████████████████████████| 61kB 3.2MB/s 
Installing collected packages: NetfilterQueue
  Running setup.py install for NetfilterQueue ... done
Successfully installed NetfilterQueue-0.8.1

(2) Installieren Sie Scapy

root@ubuntu:~# pip install scapy-python3
Collecting scapy-python3
  Downloading scapy-python3-0.21.tar.gz (2.2MB)
    100% |████████████████████████████████| 2.2MB 694kB/s 
Installing collected packages: scapy-python3
  Running setup.py install for scapy-python3 ... done
Successfully installed scapy-python3-0.21

■ Lassen Sie uns zunächst den Betrieb von NetfilterQueue überprüfen

(1) Stellen Sie die Ping-Beispiel-App bereit

Stellen Sie zunächst die unter NetfilterQueue veröffentlichte Beispiel-App bereit.

sample_icmp.py


from netfilterqueue import NetfilterQueue

def print_and_accept(pkt):
    print(pkt)
    pkt.accept()

nfqueue = NetfilterQueue()
nfqueue.bind(1, print_and_accept)
try:
    nfqueue.run()
except KeyboardInterrupt:
    print('')

nfqueue.unbind()

(2) Stellen Sie iptables ein

root@ubuntu:~# iptables -A INPUT -p icmp -j NFQUEUE --queue-num 1

(3) Starten Sie die Beispiel-App

root@ubuntu:~# python sample_icmp.py 

(4) Wenn ich versuche, von einem anderen Terminal usw. aus zu pingen

ttsubo-no-macbook-pro:~ ttsubo$ ping 192.168.195.204
PING 192.168.195.204 (192.168.195.204): 56 data bytes
64 bytes from 192.168.195.204: icmp_seq=0 ttl=64 time=0.409 ms
64 bytes from 192.168.195.204: icmp_seq=1 ttl=64 time=0.491 ms
64 bytes from 192.168.195.204: icmp_seq=2 ttl=64 time=0.732 ms
64 bytes from 192.168.195.204: icmp_seq=3 ttl=64 time=0.753 ms
64 bytes from 192.168.195.204: icmp_seq=4 ttl=64 time=0.400 ms
^C
--- 192.168.195.204 ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.400/0.557/0.753/0.155 ms

** Ping ist ohne Probleme erfolgreich. ** **.

(5) Zuvor wurde die Beispielanwendung auf dem Startbildschirm angezeigt ...

root@ubuntu:~# python sample_icmp.py 
ICMP packet, 84 bytes
ICMP packet, 84 bytes
ICMP packet, 84 bytes
ICMP packet, 84 bytes
ICMP packet, 84 bytes

Mit diesem Gefühl kann ich jetzt bestätigen, dass das ICMP-Paket empfangen wurde.

■ Lassen Sie uns als Nächstes die Scapy-Operation überprüfen

(1) Erweitern Sie die Ping-Beispiel-App

Wenn die Sequenznummer der ICMP-Echoanforderung "ein Vielfaches von 5" ist, ändern Sie die obige Beispiel-App so, dass sie nicht auf die ICMP-Echoantwort antwortet.

sample_icmp_fake.py


from scapy.all import *
from netfilterqueue import NetfilterQueue


def print_and_accept(pkt):
    packet = IP(pkt.get_payload())
    icmp = packet[ICMP]
    if (icmp.seq % 5) == 0:
        pkt.drop()
    else:
        pkt.accept()

if __name__ == "__main__":
    nfqueue = NetfilterQueue()
    nfqueue.bind(1, print_and_accept)
    try:
        nfqueue.run()
    except KeyboardInterrupt:
        print('')

    nfqueue.unbind()

(2) Starten Sie die Beispiel-App

root@ubuntu:~# python sample_icmp_fake.py 
WARNING: No route found for IPv6 destination :: (no default route?). This affects only IPv6

(3) Wenn ich versuche, von einem anderen Terminal usw. aus zu pingen

ttsubo-no-macbook-pro:~ ttsubo$ ping 192.168.195.204
PING 192.168.195.204 (192.168.195.204): 56 data bytes
Request timeout for icmp_seq 0
64 bytes from 192.168.195.204: icmp_seq=1 ttl=64 time=1.515 ms
64 bytes from 192.168.195.204: icmp_seq=2 ttl=64 time=1.507 ms
64 bytes from 192.168.195.204: icmp_seq=3 ttl=64 time=1.367 ms
64 bytes from 192.168.195.204: icmp_seq=4 ttl=64 time=1.383 ms
Request timeout for icmp_seq 5
64 bytes from 192.168.195.204: icmp_seq=6 ttl=64 time=1.453 ms
64 bytes from 192.168.195.204: icmp_seq=7 ttl=64 time=1.694 ms
64 bytes from 192.168.195.204: icmp_seq=8 ttl=64 time=1.301 ms
64 bytes from 192.168.195.204: icmp_seq=9 ttl=64 time=1.376 ms
Request timeout for icmp_seq 10
64 bytes from 192.168.195.204: icmp_seq=11 ttl=64 time=1.273 ms
64 bytes from 192.168.195.204: icmp_seq=12 ttl=64 time=1.358 ms
64 bytes from 192.168.195.204: icmp_seq=13 ttl=64 time=1.161 ms
64 bytes from 192.168.195.204: icmp_seq=14 ttl=64 time=1.180 ms
Request timeout for icmp_seq 15
64 bytes from 192.168.195.204: icmp_seq=16 ttl=64 time=1.305 ms
64 bytes from 192.168.195.204: icmp_seq=17 ttl=64 time=1.288 ms
^C
--- 192.168.195.204 ping statistics ---
18 packets transmitted, 14 packets received, 22.2% packet loss
round-trip min/avg/max/stddev = 1.161/1.369/1.694/0.135 ms

** Wenn icmp_seq "ein Vielfaches von 5" ist, schlägt der Ping erwartungsgemäß fehl. ** **.

■ Endlich

Wie oben erwähnt, konnte ich den Vorgang bestätigen, obwohl es sich um einen kleinen Teil handelt. Ich war sehr beeindruckt von der Tatsache, dass die Paketsteuerung ohne OpenFlow durchgeführt werden kann.

Recommended Posts

Es ist eine Huckepack-Geschichte über den Dienst, der "Nyan" zurückgibt, wenn Sie Ping drücken
Die Geschichte, dass ein Hash-Fehler bei der Verwendung von Pipenv auftrat
Die Geschichte, einen Slackbot zu erstellen, der beim Senden des Verarbeitungscodes ein GIF oder PNG ausgibt
[AtCoder für Anfänger] Sprechen Sie über den Rechenaufwand, den Sie grob wissen möchten
[Stada] Ein Skript, das Sie aufruft, wenn Pokemon GO veröffentlicht wird
Eine Geschichte, die blau wird, wenn die von Pillow gelesenen Daten konvertiert werden, damit sie von OpenCV verarbeitet werden können
Es scheint, dass die Version von Pyflakes nicht die neueste ist, wenn flake8 installiert ist
Tiefes Lernen! Die Geschichte der Daten selbst, die gelesen werden, wenn sie nach der handschriftlichen Nummernerkennung nicht folgen
Eine Geschichte, die praktisch war, als ich versuchte, das Python-IP-Adressmodul zu verwenden
Eine Geschichte, die fehlgeschlagen ist, als versucht wurde, das Suffix mit rstrip aus einem String zu entfernen
Eine Geschichte, die beim Versuch, die Python-Version mit GCE zu aktualisieren, hängen blieb
Es gibt ein Muster, das das Programm bei Verwendung von Python-Threading nicht gestoppt hat
Eine Geschichte, die den Aufwand für Betrieb / Wartung reduziert
#Eine Funktion, die den Zeichencode einer Zeichenfolge zurückgibt
Die Geschichte, eine harte Zeit mit der gemeinsamen Menge HTTP_PROXY = ~ zu haben
Eine Geschichte über die Änderung des Master-Namens von BlueZ
Zip 4 Gbyte Problem ist eine Geschichte der Vergangenheit
Eine Geschichte, die die Lieferung von Nico Nama analysierte.
Wenn Sie das Update von ManjaroLinux für seltsam halten
Erstellen einer Liste, wenn die Nomenklatur für einen bestimmten Zeitraum gültig ist
Kündigen Sie intelligent an, dass es sich um eine veraltete Implementierung handelt - debtcollerctor
Passwort für ein PDF mit Passwort vergessen? pdfcrack kann etwas dagegen tun
Die Geschichte von PHP, die in der Entwicklungsumgebung in Ordnung war, in der Produktionsumgebung jedoch fehlerhaft LEVEL1 ~ 3 + 1
Über den Fall, dass es nach dem Update mit Linux eine chinesische Schriftart wurde (Korrekturmethode)
Über die Angelegenheit, dass Nosetests nicht bestanden werden, wenn __init__.py im Projektverzeichnis erstellt wird
Eine Geschichte, die es einfach macht, den Wohnbereich mit Elasticsearch und Python abzuschätzen
Über den Inhalt von wscript beim Erstellen einer solchen D-Sprachumgebung mit Waf
Eine Geschichte, die das Debuggen von Modellen in der Django + SQLAlchemy-Umgebung einfacher macht
Die Geschichte, dass pyenv den Python-Ausführungsbefehl PATH nicht bestanden hat