From 4ee9c3e2b599115700d19ec057bbfbe9a8eb5111 Mon Sep 17 00:00:00 2001 From: George Hunt Date: Fri, 24 Aug 2018 00:26:20 +0000 Subject: [PATCH 01/28] add in template dir rebase bassed upon copy in cut out obvious dead code working on put-204 make users a sqlite db sqlite db has users, and agent info android timeouts not yet working android 5 and 6 both work. lost mac return to a working version for the MAC. Missing the splash android,mac,windows all appear to work sqlite get status of execute row == Null initialize lasttimestamp with ajax call when home is triggered remove commented code, move towards logging vs print statements add logging with the -l flag no changes to default_vars.yml drop iptables captive portal stuff not using port 8090, and dnsmasq missed deleting trap_enabled fixes for 6.7 defaults add in template dir rebase bassed upon copy in cut out obvious dead code working on put-204 make users a sqlite db sqlite db has users, and agent info android timeouts not yet working android 5 and 6 both work. lost mac return to a working version for the MAC. Missing the splash android,mac,windows all appear to work sqlite get status of execute row == Null initialize lasttimestamp with ajax call when home is triggered remove commented code, move towards logging vs print statements drop iptables captive portal stuff not using port 8090, and dnsmasq missed deleting trap_enabled fixes for 6.7 defaults dispense with apache logs for captive portal, use the rotating portal.log instead bring in clean defaults and py Squash debugging details remove backup file still cannot dispense with cna on iphone. mac escape from cna broke with these changes captive comes after iiab in apache config one filename wrong logging used for debug, lost mac escape from cna typos got mac/iphone full browser back remove dead code python was not creating db, or putting ip when first encountered --- roles/1-prep/templates/.iiab.env.j2.un~ | Bin 0 -> 649 bytes roles/1-prep/templates/iiab.env.j2 | 2 + roles/httpd/templates/010-iiab.conf.j2 | 19 +- roles/network/files/mac.template | 54 ++ roles/network/files/simple.template | 100 ++++ roles/network/tasks/captive_portal.yml | 105 +++- roles/network/tasks/hosts.yml | 2 +- .../captive-portal/captive-portal.conf | 14 + .../captive-portal.py.j2} | 0 .../captive-portal.service.j2} | 2 +- .../templates/captive-portal/capture-wsgi.py | 550 ++++++++++++++++++ .../templates/captive-portal/checkurls | 21 + .../templates/captive-portal/iiab-catch | 9 + .../templates/captive-portal/iiab-uncatch | 13 + .../templates/gateway/iiab-gen-iptables | 14 +- vars/default_vars.yml | 30 + 16 files changed, 897 insertions(+), 38 deletions(-) create mode 100644 roles/1-prep/templates/.iiab.env.j2.un~ create mode 100644 roles/network/files/mac.template create mode 100644 roles/network/files/simple.template create mode 100644 roles/network/templates/captive-portal/captive-portal.conf rename roles/network/templates/{captive_portal/captive_portal.py.j2 => captive-portal/captive-portal.py.j2} (100%) rename roles/network/templates/{captive_portal/captive_portal.service.j2 => captive-portal/captive-portal.service.j2} (80%) create mode 100755 roles/network/templates/captive-portal/capture-wsgi.py create mode 100755 roles/network/templates/captive-portal/checkurls create mode 100755 roles/network/templates/captive-portal/iiab-catch create mode 100755 roles/network/templates/captive-portal/iiab-uncatch diff --git a/roles/1-prep/templates/.iiab.env.j2.un~ b/roles/1-prep/templates/.iiab.env.j2.un~ new file mode 100644 index 0000000000000000000000000000000000000000..b9f549ce150d79452aff79c6fd84e04a84434ffa GIT binary patch literal 649 zcmWH`%$*;a=aT=Ff$4SHzK_+9-*>-EeYak3r9$M11vQ8F3tLUTw^E#I?MGJ$1_lNm zAVvm^Kn@6l0E`XhM=!Kk&jJyNzW|X(Awg1{Fp>X205=9EI7$;A0`QOoYC(>oFqjd* z=vW7hj<2A2 - - Options Indexes FollowSymLinks - AllowOverride None - Require all granted - - + + ErrorLog /var/log/apache2/error.log + CustomLog /var/log/apache2/access.log combined + ServerName box + ServerAlias box.lan + + Options Indexes FollowSymLinks + AllowOverride None + Require all granted + + # # UserDir: The name of the directory that is appended onto a user's home # directory if a ~user request is received. diff --git a/roles/network/files/mac.template b/roles/network/files/mac.template new file mode 100644 index 000000000..658aa6b98 --- /dev/null +++ b/roles/network/files/mac.template @@ -0,0 +1,54 @@ + + + + + Success + + + + Success +
+
+ +

Welcome to IIAB

+

+ {{ message }} +
+

+

+

+

+ {{ btn1 }} +
+ + diff --git a/roles/network/files/simple.template b/roles/network/files/simple.template new file mode 100644 index 000000000..152a1607c --- /dev/null +++ b/roles/network/files/simple.template @@ -0,0 +1,100 @@ + + + + Success + + + + + + + + {% if success_token is defined %} + Success + {% endif %} +
+
+ +

Welcome to IIAB

+

+ {{ message }} +
+ {% if btn2 is defined %} + {{ btn2 }} + {% endif %} +

+

+

+

+ + {{ btn1 }} +
+ + diff --git a/roles/network/tasks/captive_portal.yml b/roles/network/tasks/captive_portal.yml index 033314121..7fc549af7 100644 --- a/roles/network/tasks/captive_portal.yml +++ b/roles/network/tasks/captive_portal.yml @@ -1,3 +1,9 @@ +- name: Get python dateutil + package: + name: python-dateutil + state: present + when: py_captive_portal_install + - name: Create directory for Captive Portal script file: path: /opt/iiab/captive-portal @@ -6,42 +12,105 @@ - 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: root - group: root - mode: 0740 + src: "{{ item.src }}" + dest: /opt/iiab/captive-portal/ + mode: "{{ item.mode }}" + with_items: + - { src: roles/network/templates/captive-portal/checkurls, mode: '0644' } + - { src: roles/network/templates/captive-portal/capture-wsgi.py, mode: '0755' } when: py_captive_portal_install +- name: Copy the jinja2 template to captive portal + copy: + src: roles/network/files/simple.template + dest: /opt/iiab/captive-portal/ + +- name: Copy the jinja2 template to captive portal + copy: + src: roles/network/files/mac.template + dest: /opt/iiab/captive-portal/ + +- name: Copy Captive Portal scripts + template: + src: "{{ item.src }}" + dest: /usr/bin/ + owner: root + group: root + mode: 0755 + with_items: + - src: roles/network/templates/captive-portal/iiab-catch + - src: roles/network/templates/captive-portal/iiab-uncatch + when: py_captive_portal_install + +- name: Generate the diversion lists for dnsmasq and apache2 + shell: /usr/bin/iiab-uncatch + when: py_captive_portal_install + + 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 + src: roles/network/templates/captive-portal/captive-portal.service.j2 + dest: /etc/systemd/system/captive-portal.service owner: root group: root mode: 0644 when: py_captive_portal_install -- name: Enable captive_portal after copying files +- name: Copy Captive Portal Apache config file + template: + src: roles/network/templates/captive-portal/captive-portal.conf + dest: /etc/{{ apache_config_dir }}/captive-portal.conf + owner: root + group: root + mode: 0740 + when: py_captive_portal_install and py_captive_portal_enabled + +- name: Enable captive-portal after copying files service: - name: captive_portal.service + name: captive-portal.service enabled: yes when: py_captive_portal_install and py_captive_portal_enabled -- name: Start captive_portal after copying files +- name: Enable Apache config file + file: + src: /etc/apache2/sites-available/captive-portal.conf + dest: /etc/apache2/sites-enabled/captive-portal.conf + state: link + when: py_captive_portal_enabled and is_debuntu + +- name: Enable Apache ssl config file + file: + src: /etc/apache2/sites-available/default-ssl.conf + dest: /etc/apache2/sites-enabled/default-ssl.conf + state: link + when: py_captive_portal_enabled and is_debuntu + +- name: Start captive-portal after copying files service: - name: captive_portal.service + name: captive-portal.service state: started when: py_captive_portal_install and py_captive_portal_enabled -- name: Disable captive_portal after copying files +- name: Disable captive-portal after copying files service: - name: captive_portal.service + name: captive-portal.service enabled: no - when: py_captive_portal_install and py_captive_portal_enabled + when: py_captive_portal_install and not py_captive_portal_enabled -- name: Stop captive_portal after copying files +- name: Stop captive-portal after copying files service: - name: captive_portal.service - state: started - when: py_captive_portal_install and py_captive_portal_enabled + name: captive-portal.service + state: stopped + when: py_captive_portal_install and not py_captive_portal_enabled + +- name: Disable Apache config file + file: + dest: /etc/apache2/sites-enabled/captive-portal.conf + state: absent + when: not py_captive_portal_enabled and is_debuntu + +- name: Make sure dnsmasq is not diverting if captive-portal disabled + file: + dest: /etc/dnsmasq.d/capture + state: absent + when: not py_captive_portal_enabled diff --git a/roles/network/tasks/hosts.yml b/roles/network/tasks/hosts.yml index cf4b38278..311722aea 100644 --- a/roles/network/tasks/hosts.yml +++ b/roles/network/tasks/hosts.yml @@ -15,7 +15,7 @@ - name: Configure fqdn in /etc/hosts appliance mode lineinfile: dest=/etc/hosts regexp='^127\.0\.0\.1' - line='127.0.0.1 localhost.localdomain localhost {{ iiab_hostname }}.{{ iiab_domain }} {{ iiab_hostname }} box ' + line='127.0.0.1 localhost.localdomain localhost' owner=root group=root mode=0644 diff --git a/roles/network/templates/captive-portal/captive-portal.conf b/roles/network/templates/captive-portal/captive-portal.conf new file mode 100644 index 000000000..6c5a8a012 --- /dev/null +++ b/roles/network/templates/captive-portal/captive-portal.conf @@ -0,0 +1,14 @@ + + # The ServerName directive sets the request scheme, hostname and port that + # the server uses to identify itself. This is used when creating + # redirection URLs. In the context of virtual hosts, the ServerName + # specifies what hostname must appear in the request's Host: header to + # match this virtual host. For the default virtual host (this file) this + # value is not decisive as it is used as a last resort host regardless. + # However, you must set it for any further virtual host explicitly. + ServerName iiab.io + Include /etc/apache2/capture + ProxyPreserveHost On + ProxyPass / http://box.lan:{{ py_captive_portal_port }}/ + ProxyPassReverse / http://box.lan:{{ py_captive_portal_port }}/ + diff --git a/roles/network/templates/captive_portal/captive_portal.py.j2 b/roles/network/templates/captive-portal/captive-portal.py.j2 similarity index 100% rename from roles/network/templates/captive_portal/captive_portal.py.j2 rename to roles/network/templates/captive-portal/captive-portal.py.j2 diff --git a/roles/network/templates/captive_portal/captive_portal.service.j2 b/roles/network/templates/captive-portal/captive-portal.service.j2 similarity index 80% rename from roles/network/templates/captive_portal/captive_portal.service.j2 rename to roles/network/templates/captive-portal/captive-portal.service.j2 index 03f3c33d5..f1c398bef 100644 --- a/roles/network/templates/captive_portal/captive_portal.service.j2 +++ b/roles/network/templates/captive-portal/captive-portal.service.j2 @@ -7,7 +7,7 @@ Type=simple User=root Group=root WorkingDirectory=/opt/iiab/captive-portal -ExecStart=/opt/iiab/captive-portal/captive_portal.py +ExecStart=/opt/iiab/captive-portal/capture-wsgi.py StandardOutput=syslog StandardError=syslog diff --git a/roles/network/templates/captive-portal/capture-wsgi.py b/roles/network/templates/captive-portal/capture-wsgi.py new file mode 100755 index 000000000..3c36c3c34 --- /dev/null +++ b/roles/network/templates/captive-portal/capture-wsgi.py @@ -0,0 +1,550 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# using Python's bundled WSGI server + +from wsgiref.simple_server import make_server +import subprocess +from dateutil.tz import * +import datetime +import logging +from logging.handlers import RotatingFileHandler +import os +import sys +from jinja2 import Environment, FileSystemLoader +import sqlite3 +import re + +# Notes on timeout strategy +# every client timestamp is recorded into current_ts +# When splash page is clicked , return 204 timeout starts (via ajax call), +# Return 204 is android (may be different for different versions) +# captive portal redirect is triggered after inactivity timeout, +# which needs to be longer than period of normal connecetivity checks by OS +# + +# Create the jinja2 environment. +CAPTIVE_PORTAL_BASE = "/opt/iiab/captive-portal" +j2_env = Environment(loader=FileSystemLoader(CAPTIVE_PORTAL_BASE),trim_blocks=True) + +# Define time outs +INACTIVITY_TO = 30 +PORTAL_TO = 0 # delay after triggered by ajax upon click of link to home page +# I had hoped that returning 204 status after some delay +# would dispense with android's "sign-in to network" (no work) + + +# Get the IIAB variables +sys.path.append('/etc/iiab/') +from iiab_env import get_iiab_env +doc_root = get_iiab_env("WWWROOT") + +# make a way to find new URLs queried by new clients +# CATCH substitues this server for apache at port 80 +CATCH = False +if len(sys.argv) > 1 and sys.argv[1] == '-d': + CATCH = True + PORT=80 +else: + PORT=9090 + +# set up some logging -- selectable for diagnostics +# Create dummy iostream to capture stderr and stdout +class StreamToLogger(object): + """ + Fake file-like stream object that redirects writes to a logger instance. + """ + def __init__(self, logger, log_level=logging.INFO): + self.logger = logger + self.log_level = log_level + self.linebuf = '' + + def write(self, buf): + for line in buf.rstrip().splitlines(): + self.logger.log(self.log_level, line.rstrip()) + +if len(sys.argv) > 1 and sys.argv[1] == '-l': + loggingLevel = logging.DEBUG +else: + loggingLevel = logging.ERROR +loggingLevel = logging.DEBUG +logging.basicConfig(filename='/var/log/apache2/portal.log',format='%(asctime)s.%(msecs)03d:%(name)s:%(message)s', datefmt='%M:%S',level=loggingLevel) + + +logger = logging.getLogger('/var/log/apache2/portal.log') +handler = RotatingFileHandler("/var/log/apache2/portal.log", maxBytes=100000, backupCount=2) +logger.addHandler(handler) + + +# divert stdout and stderr to logger +stdout_logger = logging.getLogger('STDOUT') +sl = StreamToLogger(stdout_logger, logging.ERROR) +#sys.stdout = sl + +stderr_logger = logging.getLogger('STDERR') +sl = StreamToLogger(stderr_logger, logging.ERROR) +sys.stderr = sl + + +# Define globals +MAC_SUCCESS=False +ANDROID_TRIGGERED=False + +logger.debug("") +logger.debug('##########################################') +# what language are we speaking? +lang = os.environ['LANG'][0:2] +logger.debug('speaking: %s'%lang) + +def tstamp(dtime): + '''return a UNIX style seconds since 1970 for datetime input''' + epoch = datetime.datetime(1970, 1, 1,tzinfo=tzutc()) + newdtime = dtime.astimezone(tzutc()) + since_epoch_delta = newdtime - epoch + return since_epoch_delta.total_seconds() + +# ##########database operations ############## +# Use a sqlite database to store per client information +user_db = os.path.join(CAPTIVE_PORTAL_BASE,"users.sqlite") +conn = sqlite3.connect(user_db) +if not os.path.exists(user_db): + conn.close() + conn = sqlite3.connect(user_db) +c = conn.cursor() +c.row_factory = sqlite3.Row +c.execute( """create table IF NOT EXISTS users + (ip text PRIMARY KEY, mac text, current_ts integer, + lasttimestamp integer, send204after integer, + os text, os_version text, + ymd text)""") + +def update_user(ip, mac, system, system_version, ymd): + sql = "SELECT * FROM users WHERE ip = ?" + c.execute(sql,(ip,)) + row = c.fetchone() + if row == None: + sql = "INSERT INTO users (ip,mac,os,os_version,ymd) VALUES (?,?,?,?,?)" + c.execute(sql,(ip, mac, system, system_version, ymd )) + else: + sql = "UPDATE users SET (mac,os,os_version,ymd) = ( ?, ?, ?, ? ) WHERE ip = ?" + c.execute(sql,(mac, system, system_version, ymd, ip,)) + conn.commit() + +def platform_info(ip): + sql = "select * FROM users WHERE ip = ?" + c.execute(sql,(ip,)) + row = c.fetchone() + if row is None: return ('','',) + return (row['os'],row['os_version']) + +def timeout_info(ip): + sql = "select * FROM users WHERE ip = ?" + c.execute(sql,(ip,)) + row = c.fetchone() + if row is None: return (0,0,0,) + return [row['current_ts'],row['lasttimestamp'],row['send204after']] + +def is_inactive(ip): + ts=tstamp(datetime.datetime.now(tzutc())) + current_ts, last_ts, send204after = timeout_info(ip) + if not last_ts: + return True + if ts - int(last_ts) > INACTIVITY_TO: + return True + else: + return False + +def is_after204_timeout(ip): + ts=tstamp(datetime.datetime.now(tzutc())) + current_ts, last_ts, send204after = timeout_info(ip) + if send204after == 0: return False + logger.debug("function: is_after204_timeout send204after:%s current: %s"%(send204after,ts,)) + if not send204after: + return False + if ts - int(send204after) > 0: + return True + else: + return False + +def set_204after(ip,value): + global ANDROID_TRIGGERED + ts=tstamp(datetime.datetime.now(tzutc())) + sql = 'UPDATE users SET send204after = ? where ip = ?' + c.execute(sql,(ts + value,ip,)) + conn.commit() + ANDROID_TRIGGERED = False + +def set_lasttimestamp(ip): + ts=tstamp(datetime.datetime.now(tzutc())) + sql = 'UPDATE users SET lasttimestamp = ? where ip = ?' + c.execute(sql,(ts,ip,)) + conn.commit() + +# ################### Action routines based on OS ################3 +def microsoft(environ,start_response): + #logger.debug("sending microsoft response") + en_txt={ 'message':"Click on the button to go to the IIAB home page",\ + 'btn1':"GO TO IIAB HOME PAGE",'doc_root':get_iiab_env("WWWROOT")} + es_txt={ 'message':"Haga clic en el botón para ir a la página de inicio de IIAB",\ + 'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")} + if lang == "en": + txt = en_txt + elif lang == "es": + txt = es_txt + response_body = str(j2_env.get_template("simple.template").render(**txt)) + status = '200 OK' + response_headers = [('Content-type','text/html'), + ('Content-Length',str(len(response_body)))] + start_response(status, response_headers) + return [response_body] + +def android(environ, start_response): + global ANDROID_TRIGGERED + ip = environ['HTTP_X_FORWARDED_FOR'].strip() + system,system_version = platform_info(ip) + if system_version[0:1] < '6': + logger.debug("system < 6:%s"%system_version) + location = '/android_splash' + set_204after(ip,0) + else: + set_204after(ip,20) + location = '/android_https' + agent = environ['HTTP_USER_AGENT'] + response_body = "hello" + status = '302 Moved Temporarily' + response_headers = [('Location',location)] + start_response(status, response_headers) + return [response_body] + +def android_splash(environ, start_response): + en_txt={ 'message':"Click on the button to go to the IIAB home page",\ + 'btn1':"GO TO IIAB HOME PAGE", \ + 'doc_root':get_iiab_env("WWWROOT") } + es_txt={ 'message':"Haga clic en el botón para ir a la página de inicio de IIAB",\ + 'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")} + if lang == "en": + txt = en_txt + elif lang == "es": + txt = es_txt + response_body = str(j2_env.get_template("simple.template").render(**txt)) + status = '200 OK' + response_headers = [('Content-type','text/html'), + ('Content-Length',str(len(response_body)))] + start_response(status, response_headers) + return [response_body] + +def android_https(environ, start_response): + en_txt={ 'message':"""Please ignore the SECURITY warning which appears after clicking the first button""",\ + 'btn2':'Click this first Go to the browser we need',\ + 'btn1':'Then click this to go to IIAB home page',\ + 'doc_root':get_iiab_env("WWWROOT") } + es_txt={ 'message':"Haga clic en el botón para ir a la página de inicio de IIAB",\ + 'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")} + if lang == "en": + txt = en_txt + elif lang == "es": + txt = es_txt + response_body = str(j2_env.get_template("simple.template").render(**txt)) + status = '200 OK' + response_headers = [('Content-type','text/html'), + ('Content-Length',str(len(response_body)))] + start_response(status, response_headers) + return [response_body] + +def mac_splash(environ,start_response): + logger.debug("in function mac_splash") + en_txt={ 'message':"Click on the button to go to the IIAB home page",\ + 'btn1':"GO TO IIAB HOME PAGE",'success_token': 'Success', + 'doc_root':get_iiab_env("WWWROOT")} + es_txt={ 'message':"Haga clic en el botón para ir a la página de inicio de IIAB",\ + 'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")} + if lang == "en": + txt = en_txt + elif lang == "es": + txt = es_txt + set_lasttimestamp(ip) + response_body = str(j2_env.get_template("mac.template").render(**txt)) + status = '200 Success' + response_headers = [('Content-type','text/html'), + ('Content-Length',str(len(response_body)))] + start_response(status, response_headers) + return [response_body] + +def macintosh(environ, start_response): + global ip + logger.debug("in function mcintosh") + if not is_inactive(ip): + set_lasttimestamp(ip) + return success(environ,start_response) + # determine if it is time to redirect again + if is_after204_timeout(ip): + set_204after(ip,10) + response_body = """""" + status = '302 Moved Temporarily' + response_headers = [('content','text/html')] + start_response(status, response_headers) + return [response_body] + else: + return mac_splash(environ,start_response) + +def microsoft_connect(environ,start_response): + status = '200 ok' + headers = [('Content-type', 'text/html')] + start_response(status, headers) + return ["Microsoft Connect Test"] + +# ============= Return html pages ============================ +def banner(environ, start_response): + status = '200 OK' + headers = [('Content-type', 'image/png')] + start_response(status, headers) + image = open("%s/iiab-menu/menu-files/images/iiab_banner6.png"%doc_root, "rb").read() + return [image] + +def bootstrap(environ, start_response): + logger.debug("in bootstrap") + status = '200 OK' + headers = [('Content-type', 'text/javascript')] + start_response(status, headers) + boot = open("%s/common/js/bootstrap.min.js"%doc_root, "rb").read() + return [boot] + +def jquery(environ, start_response): + logger.debug("in jquery") + status = '200 OK' + headers = [('Content-type', 'text/javascript')] + start_response(status, headers) + boot = open("%s/common/js/jquery.min.js"%doc_root, "rb").read() + return [boot] + +def bootstrap_css(environ, start_response): + logger.debug("in bootstrap_css") + status = '200 OK' + headers = [('Content-type', 'text/css')] + start_response(status, headers) + boot = open("%s/common/css/bootstrap.min.css"%doc_root, "rb").read() + return [boot] + +def null(environ, start_response): + status = '200 ok' + headers = [('Content-type', 'text/html')] + start_response(status, headers) + return [""] + +def success(environ, start_response): + status = '200 ok' + html = 'SuccessSuccess' + headers = [('Content-type', 'text/html')] + start_response(status, headers) + return [html] + +def put_204(environ, start_response): + status = '204 No Data' + response_body = '' + response_headers = [('Content-type','text/html'), + ('Content-Length',str(len(response_body)))] + start_response(status, response_headers) + logger.debug("sending 204 html response") + return [response_body] + +def parse_agent(agent): + system = '' + system_version = '' + match = re.search(r"(Android)\s([.\d]*)",agent) + if match: + system = match.group(1) + system_version = match.group(2) + match = re.search(r"(OS X)\s([\d_]*)",agent) + if match: + system = match.group(1) + system_version = match.group(2) + match = re.search(r"(iPhone OS)\s([\d_]*)",agent) + if match: + system = match.group(1) + system_version = match.group(2) + match = re.search(r"(Windows NT)\s([\d.]*)",agent) + if match: + system = match.group(1) + system_version = match.group(2) + return (system, system_version) + +# +# ================== Start serving the wsgi application ================= +def application (environ, start_response): + global ip + global CATCH + global LIST + global INACTIVITY_TO + global ANDROID_TRIGGERED + + # Log the URLs that are not in checkurls + # This "CATCH" mode substitutes this server for apache at port 80 + # CATCH mode is started by "iiab-catch" and turned off by "iiab-uncath". + if CATCH: + logger.debug("Checking for url %s. USER_AGENT:%s"%(environ['HTTP_HOST'],\ + environ['HTTP_USER_AGENT'],)) + if environ['HTTP_HOST'] == '/box.lan': + return + if 'HTTP_X_FORWARDED_FOR' in environ: + ip = environ['HTTP_X_FORWARDED_FOR'].strip() + else: + ip = environ['HTTP_HOST'].strip() + cmd="arp -an %s|gawk \'{print $4}\'" % ip + mac = subprocess.check_output(cmd, shell=True) + data = [] + data.append("host: %s\n"%environ['HTTP_HOST']) + data.append("path: %s\n"%environ['PATH_INFO']) + data.append("query: %s\n"%environ['QUERY_STRING']) + data.append("ip: %s\n"%ip) + agent = environ['HTTP_USER_AGENT'] + data.append("AGENT: %s\n"%agent) + #print(data) + found = False + url_list = os.path.join(CAPTIVE_PORTAL_BASE,"checkurls") + if os.path.exists(url_list): + with open(url_list,"r") as checkers: + for line in checkers: + if line.find(environ['HTTP_HOST']) > -1: + found = True + break + if not found: + with open(url_list,"a") as checkers: + outstr ="%s\n" % (environ['HTTP_HOST']) + checkers.write(outstr) + data = ['%s: %s\n' % (key, value) for key, value in sorted(environ.items()) ] + logger.debug("This url was missing from checkurls:%s"%data) + + # Normal query for captive portal + else: + if 'HTTP_X_FORWARDED_FOR' in environ: + ip = environ['HTTP_X_FORWARDED_FOR'].strip() + else: + data = ['%s: %s\n' % (key, value) for key, value in sorted(environ.items()) ] + #logger.debug("need the correct ip:%s"%data) + ip = environ['REMOTE_ADDR'].strip() + cmd="arp -an %s|gawk \'{print $4}\'" % ip + mac = subprocess.check_output(cmd, shell=True) + data = [] + data.append("host: %s\n"%environ['HTTP_HOST']) + data.append("path: %s\n"%environ['PATH_INFO']) + data.append("query: %s\n"%environ['QUERY_STRING']) + data.append("ip: %s\n"%ip) + agent = environ['HTTP_USER_AGENT'] + data.append("AGENT: %s\n"%agent) + logger.debug(data) + #print(data) + found = False + return_204_flag = "False" + + # record the activity with this ip + ts=tstamp(datetime.datetime.now(tzutc())) + sql = "INSERT or IGNORE INTO users (current_ts,ip) VALUES (?,?)" + c.execute(sql,(ts,ip,)) + sql = "UPDATE users SET current_ts = ? where ip = ?" + c.execute(sql,(ts,ip,)) + if c.rowcount == 0: + logger.debug("failed UPDATE users SET current_ts = %s WHERE ip = %s"%(ts,ip,)) + conn.commit() + ymd=datetime.datetime.today().strftime("%y%m%d-%H%M") + + system,system_version = parse_agent(agent) + if system != '': + update_user(ip, mac, system, system_version, ymd) + +####### Return pages based upon PATH ############### + # do more specific stuff first + if environ['PATH_INFO'] == "/iiab_banner6.png": + return banner(environ, start_response) + + if environ['PATH_INFO'] == "/bootstrap.min.js": + return bootstrap(environ, start_response) + + if environ['PATH_INFO'] == "/bootstrap.min.css": + return bootstrap_css(environ, start_response) + + if environ['PATH_INFO'] == "/jquery.min.js": + return jquery(environ, start_response) + + if environ['PATH_INFO'] == "/favicon.ico": + return null(environ, start_response) + + if environ['PATH_INFO'] == "/home_selected": + # the js link to home page triggers this ajax url + # mark the sign-in conversation completed, return 204 or Success or Success + ANDROID_TRIGGERED = True + #data = ['%s: %s\n' % (key, value) for key, value in sorted(environ.items()) ] + #logger.debug("need the correct ip:%s"%data) + logger.debug("function: home_selected. Setting flag to return_204") + #print("setting flag to return_204") + set_204after(ip,PORTAL_TO) + set_lasttimestamp(ip) + status = '200 OK' + headers = [('Content-type', 'text/html')] + start_response(status, headers) + return [""] + +#### parse OS platform based upon URL ################## + # mac + if environ['PATH_INFO'] == "/mac_splash": + return mac_splash(environ, start_response) + + if environ['PATH_INFO'] == "/step2": + return step2(environ, start_response) + + if environ['HTTP_HOST'] == "captive.apple.com" or\ + environ['HTTP_HOST'] == "appleiphonecell.com" or\ + environ['HTTP_HOST'] == "detectportal.firefox.com" or\ + environ['HTTP_HOST'] == "*.apple.com.edgekey.net" or\ + environ['HTTP_HOST'] == "gsp1.apple.com" or\ + environ['HTTP_HOST'] == "apple.com" or\ + environ['HTTP_HOST'] == "www.apple.com": + current_ts, last_ts, send204after = timeout_info(ip) + if not send204after: + # take care of uninitialized state + set_204after(ip,0) + return macintosh(environ, start_response) + + # android + if environ['PATH_INFO'] == "/android_splash": + return android_splash(environ, start_response) + if environ['PATH_INFO'] == "/android_https": + return android_https(environ, start_response) + if environ['HTTP_HOST'] == "clients3.google.com" or\ + environ['HTTP_HOST'] == "mtalk.google.com" or\ + environ['HTTP_HOST'] == "alt7-mtalk.google.com" or\ + environ['HTTP_HOST'] == "alt6-mtalk.google.com" or\ + environ['HTTP_HOST'] == "connectivitycheck.android.com" or\ + environ['HTTP_HOST'] == "connectivitycheck.gstatic.com": + current_ts, last_ts, send204after = timeout_info(ip) + if not last_ts or (ts - int(last_ts) > INACTIVITY_TO): + return android(environ, start_response) + elif is_after204_timeout(ip): + return put_204(environ,start_response) + return #return without doing anything + + # microsoft + if environ['PATH_INFO'] == "/connecttest.txt" and not is_inactive(ip): + return microsoft_connect(environ, start_response) + if environ['HTTP_HOST'] == "ipv6.msftncsi.com" or\ + environ['HTTP_HOST'] == "ipv6.msftncsi.com.edgesuite.net" or\ + environ['HTTP_HOST'] == "www.msftncsi.com" or\ + environ['HTTP_HOST'] == "www.msftncsi.com.edgesuite.net" or\ + environ['HTTP_HOST'] == "www.msftconnecttest.com" or\ + environ['HTTP_HOST'] == "teredo.ipv6.microsoft.com" or\ + environ['HTTP_HOST'] == "teredo.ipv6.microsoft.com.nsatc.net": + return microsoft(environ, start_response) + + logger.debug("executing the defaut 204 response. [%s"%data) + return put_204(environ,start_response) + +# Instantiate the server +httpd = make_server ( + "", # The host name + PORT, # A port number where to wait for the request + application # The application object name, in this case a function +) + +httpd.serve_forever() +#vim: tabstop=3 expandtab shiftwidth=3 softtabstop=3 background=dark + diff --git a/roles/network/templates/captive-portal/checkurls b/roles/network/templates/captive-portal/checkurls new file mode 100755 index 000000000..445022872 --- /dev/null +++ b/roles/network/templates/captive-portal/checkurls @@ -0,0 +1,21 @@ +clients3.google.com +connectivitycheck.gstatic.com +detectportal.firefox.com +*.akamaitechnologies.com +appleiphonecell.com +thinkdifferent.us +*.apple.com.edgekey.net +ipv6.msftncsi.com +ipv6.msftncsi.com.edgesuite.net +www.msftncsi.com +www.msftncsi.com.edgesuite.net +www.msftconnecttest.com +teredo.ipv6.microsoft.com +teredo.ipv6.microsoft.com.nsatc.net +captive.apple.com +init-p01st.push.apple.com +mtalk.google.com +connectivitycheck.android.com +alt7-mtalk.google.com +alt6-mtalk.google.com +captive.lan diff --git a/roles/network/templates/captive-portal/iiab-catch b/roles/network/templates/captive-portal/iiab-catch new file mode 100755 index 000000000..dcff8ab90 --- /dev/null +++ b/roles/network/templates/captive-portal/iiab-catch @@ -0,0 +1,9 @@ +#!/bin/bash -x +# substitute our own server to catch OS connectivity checking URL's + +systemctl stop apache2 +systemctl stop captive-portal +echo address=/#/172.18.96.1 > /etc/dnsmasq.d/capture +/opt/iiab/captive-portal/capture-wsgi.py -d & +# write the pid just started +echo $! > /opt/iiab/captive-portal/pid diff --git a/roles/network/templates/captive-portal/iiab-uncatch b/roles/network/templates/captive-portal/iiab-uncatch new file mode 100755 index 000000000..8b885c332 --- /dev/null +++ b/roles/network/templates/captive-portal/iiab-uncatch @@ -0,0 +1,13 @@ +#!/bin/bash -x +# Turn off URL recording mode, and return to serving with apache2 + +kill $(cat /opt/iiab/captive-portal/pid) +# during testing, I start capture by hand -- recorded pid may be stale +pid=$(ps aux | grep "capture-wsgi.py -d" | grep -v grep | awk '{print $2}') +if [ -n "$pid" ];then + kill $pid +fi +awk '{print("address=/" $1 "/172.18.96.1")}' /opt/iiab/captive-portal/checkurls > /etc/dnsmasq.d/capture +awk '{print("ServerAlias ",$1)}' /opt/iiab/captive-portal/checkurls > /etc/apache2/capture +systemctl start captive-portal +systemctl start apache2 diff --git a/roles/network/templates/gateway/iiab-gen-iptables b/roles/network/templates/gateway/iiab-gen-iptables index fdd91f56d..22fd10e08 100755 --- a/roles/network/templates/gateway/iiab-gen-iptables +++ b/roles/network/templates/gateway/iiab-gen-iptables @@ -62,7 +62,6 @@ transmission_http_port={{ transmission_http_port }} transmission_peer_port={{ transmission_peer_port }} sugarizer_port={{ sugarizer_port }} block_DNS={{ block_DNS }} -captive_portal_enabled={{ captive_portal_enabled }} py_captive_portal_enabled={{ py_captive_portal_enabled }} echo "LAN is $lan and WAN is $wan" @@ -124,16 +123,11 @@ if [ "$block_DNS" == "True" ];then $IPTABLES -t nat -A PREROUTING -i $lan -p udp --dport 53 ! -d {{ lan_ip }} -j DNAT --to {{ lan_ip }}:53 fi -if [ "$captive_portal_enabled" == "True" ];then - $IPTABLES -t mangle -N internet - $IPTABLES -t mangle -A PREROUTING -i {{ iiab_lan_iface }} -p tcp -m tcp --dport 80 -j internet - $IPTABLES -t mangle -A internet -j MARK --set-mark 99 - $IPTABLES -t nat -A PREROUTING -i {{ iiab_lan_iface }} -p tcp -m mark --mark 99 -m tcp --dport 80 -j DNAT --to-destination {{ lan_ip }} +if [ "$py_captive_portal_enabled" == "True" ];then + $IPTABLES -t nat -A PREROUTING -i $lan -p tcp --dport 80 ! -d {{ lan_ip }} -j DNAT --to {{ lan_ip }}:{{ py_captive_portal_port }} +fi -elif [ "py_$captive_portal_enabled" == "True" ];then - $IPTABLES -t nat -A PREROUTING -i $lan -p tcp --dport 80 ! -d {{ lan_ip }} -j DNAT --to {{ lan_ip }}:{{ py_captive_portal_port }} - -elif [ "$HTTPCACHE_ON" == "True" ]; then +if [ "$HTTPCACHE_ON" == "True" ]; then $IPTABLES -t nat -A PREROUTING -i $lan -p tcp --dport 80 ! -d {{ lan_ip }} -j DNAT --to {{ lan_ip }}:3128 fi diff --git a/vars/default_vars.yml b/vars/default_vars.yml index ac666d5a3..01a15c72a 100644 --- a/vars/default_vars.yml +++ b/vars/default_vars.yml @@ -158,6 +158,8 @@ wan_nameserver: # 2-COMMON +<<<<<<< HEAD +<<<<<<< HEAD # 3-BASE-SERVER # roles/httpd (Apache configuration) runs here @@ -168,6 +170,34 @@ apache_allow_sudo: True # For schools that use WordPress and/or Moodle intensively. See iiab/iiab #1147 # WARNING: Enabling this (might) cause excess use of RAM or other resources? apache_high_php_limits: False +======= + # Intended for developers: ONLY CHANGE THESE IF YOU KNOW WHAT YOU ARE DOING + # The following 2 override the detection when not "auto" + user_wan_iface: auto + user_lan_iface: auto + wan_ip: dhcp + wan_netmask: + wan_gateway: + wan_nameserver: + # exFAT is auto-enabled for all "debuntu" OS's as of Nov 2017, in roles/2-common/tasks/packages.yml#L35-L36 + # exFAT_enabled: True + + # Parameters by Aggregate Roles + # Each Role must have the following variables which are either True or False: + # _install + # _enabled +>>>>>>> da77e233... add in template dir + + # Our past convention was to install everything in all aggregates + # And to enable everything in 1-PREP, 2-COMMON, and 3-BASE-SERVER +======= +# 3-BASE-SERVER +>>>>>>> ce391f0a... bring in clean defaults and py + +# Make this False to disable http://box/common/services/power_off.php button: +allow_apache_sudo: True + +# roles/httpd runs here # roles/iiab-admin runs here From 2f23ea395a5bd340bd358223ef109ad57d3da953 Mon Sep 17 00:00:00 2001 From: George Hunt Date: Sat, 29 Sep 2018 03:46:24 +0000 Subject: [PATCH 02/28] try to keep default vars from master --- vars/default_vars.yml | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/vars/default_vars.yml b/vars/default_vars.yml index 01a15c72a..ac666d5a3 100644 --- a/vars/default_vars.yml +++ b/vars/default_vars.yml @@ -158,8 +158,6 @@ wan_nameserver: # 2-COMMON -<<<<<<< HEAD -<<<<<<< HEAD # 3-BASE-SERVER # roles/httpd (Apache configuration) runs here @@ -170,34 +168,6 @@ apache_allow_sudo: True # For schools that use WordPress and/or Moodle intensively. See iiab/iiab #1147 # WARNING: Enabling this (might) cause excess use of RAM or other resources? apache_high_php_limits: False -======= - # Intended for developers: ONLY CHANGE THESE IF YOU KNOW WHAT YOU ARE DOING - # The following 2 override the detection when not "auto" - user_wan_iface: auto - user_lan_iface: auto - wan_ip: dhcp - wan_netmask: - wan_gateway: - wan_nameserver: - # exFAT is auto-enabled for all "debuntu" OS's as of Nov 2017, in roles/2-common/tasks/packages.yml#L35-L36 - # exFAT_enabled: True - - # Parameters by Aggregate Roles - # Each Role must have the following variables which are either True or False: - # _install - # _enabled ->>>>>>> da77e233... add in template dir - - # Our past convention was to install everything in all aggregates - # And to enable everything in 1-PREP, 2-COMMON, and 3-BASE-SERVER -======= -# 3-BASE-SERVER ->>>>>>> ce391f0a... bring in clean defaults and py - -# Make this False to disable http://box/common/services/power_off.php button: -allow_apache_sudo: True - -# roles/httpd runs here # roles/iiab-admin runs here From f59dbfbce93c6bf9adfc9d153f74111b556b4910 Mon Sep 17 00:00:00 2001 From: George Hunt Date: Sat, 29 Sep 2018 19:42:49 +0000 Subject: [PATCH 03/28] fix android 7 -- return non 204 --- roles/network/templates/captive-portal/capture-wsgi.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/roles/network/templates/captive-portal/capture-wsgi.py b/roles/network/templates/captive-portal/capture-wsgi.py index 3c36c3c34..c98948e3f 100755 --- a/roles/network/templates/captive-portal/capture-wsgi.py +++ b/roles/network/templates/captive-portal/capture-wsgi.py @@ -345,7 +345,7 @@ def put_204(environ, start_response): response_headers = [('Content-type','text/html'), ('Content-Length',str(len(response_body)))] start_response(status, response_headers) - logger.debug("sending 204 html response") + logger.debug("in function put_204: sending 204 html response") return [response_body] def parse_agent(agent): @@ -517,11 +517,12 @@ def application (environ, start_response): environ['HTTP_HOST'] == "connectivitycheck.android.com" or\ environ['HTTP_HOST'] == "connectivitycheck.gstatic.com": current_ts, last_ts, send204after = timeout_info(ip) + logger.debug("current_ts: %s laat_ts: %s send204after: %s"%(current_ts, last_ts, send204after,)) if not last_ts or (ts - int(last_ts) > INACTIVITY_TO): return android(environ, start_response) elif is_after204_timeout(ip): return put_204(environ,start_response) - return #return without doing anything + return null(environ,start_response) #return without doing anything # microsoft if environ['PATH_INFO'] == "/connecttest.txt" and not is_inactive(ip): From 25eb4acadadde8ba8f19f14728efec5e2d8e05d0 Mon Sep 17 00:00:00 2001 From: George Hunt Date: Sun, 30 Sep 2018 02:46:58 +0000 Subject: [PATCH 04/28] remove the default debug logging that will use up SD card --- roles/network/templates/captive-portal/capture-wsgi.py | 1 - 1 file changed, 1 deletion(-) diff --git a/roles/network/templates/captive-portal/capture-wsgi.py b/roles/network/templates/captive-portal/capture-wsgi.py index c98948e3f..e7e43d0fb 100755 --- a/roles/network/templates/captive-portal/capture-wsgi.py +++ b/roles/network/templates/captive-portal/capture-wsgi.py @@ -66,7 +66,6 @@ if len(sys.argv) > 1 and sys.argv[1] == '-l': loggingLevel = logging.DEBUG else: loggingLevel = logging.ERROR -loggingLevel = logging.DEBUG logging.basicConfig(filename='/var/log/apache2/portal.log',format='%(asctime)s.%(msecs)03d:%(name)s:%(message)s', datefmt='%M:%S',level=loggingLevel) From f91c67ad58edff78805ea43e50f3f11a69181928 Mon Sep 17 00:00:00 2001 From: George Hunt Date: Mon, 1 Oct 2018 18:16:51 +0000 Subject: [PATCH 05/28] fix dual when --- roles/network/tasks/captive_portal.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/roles/network/tasks/captive_portal.yml b/roles/network/tasks/captive_portal.yml index 7fc549af7..a5b1c5f89 100644 --- a/roles/network/tasks/captive_portal.yml +++ b/roles/network/tasks/captive_portal.yml @@ -1,9 +1,12 @@ - name: Get python dateutil package: - name: python-dateutil + name: '(( item }}' state: present when: py_captive_portal_install - + with_item: + - python-dateutil + - sqlite3 + - name: Create directory for Captive Portal script file: path: /opt/iiab/captive-portal @@ -46,7 +49,6 @@ shell: /usr/bin/iiab-uncatch when: py_captive_portal_install - when: py_captive_portal_install - name: Copy Captive Portal service file template: src: roles/network/templates/captive-portal/captive-portal.service.j2 From c91cb6cd32b78dcf47f8a3b54897882ce8ec9084 Mon Sep 17 00:00:00 2001 From: George Hunt Date: Mon, 1 Oct 2018 18:18:36 +0000 Subject: [PATCH 06/28] no change to hosts --- roles/network/tasks/hosts.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/network/tasks/hosts.yml b/roles/network/tasks/hosts.yml index 311722aea..cf4b38278 100644 --- a/roles/network/tasks/hosts.yml +++ b/roles/network/tasks/hosts.yml @@ -15,7 +15,7 @@ - name: Configure fqdn in /etc/hosts appliance mode lineinfile: dest=/etc/hosts regexp='^127\.0\.0\.1' - line='127.0.0.1 localhost.localdomain localhost' + line='127.0.0.1 localhost.localdomain localhost {{ iiab_hostname }}.{{ iiab_domain }} {{ iiab_hostname }} box ' owner=root group=root mode=0644 From 18d23154381acff0c3998dc8cb2a1a6366e7a34e Mon Sep 17 00:00:00 2001 From: George Hunt Date: Mon, 1 Oct 2018 18:27:54 +0000 Subject: [PATCH 07/28] service->systemd --- roles/network/tasks/captive_portal.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/roles/network/tasks/captive_portal.yml b/roles/network/tasks/captive_portal.yml index a5b1c5f89..710310d3f 100644 --- a/roles/network/tasks/captive_portal.yml +++ b/roles/network/tasks/captive_portal.yml @@ -68,9 +68,10 @@ when: py_captive_portal_install and py_captive_portal_enabled - name: Enable captive-portal after copying files - service: + systemd: name: captive-portal.service enabled: yes + daemon-reload: yes when: py_captive_portal_install and py_captive_portal_enabled - name: Enable Apache config file @@ -88,15 +89,16 @@ when: py_captive_portal_enabled and is_debuntu - name: Start captive-portal after copying files - service: + systemd: name: captive-portal.service state: started when: py_captive_portal_install and py_captive_portal_enabled - name: Disable captive-portal after copying files - service: + systemd: name: captive-portal.service enabled: no + daemon-reload: yes when: py_captive_portal_install and not py_captive_portal_enabled - name: Stop captive-portal after copying files From e26aa688c79e6e9ad103741e9c8cf1c1c77be658 Mon Sep 17 00:00:00 2001 From: George Hunt Date: Mon, 1 Oct 2018 18:52:00 +0000 Subject: [PATCH 08/28] with_items --- roles/network/tasks/captive_portal.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/network/tasks/captive_portal.yml b/roles/network/tasks/captive_portal.yml index 710310d3f..cb37e7783 100644 --- a/roles/network/tasks/captive_portal.yml +++ b/roles/network/tasks/captive_portal.yml @@ -1,9 +1,9 @@ - name: Get python dateutil package: - name: '(( item }}' + name: '{{ item }}' state: present when: py_captive_portal_install - with_item: + with_items: - python-dateutil - sqlite3 From d90b6becb9e5637a8d505a83923c759935f80742 Mon Sep 17 00:00:00 2001 From: George Hunt Date: Mon, 1 Oct 2018 19:48:08 +0000 Subject: [PATCH 09/28] hard code a ficticious, but stable, server name for url linked to by captive portal --- roles/1-prep/templates/.iiab.env.j2.un~ | Bin 649 -> 1090 bytes roles/1-prep/templates/iiab.env.j2 | 1 + roles/httpd/templates/010-iiab.conf.j2 | 4 ++-- roles/network/files/mac.template | 2 +- roles/network/files/simple.template | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/roles/1-prep/templates/.iiab.env.j2.un~ b/roles/1-prep/templates/.iiab.env.j2.un~ index b9f549ce150d79452aff79c6fd84e04a84434ffa..f4f008fed86220fc816d5d29c8031c3fd8f387e3 100644 GIT binary patch delta 226 zcmeBVJ;YHTmYF+0G|wgfDFf5?zq*$b7W(^Vzkj)7?$*^pT4!Wto^X|$yL|P76uA#y z{xC2w@B%Riz-UGwn+Yrep+RggKYCNXDGNk4{sNK$D3bvs#Rp7UDz$!o@$N*#v i&&C>0#)%6Q&4I?5K#lt<0g^yc3D$@q%3#{~d=&ud(kDFt delta 115 zcmX@a(aD+;mYF+0G|wgfDFf5%w0$3|AHVN@nfh+M-b#hY6ANk%?-#b3d~c;V*V>P+ q5)2FsJV1;L7=auR1_2lw%#U7Zv7QAY5`SUhMB$C)0!&QLR{;Raz8?$# diff --git a/roles/1-prep/templates/iiab.env.j2 b/roles/1-prep/templates/iiab.env.j2 index 07e8766b6..1f6220dfb 100644 --- a/roles/1-prep/templates/iiab.env.j2 +++ b/roles/1-prep/templates/iiab.env.j2 @@ -10,3 +10,4 @@ OS={{ ansible_local.local_facts.os }} OS_VER={{ ansible_local.local_facts.os_ver }} WWWROOT={{ doc_root }} STAGE=1 +FQDN={{ iiab-fqdn }} diff --git a/roles/httpd/templates/010-iiab.conf.j2 b/roles/httpd/templates/010-iiab.conf.j2 index aa3cbe231..2558f9c94 100755 --- a/roles/httpd/templates/010-iiab.conf.j2 +++ b/roles/httpd/templates/010-iiab.conf.j2 @@ -176,8 +176,8 @@ DocumentRoot "{{ doc_root }}" ErrorLog /var/log/apache2/error.log CustomLog /var/log/apache2/access.log combined - ServerName box - ServerAlias box.lan + ServerName {{ iiab_hostname }} + ServerAlias server.lan Options Indexes FollowSymLinks AllowOverride None diff --git a/roles/network/files/mac.template b/roles/network/files/mac.template index 658aa6b98..049c2ff19 100644 --- a/roles/network/files/mac.template +++ b/roles/network/files/mac.template @@ -48,7 +48,7 @@





- {{ btn1 }} + {{ btn1 }}
diff --git a/roles/network/files/simple.template b/roles/network/files/simple.template index 152a1607c..3919528fb 100644 --- a/roles/network/files/simple.template +++ b/roles/network/files/simple.template @@ -69,7 +69,7 @@