From 74fb19864f001892f2378bd12090cc7274f6316b Mon Sep 17 00:00:00 2001 From: Anish Mangal Date: Wed, 4 Jul 2018 12:42:10 +0000 Subject: [PATCH] Initial working copy of the captive portal --- roles/network/defaults/main.yml | 7 ++ roles/network/tasks/captive_portal.yml | 37 +++++++ roles/network/tasks/main.yml | 8 ++ .../captive_portal/captive_portal.py.j2 | 97 +++++++++++++++++++ .../captive_portal/captive_portal.service.j2 | 15 +++ 5 files changed, 164 insertions(+) create mode 100644 roles/network/tasks/captive_portal.yml create mode 100755 roles/network/templates/captive_portal/captive_portal.py.j2 create mode 100644 roles/network/templates/captive_portal/captive_portal.service.j2 diff --git a/roles/network/defaults/main.yml b/roles/network/defaults/main.yml index 4524918df..2fb7bc256 100644 --- a/roles/network/defaults/main.yml +++ b/roles/network/defaults/main.yml @@ -71,3 +71,10 @@ named_enabled: True dnsmasq_enabled: False dnsmasq_install: False captive_portal_enabled: False + +# for simple python captive portal +py_captive_portal_install: True +py_captive_portal_enabled: True +captive_portal_port: "9090" +captive_portal_username: "Admin" +captive_portal_password: "g0adm1n" diff --git a/roles/network/tasks/captive_portal.yml b/roles/network/tasks/captive_portal.yml new file mode 100644 index 000000000..73176709c --- /dev/null +++ b/roles/network/tasks/captive_portal.yml @@ -0,0 +1,37 @@ +- name: Create directory for captive portal script + file: path=/opt/iiab/captive-portal state=directory + when: py_captive_portal_install + +- name: Copy captive portal script + template: + src: roles/network/templates/captive_portal/captive_portal.py.j2 + dest: /opt/iiab/captive-portal/captive_portal.py + owner: iiab-admin + group: iiab-admin + mode: 0740 + when: py_captive_portal_install + +- name: Copy captive portal service file + template: + src: roles/network/templates/captive_portal/captive_portal.service.j2 + dest: /etc/systemd/system/captive_portal.service + owner: iiab-admin + group: iiab-admin + mode: 0644 + when: py_captive_portal_install + +- name: Enable captive_portal after copying files + service: name=captive_portal.service enabled=yes + when: py_captive_portal_install and py_captive_portal_enabled + +- name: Start captive_portal after copying files + service: name=captive_portal.service state=started + when: py_captive_portal_install and py_captive_portal_enabled + +- name: Disable captive_portal after copying files + service: name=captive_portal.service enabled=no + when: py_captive_portal_install and py_captive_portal_enabled + +- name: Stop captive_portal after copying files + service: name=captive_portal.service state=started + when: py_captive_portal_install and py_captive_portal_enabled diff --git a/roles/network/tasks/main.yml b/roles/network/tasks/main.yml index 6e73f7d4c..959c0b368 100644 --- a/roles/network/tasks/main.yml +++ b/roles/network/tasks/main.yml @@ -74,6 +74,14 @@ include_tasks: squid.yml when: FQDN_changed and squid_install and iiab_stage|int == 9 +#- name: FOREFULLY ENABLE CAPTIVE PORTAL +# set_fact: +# py_captive_portal_install: True + +- name: (Re)Installing captive portal + include_tasks: captive_portal.yml + when: py_captive_portal_install + #### start services - include_tasks: avahi.yml tags: diff --git a/roles/network/templates/captive_portal/captive_portal.py.j2 b/roles/network/templates/captive_portal/captive_portal.py.j2 new file mode 100755 index 000000000..c6021d87c --- /dev/null +++ b/roles/network/templates/captive_portal/captive_portal.py.j2 @@ -0,0 +1,97 @@ +#!/usr/bin/python + +# Captive portal script adapted from https://github.com/nikosft/captive-portal + +import subprocess +import BaseHTTPServer +import cgi + +# These variables are used as settings +PORT = int("{{ captive_portal_port }}") # the port in which the captive portal web server listens +IFACE = "{{ iiab_lan_iface }}" # the interface that captive portal protects +IP_ADDRESS = "172.18.96.1" # the ip address of the captive portal (it can be the IP of IFACE) + +''' +This it the http server used by the the captive portal +''' +class CaptivePortal(BaseHTTPServer.BaseHTTPRequestHandler): + #this is the index of the captive portal + #it simply redirects the user to the to login page + html_redirect = """ + + + + + + Redirecting to login page + + + """%(IP_ADDRESS, PORT) + #the login page + html_login = """ + + + Login Form +
+ Username:
+ Password:
+ +
+ + + """ + + ''' + if the user requests the login page show it, else + use the redirect page + ''' + def do_GET(self): + path = self.path + self.send_response(200) + self.send_header("Content-type", "text/html") + self.end_headers() + if path == "/login": + self.wfile.write(self.html_login) + else: + self.wfile.write(self.html_redirect) + ''' + this is called when the user submits the login form + ''' + def do_POST(self): + self.send_response(200) + self.send_header("Content-type", "text/html") + self.end_headers() + form = cgi.FieldStorage( + fp=self.rfile, + headers=self.headers, + environ={'REQUEST_METHOD':'POST', + 'CONTENT_TYPE':self.headers['Content-Type'], + }) + username = form.getvalue("username") + password = form.getvalue("password") + #dummy security check + if username == '{{ captive_portal_username }}' and password == '{{ captive_portal_password }}': + #authorized user + remote_IP = self.client_address[0] + print 'New authorization from '+ remote_IP + print 'Updating IP tables' + subprocess.call(["iptables","-t", "nat", "-I", "PREROUTING","1", "-s", remote_IP, "-j" ,"ACCEPT"]) + subprocess.call(["iptables", "-I", "FORWARD", "-s", remote_IP, "-j" ,"ACCEPT"]) + self.wfile.write("You are now authorized. Navigate to any URL") + else: + #show the login form + self.wfile.write(self.html_login) + + #the following function makes server produce no output + #comment it out if you want to print diagnostic messages + #def log_message(self, format, *args): + # return + +print "Starting captive portal web server" +httpd = BaseHTTPServer.HTTPServer(('', PORT), CaptivePortal) + +try: + httpd.serve_forever() +except KeyboardInterrupt: + pass +httpd.server_close() diff --git a/roles/network/templates/captive_portal/captive_portal.service.j2 b/roles/network/templates/captive_portal/captive_portal.service.j2 new file mode 100644 index 000000000..77a055cb4 --- /dev/null +++ b/roles/network/templates/captive_portal/captive_portal.service.j2 @@ -0,0 +1,15 @@ +[Unit] +Description=Captive portal +After=syslog.target + +[Service] +Type=simple +User=iiab-admin +Group=iiab-admin +WorkingDirectory=/opt/iiab/captive-portal +ExecStart=/opt/iiab/captive-portal/captive_portal.py +StandardOutput=syslog +StandardError=syslog + +[Install] +WantedBy=multi-user.target