Merge branch 'master' of ssh://git.crans.org/git/usr-scripts
This commit is contained in:
commit
a9b7d12314
57 changed files with 19532 additions and 17967 deletions
|
@ -1,11 +1,11 @@
|
|||
Configuration des scripts
|
||||
=========================
|
||||
config -- Configuration des scripts
|
||||
===================================
|
||||
|
||||
Table des matières :
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:glob:
|
||||
|
||||
|
||||
*
|
||||
mails/index
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Configuration des mails automatiquement envoyés
|
||||
===============================================
|
||||
mails -- Configuration des mails automatiquement envoyés
|
||||
========================================================
|
||||
|
||||
Table des matières :
|
||||
|
||||
|
|
7
doc/source/gestion/gen_confs/firewall4.rst
Normal file
7
doc/source/gestion/gen_confs/firewall4.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
|
||||
gen_confs.firewall4 -- Le pare-feu ipv4
|
||||
=======================================
|
||||
|
||||
.. automodule:: gestion.gen_confs.firewall4
|
||||
:members:
|
||||
:special-members:
|
10
doc/source/gestion/gen_confs/index.rst
Normal file
10
doc/source/gestion/gen_confs/index.rst
Normal file
|
@ -0,0 +1,10 @@
|
|||
gen_confs -- Cr@ns Configuration Generator
|
||||
==========================================
|
||||
|
||||
Table des matières :
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:glob:
|
||||
|
||||
*
|
|
@ -1,5 +1,5 @@
|
|||
gestion - scripts de gestion du Cr@ns
|
||||
=====================================
|
||||
gestion -- scripts de gestion du Cr@ns
|
||||
======================================
|
||||
|
||||
Table des matières :
|
||||
|
||||
|
@ -7,3 +7,4 @@ Table des matières :
|
|||
:maxdepth: 2
|
||||
|
||||
config/index
|
||||
gen_confs/index
|
||||
|
|
5
doc/source/impression/canon_wrapper.rst
Normal file
5
doc/source/impression/canon_wrapper.rst
Normal file
|
@ -0,0 +1,5 @@
|
|||
canon_wrapper -- Soumission de jobs à l'imprimante canon
|
||||
========================================================
|
||||
|
||||
.. automodule:: impression.canon_wrapper
|
||||
:members:
|
11
doc/source/impression/index.rst
Normal file
11
doc/source/impression/index.rst
Normal file
|
@ -0,0 +1,11 @@
|
|||
impression -- Scripts relatifs au service d'impression du Cr@ns
|
||||
===============================================================
|
||||
|
||||
Table des matières :
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:glob:
|
||||
|
||||
*
|
||||
|
|
@ -12,6 +12,7 @@ Table des matières :
|
|||
:maxdepth: 5
|
||||
|
||||
gestion/index
|
||||
impression/index
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
|
|
@ -2,27 +2,29 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import psycopg2
|
||||
from functools import wraps
|
||||
|
||||
try:
|
||||
if __name__ == 'annuaires_pg_test':
|
||||
conn = psycopg2.connect(user='crans', database='switchs', host='localhost')
|
||||
else:
|
||||
conn = psycopg2.connect(user='crans', database='switchs', host='pgsql.adm.crans.org')
|
||||
|
||||
# Population de la tâble avec les bâtiments
|
||||
cur = conn.cursor()
|
||||
|
||||
cur.execute("SELECT DISTINCT batiment FROM prises")
|
||||
bat_switchs = [i[0] for i in cur.fetchall()]
|
||||
cur.close()
|
||||
del cur
|
||||
except psycopg2.OperationalError:
|
||||
bat_switchs = ["a", "b", "c", "g", "h", "i", "j", "m", "o", "p"]
|
||||
conn = None
|
||||
def _need_conn(f):
|
||||
"""Décorateur à appliquer aux fonctions nécessitant une connexion pgsql"""
|
||||
@wraps(f)
|
||||
def first_connect(*args, **kwargs):
|
||||
global conn
|
||||
if conn == None:
|
||||
if __name__ == 'annuaires_pg_test':
|
||||
host='localhost'
|
||||
else:
|
||||
host='pgsql.adm.crans.org'
|
||||
# "connecting …"
|
||||
conn = psycopg2.connect(user='crans', database='switchs', host=host)
|
||||
return f(*args, **kwargs)
|
||||
return first_connect
|
||||
|
||||
bat_switchs = ["a", "b", "c", "g", "h", "i", "j", "m", "o", "p"]
|
||||
|
||||
bat_manuels = []
|
||||
|
||||
|
||||
@_need_conn
|
||||
def chbre_prises(batiment, chambre = None):
|
||||
"""Correspondance chambre -> prise"""
|
||||
batiment = batiment.lower()
|
||||
|
@ -44,6 +46,7 @@ def chbre_prises(batiment, chambre = None):
|
|||
raise ValueError("Batiment inexistant")
|
||||
return ret
|
||||
|
||||
@_need_conn
|
||||
def chbre_commentaire(batiment, chambre):
|
||||
""" Renvoie le commentaire associé à la chambre """
|
||||
global conn
|
||||
|
@ -55,6 +58,7 @@ def chbre_commentaire(batiment, chambre):
|
|||
except TypeError:
|
||||
raise ValueError("Chambre inexistante")
|
||||
|
||||
@_need_conn
|
||||
def reverse(batiment, prise = None):
|
||||
"""Correspondance prise -> chambre"""
|
||||
batiment = batiment.lower()
|
||||
|
@ -79,6 +83,7 @@ def reverse(batiment, prise = None):
|
|||
raise ValueError("Batiment inexistant")
|
||||
return ret
|
||||
|
||||
@_need_conn
|
||||
def is_crans(batiment, chambre):
|
||||
"""Chambre cablee au Cr@ns ?"""
|
||||
batiment = batiment.lower()
|
||||
|
@ -87,6 +92,7 @@ def is_crans(batiment, chambre):
|
|||
cur.execute("SELECT crans FROM prises WHERE (batiment, chambre) = (%s, %s)", (batiment, chambre))
|
||||
return cur.fetchone()[0]
|
||||
|
||||
@_need_conn
|
||||
def is_connected(batiment, chambre):
|
||||
"""Cablage physique effectue ?"""
|
||||
batiment = batiment.lower()
|
||||
|
@ -95,6 +101,7 @@ def is_connected(batiment, chambre):
|
|||
cur.execute("SELECT cablage_effectue FROM prises WHERE (batiment, chambre) = (%s, %s)", (batiment, chambre))
|
||||
return cur.fetchone()[0]
|
||||
|
||||
@_need_conn
|
||||
def crous_to_crans(batiment, chambre):
|
||||
"""Passage d'une chambre de CROUS a Cr@ns"""
|
||||
batiment = batiment.lower()
|
||||
|
@ -207,7 +214,7 @@ uplink_prises={ 'a' :
|
|||
# peuvent être utiles à connaître
|
||||
401: 'uplink->batp0', 402: 'uplink->batp-1',
|
||||
403: 'uplink->batp2', 403: 'uplink->batp-3',
|
||||
405: 'libre-service', 406: 'uplink->backbone',
|
||||
405: 'libre-service', 406: 'uplink->bato-1',
|
||||
},
|
||||
'o' :
|
||||
{
|
||||
|
@ -223,9 +230,9 @@ uplink_prises={ 'a' :
|
|||
'A2': 'komaz-ens', 'B2': 'multiprise-wifi',
|
||||
'A3': 'sable', 'B3': 'dyson',
|
||||
'A4': 'komaz', 'B4': 'fy',
|
||||
'A5': 'malloc-1', 'B5': 'switch-ilo',
|
||||
'A5': 'zbee' , 'B5': 'switch-ilo',
|
||||
'B6': 'vigile 0B',
|
||||
'B7': 'daath',
|
||||
'B7': 'kdell',
|
||||
'B8': 'batb',
|
||||
'B9': '2b',
|
||||
'B10': 'fz',
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
""" Pour détecter les gens en chambre invalide, les prévenir, et supprimer leurs machines
|
||||
en l'absence de réponse. Récupérer des IPs, c'est cool."""
|
||||
|
||||
# Codé par b2moo, commenté par 20-100, cr{itiqu|on}é par Nit
|
||||
# <daniel.stan@crans.org>
|
||||
# <legallic@crans.org>
|
||||
# <samir@crans.org>
|
||||
|
||||
import datetime
|
||||
import time
|
||||
|
@ -10,13 +16,22 @@ import ldap_crans
|
|||
conn = ldap_crans.CransLdap()
|
||||
|
||||
import sys
|
||||
#: envoyer un mail à chaque adhérent concerné
|
||||
sendmails = False
|
||||
if "--mail-all" in sys.argv:
|
||||
sendmails = True
|
||||
import email.Header
|
||||
|
||||
import os
|
||||
#: Envoyer un mail à respbats
|
||||
sendmail_respbats = True
|
||||
if "--no-mail" in sys.argv:
|
||||
sendmail_respbats = False
|
||||
|
||||
DEBUG = False
|
||||
if "--debug" in sys.argv:
|
||||
DEBUG = True
|
||||
|
||||
import os
|
||||
import config
|
||||
year = config.ann_scol
|
||||
delai = config.demenagement_delai
|
||||
|
@ -24,8 +39,10 @@ delai = config.demenagement_delai
|
|||
import config.mails.demenagement
|
||||
|
||||
# On récupère ceux qui n'ont pas payé cette année
|
||||
bad_boys_e_s = conn.search('chbre=????&paiement=%d&paiement!=%d' % (year-1,year))['adherent']
|
||||
|
||||
if config.periode_transitoire:
|
||||
bad_boys_e_s = conn.search('chbre=????&paiement=%d&paiement!=%d' % (year-1,year))['adherent']
|
||||
else:
|
||||
bad_boys_e_s = conn.search('chbre=????&paiement=%d' % year)['adherent']
|
||||
now = time.time()
|
||||
|
||||
|
||||
|
@ -46,7 +63,7 @@ for clandestin in bad_boys_e_s:
|
|||
delta = now - kickout_date
|
||||
ttl = delai*86400 - delta
|
||||
if ttl > 0:
|
||||
if sendmails and machine_liste != []:
|
||||
if (sendmails and machine_liste != [] or DEBUG) and (ttl >= (delai - 1)*86400 or 0 < ttl <= 86400):
|
||||
# On lui envoie un mail pour le prévenir
|
||||
to = clandestin.mail()
|
||||
if not "@" in to:
|
||||
|
@ -55,15 +72,14 @@ for clandestin in bad_boys_e_s:
|
|||
"chambre" : exchambre,
|
||||
"jours" : int(ttl/86400) + 1,
|
||||
"to" : to}
|
||||
if DEBUG:
|
||||
print mail
|
||||
mailer = os.popen("/usr/sbin/sendmail -t", "w")
|
||||
mailer.write(mail.encode("utf-8") + "\n.")
|
||||
mailer.close()
|
||||
|
||||
else:
|
||||
for m in machine_liste:
|
||||
# On n'a pas envie d'essayer de supprimer une machine qui a une blackliste
|
||||
if len(m.blacklist_actif()) > 0:
|
||||
continue
|
||||
to_print.append( (clandestin.id(), m.ip(), m.id(), m.nom()) )
|
||||
m2 = conn.search('mid=%s' % m.id(),mode='w')['machine'][0]
|
||||
m2.delete('Adherent sans chambre valide depuis %d jours' % delai)
|
||||
|
@ -74,7 +90,7 @@ if to_print != []:
|
|||
hostnamemaxsize = max([len(i[3]) for i in to_print])
|
||||
template = u"| %%4s | %%-15s | %%4s | %%-%ss |\n" % (hostnamemaxsize)
|
||||
message = u""
|
||||
message += u"\nListe des machines supprimée pour chambre invalide depuis plus de %s jours :\n" % delai
|
||||
message += u"\nListe des machines supprimées pour chambre invalide depuis plus de %s jours :\n" % delai
|
||||
tiret_line = u"+------+-----------------+------+-%s-+\n" % ("-" * hostnamemaxsize)
|
||||
message += tiret_line
|
||||
message += template % ("aid", " ip", "mid", (" " * (max((hostnamemaxsize-8)/2,0)) + "hostname"))
|
||||
|
@ -86,7 +102,9 @@ if to_print != []:
|
|||
headers += u"Content-Type: text/plain; charset=UTF-8\n"
|
||||
headers += u"To: respbats@crans.org\n"
|
||||
mail = headers + "\n" + message
|
||||
mailer = os.popen("/usr/sbin/sendmail -t", "w")
|
||||
mailer.write(mail.encode("utf-8") + "\n.")
|
||||
mailer.close()
|
||||
|
||||
if sendmails:
|
||||
mailer = os.popen("/usr/sbin/sendmail -t", "w")
|
||||
mailer.write(mail.encode("utf-8") + "\n.")
|
||||
mailer.close()
|
||||
else:
|
||||
print mail
|
||||
|
|
|
@ -168,7 +168,9 @@ NETs_regexp = { 'all' : '^138\.231\.1(3[6789]|4[0123456789]|5[01])\.\d+$' }
|
|||
# ci-dessus...
|
||||
rid = {
|
||||
# Rid pour les machines fixes
|
||||
'fil' : (256, 2047),
|
||||
'adherents' : (256, 2047),
|
||||
# Rid pour les machines filaire ipv4
|
||||
'fil' : (0, 2047),
|
||||
# Rid pour les machines wifi
|
||||
'wifi' : (2048, 4095),
|
||||
# Rid pour les machines du vlan adm
|
||||
|
@ -204,7 +206,8 @@ ipv6_machines_speciales = {
|
|||
|
||||
# Les préfixes ipv6
|
||||
prefix = { 'subnet' : [ '2a01:240:fe3d::/48' ],
|
||||
'serveurs' : [ '2a01:240:fe3d:4::/64'],
|
||||
'serveurs' : [ '2a01:240:fe3d:4::/64' ],
|
||||
'adherents' : [ '2a01:240:fe3d:4::/64' ],
|
||||
'fil' : [ '2a01:240:fe3d:4::/64' ],
|
||||
'adm' : [ '2a01:240:fe3d:c804::/64' ],
|
||||
'wifi' : [ '2a01:240:fe3d:c04::/64' ],
|
||||
|
@ -274,9 +277,12 @@ file_pickle = { 4 : '/tmp/ipt_pickle',
|
|||
6 : '/tmp/ip6t_pickle'
|
||||
}
|
||||
|
||||
blacklist_sanctions = ['upload', 'warez', 'p2p', 'autodisc_p2p','autodisc_virus','virus','autodisc_upload', 'bloq']
|
||||
blacklist_sanctions = ['upload', 'warez', 'p2p', 'autodisc_p2p','autodisc_virus','virus', 'bloq']
|
||||
if bl_carte_et_definitif:
|
||||
blacklist_sanctions.append('carte_etudiant')
|
||||
blacklist_sanctions_soft = ['autodisc_virus','ipv6_ra','mail_invalide','virus',
|
||||
'upload', 'warez', 'p2p', 'autodisc_p2p', 'autodisc_upload', 'bloq','carte_etudiant','chambre_invalide']
|
||||
'upload', 'warez', 'p2p', 'autodisc_p2p', 'bloq','carte_etudiant','chambre_invalide']
|
||||
blacklist_bridage_upload = ['autodisc_upload']
|
||||
|
||||
adm_users = [ 'root', 'identd', 'daemon', 'postfix', 'freerad', 'amavis',
|
||||
'nut', 'respbats', 'list', 'sqlgrey', 'ntpd', 'lp' ]
|
||||
|
|
|
@ -4,6 +4,28 @@
|
|||
""" Variables de configuration pour le firewall """
|
||||
|
||||
import datetime
|
||||
#: Interfaces réseaux des machines ayant un pare-feu particulié
|
||||
dev = {
|
||||
'komaz': {
|
||||
'out' : 'ens',
|
||||
'wifi' : 'crans.3',
|
||||
'fil' : 'crans',
|
||||
'app' : 'crans.21',
|
||||
'adm' : 'crans.2',
|
||||
'tun-ovh' : 'tun-ovh'
|
||||
},
|
||||
'zamok': {
|
||||
'fil' : 'crans',
|
||||
'adm' : 'crans.2'
|
||||
},
|
||||
'routeur': {
|
||||
'fil' : 'eth0',
|
||||
'adm' : 'eth1',
|
||||
'accueil' : 'eth2',
|
||||
'isolement' : 'eth3',
|
||||
'app' : 'eth4'
|
||||
},
|
||||
}
|
||||
|
||||
#: Pour marquer les paquets
|
||||
mark = { 'https-radin': '0x3',
|
||||
|
@ -27,4 +49,22 @@ else:
|
|||
#: Débit maximal autorisé
|
||||
debit_max = 500 * 1024 / 8 # connexion de nuit et du week-end
|
||||
#: Est-ce qu'on est en connexion de jour ou de nuit/week-end ?
|
||||
debit_jour = False
|
||||
debit_jour = False
|
||||
|
||||
#: Liste des réseaux non routables
|
||||
reseaux_non_routables = [ '10.0.0.0/8', '172.16.0.0/12','198.18.0.0/15',
|
||||
'169.254.0.0/16', '192.168.0.0/16', '224.0.0.0/4', '100.64.0.0/10',
|
||||
'0.0.0.0/8','127.0.0.0/8','192.0.2.0/24','198.51.100.0/24','203.0.113.0/24',
|
||||
]
|
||||
|
||||
#: Ports ouverts à défaut pour les adhérents dans le pare-feu
|
||||
ports_default = {
|
||||
'tcp' : {
|
||||
'input' : [ '22' ],
|
||||
'output' : [ ':24', '26:79', '80:134', '136', '140:444', '446:']
|
||||
},
|
||||
'udp' : {
|
||||
'input' : [],
|
||||
'output' : [ ':136','140:']
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ logiciels envoyant une très grande quantité de petites données
|
|||
(vidéo-conférence par exemple). Il peut y avoir d'autres raisons.
|
||||
|
||||
|
||||
Si cela continuait, et que tu dépassais la limite acceptable des 4096
|
||||
Mo sur 24 heures, tu serais automatiquement déconnecté du réseau pour
|
||||
Si cela continuait, et que tu dépassais la limite acceptable des 3789
|
||||
Mo sur 24 heures, ton débit serais automatiquement fortement limité pour
|
||||
une durée de 24 heures. Il t'appartient donc de surveiller cela de
|
||||
plus près et de faire en sorte que tes machines n'uploadent pas de
|
||||
manière excessive à l'avenir.
|
||||
|
@ -50,15 +50,13 @@ Content-Type: text/plain; charset="utf-8"
|
|||
|
||||
Bonjour %(proprio)s,
|
||||
|
||||
Tu as temporairement été déconnecté du réseau en raison de l'envoi trop
|
||||
Ton débit à été temporairement limité en raison de l'envoi trop
|
||||
important de données vers l'extérieur (%(upload)s Mo en 24h).
|
||||
|
||||
Tu as toujours accès au web ainsi qu'à tes mails crans mais tous les
|
||||
autres services te sont suspendus. Si cela devait se renouveler trop
|
||||
souvent, tu serais déconnecté complètement pour une durée plus
|
||||
importante. Il t'appartient donc de surveiller cela de plus près et de
|
||||
faire en sorte que ta machine n'uploade plus de manière excessive à
|
||||
l'avenir.
|
||||
Si cela devait se renouveler trop souvent, tu serais déconnecté
|
||||
complètement pour une durée plus importante.
|
||||
Il t'appartient donc de surveiller cela de plus près et de faire en sorte que
|
||||
ta machine n'uploade plus de manière excessive à l'avenir.
|
||||
|
||||
Pour plus d'informations, tu peux consulter la page :
|
||||
http://wiki.crans.org/VieCrans/DéconnexionPourUpload
|
||||
|
@ -85,10 +83,10 @@ Message créé par deconnexion.py"""
|
|||
#: Envoyé à la ML disconnect@ en cas de dépassement de la limite hard
|
||||
message_disconnect_hard = u"""From: %(from)s
|
||||
To: %(to)s
|
||||
Subject: %(proprio)s a =?iso-8859-1?Q?=E9t=E9=20d=E9connect=E9?=
|
||||
Subject: %(proprio)s a =?iso-8859-1?Q?=E9t=E9=20brid=E9?=
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
%(proprio)s a été déconnecté pour upload (%(upload)s Mo).
|
||||
%(proprio)s (aid=%(aid)s) a été limité en débit montant upload (%(upload)s Mo).
|
||||
|
||||
Ses machines ont été aperçues pour la dernière fois à ces endroits :
|
||||
%(mdc)s
|
||||
|
@ -101,14 +99,14 @@ Message créé par deconnexion.py"""
|
|||
#: Envoyé à la ML disconnect@ en cas de dépassement de la limite hard plusieurs fois
|
||||
message_disconnect_multi = u"""From: %(from)s
|
||||
To: %(to)s
|
||||
Subject: %(proprio)s a =?iso-8859-1?Q?=E9t=E9=20d=E9connect=E9?=
|
||||
Subject: %(proprio)s a =?iso-8859-1?Q?=E9t=E9=20brid=E9?=
|
||||
%(nbdeco)d fois pour upload en un mois !
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
L'adhérent %(proprio)s a été déconnecté %(nbdeco)d fois pour upload en un mois !
|
||||
L'adhérent %(proprio)s a été bridé %(nbdeco)d fois pour upload en un mois !
|
||||
|
||||
Le PS a été généré et se trouve sur zamok :
|
||||
%(ps)s
|
||||
|
||||
--\u0020
|
||||
Message créé par deconnexion.py"""
|
||||
Message créé par deconnexion.py"""
|
||||
|
|
|
@ -11,7 +11,7 @@ exempt = [ ['138.231.136.0/21', '138.231.0.0/16'],
|
|||
soft = 300
|
||||
|
||||
#: limite hard
|
||||
hard = 4096
|
||||
hard = 3789
|
||||
|
||||
#: envoyer des mails à disconnect@ en cas de dépassement soft ?
|
||||
disconnect_mail_soft = False
|
||||
|
|
35328
gestion/ethercodes.dat
35328
gestion/ethercodes.dat
File diff suppressed because it is too large
Load diff
|
@ -46,7 +46,7 @@ class del_user:
|
|||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
def delete_daath(self):
|
||||
def delete_zbee(self):
|
||||
cprint(u'Archivage fichiers utilisateur', 'gras')
|
||||
for args in self.args:
|
||||
anim('\t' + args)
|
||||
|
@ -54,7 +54,7 @@ class del_user:
|
|||
login, home = args.split(',')
|
||||
if not login or not home:
|
||||
raise ValueError('Argument invalide')
|
||||
if home.startswith('/home/') and hostname == "daath":
|
||||
if home.startswith('/home/') and hostname == "zbee":
|
||||
home = "/home-adh/" + home[6:]
|
||||
warn = ''
|
||||
f = '%s/files/%s_%s.tar.bz2' % ('/home-adh/cimetiere',
|
||||
|
@ -85,8 +85,8 @@ class del_user:
|
|||
traceback.print_exc()
|
||||
|
||||
def reconfigure(self):
|
||||
if hostname == "daath":
|
||||
self.delete_daath()
|
||||
if hostname == "zbee":
|
||||
self.delete_zbee()
|
||||
elif hostname == "owl":
|
||||
self.delete_directory(u"Suppression des fichiers index de dovecot",
|
||||
"/var/dovecot-indexes/%s")
|
||||
|
@ -110,9 +110,6 @@ class home:
|
|||
except ValueError:
|
||||
home, uid, login = args.split(',')
|
||||
mail_redirect = None
|
||||
# Kludge pour daath (nfs) normalement inutile
|
||||
if home.startswith('/home/') and hostname == "daath":
|
||||
home = "/home-adh/" + home[6:]
|
||||
### Home
|
||||
if not os.path.exists(home):
|
||||
# Le home n'existe pas
|
||||
|
|
1202
gestion/gen_confs/firewall4.py
Executable file
1202
gestion/gen_confs/firewall4.py
Executable file
File diff suppressed because it is too large
Load diff
|
@ -343,16 +343,16 @@ class firewall_crans :
|
|||
if ip.startswith("138.231.1"):
|
||||
if machine.__class__.__name__ == "MachineWifi" and hostname != 'gordon':
|
||||
# Machine Wifi, c'est la mac de gordon
|
||||
rules[self.mac_ip_set].append((ip,mac_wifi))
|
||||
rules[self.mac_ip_set].append("%s,%s" % (ip,mac_wifi))
|
||||
else:
|
||||
# Machine fixe
|
||||
rules[self.mac_ip_set].append((ip,machine.mac()))
|
||||
rules[self.mac_ip_set].append("%s,%s" % (ip,machine.mac()))
|
||||
if machine.__class__.__name__ == "MachineWifi" and hostname == 'komaz':
|
||||
rules[self.mac_ip_set_wifi].append((ip,machine.mac()))
|
||||
rules[self.mac_ip_set_wifi].append("%s,%s" % (ip,machine.mac()))
|
||||
elif machine.__class__.__name__ == "MachineWifi" and hostname != 'komaz':
|
||||
rules[self.mac_ip_set_wifi].append((ip,mac_komaz))
|
||||
rules[self.mac_ip_set_wifi].append("%s,%s" % (ip,mac_komaz))
|
||||
elif ip.startswith("10.231.136."):
|
||||
rules[self.mac_ip_adm_set].append((ip,machine.mac()))
|
||||
rules[self.mac_ip_adm_set].append("%s,%s" % (ip,machine.mac()))
|
||||
def mac_ip_gen(self):
|
||||
self.anim = anim('\tChaîne TEST_MAC-IP', len(self.__machines()))
|
||||
self.anim.reinit()
|
||||
|
@ -485,10 +485,10 @@ class firewall_komaz(firewall_crans) :
|
|||
eth_adm = "crans.2"
|
||||
|
||||
# Ports ouverts
|
||||
ports_default = { 'tcp_EXT_VERS_CRANS' : [ '22' ],
|
||||
'tcp_CRANS_VERS_EXT': [ ':24', '26:79', '80:134', '136', '140:444', '446:'],
|
||||
'udp_EXT_VERS_CRANS' : [ ],
|
||||
'udp_CRANS_VERS_EXT': [ ':136','140:'] }
|
||||
ports_default = { 'tcp_EXT_VERS_CRANS' : config.firewall.ports_default['tcp']['input'],
|
||||
'tcp_CRANS_VERS_EXT': config.firewall.ports_default['tcp']['output'],
|
||||
'udp_EXT_VERS_CRANS' : config.firewall.ports_default['udp']['input'],
|
||||
'udp_CRANS_VERS_EXT': config.firewall.ports_default['udp']['output'] }
|
||||
|
||||
|
||||
# on retire 445 et 135 en tcp car plein de mac se font deconnecter
|
||||
|
@ -512,10 +512,7 @@ class firewall_komaz(firewall_crans) :
|
|||
|
||||
ports_p2p = [ '412', '1214', '4662:4665' , '6346:6347', '6699', '6881:6889' ]
|
||||
|
||||
liste_reseaux_non_routables = [ '10.0.0.0/8', '172.16.0.0/12','198.18.0.0/15',
|
||||
'169.254.0.0/16', '192.168.0.0/16', '224.0.0.0/4', '100.64.0.0/10',
|
||||
'0.0.0.0/8','127.0.0.0/8','192.0.2.0/24','198.51.100.0/24','203.0.113.0/24',
|
||||
'255.255.255.255/32']
|
||||
liste_reseaux_non_routables = config.firewall.reseaux_non_routables
|
||||
|
||||
def reseaux_non_routables(self) :
|
||||
""" Construction de RESEAUX_NON_ROUTABLES_{DST,SRC} """
|
||||
|
@ -1313,7 +1310,7 @@ class firewall_zamok(firewall_crans) :
|
|||
|
||||
# Pour le nfs (le paquet à laisser passer n'a pas d'owner)
|
||||
iptables("-A SERV_OUT_ADM -d fx.adm.crans.org -j ACCEPT")
|
||||
iptables("-A SERV_OUT_ADM -d daath.adm.crans.org -j ACCEPT")
|
||||
iptables("-A SERV_OUT_ADM -d nfs.adm.crans.org -j ACCEPT")
|
||||
|
||||
# Rien d'autre ne passe
|
||||
iptables("-A SERV_OUT_ADM -j REJECT --reject-with icmp-net-prohibited")
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
# Copyright (C) Frédéric Pauget
|
||||
# Licence : GPLv2
|
||||
|
||||
"""Ce script permet de lancer la reconfiguration des divers services
|
||||
|
||||
Usage: %(prog)s options
|
||||
Les options possibles sont :
|
||||
\t%(options)s
|
||||
Les options avec = doivent être suivies d'un argument. Plusieurs
|
||||
arguments peuvent être founis pour une même option, les séparer par &
|
||||
"""
|
||||
#"""Ce script permet de lancer la reconfiguration des divers services
|
||||
#
|
||||
#Usage: %(prog)s options
|
||||
#Les options possibles sont :
|
||||
#\t%(options)s
|
||||
#Les options avec = doivent être suivies d'un argument. Plusieurs
|
||||
#arguments peuvent être founis pour une même option, les séparer par &
|
||||
#"""
|
||||
|
||||
import sys, signal, os, getopt
|
||||
|
||||
|
@ -27,34 +27,30 @@ from syslog import *
|
|||
import platform
|
||||
openlog("generate")
|
||||
|
||||
# On vérifie que l'on est root
|
||||
if os.getuid() != 0:
|
||||
sys.stderr.write("Il faut être root\n")
|
||||
sys.exit(1)
|
||||
|
||||
signal.signal(signal.SIGINT, signal.SIG_IGN) # Pas de Ctrl-C
|
||||
|
||||
db = crans_ldap()
|
||||
make_lock('auto_generate', 'Big lock', nowait=1)
|
||||
|
||||
class base_reconfigure:
|
||||
__firewalled_servers = [ 'redisdead', 'zamok', 'sable', 'komaz', 'gordon', 'routeur' ]
|
||||
__blacklist_servers = [ _s + '-blacklist' for _s in __firewalled_servers ]
|
||||
__service_develop = {
|
||||
'macip': [ 'redisdead-macip', 'zamok-macip', 'sable-macip', 'komaz-macip', 'gordon-macip',
|
||||
'routeur-macip' ],
|
||||
'macip': [ _s + '-macip' for _s in __firewalled_servers ],
|
||||
# 'droits': [ 'rouge-droits', 'ragnarok-droits' ],
|
||||
'bl_carte_etudiant':['komaz-blacklist'],
|
||||
'bl_chbre_invalide':['komaz-blacklist'],
|
||||
'blacklist_mail_invalide':['komaz-blacklist'],
|
||||
'blacklist_virus':['komaz-blacklist'],
|
||||
'blacklist_warez':['komaz-blacklist'],
|
||||
'blacklist_ipv6_ra':['komaz-blacklist'],
|
||||
'blacklist_upload': ['komaz-blacklist', 'zamok-blacklist' ],
|
||||
'blacklist_p2p': ['komaz-blacklist', 'zamok-blacklist' ],
|
||||
'blacklist_autodisc_virus':['komaz-blacklist'],
|
||||
'blacklist_autodisc_upload': ['komaz-blacklist', 'zamok-blacklist'],
|
||||
'blacklist_autodisc_p2p': ['komaz-blacklist', 'zamok-blacklist'],
|
||||
'blacklist_bloq': [ 'komaz-blacklist', 'zamok-blacklist', 'dns' ],
|
||||
'del_user': [ 'daath-del_user', 'owl-del_user', 'zamok-del_user' ]
|
||||
'bl_carte_etudiant': __blacklist_servers,
|
||||
'bl_chbre_invalide': __blacklist_servers,
|
||||
'blacklist_mail_invalide': __blacklist_servers,
|
||||
'blacklist_virus': __blacklist_servers,
|
||||
'blacklist_warez': __blacklist_servers,
|
||||
'blacklist_ipv6_ra': __blacklist_servers,
|
||||
'blacklist_upload': __blacklist_servers,
|
||||
'blacklist_p2p': __blacklist_servers,
|
||||
'blacklist_autodisc_virus': __blacklist_servers,
|
||||
'blacklist_autodisc_upload': __blacklist_servers,
|
||||
'blacklist_autodisc_p2p': __blacklist_servers,
|
||||
'blacklist_bloq': __blacklist_servers,
|
||||
'del_user': [ 'zbee-del_user', 'owl-del_user', 'zamok-del_user' ]
|
||||
}
|
||||
#Y R U Aliasing !
|
||||
__service_develop.update({
|
||||
|
@ -72,6 +68,11 @@ class base_reconfigure:
|
|||
|
||||
def __init__(self, to_do=None):
|
||||
|
||||
# On vérifie que l'on est root
|
||||
if os.getuid() != 0:
|
||||
sys.stderr.write("Il faut être root\n")
|
||||
sys.exit(1)
|
||||
|
||||
if not to_do:
|
||||
if debug:
|
||||
print 'Lecture des services à redémarrer dans la base LDAP...'
|
||||
|
@ -144,14 +145,19 @@ class base_reconfigure:
|
|||
service.machines = machines
|
||||
service.reconfigure()
|
||||
|
||||
def _fw(self):
|
||||
if not hasattr(self, '__real_fw'):
|
||||
from firewall4 import firewall
|
||||
self.__real_fw = firewall()
|
||||
return self.__real_fw
|
||||
|
||||
def macip(self, ips):
|
||||
if platform.dist()[1] >= '6':
|
||||
import firewall_new
|
||||
firewall = firewall_new
|
||||
else:
|
||||
import firewall
|
||||
cprint(u"Mise a jour correspondance MAC-IP", 'gras')
|
||||
eval("firewall.firewall_%s()" % hostname).mac_ip_maj(ips)
|
||||
self._fw().mac_ip_maj(ips)
|
||||
|
||||
def blacklist(self, ips):
|
||||
cprint(u"Mise a jour des blacklists", 'gras')
|
||||
self._fw().blacklist_maj(ips)
|
||||
|
||||
class redisdead(base_reconfigure):
|
||||
def droits(self):
|
||||
|
@ -215,11 +221,7 @@ class zamok(base_reconfigure):
|
|||
from adherents import del_user
|
||||
self._do(del_user(args))
|
||||
|
||||
def blacklist(self):
|
||||
from firewall import firewall_zamok
|
||||
firewall_zamok().blacklist()
|
||||
|
||||
class daath(base_reconfigure):
|
||||
class zbee(base_reconfigure):
|
||||
def home(self, args):
|
||||
from adherents import home
|
||||
self._do(home(args))
|
||||
|
@ -235,11 +237,6 @@ class daath(base_reconfigure):
|
|||
|
||||
|
||||
class komaz(base_reconfigure):
|
||||
def __fw(self):
|
||||
if not hasattr(self, '__real_fw'):
|
||||
from firewall_new import firewall_komaz
|
||||
self.__real_fw = firewall_komaz()
|
||||
return self.__real_fw
|
||||
|
||||
# Mimétisme de ma part -- xhub
|
||||
def __fw6(self):
|
||||
|
@ -251,33 +248,30 @@ class komaz(base_reconfigure):
|
|||
|
||||
def macip(self, ips):
|
||||
cprint(u"Mise a jour correspondance MAC-IP", 'gras')
|
||||
self.__fw().mac_ip_maj(ips)
|
||||
self._fw().mac_ip_maj(ips)
|
||||
self.__fw6().macs([], 6)
|
||||
|
||||
def ports(self, ips):
|
||||
self.__fw().port_maj(ips)
|
||||
self._fw().filtrage_ports_maj(ips)
|
||||
#self.__fw6().ports(map(self.midt.from_ipv4, ips), 6)
|
||||
|
||||
def blacklist(self):
|
||||
self.__fw().blacklist()
|
||||
def blacklist(self, ips):
|
||||
self._fw().blacklist_maj(ips)
|
||||
self.__fw6().blacklist(6)
|
||||
|
||||
def classify(self, ips):
|
||||
self.__fw().classes_p2p_maj(ips)
|
||||
#self.__fw().classes_p2p_maj(ips)
|
||||
pass
|
||||
|
||||
class dyson(base_reconfigure):
|
||||
def autostatus(self):
|
||||
from autostatus import autostatus
|
||||
self._do(autostatus())
|
||||
|
||||
def dhcp(self):
|
||||
from gen_confs.dhcpd_new import dhcp
|
||||
self._do(dhcp(), self._machines())
|
||||
|
||||
class dhcp(base_reconfigure):
|
||||
def dhcp(self):
|
||||
from gen_confs.dhcpd_new import dhcp
|
||||
self._do(dhcp(), self._machines())
|
||||
self._do(dhcp(), db.search("mid=*")['machine'])
|
||||
|
||||
class sable(base_reconfigure):
|
||||
|
||||
|
@ -285,10 +279,6 @@ class sable(base_reconfigure):
|
|||
from gen_confs.bind import dns
|
||||
self._do(dns(), self._machines())
|
||||
|
||||
def macip(self, ips):
|
||||
from firewall_new import firewall_sable
|
||||
firewall_sable().mac_ip_maj(ips)
|
||||
|
||||
class ovh(base_reconfigure):
|
||||
pass
|
||||
|
||||
|
|
|
@ -17,13 +17,12 @@
|
|||
|
||||
import sys
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
sys.path.append('/usr/scripts/lc_ldap')
|
||||
|
||||
import commands
|
||||
import lock
|
||||
import os
|
||||
|
||||
|
||||
import lc_ldap
|
||||
import secrets
|
||||
|
||||
class IpsetError(Exception):
|
||||
# Gestion des erreurs d'ipset
|
||||
|
@ -36,10 +35,23 @@ class IpsetError(Exception):
|
|||
|
||||
class Ipset(object):
|
||||
ipset="/usr/sbin/ipset"
|
||||
|
||||
def __str__(self):
|
||||
return self.set
|
||||
|
||||
def __init__(self,set,type,typeopt=''):
|
||||
self.set=set
|
||||
self.type=type
|
||||
self.typeopt=typeopt
|
||||
self.squeeze = os.uname()[2] < '3'
|
||||
try:
|
||||
self.create()
|
||||
except IpsetError as error:
|
||||
if error.err_code != 256:
|
||||
raise
|
||||
elif not "already exists" in error.output:
|
||||
raise
|
||||
pass
|
||||
|
||||
def call(self,cmd,arg=''):
|
||||
"""Appel système à ipset"""
|
||||
|
@ -71,15 +83,19 @@ class Ipset(object):
|
|||
def restore(self,rules):
|
||||
""" restore le set courrant"""
|
||||
rules_str=self.restore_format(rules)
|
||||
create_str="-N %s %s %s" % (self.set,self.type,self.typeopt)
|
||||
str="%s\n%s\nCOMMIT\n" % (create_str,rules_str)
|
||||
if self.squeeze:
|
||||
create_str="-N %s %s %s" % (self.set,self.type,self.typeopt)
|
||||
str="%s\n%s\nCOMMIT\n" % (create_str,rules_str)
|
||||
else:
|
||||
str="%s\nCOMMIT\n" % rules_str
|
||||
path='/tmp/ipset_%s' % self.set
|
||||
f=open(path, 'w+')
|
||||
f.write(str)
|
||||
f.close()
|
||||
try:
|
||||
self.flush()
|
||||
self.destroy()
|
||||
if self.squeeze:
|
||||
self.destroy()
|
||||
except IpsetError: pass
|
||||
cmd="cat %s | %s -R" % (path,self.ipset)
|
||||
status,output=commands.getstatusoutput(cmd)
|
||||
|
@ -94,5 +110,5 @@ class Ipset(object):
|
|||
self.call("-X")
|
||||
|
||||
def restore_format(self,rules):
|
||||
return '\n'.join(["-A %s %s,%s" % (self.set,ip,mac) for (ip,mac) in rules])
|
||||
return '\n'.join(["-A %s %s" % (self.set,data) for data in rules])
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" met à jour les propriétés des prises des switchs du bat :
|
||||
mac autorisée(s), état (activé ou non) et nom de la prise
|
||||
""" met à jour les propriétés des prises des switchs du bat :
|
||||
mac autorisée(s), état (activé ou non) et nom de la prise
|
||||
argument : nom du switch
|
||||
|
||||
procédure de configuration initiale :
|
||||
procédure de configuration initiale :
|
||||
* mot de passe admin (password manager user-name <username>)
|
||||
* activation du ssh (crypto key generate ssh)
|
||||
* copie fichier de conf
|
||||
|
@ -23,9 +23,10 @@ from ldap_crans import crans_ldap, BorneWifi
|
|||
from annuaires_pg import uplink_prises, reverse, bat_manuels, all_switchs, bat_switchs
|
||||
from random import shuffle
|
||||
from gen_confs import *
|
||||
from time import localtime
|
||||
import datetime
|
||||
import config
|
||||
import re
|
||||
from crans.deprecated import deprecated
|
||||
|
||||
capture_model = re.compile(r'\((.*)\)')
|
||||
headers_by_model = {
|
||||
|
@ -38,27 +39,20 @@ headers_by_model = {
|
|||
|
||||
gigabit_models = ['J9021A', 'J9145A']
|
||||
|
||||
try:
|
||||
any
|
||||
except NameError:
|
||||
def any(iterable):
|
||||
for item in iterable:
|
||||
if item:
|
||||
return True
|
||||
return False
|
||||
|
||||
class switch(gen_config) :
|
||||
# Répertoire ou écire les fichiers de conf
|
||||
CONF_REP='/tmp/' # avec un / derrière
|
||||
"""Classe de configuration d'un switch"""
|
||||
# Répertoire ou écire les fichiers de conf
|
||||
CONF_REP='/tmp/' # avec un / derrière
|
||||
|
||||
config = """%(switch_config_header)s
|
||||
|
||||
hostname "%(switch)s"
|
||||
; Generated %(date_gen)s by switchs.py
|
||||
%(module-type)s
|
||||
;-------------------------------------------------------- Snmp
|
||||
snmp-server contact "root@crans.org"
|
||||
snmp-server location "Batiment %(bat)s"
|
||||
;A faire à la main
|
||||
;A faire à la main
|
||||
snmpv3 enable
|
||||
snmpv3 restricted-access
|
||||
;snmpv3 user "initial"
|
||||
|
@ -121,7 +115,7 @@ vlan %(vlan_appts)s
|
|||
exit
|
||||
;-------------------------------------------------------- Logs
|
||||
%(INTERFACES_CONF)s
|
||||
;------------------------------------------------------- Accès d'administration
|
||||
;------------------------------------------------------- Accès d'administration
|
||||
no telnet-server
|
||||
no web-management
|
||||
aaa authentication ssh login public-key none
|
||||
|
@ -144,7 +138,7 @@ no cdp run
|
|||
no stack
|
||||
"""
|
||||
|
||||
# Serveur DHCP des différent vlans
|
||||
# Serveur DHCP des différent vlans
|
||||
dhcp_servers = {
|
||||
'1':'138.231.136.34',
|
||||
'3':'138.231.148.34',
|
||||
|
@ -187,7 +181,7 @@ exit
|
|||
* un _tulpe_ de noms de switch => reconfig de ces swiths"""
|
||||
self.db = crans_ldap() # connexion LDAP
|
||||
if type(truc) == list :
|
||||
# On enlève les chambres "CRA", "????" et EXT qui n'ont pas besion de config
|
||||
# On enlève les chambres "CRA", "????" et EXT qui n'ont pas besion de config
|
||||
self.chbres = [ch for ch in truc if (ch not in [ "CRA", "????", "EXT" ]) ]
|
||||
self.switch = None
|
||||
else :
|
||||
|
@ -199,10 +193,10 @@ exit
|
|||
|
||||
def restart(self) :
|
||||
if self.chbre :
|
||||
# Tout est déja fait
|
||||
# Tout est déja fait
|
||||
return
|
||||
####### Vu qu'il n'y a pas de serveur tftp ici
|
||||
# on excécute pas le truc en dessous
|
||||
# on excécute pas le truc en dessous
|
||||
#for switch in self.switch :
|
||||
# self.aff = anim('\treboot de %s' % switch)
|
||||
# sw = hptools.switch(switch)
|
||||
|
@ -217,61 +211,11 @@ exit
|
|||
for switch in self.switch :
|
||||
self.configure_switch(switch)
|
||||
|
||||
@deprecated("Tous les switchs possèdent une authentification radius.")
|
||||
def configure_chbre(self,chbre) :
|
||||
""" Recontigure la chambre fournie chambre """
|
||||
try :
|
||||
bat = chbre[0].lower()
|
||||
if bat in bat_switchs :
|
||||
prise = sw_chbre(chbre)
|
||||
prise.reconfigure() # Vitesse et nom (juste au cas ou ca aurait changé)
|
||||
elif bat in bat_manuels :
|
||||
class prise_non_manageable :
|
||||
def __init__(self,chbre) :
|
||||
self.chbre = chbre
|
||||
|
||||
def __mail(self,sujet) :
|
||||
To = "clef%s@crans.org" % self.chbre[0].lower()
|
||||
From = To
|
||||
conn=smtplib.SMTP('localhost')
|
||||
txt_mail = "From: Crans scripts <%(From)s>\n"
|
||||
txt_mail+= "To: %(To)s\n"
|
||||
txt_mail+= "Subject: (CRANS) %s\n\nMerci." % sujet
|
||||
conn.sendmail(From, To , txt_mail % { 'From' : From, 'To' : To })
|
||||
conn.quit()
|
||||
|
||||
def disable(self) :
|
||||
self.__mail("Chambre %s à débrancher." % self.chbre)
|
||||
def enable(self) :
|
||||
self.__mail("Chambre %s à brancher." % self.chbre)
|
||||
|
||||
prise=prise_non_manageable(chbre)
|
||||
|
||||
else :
|
||||
# Rien a faire
|
||||
print OK
|
||||
return True
|
||||
|
||||
|
||||
a = self.db.search('chbre=%s&paiement=ok' % chbre)
|
||||
a = a['adherent'] + a['club']
|
||||
if a and 'bloq' not in a[0].blacklist_actif() :
|
||||
# Il faut activer la prise
|
||||
anim('\tactivation chbre %s' % chbre)
|
||||
prise.enable()
|
||||
else :
|
||||
# Il faut désactiver la prise
|
||||
anim('\tdésactivation chbre %s' % chbre)
|
||||
prise.disable()
|
||||
|
||||
print OK
|
||||
except :
|
||||
print ERREUR
|
||||
if self.debug :
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
return True
|
||||
""" Recontigure la chambre fournie chambre.
|
||||
Déprécié. Tous les switchs possèdent une authentification radius."""
|
||||
return False
|
||||
|
||||
def configure_switch(self,switch) :
|
||||
self.aff = anim('\tconfiguration de %s' % switch)
|
||||
|
@ -291,9 +235,9 @@ exit
|
|||
return 1
|
||||
|
||||
def __configure_switch(self,switch) :
|
||||
""" Génère le fichier de conf du switch donné """
|
||||
### Récupération données du switch
|
||||
# Batiment et numéro du switch
|
||||
""" Génère le fichier de conf du switch donné """
|
||||
### Récupération données du switch
|
||||
# Batiment et numéro du switch
|
||||
bat = switch[3].lower()
|
||||
sw_num = int(switch[5])
|
||||
dhcp_servers = self.dhcp_servers
|
||||
|
@ -303,12 +247,13 @@ exit
|
|||
|
||||
self.aff.cycle()
|
||||
|
||||
## On veut par défaut tout confier au serveur radius principal
|
||||
## On veut par défaut tout confier au serveur radius principal
|
||||
#shuffle(self.rad_servs)
|
||||
rad = self.rad_template * len(self.rad_servs)
|
||||
|
||||
|
||||
params = { 'switch' : switch, 'bat' : bat.upper() ,
|
||||
'date_gen': str(datetime.datetime.now()),
|
||||
'radius_key' : radius_key ,
|
||||
'radius-serveurs' : rad[:-1] % tuple(self.rad_servs),
|
||||
}
|
||||
|
@ -328,7 +273,7 @@ exit
|
|||
res, msg = commands.getstatusoutput("scp bat%s-%i:cfg/startup-config %s" % (bat, sw_num, old_config.name))
|
||||
|
||||
if res != 0:
|
||||
raise RuntimeError(u"Erreur : impossible de récupérer l'ancienne configuration du switch")
|
||||
raise RuntimeError(u"Erreur : impossible de récupérer l'ancienne configuration du switch")
|
||||
|
||||
params['switch_config_header'] = old_config.readline()
|
||||
old_config.close()
|
||||
|
@ -346,7 +291,7 @@ exit
|
|||
sys.stderr.write(model)
|
||||
params['switch_config_header']=headers_by_model[model]
|
||||
except:
|
||||
sys.stderr.write('Impossible de déterminer le header à utiliser (switch %s)' % switch)
|
||||
sys.stderr.write('Impossible de déterminer le header à utiliser (switch %s)' % switch)
|
||||
params['switch_config_header']= '; J4899A Configuration Editor; Created on release #H.10.50'
|
||||
|
||||
model = params['switch_config_header'].split(' ', 2)[1]
|
||||
|
@ -357,10 +302,10 @@ exit
|
|||
|
||||
self.aff.cycle()
|
||||
|
||||
# Nombre de prises et modèle
|
||||
# Nombre de prises et modèle
|
||||
nb_prises = machine.nombrePrises()
|
||||
if nb_prises < 0 :
|
||||
raise RuntimeError("Erreur : impossible de déterminer les caractéristiques du switch.")
|
||||
raise RuntimeError("Erreur : impossible de déterminer les caractéristiques du switch.")
|
||||
|
||||
has_dhcp_snooping = "2810" not in " ".join(machine.info())
|
||||
|
||||
|
@ -370,7 +315,7 @@ exit
|
|||
# Dictionnaire prise -> chambre
|
||||
prise_chbres = reverse(bat)
|
||||
|
||||
# Prises occupées par des machines du Cr@ns
|
||||
# Prises occupées par des machines du Cr@ns
|
||||
crans_prises={}
|
||||
for m in self.db.search('prise=%s%i*' % (bat.upper(), sw_num))['machine'] :
|
||||
try: crans_prises[m.prise()].append(m)
|
||||
|
@ -378,7 +323,7 @@ exit
|
|||
|
||||
self.aff.iter = nb_prises+1
|
||||
|
||||
# Paramètres à affecter
|
||||
# Paramètres à affecter
|
||||
for key in ( 'uplinks', 'non_uplinks' ) :
|
||||
params[key] = []
|
||||
|
||||
|
@ -387,21 +332,21 @@ exit
|
|||
'adm_tagged' : [] , 'adm_untagged' : [] ,
|
||||
'appts_tagged' : [], 'appts_untagged' : [],
|
||||
|
||||
# VLans pour le reste: le vlan des adhérents, des
|
||||
# VLans pour le reste: le vlan des adhérents, des
|
||||
# inconnus et de ceux qui ne paie pas
|
||||
'default' : [] }
|
||||
|
||||
personnels_loges = self.db.search('etudes=Personnel ENS')['adherent']
|
||||
prises_appartements= [ p.chbre() for p in personnels_loges ]
|
||||
|
||||
# Génération de la conf de chaque prise
|
||||
# Génération de la conf de chaque prise
|
||||
for prise in range(1,nb_prises+1):
|
||||
self.aff.cycle()
|
||||
|
||||
# Conf par défaut : activée, autonégociation
|
||||
# Conf par défaut : activée, autonégociation
|
||||
prise_params = { 'prise' : prise , 'speed' : '',
|
||||
'etat' : '', 'no_flowcontrol': '' }
|
||||
annu_prise = '%i%02i' % (sw_num, prise) # prise telle que notée dans l'annuaire
|
||||
annu_prise = '%i%02i' % (sw_num, prise) # prise telle que notée dans l'annuaire
|
||||
|
||||
if uplink_prises[bat].has_key(int(annu_prise)) :
|
||||
### Prise d'uplink
|
||||
|
@ -419,7 +364,7 @@ exit
|
|||
params['non_uplinks'].append(prise)
|
||||
|
||||
if crans_prises.has_key("%s%s" % (bat.upper(), annu_prise)) :
|
||||
### Prise réservée à l'association
|
||||
### Prise réservée à l'association
|
||||
wifi=0
|
||||
adm=0
|
||||
autres=0
|
||||
|
@ -466,7 +411,7 @@ exit
|
|||
# chambres.
|
||||
chbres = prise_chbres.get(annu_prise, [])
|
||||
|
||||
# Pour les switchs gigabit, on bloque le gigabit par défaut, sauf
|
||||
# Pour les switchs gigabit, on bloque le gigabit par défaut, sauf
|
||||
# pour les membres actifs et les clubs (cf plus bas)
|
||||
if model in gigabit_models:
|
||||
prise_params['speed'] = 'speed-duplex auto-10-100'
|
||||
|
@ -478,7 +423,7 @@ exit
|
|||
# On selectionne les eventuels adherents y residant
|
||||
residents = self.db.search("chbre=%s%s" % (bat, chb))
|
||||
for adherent in residents['adherent']:
|
||||
if adherent.droits(): #Seuls les membres actifs ont le droit à plus
|
||||
if adherent.droits(): #Seuls les membres actifs ont le droit à plus
|
||||
prise_params['speed'] = ''
|
||||
# On selectionne les machines fixes de l'adherent, et on ajoute le nombre au quota
|
||||
nombre_de_machines += len(adherent.machines_fixes())
|
||||
|
@ -487,9 +432,9 @@ exit
|
|||
|
||||
# Authentification RADIUS, pas pour les clubs...
|
||||
if not any("cl" in chbre.lower() for chbre in chbres):
|
||||
# "unauth-vid" est le vlan sur lequel sont envoyés les machines
|
||||
# quand l'authentification RADIUS échoue. On met le VLAN 1 pour
|
||||
# éviter les problèmes quand LDAP se ch@#! dessus.
|
||||
# "unauth-vid" est le vlan sur lequel sont envoyés les machines
|
||||
# quand l'authentification RADIUS échoue. On met le VLAN 1 pour
|
||||
# éviter les problèmes quand LDAP se ch@#! dessus.
|
||||
params['INTERFACES_CONF'] += """aaa port-access mac-based %(prise)s
|
||||
aaa port-access mac-based %(prise)s addr-limit %(nbmac)s
|
||||
aaa port-access mac-based %(prise)s logoff-period 3600
|
||||
|
@ -497,11 +442,11 @@ aaa port-access mac-based %(prise)s unauth-vid 1
|
|||
""" % { 'nbmac': 2 + nombre_de_machines, 'prise': prise }
|
||||
# On regle le nombre de machines connectables a la prise au nombre de machines
|
||||
# sur cette prise dans l'annuaire plus 2
|
||||
else: # ... et pour les clubs, vlans par défaut
|
||||
else: # ... et pour les clubs, vlans par défaut
|
||||
vlans['default'].append(prise)
|
||||
|
||||
# On donne à la prise un nom qui dépend des chambres
|
||||
# connectés dessus
|
||||
# On donne à la prise un nom qui dépend des chambres
|
||||
# connectés dessus
|
||||
if chbres :
|
||||
prise_params['nom'] = 'Chambre'
|
||||
if len(chbres) > 1 : prise_params['nom'] += 's'
|
||||
|
@ -522,7 +467,7 @@ aaa port-access mac-based %(prise)s unauth-vid 1
|
|||
|
||||
# Petite verif
|
||||
if not params['uplinks'] or not params['non_uplinks'] :
|
||||
raise RuntimeError('Switch sans uplink ou sans prise adhérent.')
|
||||
raise RuntimeError('Switch sans uplink ou sans prise adhérent.')
|
||||
|
||||
def mk_list(liste_prise) :
|
||||
"""
|
||||
|
@ -544,12 +489,12 @@ aaa port-access mac-based %(prise)s unauth-vid 1
|
|||
if nouveau == groupe[1] + 1 :
|
||||
groupe[1] += 1
|
||||
else :
|
||||
# Ajout du groupe au résultat
|
||||
# Ajout du groupe au résultat
|
||||
if groupe[0] == groupe[1] :
|
||||
result.append(str(groupe[0]))
|
||||
else :
|
||||
result.append('-'.join(map(str,groupe)))
|
||||
# Réinit de groupe
|
||||
# Réinit de groupe
|
||||
groupe = [ nouveau, nouveau ]
|
||||
|
||||
return ','.join(result)
|
||||
|
@ -563,7 +508,7 @@ aaa port-access mac-based %(prise)s unauth-vid 1
|
|||
for key, prises in vlans.items() :
|
||||
vlans[key]=mk_list(prises)
|
||||
|
||||
# Config des vlans spéciaux (adm, wifi et appartements)
|
||||
# Config des vlans spéciaux (adm, wifi et appartements)
|
||||
for v in ('adm', 'wifi', 'hotspot', 'appts') :
|
||||
params['prises_%s' % v] = ''
|
||||
for t in ('tagged' , 'untagged') :
|
||||
|
@ -590,7 +535,7 @@ if __name__ == '__main__' :
|
|||
opts, args = getopt.getopt(sys.argv[1:], 'hga', ['get-conf', 'help', 'all', 'header=' ])
|
||||
if '-h' in sys.argv or '--help' in sys.argv or len(sys.argv) == 1 :
|
||||
print "%s [-g|--get-conf] <switch>" % sys.argv[0].split('/')[-1].split('.')[0]
|
||||
print "Génération du fichier de configuration des switchs donnés."
|
||||
print "Génération du fichier de configuration des switchs donnés."
|
||||
sys.exit(255)
|
||||
|
||||
if args[0] == 'all' or 'a' in opts or '--all' in opts :
|
||||
|
|
|
@ -25,13 +25,14 @@ import os, re, syslog, cPickle, socket
|
|||
from ldap_crans import crans_ldap, hostname
|
||||
from commands import getstatusoutput
|
||||
from config import NETs, role, prefix, rid, output_file, filter_policy
|
||||
from config import blacklist_sanctions, blacklist_sanctions_soft, file_pickle, ann_scol, periode_transitoire
|
||||
from config import blacklist_sanctions, blacklist_sanctions_soft, blacklist_bridage_upload, file_pickle, ann_scol, periode_transitoire
|
||||
from iptools import AddrInNet
|
||||
from ridtools import Rid
|
||||
import subprocess
|
||||
import netaddr
|
||||
|
||||
blacklist_sanctions.extend(blacklist_sanctions_soft)
|
||||
blacklist_sanctions.extend(blacklist_bridage_upload)
|
||||
|
||||
Mangle_policy = """
|
||||
*mangle
|
||||
|
|
|
@ -119,6 +119,25 @@ def AddrInNets(ip,nets) :
|
|||
return net
|
||||
return ''
|
||||
|
||||
def NetInNet(net1, net2) :
|
||||
"""
|
||||
net1 est de la forme xxx.xxx.xxx.xxx/yy
|
||||
net2 est de la forme xxx.xxx.xxx.xxx/yy
|
||||
Retourne True si net1 est un sous-réseaux de net2
|
||||
"""
|
||||
n1 = param(net1, raw=True)
|
||||
n2 = param(net2, raw=True)
|
||||
s1 = net1.split('/')[1]
|
||||
s2 = net1.split('/')[1]
|
||||
return s1<=s2 and (n1['network'] == n2['network'] or AddrInNet(DecToQuad(n1['network']), net2))
|
||||
|
||||
def NetInNets(net1, nets):
|
||||
""" Vérifie si le premier paramètre est un sous-réseau des réseaux de la liste du second paramètre"""
|
||||
for net in nets:
|
||||
if NetInNet(net1, net) :
|
||||
return net
|
||||
return ''
|
||||
|
||||
def is_crans(ip):
|
||||
""" Vérifie que l'ip est dans le réseau CRANS
|
||||
"""
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
'''Bibliothèque pour accéder à la baie de stockage nols, récupère les données
|
||||
formatées en XML'''
|
||||
|
||||
import telnetlib, re
|
||||
import telnetlib
|
||||
import re
|
||||
from xml.etree.ElementTree import ElementTree, fromstring
|
||||
|
||||
# Message envoyé par le serveur pour attendre l'appuie sur touche
|
||||
|
@ -24,6 +25,11 @@ password = ""
|
|||
# Récupère des identifiants
|
||||
execfile("/etc/crans/secrets/nols.py")
|
||||
|
||||
class NolsError(Exception):
|
||||
def __init__(self, msg):
|
||||
Exception.__init__(self, msg)
|
||||
|
||||
|
||||
class Nols(object):
|
||||
'''Objet représentant la baie de stockage'''
|
||||
|
||||
|
@ -83,6 +89,9 @@ class Nols(object):
|
|||
|
||||
# Remplace les fins de ligne dos par des fin de lignes unix
|
||||
resp = crlf_regexp.sub("\n", resp)
|
||||
if resp.lower().startswith("error"):
|
||||
raise NolsError(resp.replace("Error: ", ""))
|
||||
|
||||
return resp
|
||||
|
||||
def show(self, what):
|
||||
|
@ -152,7 +161,7 @@ class Nols(object):
|
|||
while lun in map: lun = lun + 1
|
||||
|
||||
# Création du volume
|
||||
self.cmd("create volume vdisk %s size %d%s lun %d %s" % (vdisk, size, unit, lun, name))
|
||||
result = self.cmd("create volume vdisk %s size %d%s lun %d %s" % (vdisk, size, unit, lun, name))
|
||||
|
||||
print "Le volume %s a été créé, son numéro d'identification est %d" %(name, lun)
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ Copyright (C) Alexandre Bos, largement pompe sur ldap_crans.py
|
|||
Licence : GPLv2
|
||||
"""
|
||||
|
||||
|
||||
import sys
|
||||
from config import NETs
|
||||
from iptools import AddrInNet
|
||||
try:
|
||||
|
@ -79,13 +79,20 @@ def update_ip_wifi_adh(occupees):
|
|||
update_ip('wifi-adh','ip_wifi-adh', occupees)
|
||||
|
||||
if __name__ == "__main__":
|
||||
dlg = Dialog()
|
||||
dlg.gauge_start(text="Recherche des machines...", backtitle="numeros_disponibles")
|
||||
if "--cron" in sys.argv:
|
||||
cron = True
|
||||
else:
|
||||
cron = False
|
||||
if not cron:
|
||||
dlg = Dialog()
|
||||
dlg.gauge_start(text="Recherche des machines...", backtitle="numeros_disponibles")
|
||||
ip_occupees = lister_ip_utilisees()
|
||||
done = 1
|
||||
for net in NETs.keys():
|
||||
dlg.gauge_update(int(done*100/(len(NETs)+1)), text="IP libres dans %s" % net, update_text=True)
|
||||
if not cron:
|
||||
dlg.gauge_update(int(done*100/(len(NETs)+1)), text="IP libres dans %s" % net, update_text=True)
|
||||
update_ip(net, ip_occupees)
|
||||
done += 1
|
||||
dlg.gauge_update(100, text="Fini !", update_text=True)
|
||||
dlg.gauge_stop()
|
||||
if not cron:
|
||||
dlg.gauge_update(100, text="Fini !", update_text=True)
|
||||
dlg.gauge_stop()
|
||||
|
|
|
@ -445,23 +445,23 @@ def ressuscite_adherent(old):
|
|||
title=u"Compte existant")
|
||||
if no:
|
||||
return
|
||||
if True:
|
||||
# On croise les doigts
|
||||
try:
|
||||
modlist = ldap.modlist.addModlist(data)
|
||||
db.conn.add_s(dn, modlist)
|
||||
dlg.msgbox(text=u"Résurrection effectée ! Veuillez maintenant restaurer le home et les mails",
|
||||
title=u"Fin")
|
||||
# Au cas où l'adhérent avait des droits
|
||||
db.services_to_restart('droits')
|
||||
# On notifie après une résurrection
|
||||
db.services_to_restart('mail_modif', ['uid=' + login])
|
||||
except Exception, e:
|
||||
dlg.msgbox(text=unicode(e), title=u"Erreur")
|
||||
if True:
|
||||
# On croise les doigts
|
||||
try:
|
||||
modlist = ldap.modlist.addModlist(data)
|
||||
db.conn.add_s(dn, modlist)
|
||||
dlg.msgbox(text=u"Résurrection effectée ! Veuillez maintenant restaurer le home et les mails",
|
||||
title=u"Fin")
|
||||
# Au cas où l'adhérent avait des droits
|
||||
db.services_to_restart('droits')
|
||||
# On notifie après une résurrection
|
||||
db.services_to_restart('mail_modif', ['uid=' + login])
|
||||
except Exception, e:
|
||||
dlg.msgbox(text=unicode(e), title=u"Erreur")
|
||||
|
||||
else:
|
||||
print data
|
||||
raise ValueError("debug")
|
||||
else:
|
||||
print data
|
||||
raise ValueError("debug")
|
||||
|
||||
def ressuscite_club(old):
|
||||
"""Ressuscite une instance d'un club"""
|
||||
|
|
0
impression/__init__.py
Normal file
0
impression/__init__.py
Normal file
|
@ -1,9 +1,14 @@
|
|||
#!/usr/bin/python
|
||||
# -*- encoding: utf-8 -*-
|
||||
# canon_wrapper.py
|
||||
# Authors: Daniel STAN <dstan@crans.org>
|
||||
# Antoine Durand-Gasselin <adg@crans.org>
|
||||
# License: GPLv3
|
||||
#canon_wrapper.py
|
||||
"""
|
||||
.. codeauthor:: Daniel STAN <dstan@crans.org>
|
||||
.. codeauthor:: Antoine Durand-Gasselin <adg@crans.org>
|
||||
|
||||
Pour envoyer des jobs d'impression à l'imprimante canon via son interface web.
|
||||
|
||||
License: GPLv3
|
||||
"""
|
||||
|
||||
import requests #pip install requests
|
||||
# See:
|
||||
|
@ -106,6 +111,7 @@ def build_url(name):
|
|||
|
||||
|
||||
def range_checker(a, b):
|
||||
"""Type function for a given range"""
|
||||
def cast(x):
|
||||
try:
|
||||
v = int(x)
|
||||
|
@ -117,6 +123,7 @@ def range_checker(a, b):
|
|||
return cast
|
||||
|
||||
def build_parser():
|
||||
"""Make argparse object"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="HTTP printing driver for irc3580, with compatibility mode.",
|
||||
epilog="logs are sent to syslog (eg /var/log/canon_wrapper.log)",
|
||||
|
@ -159,6 +166,7 @@ def build_parser():
|
|||
return parser
|
||||
|
||||
def do_print(args):
|
||||
"""Effectively compatibilize then print the file"""
|
||||
opt=build_options(args)
|
||||
syslog('Options: %s' % repr(opt))
|
||||
#syslog('Starting ghostscript compat, piped mode')
|
||||
|
@ -205,3 +213,7 @@ if __name__ == '__main__':
|
|||
syslog('Caught exception %s' % repr(e))
|
||||
raise
|
||||
|
||||
else:
|
||||
parser = build_parser()
|
||||
__doc__ += '''\nHelp message : ::\n\n'''
|
||||
__doc__ += '\n'.join(' ' + l for l in parser.format_help().split('\n')) + "\n"
|
||||
|
|
|
@ -202,7 +202,7 @@ class impression:
|
|||
# on compte les pages et on regarde le format
|
||||
pdfinfo = Popen(["pdfinfo",self._fichier],stdout=PIPE,stderr=PIPE).communicate()
|
||||
if pdfinfo[1] <> '':
|
||||
raise FichierInvalide(u"pdfinfo n'arrive pas a lire le fichier (il est peut-etre corrompu ou protege par un mot de passe)",path_to_pdf)
|
||||
raise FichierInvalide(u"pdfinfo n'arrive pas a lire le fichier (il est peut-etre corrompu ou protege par un mot de passe), https://wiki.crans.org/VieCrans/ImpressionReseau#Format_des_fichiers",path_to_pdf)
|
||||
self._pages = -1
|
||||
for line in pdfinfo[0].split('\n'):
|
||||
if line.startswith('Pages'):
|
||||
|
@ -378,6 +378,8 @@ class impression:
|
|||
"""
|
||||
self._jid = _uniq_jid()
|
||||
|
||||
# imprime le document
|
||||
self._exec_imprime()
|
||||
# debite l'adhérent si adherent il y a
|
||||
if (self._adh != None):
|
||||
adh = self._adh.split('@')
|
||||
|
@ -389,9 +391,6 @@ class impression:
|
|||
adh.solde(-self._prix, "impression(%d): %s par %s" % (self._jid,self._fichier,self._adh))
|
||||
adh.save()
|
||||
del adh
|
||||
# imprime le document
|
||||
self._exec_imprime()
|
||||
|
||||
|
||||
def _calcule_prix(self):
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import smtplib
|
|||
from ldap_crans import crans_ldap
|
||||
|
||||
last_print_filename = "/var/run/print_status/last_print.txt"
|
||||
error_filename = "/var/run/print_status/error.txt"
|
||||
# Cette chaîne est utilisée pour construire une regexp, il faut que ce soit une chaîne brute.
|
||||
files_directory = r"/var/impression/fichiers/"
|
||||
printer_host = "imprimante.adm.crans.org"
|
||||
|
@ -102,11 +103,25 @@ def sendMail(from_addr, to_addrs, mail_content):
|
|||
http = httplib2.Http()
|
||||
|
||||
# On récupère la liste des tâches. Pour faire la requête, on doit récupérer un cookie de session.
|
||||
headers, _ = http.request("http://" + printer_host + "/twelcome.cgi?CorePGTAG=0&Dummy=" + getMSE())
|
||||
_, content = http.request("http://" + printer_host + "/pprint.csv?Flag=Csv_Data&LogType=0&Dummy=" + getMSE(), 'GET', headers={'Cookie': headers['set-cookie']})
|
||||
try:
|
||||
headers, _ = http.request("http://" + printer_host + "/twelcome.cgi?CorePGTAG=0&Dummy=" + getMSE())
|
||||
_, content = http.request("http://" + printer_host + "/pprint.csv?Flag=Csv_Data&LogType=0&Dummy=" + getMSE(), 'GET', headers={'Cookie': headers['set-cookie']})
|
||||
except:
|
||||
# En cas d’erreur sur l’imprimante, plutôt que de spamer sur roots@crans.org, on note l’échec quelque part à l’attention d’un service de monitoring.
|
||||
error_file = open(error_filename, "w+")
|
||||
error_file.write("L’imprimante semble injoignable.")
|
||||
error_file.close()
|
||||
exit(0)
|
||||
|
||||
task_list = content.split('\n')
|
||||
# On enlève les entêtes et les deux lignes vides à la fin de la liste.
|
||||
task_list.pop(0)
|
||||
# On vérifie que ce qu’on a récupéré ressemble à du CSV. Si tout se passe bien, l’imprimante envoie 13 champs par tâche.
|
||||
# On fait le test sur les entêtes, ce qui permet de s’en débarasser au passage.
|
||||
if len(task_list.pop(0).split(',')) != 13:
|
||||
error_file = open(error_filename, "w+")
|
||||
error_file.write("La liste des tâches renvoyée par l’imprimante n’a pas le format attendu.")
|
||||
error_file.close()
|
||||
exit(0)
|
||||
# On enlève aussi les deux lignes vides à la fin de la liste.
|
||||
task_list.pop()
|
||||
task_list.pop()
|
||||
|
||||
|
@ -137,7 +152,7 @@ tasks_to_treat.reverse()
|
|||
for item in tasks_to_treat:
|
||||
fields = item.split(',', 6)
|
||||
# On met à jour le numéro de la dernière tâche traitée.
|
||||
last_file = open(last_print_filename, "w")
|
||||
last_file = open(last_print_filename, "w+")
|
||||
last_file.write(fields[0])
|
||||
last_file.close()
|
||||
if fields[3].strip('"') in ["root",'DIRECT PRINT']:
|
||||
|
@ -146,7 +161,7 @@ for item in tasks_to_treat:
|
|||
if len(jobinfos) <= 2:
|
||||
print "Skipping: %s" % fields[2]
|
||||
continue
|
||||
taskID, user, _ = jobinfos
|
||||
taskID, user, filename = jobinfos
|
||||
user = user.split('@').pop() # On récupère le nom du club si besoin.
|
||||
date = buildDate(fields[5])
|
||||
match_taskID = re.compile(r"impression\(%s\)" % taskID)
|
||||
|
@ -180,3 +195,6 @@ for item in tasks_to_treat:
|
|||
else:
|
||||
mail_content = error_mail % (error_send_to, error_send_to, filename, taskID, full_name, user, date, result, u"\n".join(send_to))
|
||||
sendMail(error_send_to, error_send_to, mail_content.encode("utf-8"))
|
||||
|
||||
error_file = open(error_filename, "w+")
|
||||
error_file.close()
|
||||
|
|
31
lib/deprecated.py
Normal file
31
lib/deprecated.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import warnings
|
||||
import functools
|
||||
|
||||
def deprecated(replace=None):
|
||||
'''This is a decorator which can be used to mark functions
|
||||
as deprecated. It will result in a warning being emitted
|
||||
when the function is used.'''
|
||||
|
||||
if replace == None:
|
||||
instead = ""
|
||||
elif isinstance(replace, str) or isinstance(replace, unicode):
|
||||
instead = " " + replace
|
||||
else:
|
||||
instead = " Use %s instead." % (replace.__name__,)
|
||||
|
||||
def real_decorator(func):
|
||||
"""Nested because a decorator with a parameter has to be coded this way"""
|
||||
@functools.wraps(func)
|
||||
def new_func(*args, **kwargs):
|
||||
warnings.warn_explicit(
|
||||
"Call to deprecated function %s.%s" % (func.__name__, instead),
|
||||
category=DeprecationWarning,
|
||||
filename=func.func_code.co_filename,
|
||||
lineno=func.func_code.co_firstlineno + 1
|
||||
)
|
||||
return func(*args, **kwargs)
|
||||
return new_func
|
||||
return real_decorator
|
44
munin/ipset
Executable file
44
munin/ipset
Executable file
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Compteur des sets ipset
|
||||
|
||||
import sys,commands,string
|
||||
|
||||
IPSET = "ipset -L "
|
||||
|
||||
|
||||
if sys.argv[0].endswith('macip'):
|
||||
MACIP = True
|
||||
else:
|
||||
MACIP = False
|
||||
|
||||
try :
|
||||
arg = sys.argv[1]
|
||||
except :
|
||||
arg = ''
|
||||
|
||||
CHAINS = commands.getoutput('%s | grep -- ^Name: | awk \'{print $2}\'' % IPSET).split('\n')
|
||||
CHAINS = [ chain for chain in CHAINS if (not MACIP and not chain.startswith('MAC-IP')) or ( MACIP and chain.startswith('MAC-IP')) ]
|
||||
|
||||
if arg == "config" :
|
||||
print 'graph_title Ipset' + (MACIP and ' test mac-ip' or '')
|
||||
print 'graph_args --base 1000 --lower-limit 0'
|
||||
print 'graph_category network'
|
||||
print "graph_vlabel nb de regles"
|
||||
for chain in CHAINS :
|
||||
nom = string.lower(chain.replace('_', '').replace('-', '').replace('.','').replace('/', ''))
|
||||
label = chain.replace('_', '-').replace('.','-').replace('/','-')
|
||||
print "%s.label %s" % (nom, label)
|
||||
if CHAINS.index(chain) == 0 :
|
||||
print "%s.draw AREA" % nom
|
||||
else :
|
||||
print "%s.draw STACK" % nom
|
||||
|
||||
|
||||
else :
|
||||
for chain in CHAINS :
|
||||
nom = string.lower(chain.replace('_', '').replace('-', '').replace('.','').replace('/', ''))
|
||||
label = chain.replace('_', '-').replace('.','-').replace('/','-')
|
||||
value = int(commands.getoutput('%s %s | wc -l' % (IPSET, chain))) - 6
|
||||
print "%s.value %d" % (nom, value)
|
|
@ -70,6 +70,9 @@ def do_auth(mac, prise):
|
|||
if ('virus' in m[0].blacklist_actif() or 'ipv6_ra' in m[0].blacklist_actif()
|
||||
or 'autodisc_virus' in m[0].blacklist_actif()):
|
||||
return (0, "Bad boy", "isolement")
|
||||
|
||||
if ('carte_etudiant' in m[0].blacklist_actif()):
|
||||
return (0, "Manque carte etudiant", "accueil")
|
||||
|
||||
# Paiement proprio ?
|
||||
if not paiement_ok(proprio):
|
||||
|
|
|
@ -126,6 +126,13 @@ def stats(ip_crans=[], ip_ext=[],
|
|||
|
||||
# on transforme tout en chaine
|
||||
results = [ [ str(x) for x in line ] for line in results ]
|
||||
upload = 0
|
||||
download = 0
|
||||
for line in results:
|
||||
upload+=int(line[4])
|
||||
download+=int(line[3])
|
||||
print " upload: %sMo" % (upload/1024/1024)
|
||||
print " download: %sMo" % (download/1024/1024)
|
||||
|
||||
# on modifie les ip en noms de machine et les ports en noms
|
||||
def nom_de_machine (ip) :
|
||||
|
|
|
@ -167,14 +167,15 @@ uploadeurs = curseur.fetchall()
|
|||
|
||||
|
||||
# On regarde s'il y a deux ipv6 identiques avec des mac non identiques
|
||||
collision_mac_ip_request = "SELECT DISTINCT (a.*) FROM mac_ip as a, mac_ip as b where a.ip=b.ip AND a.mac != b.mac AND a.date >= b.date AND a.date - b.date < interval '3 day' ORDER BY a.date;"
|
||||
collision_mac_ip_request = "SELECT DISTINCT a.date as date1, a.mac as mac1, a.ip as ip1, b.date as date2, b.mac as mac2, b.ip as ip2 FROM mac_ip as a, mac_ip as b where a.ip=b.ip AND a.mac != b.mac AND a.date >= b.date AND a.date - b.date < interval '3 day' ORDER BY a.date;"
|
||||
curseur.execute(collision_mac_ip_request)
|
||||
collision_mac_ip = curseur.fetchall()
|
||||
|
||||
if collision_mac_ip != []:
|
||||
print "Collision d'addresses ipv6 : "
|
||||
for (date, mac, ip) in collision_mac_ip:
|
||||
print "%s %s %s" % (date, ipt.mac_addr(mac), ip)
|
||||
for (date1, mac1, ip1, date2, mac2, ip2) in collision_mac_ip:
|
||||
print "%s %s %s" % (date1, ipt.mac_addr(mac1), ip1)
|
||||
print "%s %s %s" % (date2, ipt.mac_addr(mac2), ip2)
|
||||
|
||||
# Table des avertis
|
||||
###################
|
||||
|
@ -250,7 +251,7 @@ for elupload, eltype, elid in uploadeurs:
|
|||
# On envoie un mail à disconnect
|
||||
################################
|
||||
if upload.disconnect_mail_hard:
|
||||
corps = config.mails.upload.message_disconnect_hard % {'from': upload.expediteur, 'to': upload.expediteur, 'upload': elupload, 'proprio': proprio.Nom(), 'mdc': mdcf, 'chambre': proprio.chbre()}
|
||||
corps = config.mails.upload.message_disconnect_hard % {'from': upload.expediteur, 'to': upload.expediteur, 'upload': elupload, 'proprio': proprio.Nom(), 'mdc': mdcf, 'chambre': proprio.chbre(), 'aid':proprio.id()}
|
||||
corps = corps.encode('utf-8')
|
||||
mail.sendmail(upload.expediteur, upload.expediteur, corps)
|
||||
|
||||
|
@ -311,7 +312,7 @@ for elupload, eltype, elid in uploadeurs:
|
|||
mail.sendmail(upload.expediteur, upload.expediteur, corps)
|
||||
|
||||
# On supprime les vieux avertisements
|
||||
curseur.execute("DELETE FROM avertis_upload_hard WHERE date < timestamp 'now' - interval '1 day'")
|
||||
curseur.execute("DELETE FROM avertis_upload_hard WHERE date < timestamp 'now' - interval '85200 seconds'") # 23h et 40min pour prolonger les blacklists toujours au dessus de la limite
|
||||
curseur.execute("DELETE FROM avertis_upload_soft WHERE date < timestamp 'now' - interval '1 day'")
|
||||
|
||||
################################################################################
|
||||
|
|
|
@ -137,7 +137,7 @@ Subject: %(subject)s
|
|||
Content-Type: multipart/mixed; boundary="_424234545aaff-ffca234efff-556adceff5646_"
|
||||
|
||||
--_424234545aaff-ffca234efff-556adceff5646_
|
||||
Content-Type: text/plain, charset="UTF-8"
|
||||
Content-Type: text/plain; charset="UTF-8"
|
||||
|
||||
%(contenu)s
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ if __name__ == '__main__':
|
|||
message = """From: %(from)s
|
||||
To: %(to)s
|
||||
Subject: %(subject)s
|
||||
Content-Type: text/plain, charset="UTF-8"
|
||||
Content-Type: text/plain; charset="UTF-8"
|
||||
|
||||
%(contenu)s
|
||||
|
||||
|
|
|
@ -4,15 +4,19 @@
|
|||
|
||||
-- effacement des vieux enregistrements
|
||||
DELETE FROM upload where date< timestamp 'now' - interval '2 days';
|
||||
-- la même pour upload6
|
||||
DELETE FROM upload6 WHERE date< timestamp 'now' - interval '2 days';
|
||||
-- On ne blackliste plus pour virus, on droppe seulement
|
||||
-- DELETE FROM virus where date< timestamp 'now' - interval '2 days';
|
||||
DELETE FROM flood where date< timestamp 'now' - interval '2 days';
|
||||
-- Idem pour flood
|
||||
-- DELETE FROM flood where date< timestamp 'now' - interval '2 days';
|
||||
|
||||
-- suppression complète des entrées
|
||||
VACUUM;
|
||||
|
||||
-- réindexation des tables
|
||||
REINDEX TABLE upload;
|
||||
REINDEX TABLE virus;
|
||||
REINDEX TABLE upload6;
|
||||
-- REINDEX TABLE virus;
|
||||
-- REINDEX TABLE flood; -- flood n'a pas d'index
|
||||
REINDEX TABLE p2p;
|
||||
|
|
0
utils/__init__.py
Normal file
0
utils/__init__.py
Normal file
|
@ -2,7 +2,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# check_cert.py -- Petit mail de vérification du certificat d'un serveur
|
||||
# ce script vérifie principalement la date
|
||||
# ce script vérifie principalement la date d'expiration et envoie un mail
|
||||
# d'avertissement si celle-ci est proche (paramétrable)
|
||||
#
|
||||
# Copyright (c) 2013 Daniel STAN
|
||||
# Authors: Daniel STAN <daniel.stan@crans.org>
|
||||
|
@ -20,7 +21,9 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
from M2Crypto import SSL
|
||||
from M2Crypto import X509
|
||||
import datetime
|
||||
import sys
|
||||
|
||||
|
@ -31,8 +34,9 @@ import smtplib
|
|||
#
|
||||
# Config !
|
||||
#
|
||||
host = 'webmail.crans.org'
|
||||
host = 'localhost'
|
||||
port = 443
|
||||
filename = False # if True, port ignored and host is in fact a path
|
||||
# afficher la sortie plutôt que l'envoyer:
|
||||
verb = False
|
||||
# delai d'avertissement
|
||||
|
@ -42,46 +46,60 @@ delay = datetime.timedelta(days=15)
|
|||
mail_src = 'root@crans.org'
|
||||
mail_dest = "roots@crans.org"
|
||||
mail_host = 'localhost'
|
||||
|
||||
#
|
||||
# Argument parsing !
|
||||
#
|
||||
# TODO argparse + doc
|
||||
for arg in sys.argv[1:]:
|
||||
if arg == '-v':
|
||||
verb = True
|
||||
continue
|
||||
if arg == '--filename':
|
||||
filename = True
|
||||
try:
|
||||
port = int(arg)
|
||||
except ValueError:
|
||||
host = arg
|
||||
|
||||
# TODO: permettre la vérification directement sur un fichier
|
||||
# get cert:
|
||||
conn = SSL.Connection(SSL.Context())
|
||||
try:
|
||||
conn.connect((host, port))
|
||||
except SSL.Checker.WrongHost:
|
||||
if host != 'localhost':
|
||||
raise
|
||||
#
|
||||
# Getting cert !
|
||||
#
|
||||
if filename:
|
||||
cert = X509.load_cert(host)
|
||||
else:
|
||||
conn = SSL.Connection(SSL.Context())
|
||||
try:
|
||||
conn.connect((host, port))
|
||||
except SSL.Checker.WrongHost:
|
||||
if host != 'localhost':
|
||||
raise
|
||||
|
||||
cert = conn.get_peer_cert()
|
||||
conn.close()
|
||||
cert = conn.get_peer_cert()
|
||||
conn.close()
|
||||
|
||||
#
|
||||
# Real computation (woah !)
|
||||
#
|
||||
expire_date = cert.get_not_after().get_datetime()
|
||||
now = datetime.datetime.now(expire_date.tzinfo)
|
||||
|
||||
if now + delay > expire_date:
|
||||
if now + delay > expire_date or verb:
|
||||
subject = cert.get_subject().as_text()
|
||||
short_sub = subject
|
||||
try:
|
||||
subject += "(alt: %s)" % cert.get_ext('subjectAltName').get_value()
|
||||
except LookupError:
|
||||
pass
|
||||
conn = smtplib.SMTP(mail_host)
|
||||
msg = MIMEText(u"""Attention, le certificat suivant arrive bientôt à expiration :\n%s\n
|
||||
Temps avant expiration: %s""" % (subject,(expire_date - now)), _charset="utf-8")
|
||||
msg['From'] = mail_src
|
||||
msg['To'] = mail_dest
|
||||
msg['Subject'] = u"Expiration imminente du certificat %s" % short_sub
|
||||
if not verb:
|
||||
conn = smtplib.SMTP(mail_host)
|
||||
conn.sendmail(mail_src, mail_dest, msg.as_string())
|
||||
conn.quit()
|
||||
else:
|
||||
print msg.as_string()
|
||||
conn.quit()
|
||||
print msg.get_payload(decode=True)
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ TEMPFILE=`tempfile`
|
|||
# on évite de casser le dépôt darcs
|
||||
umask 002
|
||||
wget -o /dev/null -O $TEMPFILE http://standards.ieee.org/regauth/oui/oui.txt \
|
||||
&& awk -F '[\t ]*(hex)[ \t]*' '(/(hex)/) {gsub("-",":",$1) ; print $1" "$2}' < $TEMPFILE > /usr/scripts/gestion/ethercodes.dat \
|
||||
&& awk -F '[\t ]*(hex)[ \t]*' '(/(hex)/) {gsub("-",":",$1) ; {gsub("^ *", "", $1)}; {gsub("\\(", "", $1)}; {gsub("\\)", "", $2)}; print $1" "$2}' < $TEMPFILE > /usr/scripts/gestion/ethercodes.dat \
|
||||
&& cd /usr/scripts/gestion \
|
||||
&& git commit --author="Cron Daemon <root@crans.org>" -m "[ethercodes.dat] Mise à jour du fichier vendeur" ethercodes.dat > /dev/null \
|
||||
&& git push > /dev/null
|
||||
|
|
|
@ -3,17 +3,16 @@
|
|||
import os
|
||||
import PagesPerso
|
||||
|
||||
def comptes():
|
||||
"""Retourne la liste des comptes"""
|
||||
return filter(lambda x: os.path.isdir(u"/home/club/%s" % x) and not os.path.islink(u"/home/club/%s" % x),
|
||||
os.listdir(u"/home/club"))
|
||||
class ClubList(PagesPerso.AccountList):
|
||||
home = "/home/club"
|
||||
www = ""
|
||||
url = "http://clubs.ens-cachan.fr/%s/"
|
||||
|
||||
def url(self):
|
||||
"""URL vers la page perso"""
|
||||
return u"http://clubs.ens-cachan.fr/%s/" % self.login
|
||||
def comptes(self):
|
||||
"""Retourne la liste des comptes"""
|
||||
return filter(lambda x: os.path.isdir(u"/home/club/%s" % x) and not os.path.islink(u"/home/club/%s" % x),
|
||||
os.listdir(u"/home/club"))
|
||||
|
||||
def execute(macro, args):
|
||||
return macro.formatter.rawHTML(ClubList().to_html())
|
||||
|
||||
PagesPerso.comptes = comptes
|
||||
PagesPerso.account.home = "/home/club"
|
||||
PagesPerso.account.www = ""
|
||||
PagesPerso.account.url = url
|
||||
execute = PagesPerso.execute
|
||||
|
|
|
@ -2,16 +2,57 @@
|
|||
|
||||
import os
|
||||
|
||||
class account:
|
||||
"""Classe représentant la page perso d'une personne"""
|
||||
|
||||
class AccountList:
|
||||
home = "/home"
|
||||
www = "/www"
|
||||
url = "http://perso.crans.org/%s/"
|
||||
|
||||
def __init__(self, login):
|
||||
def __init__(self):
|
||||
return
|
||||
|
||||
def comptes(self):
|
||||
"""Retourne la liste des comptes"""
|
||||
return filter(lambda x: os.path.isdir(u"/home/%s/www" % x) and not os.path.islink(u"/home/%s/www" % x),
|
||||
os.listdir(u"/home/mail"))
|
||||
|
||||
|
||||
def makeAnchor(self,letter):
|
||||
return u"<div class=\"vignetteperso\"><a class=\"letter_anchor\" name=\"index_%s\"><span>%s:</span></a></div>" % ( letter, letter )
|
||||
|
||||
def makeIndex(self,letter_list):
|
||||
index = u''
|
||||
for aLetter in letter_list:
|
||||
index = u"%s<a href=\"#index_%s\">%s</a>" % ( index, aLetter, aLetter)
|
||||
return u"<div class=\"alphabetic_index\">%s</div>" % index
|
||||
|
||||
def to_html(self):
|
||||
dirs = self.comptes()
|
||||
dirs.sort()
|
||||
html = u""
|
||||
|
||||
premiere_lettre = ''
|
||||
letter_list = []
|
||||
for d in dirs:
|
||||
if premiere_lettre != d[0]:
|
||||
premiere_lettre = d[0]
|
||||
letter_list.append(premiere_lettre)
|
||||
html = u"%s\n%s" % ( html, self.makeAnchor(premiere_lettre) )
|
||||
html = u"%s\n%s" % (html, Account(self.home, d, self.www, self.url).to_html())
|
||||
|
||||
index = self.makeIndex(letter_list)
|
||||
html = index + html
|
||||
html += u'<br style="clear: both">'
|
||||
return html
|
||||
|
||||
class Account:
|
||||
"""Classe représentant la page perso d'une personne"""
|
||||
|
||||
def __init__(self, home, login, www, url):
|
||||
"""Instanciation avec le `login' de la personne"""
|
||||
self.login = login
|
||||
self.home = "%s/%s" % (self.home, login)
|
||||
self.home = "%s/%s" % (home, login)
|
||||
self.www = www
|
||||
self.url = url
|
||||
|
||||
_info = None
|
||||
def info(self, champ):
|
||||
|
@ -39,10 +80,6 @@ class account:
|
|||
"""Chemin vers le www"""
|
||||
return u"%s%s" % (self.home, self.www)
|
||||
|
||||
def url(self):
|
||||
"""URL vers la page perso"""
|
||||
return u"http://perso.crans.org/%s/" % self.login
|
||||
|
||||
def logo(self):
|
||||
"""URL du logo s'il y en a un"""
|
||||
if self.info("logo"):
|
||||
|
@ -52,13 +89,13 @@ class account:
|
|||
else:
|
||||
logo = self.info("logo")
|
||||
if os.path.isfile("%s/%s" % (self.chemin(), logo)):
|
||||
return u"%s%s" % (self.url(), logo)
|
||||
return u"%s%s" % (self.url % self.login, logo)
|
||||
return u"http://perso.crans.org/pageperso.png"
|
||||
|
||||
def __str__(self):
|
||||
def to_html(self):
|
||||
"""Renvoie le code HTML correspondant au fichier .info"""
|
||||
html = [ u'<div class="vignetteperso">',
|
||||
u'<a href="%s">' % self.url(),
|
||||
u'<a href="%s">' % (self.url % self.login),
|
||||
u'<img src="%s" alt="%s">' % (self.logo(), self.login),
|
||||
u'</a><br>',
|
||||
self.info("nom") and u'<b>%s</b><br>' % self.info("nom") or u'%s<br>' % self.login,
|
||||
|
@ -66,38 +103,6 @@ class account:
|
|||
u'</div>' ]
|
||||
return u'\n'.join(html)
|
||||
|
||||
def comptes():
|
||||
"""Retourne la liste des comptes"""
|
||||
return filter(lambda x: os.path.isdir(u"/home/%s/www" % x) and not os.path.islink(u"/home/%s/www" % x),
|
||||
os.listdir(u"/home/mail"))
|
||||
|
||||
|
||||
def makeAnchor(letter):
|
||||
return u"<div class=\"vignetteperso\"><a class=\"letter_anchor\" name=\"index_%s\"><span>%s:</span></a></div>" % ( letter, letter )
|
||||
|
||||
def makeIndex(letter_list):
|
||||
index = u''
|
||||
for aLetter in letter_list:
|
||||
index = u"%s<a href=\"#index_%s\">%s</a>" % ( index, aLetter, aLetter)
|
||||
return u"<div class=\"alphabetic_index\">%s</div>" % index
|
||||
|
||||
def execute(macro, args):
|
||||
dirs = comptes()
|
||||
dirs.sort()
|
||||
|
||||
html = u""
|
||||
|
||||
premiere_lettre = ''
|
||||
letter_list = []
|
||||
for d in dirs:
|
||||
if premiere_lettre != d[0]:
|
||||
premiere_lettre = d[0]
|
||||
letter_list.append(premiere_lettre)
|
||||
html = u"%s\n%s" % ( html, makeAnchor(premiere_lettre) )
|
||||
html = u"%s\n%s" % (html, account(d).__str__())
|
||||
|
||||
|
||||
index = makeIndex(letter_list)
|
||||
html = index + html
|
||||
html += u'<br style="clear: both">'
|
||||
return macro.formatter.rawHTML(html)
|
||||
return macro.formatter.rawHTML(AccountList().to_html())
|
||||
|
|
|
@ -33,9 +33,10 @@ class Theme(ThemeBase):
|
|||
(u'http://www.mozilla-europe.org/fr/firefox/',
|
||||
u'badges_80x15_firefox.gif', u'Get firefox'),
|
||||
(u'http://www.debian.org/', u'badges_80x15_debian.png', u'Debian powered'),
|
||||
(u'http://www.apache.org/', u'badges_80x15_apache.gif', u'Apache powered'),
|
||||
(u'http://wiki.nginx.org/', u'badges_80x15_nginx.png', u'Nginx powered'),
|
||||
(u'http://www.python.org/', u'badges_80x15_python.png', u'Python powered'),
|
||||
(u'http://www.federez.org/', u'badges_80x15_federez.png', u'Membre du réseau federez'),
|
||||
(u'/VieCrans/Donateurs', u'badges_80x15_donor.png', u'Généreux donateurs'),
|
||||
(u'http://moinmo.in/', u'badges_80x15_moinmoin.png', u'Moinmoin powered'),
|
||||
(u'http://jigsaw.w3.org/css-validator/check?uri=referer&profile=css3&warning=no',
|
||||
u'valid_css_80x15.png', u'Valid css3'),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue