From b86aca109fb11690d53f74d685927ffa920f9ce9 Mon Sep 17 00:00:00 2001 From: Daniel STAN Date: Mon, 10 Mar 2014 09:33:18 +0100 Subject: [PATCH] portail_captif: disclaimer http sur vlan 10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cela fait popper une page web (proxy transparent) sur laquelle les clients CROUS sont invités à venir adhérer. Ils peuvent néanmoins continuer à naviguer en cliquant sur un lien qui rajoute leur IP à une liste d'IP whitelistées du firewall. Penser à désactiver le keep-alive du serveur web/proxy (nginx) car sinon, on constate des trucs marrants. (Normal, le -j DNAT n'a d'effet que lors de l'établissement de la connexion). PS: détabification massive du fichier portail_captif.py (pardon aux familles) --- utils/install-party/fete-du-slip | 13 +- utils/install-party/ipset_allow | 6 + utils/portail_captif.py | 264 +++++++++++++++++-------------- 3 files changed, 161 insertions(+), 122 deletions(-) create mode 100755 utils/install-party/ipset_allow diff --git a/utils/install-party/fete-du-slip b/utils/install-party/fete-du-slip index 9213a8e7..a8635384 100755 --- a/utils/install-party/fete-du-slip +++ b/utils/install-party/fete-du-slip @@ -15,10 +15,21 @@ iptables -t mangle -F ip6tables -t mangle -F ip6tables -F + iptables -t raw -A PREROUTING -d 224.0.0.0/4 -j DROP # On log les les paquets iptables -t mangle -A PREROUTING -i eth1 -m state --state NEW -j LOG --log-prefix "LOG_ALL " iptables -t mangle -A PREROUTING -i eth0 -m state --state NEW -j LOG --log-prefix "LOG_ALL " + +# +ipset -q create allowed_guests bitmap:ip range 10.231.137.0/24 || ipset flush allowed_guests +iptables -t nat -N CAPTIF 2> /dev/null || iptables -t nat -F CAPTIF +#iptables -t nat -A PREROUTING --src 10.231.137.189 -j CAPTIF +iptables -t nat -A PREROUTING -j CAPTIF +iptables -t nat -A CAPTIF -p tcp --dport 80 -m set \! --match-set allowed_guests src -j DNAT --to-destination 10.231.137.1 +iptables -t nat -A CAPTIF -j RETURN +# + # On nat l'ipv4 iptables -t nat -A POSTROUTING -j MASQUERADE @@ -53,4 +64,4 @@ echo 1 > /proc/sys/net/ipv4/conf/eth0/forwarding echo 1 > /proc/sys/net/ipv6/conf/all/forwarding # On lance radvd -/etc/init.d/radvd start +#/etc/init.d/radvd start diff --git a/utils/install-party/ipset_allow b/utils/install-party/ipset_allow new file mode 100755 index 00000000..bd33f04a --- /dev/null +++ b/utils/install-party/ipset_allow @@ -0,0 +1,6 @@ +#!/bin/bash + +#echo "$1" | grep -q "^\([0-9]\)*\.\([0-9]\)*\.\([0-9]\)*\.\([0-9]\)*$" || exit 42 +echo "$1" | grep -q "^10\.231\.137\.\([0-9]\)*$" || exit 42 + +/usr/sbin/ipset add allowed_guests $1 diff --git a/utils/portail_captif.py b/utils/portail_captif.py index 7d9e935d..6db92216 100644 --- a/utils/portail_captif.py +++ b/utils/portail_captif.py @@ -17,141 +17,163 @@ cleanup_time=3600.0 next_cleanup=time.time() + cleanup_time def cleanup(now): - global cleanup_time, cache, cache_time, next_cleanup - if next_cleanup < now: - for ip in cache.keys(): - if cache[ip]['time']<(now - cache_time): - del cache[ip] - next_cleanup=time.time() + cleanup_time - + global cleanup_time, cache, cache_time, next_cleanup + if next_cleanup < now: + for ip in cache.keys(): + if cache[ip]['time']<(now - cache_time): + del cache[ip] + next_cleanup=time.time() + cleanup_time + deco={ - 'non_inscrit': 'ERR_CUSTOM_NON_INSCRIT.html', - 'inscrit': 'ERR_CUSTOM_INSCRIT.html', - - 'age': 'ERR_CUSTOM_AGE.html', - 'ago': 'ERR_CUSTOM_AGO.html', - - 'autodisc_p2p': 'ERR_CUSTOM_BL_AUTO_P2P.html', - 'p2p':'ERR_CUSTOM_BL_P2P.html', - 'autodisc_upload':'ERR_CUSTOM_BL_AUTO_UPLOAD.html', - 'upload':'ERR_CUSTOM_BL_UPLOAD.html', - 'chambre_invalide': 'ERR_CUSTOM_BL_CHAMBRE.html', - 'carte_etudiant':'ERR_CUSTOM_BL_NO_CARTE.html', - 'mail_invalide':'ERR_CUSTOM_BL_NO_MAIL.html', - 'mail_invalide_inscription':'ERR_DISABLED_CUSTOM_BL_NO_MAIL.html', - 'warez':'ERR_CUSTOM_BL_WAREZ.html', - 'bloq':'ERR_CUSTOM_BLOQ.html', - - 'nouvelle_annee':'ERR_CUSTOM_NOUVELLE_ANNEE.html', - 'paiement': 'ERR_CUSTOM_NOUVELLE_ANNEE.html', - 'proxy_local':'ERR_CUSTOM_PROXY_LOCAL.html', - - 'virus':'ERR_CUSTOM_BL_VIRUS.html', - 'ipv6_ra':'ERR_CUSTOM_RA.html', - 'autodisc_virus':'ERR_CUSTOM_BL_AUTO_VIRUS.html', + 'non_inscrit': 'ERR_CUSTOM_NON_INSCRIT.html', + 'inscrit': 'ERR_CUSTOM_INSCRIT.html', + + 'ex_crous': 'ERR_CUSTOM_EX_CROUS.html', + 'ex_crous_enable': 'ERR_CUSTOM_EX_CROUS_ENABLE.html', + + 'age': 'ERR_CUSTOM_AGE.html', + 'ago': 'ERR_CUSTOM_AGO.html', + + 'autodisc_p2p': 'ERR_CUSTOM_BL_AUTO_P2P.html', + 'p2p':'ERR_CUSTOM_BL_P2P.html', + 'autodisc_upload':'ERR_CUSTOM_BL_AUTO_UPLOAD.html', + 'upload':'ERR_CUSTOM_BL_UPLOAD.html', + 'chambre_invalide': 'ERR_CUSTOM_BL_CHAMBRE.html', + 'carte_etudiant':'ERR_CUSTOM_BL_NO_CARTE.html', + 'mail_invalide':'ERR_CUSTOM_BL_NO_MAIL.html', + 'mail_invalide_inscription':'ERR_DISABLED_CUSTOM_BL_NO_MAIL.html', + 'warez':'ERR_CUSTOM_BL_WAREZ.html', + 'bloq':'ERR_CUSTOM_BLOQ.html', + + 'nouvelle_annee':'ERR_CUSTOM_NOUVELLE_ANNEE.html', + 'paiement': 'ERR_CUSTOM_NOUVELLE_ANNEE.html', + 'proxy_local':'ERR_CUSTOM_PROXY_LOCAL.html', + + 'virus':'ERR_CUSTOM_BL_VIRUS.html', + 'ipv6_ra':'ERR_CUSTOM_RA.html', + 'autodisc_virus':'ERR_CUSTOM_BL_AUTO_VIRUS.html', } - + for bl in deco.keys(): - deco[bl]="/crans-deco/%s" % deco[bl] - + deco[bl]="/crans-deco/%s" % deco[bl] + blacklist_key = [ - 'non_inscrit', - 'age','ago', - 'virus','autodisc_virus','ipv6_ra', - 'p2p','autodisc_p2p','upload','autodisc_uplaod','warez', - 'carte_etudiant','chambre_invalide','mail_invalide', - 'bloq', - 'nouvelle_annee','proxy_local', 'paiement', - 'inscrit' - ] + 'non_inscrit', + 'age','ago', + 'virus','autodisc_virus','ipv6_ra', + 'p2p','autodisc_p2p','upload','autodisc_uplaod','warez', + 'carte_etudiant','chambre_invalide','mail_invalide', + 'bloq', + 'nouvelle_annee','proxy_local', 'paiement', + 'inscrit' + ] def mac_from_ip(ip): - if ip == "10.51.0.10": return u"02:72:6f:75:74:07" - cmd = '/usr/sbin/arp -na %s' % ip - p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) - output, errors = p.communicate() - if output is not None : - mac_addr = output.split()[3] - return mac_addr.strip() - else: - return None + if ip == "10.51.0.10": return u"02:72:6f:75:74:07" + cmd = '/usr/sbin/arp -na %s' % ip + p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) + output, errors = p.communicate() + if output is not None : + mac_addr = output.split()[3] + return mac_addr.strip() + else: + return None +def enable_access(ip): + """Lance la commande idoine pour autoriser l'adresse IP""" + p = subprocess.Popen(['sudo', '-n', '/usr/scripts/utils/install-party/ipset_allow', ip], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out, err = p.communicate() + if out or err: + print "ipset_allow:" + print out + print "---" + print err + return False + return True def get(str): - global QUERY - try: - return QUERY.search(str) - except ldap.SERVER_DOWN: - QUERY = _get_ldap_connection() - return QUERY.search(str) - + global QUERY + try: + return QUERY.search(str) + except ldap.SERVER_DOWN: + QUERY = _get_ldap_connection() + return QUERY.search(str) + def get_machine_by_mac(ip): - mac_addr=mac_from_ip(ip) - machines = get(u'macAddress=%s' % mac_addr) - #if machines and isinstance(machines[0], lc_ldap.objets.machineWifi): - # if not 'ipHostNumber' in machines[0].attrs.keys(): - # machine = QUERY.search(u'macAddress=%s' % mac_addr, mode='rw')[0] - # machine.set_ipv4() - return machines - + mac_addr=mac_from_ip(ip) + machines = get(u'macAddress=%s' % mac_addr) + #if machines and isinstance(machines[0], lc_ldap.objets.machineWifi): + # if not 'ipHostNumber' in machines[0].attrs.keys(): + # machine = QUERY.search(u'macAddress=%s' % mac_addr, mode='rw')[0] + # machine.set_ipv4() + return machines + def get_machine_by_ip(ip): - return get(u'ipHostNumber=%s' % ip) - + return get(u'ipHostNumber=%s' % ip) + def get_page(ip, by_mac=False, accueil=False): - try: - if by_mac: - machines=get_machine_by_mac(ip) - else: - machines=get_machine_by_ip(ip) - adherent=machines[0].proprio() - except IndexError: - return deco['non_inscrit'] - blacklist=[bl.value['type'] for bl in adherent.blacklist_actif()] - for machine in machines: - blacklist.extend([bl.value['type'] for bl in machine.blacklist_actif()]) - for bl in blacklist_key: - if bl in blacklist: - return deco[bl] - if accueil: - return deco['inscrit'] - return None - + try: + if by_mac: + machines=get_machine_by_mac(ip) + else: + machines=get_machine_by_ip(ip) + adherent=machines[0].proprio() + except IndexError: + return deco['non_inscrit'] + blacklist=[bl.value['type'] for bl in adherent.blacklist_actif()] + for machine in machines: + blacklist.extend([bl.value['type'] for bl in machine.blacklist_actif()]) + for bl in blacklist_key: + if bl in blacklist: + return deco[bl] + if accueil: + return deco['inscrit'] + return None + def app(environ, start_response): - if 'HTTP_K_REAL_IP' in environ.keys(): - ip=environ['HTTP_K_REAL_IP'] - else: - ip=environ['HTTP_REAL_IP'] - now=time.time() - cleanup(now) - if ip in cache.keys() and cache[ip]['time']>(now - cache_time): - data=cache[ip]['page'] - else: - if AddrInNet(ip,'10.51.0.0/16'): - data=get_page(ip,True,True) - elif AddrInNet(ip,'10.52.0.0/16'): - page=get_page(ip,True) - if page: - data=page - else: - data=deco['autodisc_virus'] - elif AddrInNet(ip,'138.231.136.0/21') or AddrInNet(ip,'138.231.144.0/21') or AddrInNet(ip,'10.2.9.0/24'): - page=get_page(ip) - if page: - data=page - else: - data="/crans-proxy/" - else: - data = deco['non_inscrit'] - cache[ip]={'time':time.time(),'page':data} - start_response("200 OK", [ - ("Content-Type", "text/html"), - ("Cache-Control", "no-cache, must-revalidate"), - ("Expires", "Thu, 01 Jan 1970 00:00:00 GMT"), - ("X-Accel-Redirect", data), - ("Content-Length", 0) - ]) + if 'HTTP_K_REAL_IP' in environ.keys(): + ip=environ['HTTP_K_REAL_IP'] + else: + ip=environ['HTTP_REAL_IP'] + now=time.time() + cleanup(now) + if AddrInNet(ip, '10.231.137.0/24'): + if environ.get('RAW_URI', '').startswith('/enable'): + enable_access(ip) + data = deco['ex_crous_enable'] + else: + data = deco['ex_crous'] + elif ip in cache.keys() and cache[ip]['time']>(now - cache_time): + data=cache[ip]['page'] + else: + if AddrInNet(ip,'10.51.0.0/16'): + data=get_page(ip,True,True) + elif AddrInNet(ip,'10.52.0.0/16'): + page=get_page(ip,True) + if page: + data=page + else: + data=deco['autodisc_virus'] + elif AddrInNet(ip,'138.231.136.0/21') or AddrInNet(ip,'138.231.144.0/21') or AddrInNet(ip,'10.2.9.0/24'): + page=get_page(ip) + if page: + data=page + else: + data="/crans-proxy/" + else: + data = deco['non_inscrit'] + cache[ip]={'time':time.time(),'page':data} + start_response("200 OK", [ + ("Content-Type", "text/html"), + ("Cache-Control", "no-cache, must-revalidate"), + ("Expires", "Thu, 01 Jan 1970 00:00:00 GMT"), + ("X-Accel-Redirect", data), + ("Content-Length", 0) + ]) - return "" + return ""