Portail Captif
Principe général
Ce serveur permet de fournir un accès internet temporaire sur le campus. Il fourni donc internet sur le vlan 10, 10.231.137.0/24.
Sur le principe, il s'agit d'un site web développé en django. Après inscription et création d'un compte, puis activation de celui-ci, un accès internet est fourni.
Ce portail est en place depuis juin 2016, et utilisé régulièrement.
Cas d'utilisation
Le portail est utilisé sur le campus dans les cas suivants.
De manière permanente, il est utilisé :
Au niveau du RU, ( comme on s'y est engagé auprès du CROUS) : un réseau WiFi est émis là-bas par les 2 bornes présentes au RU. Il s'agit d'un WiFi ouvert permettant à n'importe quel étudiant, membre du CRANS ou non, d'avoir un accès temporaire au RU, aux heures des repas. Voir le scheduleur et le profil Crans-RU dans le controleur unifi.
De manière temporaire :
- Lors du festival de robotique de Cachan, tous les ans en juin, pour fournir un accès internet au public,
- Pour les admissibles, via le SSID Cr@ns-Admissibles, sur les bornes du PDJ et de l'ENS.
Détails techniques
Configuration d'ytrap
Ytrap (vm de routage du vlan 10) possède 3 interfaces :
- Une sur adm pour communiquer avec les autres serveurs,
- Une sur la dmz, 185.230.79.0/24 pour avoir internet, qui doit avoir toutes les ouvertures sur le parefeu (open bar),
- Une sur le vlan 10 pour y fournir internet : 10.231.137.1.
Un serveur dns récursif, via bind, y est installé. Il doit donc pouvoir parler avec le reste du monde sur le port 53. De plus il doit aussi pouvoir transférer les zones du crans depuis silice et les autoritaires. Il est destiné à être utilisé par les
Enfin un serveur isc-dhcp-server, qui fourni une ip aux utilisateurs du vlan 10, est également installé et écoute sur l'interface vlan 10.
Internet sur le vlan 10
Les ip sont données librement sur le vlan par le dhcp d'ytrap. Le dns répond également.
L'accès internet n'est donc possible que si les paquets passent ytrap et sont routés. L'accès, ou non, à internet est donc géré au niveau du parefeu d'ytrap, géré par le service portail-captif.
Service portail-captif et portail
Le portail est servi par un serveur nginx. Ensuite, un service "portail_captif", situé dans /etc/systemd/system/portail_captif.service , gère à la fois le service web du portail, et l'insertion/délétion des règles iptables pertinentes.
Fonctionnement
Le service portail gère le parefeu, et injecte dans l'ipset les adresses mac des clients qui s'authentifie.
A l'inscription, ou à la connexion d'une nouvelle machine, la mac est relevée par le service, en inspectant sa table arp à partir de l'ip source de la requête. Cela fonctionne donc uniquement car on est sur le même sous-réseau...
Cette mac est ensuite injectée dans l'ipset, qui permettra alors à l'utilisateur de ne plus être redirigé vers le portail, et d'avoir accès à internet.
Cf ci-dessous, au démarrage du service portail-captif, les règles iptables suivants sont injectées. On active le log dans mangle, puis dans filter, on rejette tout ce qui n'est pas dans l'ipset des clients autorisés (portail_captif ici).
Enfin dans nat, tout client inconnu (donc mac non présente dans portail_captif) sera redirigée vers 185.230.79.219 et pourra alors se connecter ou créer un compte.
# Generated by iptables-save v1.6.0 on Mon Jun 3 21:35:20 2019 *mangle :PREROUTING ACCEPT [4780142:3637557853] :INPUT ACCEPT [835423:105907870] :FORWARD ACCEPT [2004367:1963512662] :OUTPUT ACCEPT [778071:1326894543] :POSTROUTING ACCEPT [2782112:3290391759] -A PREROUTING -i ens20 -m state --state NEW -j LOG --log-prefix "LOG_ALL " -A PREROUTING -i ens21 -m state --state NEW -j LOG --log-prefix "LOG_ALL " COMMIT # Completed on Mon Jun 3 21:35:20 2019 # Generated by iptables-save v1.6.0 on Mon Jun 3 21:35:20 2019 *filter :INPUT ACCEPT [835423:105907870] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [778071:1326894543] -A FORWARD -o ens19 -j REJECT --reject-with icmp-port-unreachable -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -o ens20 -m set --match-set portail_captif src,dst -j ACCEPT -A FORWARD -i ens20 -m set --match-set portail_captif src,dst -j ACCEPT -A FORWARD -o ens21 -m set --match-set portail_captif src,dst -j ACCEPT -A FORWARD -i ens21 -m set --match-set portail_captif src,dst -j ACCEPT -A FORWARD -j REJECT --reject-with icmp-port-unreachable COMMIT # Completed on Mon Jun 3 21:35:20 2019 # Generated by iptables-save v1.6.0 on Mon Jun 3 21:35:20 2019 *nat :PREROUTING ACCEPT [1963392:1555836872] :INPUT ACCEPT [23313:2129586] :OUTPUT ACCEPT [63895:4819177] :POSTROUTING ACCEPT [0:0] :CAPTIF - [0:0] -A PREROUTING -j CAPTIF -A POSTROUTING -j MASQUERADE -A CAPTIF -i ens20 -m set ! --match-set portail_captif src,dst -j DNAT --to-destination 185.230.79.219 -A CAPTIF -j RETURN COMMIT # Completed on Mon Jun 3 21:35:20 2019
Configuration du portail
Tous les réglages sont dans /var/www/django-portail-captif/portail_captif/settings_local.py
Il faut renseigner dans GENERIC_IPSET_COMMAND, le path vers la commande ipset, dans IPSET_NAME le nom de l'ipset de travail, dans FORBIDEN_INTERFACES les interfaces où bloquer la sortie du trafic (adm), dans SERVER_SELF_IP l'ip publique où rediriger le trafic, dans OUT_INTERFACE, l'interface de sortie, dans INTERNAL_INTERFACE l'interface où servir internet (vlan 10), dans CAPTIVE_IP_RANGE le range du vlan 10, et dans CAPTIVE_WIFI le SSID.
SECRET_KEY = 'plop' DB_PASSWORD = 'plop' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ADMINS = [('Root', 'root@crans.org')] SERVER_EMAIL = 'www-data@crans.org' # Obligatoire, liste des host autorisés ALLOWED_HOSTS = ['portail-captif.crans.org', 'festival.crans.org', 'frc.crans.org', 'admissibles.crans.org', '185.230.79.219'] DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'portail_captif', 'USER': 'portail_captif', 'PASSWORD': DB_PASSWORD, 'HOST': 'pgsql.adm.crans.org', }, } # Security settings SECURE_CONTENT_TYPE_NOSNIFF = True SECURE_BROWSER_XSS_FILTER = True SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True CSRF_COOKIE_HTTPONLY = True X_FRAME_OPTIONS = 'DENY' SESSION_COOKIE_AGE = 60 * 60 * 3 # Association information SITE_NAME = "Cr@ns Invités" ASSO_NAME = "CRANS" ASSO_EMAIL = "cableurs@crans.org" # Number of hours a token remains valid after having been created. Numeric and string # versions should have the same meaning. REQ_EXPIRE_HRS = 48 REQ_EXPIRE_STR = '48 heures' # Email `From` field EMAIL_FROM = 'www-data@crans.org' EMAIL_HOST = 'smtp.adm.crans.org' # Affchage des résultats SEARCH_RESULT = 15 #### Réglages du portail GENERIC_IPSET_COMMAND = "/sbin/ipset" # Nom de l'ipset utilisé IPSET_NAME = "portail_captif" ### Interfaces où la sortie est interdite (ex vlan admin) FORBIDEN_INTERFACES = ["ens19"] ### Ip où le trafic est redirigé SERVER_SELF_IP = "185.230.79.219" ### Interfaces autorisées au routage OUT_INTERFACE = "ens21" ### Interface Interne INTERNAL_INTERFACE = "ens20" ### Interfaces autorisées au routage AUTORIZED_INTERFACES = [INTERNAL_INTERFACE] + [OUT_INTERFACE] ### Activation du portail obligatoire (redirection) PORTAIL_ACTIVE = True ## Range ip du portail captif CAPTIVE_IP_RANGE = "10.231.137.0/24" ## SSID du wifi portaul captif CAPTIVE_WIFI = "Install-party"
Un réglage important : PORTAIL_ACTIVE.
- A True, le passage est obligé par le portail, les utilisateus doivent donc s'auth/s'inscrire pour avoir internet.
A False, l'accès internet est open-bar : le passage par le portail n'est plus forcé dans le parefeu. Un accès internet sans aucune authentification sera alors fourni.