jeudi 13 mars 2014

Comment contrôler si un port est ouvert/accessible sur un serveur Linux.

0°) Introduction.

En mission chez un client, j'ai rencontré une problématique intéressante.
Sur le serveur linux de développement, nous devons faire tourner plusieurs instances de notre serveur d'application (dans notre cas Tomcat) sur des ports différents. Malheureusement, les contraintes de sécurités internes, ne nous permettent pas d'utiliser les ports comme nous l'aurions souhaités. Du coup, il fallait faire une demande auprès du service concernée et attendre que celle-ci soit traitée.

Malheureusement, certaines ouvertures de ports n'étaient pas correctement traitées, et nous avions besoin de contrôler si le port était bien accessible.

1°) Dans le vif du sujet.

Mon premier réflexe a été de penser à faire une configuration spécifique avec un serveur apache/nginx et tester si je pouvais interroger le service depuis un navigateur... Mais j'avais plus  d'une vingtaine de port à tester. La solution devenait beaucoup trop lourde à mettre en oeuvre.

Après une rapide recherche sur internet, j'ai trouver un petit script python (voir ici), que j'ai donc adapter pour mes besoins. Voici le script modifié :

  #!/usr/bin/python
import datetime,BaseHTTPServer,sys
#
# Contruction de la réponse : On renvoi la date et l'heure
#
class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/plain')
        self.end_headers()
        self.wfile.write(str(datetime.datetime.now()))
        return
#
# On regarde si le port a été passé en paramétre.
# - Si oui on le récupere
# - Si non, on mets le port 18443 par défaut.
#
if len(sys.argv) > 1:
        port =  sys.argv[1]
else:
        port = "18443"
print "En écoute sur le port " + port  +  " ..."
#
# Lancement du service
#
server = BaseHTTPServer.HTTPServer(('',  int(port)), MyHandler)
server.serve_forever()


Bien sur il faut que python soit installé sur votre serveur :-)
Le fonctionnement est assez simple. Il suffit de lancer le script en indiquant le port sur lequel on veut écouter :

user# ./dummyService.py 18443
En écoute sur le port 18443 ...

On peut commencer à faire une requête en local avec wget :

users#  wget localhost:18443
--2014-03-13 15:46:45--  http://localhost:18443/
Resolving localhost... 127.0.0.1
Connecting to localhost|127.0.0.1|:18443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/plain]
Saving to: `index.html.24'

    [ <=>                                                                           ] 26          --.-K/s   in 0s

2014-03-13 15:46:45 (3.54 MB/s) - `index.html.24' saved [26]

Et ensuite essayer d'accéder au serveur depuis un navigateur :


Si le service n'est pas accessible, la réponse du navigateur sera :


Lors du lancement du script, si le port est occupé, le script nous réponds :

En ecoute sur le port 18080 ...
Traceback (most recent call last):
  File "./dummyService.py", line 26, in ?
    server = BaseHTTPServer.HTTPServer(('',  int(port)), MyHandler)
  File "/usr/lib64/python2.4/SocketServer.py", line 330, in __init__
    self.server_bind()
  File "/usr/lib64/python2.4/BaseHTTPServer.py", line 101, in server_bind
    SocketServer.TCPServer.server_bind(self)
  File "/usr/lib64/python2.4/SocketServer.py", line 341, in server_bind
    self.socket.bind(self.server_address)
  File "<string>", line 1, in bind
socket.error: (98, 'Address already in use')

2°) Conclusion.

Voilà, du coup tester si un port est accessible sur un serveur devient très simple et très rapide.
Lors de la mise en place d'un firewall, ce type d'outil peut-être très utile pour tester les règles que l'on mets en place....

Aucun commentaire:

Publier un commentaire