[PYTHON] C'est une histoire de ferroutage sur le service qui renvoie "Nyan" lorsque vous appuyez sur ping

Récemment, j'ai essayé un petit principe de fonctionnement pour "ping ASCII art", qui est devenu un sujet brûlant dans l'industrie des réseaux. Je suis désolé car c'est juste une touche, mais c'est juste pour une étude personnelle.

L'histoire originale sera le matériel de présentation de JANOG BoF & LT Night # 2 par @kooshin.

Même ainsi, @kooshin, qui a en fait incarné les idées débordantes, est vraiment incroyable.

■ J'ai essayé l'environnement Ubuntu

J'ai créé un environnement avec Ubuntu 16.04.3 LTS.

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

■ Créer un environnement virtuel python pour l'utilisateur root

Je ne veux pas polluer l'environnement python en tant qu'utilisateur root, je vais donc maintenir un environnement virtuel avec pyenv. Cela n'a rien à voir avec le sujet principal, vous pouvez donc ignorer le travail ici.

(1) Installez divers packages à l'avance

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

(2) Préparez l'environnement pyenv

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

(3) Ajoutez la variable d'environnement pyenv à l'utilisateur root

Ajoutez les variables d'environnement suivantes à .bashrc

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

Activer la variable d'environnement ajoutée

root@ubuntu:~# source .bashrc 

(4) Vérifiez le résultat de l'installation de pyenv

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

(5) Activez python 3.6.2.

installation de python3.6.2

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

Activer python3.6.2

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

■ Installez plusieurs bibliothèques Python à l'avance

Vous aurez besoin de ces environnements de bibliothèque python.

(1) Installez 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) Installez 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

■ Commençons par vérifier le fonctionnement de NetfilterQueue

(1) Déployer l'exemple d'application Ping

Tout d'abord, déployez l'exemple d'application publié sur NetfilterQueue.

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) Réglez iptables

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

(3) Démarrez en fait l'exemple d'application

root@ubuntu:~# python sample_icmp.py 

(4) Lorsque j'essaye d'envoyer un ping depuis un autre terminal, etc.

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 réussit sans aucun problème. ** **

(5) Auparavant, l'exemple d'application était affiché sur l'écran de démarrage ...

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

Avec ce sentiment, je peux maintenant confirmer que le paquet ICMP a été reçu.

■ Ensuite, vérifions le fonctionnement de la scapy

(1) Étendre l'exemple d'application Ping

Si le numéro de séquence de la demande d'écho ICMP est "un multiple de 5", modifiez l'exemple d'application ci-dessus afin qu'il ne réponde pas à la réponse d'écho ICMP.

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) Démarrez en fait l'exemple d'application

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

(3) Lorsque j'essaye d'envoyer un ping depuis un autre terminal, etc.

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

** Comme prévu, si icmp_seq est "un multiple de 5", le ping échouera. ** **

■ Enfin,

Comme mentionné ci-dessus, j'ai pu confirmer l'opération, bien qu'il s'agisse d'une petite partie. J'ai été très impressionné par le fait que le contrôle des paquets peut être effectué sans utiliser OpenFlow.

Recommended Posts

C'est une histoire de ferroutage sur le service qui renvoie "Nyan" lorsque vous appuyez sur ping
L'histoire de l'erreur de hachage est apparue lors de l'utilisation de Pipenv
L'histoire de la création d'un slackbot qui génère un gif ou un png lorsque vous envoyez le code de traitement
[Pour les débutants chez AtCoder] Parlez de la quantité de calcul que vous voulez connaître approximativement
[Stada] Un script qui vous appellera à la sortie de Pokemon GO
Une histoire qui vire au bleu lorsque les données lues par Pillow sont converties pour pouvoir être gérées par OpenCV
Il semble que la version de pyflakes ne soit pas la dernière lorsque flake8 est installé
L'apprentissage en profondeur! L'histoire des données elles-mêmes qui sont lues lorsqu'elles ne suivent pas après la reconnaissance des nombres manuscrits
Une histoire qui était pratique lorsque j'ai essayé d'utiliser le module d'adresse IP python
Une histoire qui a échoué lors de la tentative de suppression du suffixe d'une chaîne avec rstrip
Une histoire bloquée lors de la tentative de mise à niveau de la version Python avec GCE
Il y a un modèle que le programme ne s'est pas arrêté lors de l'utilisation du thread Python
Une histoire qui réduit l'effort de fonctionnement / maintenance
#Une fonction qui renvoie le code de caractère d'une chaîne de caractères
Une histoire qui a eu du mal avec l'ensemble commun HTTP_PROXY = ~
Une histoire sur le changement du nom principal de BlueZ
Le problème Zip 4 Gbyte est une histoire du passé
Une histoire qui a analysé la livraison de Nico Nama.
Quand vous pensez que la mise à jour de ManjaroLinux est étrange
Créer une liste lorsque la nomenclature est pour une certaine période de temps
Annoncez intelligemment qu'il s'agit d'une implémentation obsolète --debtcollerctor
Mot de passe oublié pour un PDF avec mot de passe? pdfcrack peut faire quelque chose à ce sujet
L'histoire de PHP qui était correcte dans l'environnement de développement mais boguée dans l'environnement de production LEVEL1 ~ 3 + 1
À propos du cas où elle est devenue une police chinoise après la mise à jour avec Linux (méthode de correction)
À propos du problème que nosetests ne passe pas lorsque __init__.py est créé dans le répertoire du projet
Une histoire qui facilite l'estimation de la surface habitable à l'aide d'Elasticsearch et de Python
À propos du contenu de wscript lors de la création d'un environnement en langage D comme celui avec Waf
Une histoire qui rend le débogage de modèle plus facile à voir dans l'environnement Django + SQLAlchemy
L'histoire selon laquelle pyenv n'a pas passé la commande d'exécution python PATH