1
0
Fork 0
mirror of https://github.com/iiab/iiab.git synced 2025-02-13 11:42:08 +00:00

Merge pull request #323 from iiab/master

sync from iiab:master
This commit is contained in:
A Holt 2020-01-02 22:04:50 -05:00 committed by GitHub
commit bf6889d9f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 449 additions and 379 deletions

View file

@ -33,7 +33,7 @@
state: present
when: is_debuntu | bool
- name: "Install 23 common packages: acpid, bridge-utils, bzip2, curl, gawk, hostapd, htop, i2c-tools, logrotate, make, mlocate, netmask, net-tools, ntfs-3g, pandoc, pastebinit, rsync, sudo, tar, unzip, usbmount, usbutils, wget"
- name: "Install 24 common packages: acpid, bridge-utils, bzip2, curl, gawk, hostapd, htop, i2c-tools, logrotate, make, mlocate, netmask, net-tools, ntfs-3g, pandoc, pastebinit, rsync, sqlite3, sudo, tar, unzip, usbmount, usbutils, wget"
package:
name:
- acpid
@ -56,6 +56,7 @@
- pandoc
- pastebinit
- rsync
- sqlite3
- sudo
- tar
- unzip

View file

@ -18,9 +18,9 @@
# To be ported soon
- name: CAPTIVE PORTAL
include_tasks: roles/captive-portal/tasks/main.yml
when: captive_portal_install | bool
tags: base, captive-portal, network, domain
include_tasks: roles/captiveportal/tasks/main.yml
when: captiveportal_install | bool
tags: base, captiveportal, network, domain
- name: MINETEST
include_role:

View file

@ -1,5 +1,5 @@
location ~ ^/awstats {
rewrite ^ http://box.lan/cgi-bin/awstats.pl?config=schoolserver;
rewrite ^ /cgi-bin/awstats.pl;
}
location ^~ /awstatsicons {
alias /usr/share/awstats/icon/;

View file

@ -1,153 +0,0 @@
- name: Download & install python-dateutil, sqlite3
package:
name: "{{ item }}"
state: present
with_items:
- python-dateutil
- sqlite3 # @georgejhunt hopes to move this to 2-common (or more likely 3-base-server, alongside MySQL) in October 2018
- name: Install libapache2-mod-wsgi (debuntu)
package:
name: libapache2-mod-wsgi
state: present
when: is_debuntu | bool
- name: Install mod_wsgi (not debuntu)
package:
name: mod_wsgi
state: present
when: not is_debuntu
- name: Create directory /opt/iiab/captive-portal for scripts & templates
file:
path: /opt/iiab/captive-portal
state: directory
owner: "{{ apache_user }}"
- name: 'Copy scripts: checkurls, capture-wsgi.py'
template:
src: "{{ item.src }}"
dest: /opt/iiab/captive-portal/
mode: "{{ item.mode }}"
with_items:
- { src: roles/captive-portal/templates/checkurls, mode: '0644' }
- { src: roles/captive-portal/templates/capture-wsgi.py, mode: '0755' }
- name: 'Copy templates: simple.template, mac.template'
copy:
src: "{{ item }}"
dest: /opt/iiab/captive-portal/
with_items:
- roles/captive-portal/files/simple.template
- roles/captive-portal/files/mac.template
- name: Copy iiab-catch & iiab-uncatch into /usr/bin/
template:
src: "{{ item }}"
dest: /usr/bin/
owner: root
group: root
mode: 0755
with_items:
- roles/captive-portal/templates/iiab-catch
- roles/captive-portal/templates/iiab-uncatch
- name: Run iiab-uncatch to generate diversion lists for dnsmasq and apache2
shell: /usr/bin/iiab-uncatch
#- name: Install systemd unit file captive-portal.service from template
# template:
# src: roles/captive-portal/templates/captive-portal.service.j2
# dest: /etc/systemd/system/captive-portal.service
# owner: root
# group: root
# mode: 0644
- name: Install Apache's captive-portal.conf from template if captive_portal_enabled
template:
src: roles/captive-portal/templates/001-captive-portal.conf
dest: /etc/{{ apache_config_dir }}/001-captive-portal.conf
owner: root
group: root
mode: 0644
when: captive_portal_enabled | bool
- name: Enable Apache's captive-portal.conf if captive_portal_enabled (debuntu)
file:
src: /etc/apache2/sites-available/001-captive-portal.conf
path: /etc/apache2/sites-enabled/001-captive-portal.conf
state: link
when: captive_portal_enabled and is_debuntu
- name: Enable Apache's default-ssl.conf if captive_portal_enabled (debuntu)
file:
src: /etc/apache2/sites-available/default-ssl.conf
path: /etc/apache2/sites-enabled/default-ssl.conf
state: link
when: captive_portal_enabled and is_debuntu
#- name: Enable & Start systemd service captive-portal.service if captive_portal_enabled
# systemd:
# name: captive-portal.service
# daemon-reload: yes
# enabled: yes
# state: started
# when: captive_portal_enabled | bool
#- name: Disable & Stop captive-portal.service if not captive_portal_enabled
# systemd:
# name: captive-portal.service
# enabled: no
# state: stopped
# when: not captive_portal_enabled
- name: Disable Apache's captive-portal.conf if not captive_portal_enabled (debuntu)
file:
path: /etc/apache2/sites-enabled/001-captive-portal.conf
state: absent
when: not captive_portal_enabled and is_debuntu
- name: Disable Apache's default-ssl.conf if not captive_portal_enabled (debuntu)
file:
path: /etc/apache2/sites-enabled/default-ssl.conf
state: absent
when: not captive_portal_enabled and is_debuntu
- name: Make sure dnsmasq is not diverting if not captive_portal_enabled
file:
path: /etc/dnsmasq.d/capture
state: absent
when: not captive_portal_enabled
- name: Add 'captive_portal_installed' variable values to {{ iiab_state_file }}
lineinfile:
dest: "{{ iiab_state_file }}"
regexp: '^captive_portal_installed'
line: 'captive_portal_installed: True'
state: present
- name: Restart Apache service ({{ apache_service }}) # i.e. apache2 on most distros
systemd:
name: "{{ apache_service }}"
state: restarted
#- name: Restart dnsmasq
# systemd:
# name: dnsmasq
# state: restarted
# when: dnsmasq_enabled | bool
# ABOVE DOES NOT WORK ON UBUNTU 16.04 -- what follows is a crude hack (seems to work!)
- name: Stop dnsmasq
systemd:
name: dnsmasq
state: stopped
when: dnsmasq_enabled | bool
- name: Start dnsmasq
systemd:
name: dnsmasq
state: started
when: dnsmasq_enabled | bool

View file

@ -1,43 +0,0 @@
<VirtualHost _default_:80>
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
<Directory {{ doc_root }}>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
<VirtualHost *:80>
# 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:{{ captive_portal_port }}/
# ProxyPassReverse / http://box.lan:{{ captive_portal_port }}/
ErrorLog /var/log/apache2/cp_error.log
WSGIScriptAlias / /opt/iiab/captive-portal/capture-wsgi.py
#WSGIScriptAlias / /opt/iiab/captive-portal/test.py
WSGIScriptReloading On
<Directory /opt/iiab/captive-portal>
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
<VirtualHost 127.0.0.1:80>
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
<Directory /library/www/html>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>

View file

@ -1,15 +0,0 @@
[Unit]
Description=Captive portal
After=syslog.target
[Service]
Type=simple
User=root
Group=root
WorkingDirectory=/opt/iiab/captive-portal
ExecStart=/opt/iiab/captive-portal/capture-wsgi.py -l
StandardOutput=syslog
StandardError=syslog
[Install]
WantedBy=multi-user.target

View file

@ -1,9 +0,0 @@
#!/bin/bash -x
# substitute our own server to catch OS connectivity checking URL's
systemctl stop {{ apache_service }}
# 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

View file

@ -1,15 +0,0 @@
#!/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
echo "#following tells windows 7 that captive portal is active" >>/etc/dnsmasq.d/capture
echo "address=/dns.msftncsi.com/131.107.255.255" >> /etc/dnsmasq.d/capture
awk '{print("ServerAlias ",$1)}' /opt/iiab/captive-portal/checkurls > /etc/apache2/capture
# systemctl start captive-portal
systemctl start {{ apache_service }}

View file

@ -0,0 +1,22 @@
## Theory of Operation
* The captive portal function is a feature of most modern operating systems. With the increased use of https/ssl (secure sockets layer), the automatic diversion to a specific web page runs the risk of being detected as a "man in the middle" attack.
* Each Operating System (OS) provides a mechanism that IIAB can use to break into a conversation, when SSL is not being used. This is an initial attempt by the OS to talk to one of its own web sites, to determine if the host os is connected to the internet. It is always performed without SSL.
* The IIAB captive portal uses a list of these OS supported web sites, and diverts these requests to the IIAB server, which in turn forwards to the IIAB home page.
## Components of the IIAB Captive Portal
* Files used
1. checkurls -- the list of urls use by at least one of the OS's.
1. iiab-divert-to-nginx -- Bash script writes dnsmasq config file which points to IIAB server
1. iiab-make-cp-servers.py -- Python script writes nginx configuration file to /etc/nginx/sites-enabled
1. capture-wsgi.py -- the script which determines the client agent, records it in sqlite database, and responds with redirects as appropriate for each OS.
1. uwsgi-captiveportal.service -- systemd unit file which runs uwsgi which makes capture-wsgi.py available on port 9090.
## Extending and Debugging Captive Portal
* The python capture script can be run interactively in terminal (use systemctl stop uwsgi-captiveportal to free up the port). This will expose any python errors easily.
* Run the capture-wsgi.py with "-l" in a terminal to increase logging to /var/log/apache2/portal.log
* To discover untrapped urls, "apt-get install tcpdump", and "tcpdump -i br0 capture.tcp". I transfer this file to a machine with a GUI, and wireshark to interpret the conversations on the wire. The DNS packets are the ones to look for.
## Known Problems
1. On Android 5-7, the browser which is brought up, during the association process, is a 'walled garden' and I cannot find a way out. This browser is not very modern, and continuously displays the "sign in to Wi-Fi network" button -- with an annoying beep.

View file

@ -1,7 +1,7 @@
# captive_portal_install: False
# captive_portal_enabled: False
# captive_portal_port: 9090
# captiveportal_port: 9090
# All above are set in: github.com/iiab/iiab/blob/master/vars/default_vars.yml
# If nec, change them by editing /etc/iiab/local_vars.yml prior to installing!

View file

@ -8,16 +8,17 @@
#header {
display: block;
height: 120px;
width:1024px;
width:900px;
background: #000 url('iiab_banner6.png') no-repeat 0 0;
border-radius: 5px;
margin: 5px;
object-fit: cover;
}
body {
background-color: #CBFFAA;
font-family: sans-serif;
font-size: 100%;
width: 1024px;
width: 900px;
margin: 3px;
}
}

View file

@ -69,8 +69,14 @@
<script>
var w = window.innerWidth;
function homeclick(){
$.ajax({
url: "/home_selected",
async: false,
success: function( data ){
console.log(data);
}
});
window.open("http://{{ FQDN }}","_system");
$.ajax("/home_selected");
}
</script>
@ -93,7 +99,6 @@
<br><br>
<br><br>
<br><br>
<!-- <a class="button" href="http://box.lan/home">{{ btn1 }}</a> -->
<a class="button" onclick="homeclick()">{{ btn1 }}</a>
</div>
</body>

View file

@ -0,0 +1,117 @@
- name: Download & install python-dateutil, sqlite3
package:
name: "{{ item }}"
state: present
with_items:
- python3-dateutil
- python3-jinja2
- name: Create directory /opt/iiab/captiveportal for scripts & templates
file:
path: /opt/iiab/captiveportal
state: directory
owner: "{{ apache_user }}"
- name: 'Copy scripts: checkurls'
template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
with_items:
- { src: roles/captiveportal/templates/checkurls, mode: '0644', dest: /opt/iiab/captiveportal/ }
- { src: roles/captiveportal/templates/iiab-make-cp-servers.py, mode: '0755', dest: /usr/sbin/ }
- { src: roles/captiveportal/templates/iiab-divert-to-nginx, mode: '0755', dest: /usr/sbin/ }
- name: Put put the python script that creates the server in place
template:
src: roles/captiveportal/templates/capture-wsgi.py
mode: '0755'
dest: /opt/iiab/captiveportal/
- name: 'Copy templates: simple.template, mac.template'
copy:
src: "{{ item }}"
dest: /opt/iiab/captiveportal/
with_items:
- roles/captiveportal/files/simple.template
- roles/captiveportal/files/mac.template
- name: Copy uWSGI config file
template:
src: roles/captiveportal/templates/captiveportal.ini.j2
dest: /opt/iiab/captiveportal/captiveportal.ini
- name: Copy unit file for uWSGI service
template:
src: roles/captiveportal/templates/uwsgi-captiveportal.service
dest: /etc/systemd/system/
- name: Start or restart server which responds to browsers trying to detect a captive portal
systemd:
name: uwsgi-captiveportal.service
state: restarted
enabled: True
when: captiveportal_enabled | bool
- name: Stop uWSGI server if captive portal has been disabled
systemd:
name: uwsgi-captiveportal.service
state: stopped
enabled: False
when: not captiveportal_enabled | bool
- name: Run divert to generate diversion lists for nginx
shell: /usr/sbin/iiab-divert-to-nginx
- name: Run script to generate nginx servers from checkurls input list
command: /usr/sbin/iiab-make-cp-servers.py
args:
creates: /etc/nginx/sites-available/capture.conf
- name: Enable nginx to service the sites in checkurls list
file:
src: /etc/nginx/sites-available/capture.conf
path: /etc/nginx/sites-enabled/capture.conf
state: link
when: captiveportal_enabled | bool
- name: Disable nginx to location definitions for checkurls
file:
src: /etc/nginx/sites-available/capture.conf
path: /etc/nginx/sites-enabled/capture.conf
state: absent
when: not captiveportal_enabled | bool
- name: Make sure dnsmasq is not diverting if not captiveportal_enabled
file:
path: /etc/dnsmasq.d/capture
state: absent
when: not captiveportal_enabled
- name: Add 'captiveportal_installed' variable values to {{ iiab_state_file }}
lineinfile:
dest: "{{ iiab_state_file }}"
regexp: '^captiveportal_installed'
line: 'captiveportal_installed: True'
state: present
#- name: Restart dnsmasq
# systemd:
# name: dnsmasq
# state: restarted
# when: dnsmasq_enabled | bool
# ABOVE DOES NOT WORK ON UBUNTU 16.04 -- what follows is a crude hack (seems to work!)
- name: Stop dnsmasq
systemd:
name: dnsmasq
state: stopped
when: dnsmasq_enabled | bool
- name: Start dnsmasq
systemd:
name: dnsmasq
state: started
when: dnsmasq_enabled | bool

View file

@ -0,0 +1,9 @@
[uwsgi]
uid = {{ apache_user }}
gid = {{ apache_user }}
http-socket = :{{ captiveportal_port }}
chdir = /opt/iiab/captiveportal
wsgi-file = capture-wsgi.py
master = true
plugins = python3
py-autoreload = 2

View file

@ -1,4 +1,4 @@
#! /usr/bin/env python
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# using Python's bundled WSGI server
@ -13,6 +13,7 @@ import sys
from jinja2 import Environment, FileSystemLoader
import sqlite3
import re
from iiab.iiab_lib import get_iiab_env
# Notes on timeout strategy
# every client timestamp is recorded into current_ts
@ -23,7 +24,7 @@ import re
#
# Create the jinja2 environment.
CAPTIVE_PORTAL_BASE = "/opt/iiab/captive-portal"
CAPTIVE_PORTAL_BASE = "/opt/iiab/captiveportal"
j2_env = Environment(loader=FileSystemLoader(CAPTIVE_PORTAL_BASE),trim_blocks=True)
# Define time outs
@ -34,61 +35,33 @@ PORTAL_TO = 20 # delay after triggered by ajax upon click of link to home page
# Get the IIAB variables
sys.path.append('/etc/iiab/')
from iiab_env import get_iiab_env
doc_root = get_iiab_env("WWWROOT")
fully_qualified_domain_name = get_iiab_env("FQDN")
loggingLevel = "ERROR"
#loggingLevel = "DEBUG"
if len(sys.argv) > 1:
if sys.argv[1] == '-l':
loggingLevel = "DEBUG"
# 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':
if True:
loggingLevel = logging.DEBUG
try:
os.remove('/var/log/apache2/portal.log')
except:
pass
else:
loggingLevel = logging.ERROR
# divert stdout and stderr to logger
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)
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
PORT={{ captive_portal_port }}
PORT={{ captiveportal_port }}
#PORT=9090
# Define globals
ANDROID_TRIGGERED=False
logger.debug("")
logger.debug('##########################################')
# what language are we speaking?
lang = os.environ['LANG'][0:2]
logger.debug('speaking: %s'%lang)
logger.debug('speaking: {}'.format(lang))
def tstamp(dtime):
'''return a UNIX style seconds since 1970 for datetime input'''
@ -141,8 +114,7 @@ def timeout_info(ip):
def is_inactive(ip):
ts=tstamp(datetime.datetime.now(tzutc()))
current_ts, last_ts, send204after = timeout_info(ip)
logger.debug("In is_inactive. current_ts:%s. last_ts:%s. send204after:%s"%\
(current_ts,last_ts,send204after,))
logger.debug("In is_inactive. current_ts:{}. last_ts:{}. send204after:{}".format(current_ts,last_ts,send204after,))
if not last_ts:
return True
if ts - int(last_ts) > INACTIVITY_TO:
@ -154,7 +126,7 @@ 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,))
logger.debug("function: is_after204_timeout send204after:{} current: {}".format(send204after,ts,))
if not send204after:
return False
if ts - int(send204after) > 0:
@ -163,12 +135,10 @@ def is_after204_timeout(ip):
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()))
@ -178,31 +148,33 @@ def set_lasttimestamp(ip):
# ################### Action routines based on OS ################3
def microsoft(environ,start_response):
logger.debug('in microsoft')
# firefox -- seems both mac and Windows use it
agent = environ.get('HTTP_USER_AGENT','default_agent')
if agent.startswith('Mozilla'):
logger.debug("sending microsoft redirect for agent Mozilla")
return home(environ, start_response)
logger.debug("sending microsoft redirect")
response_body = ""
response_body = b""
status = '302 Moved Temporarily'
response_headers = [('Location','http://box.lan/home'),
response_headers = [('Location','http://' + fully_qualified_domain_name + '{{ captiveportal_splash_page }}'),
('Content-type','text/html'),
('Content-Length',str(len(response_body)))]
start_response(status, response_headers)
logger.debug("redirect to home. Status: %s Headers: %s"%(status,repr(response_headers)))
return [response_body]
def home(environ,start_response):
logger.debug("sending direct to home")
response_body = ""
response_body = b""
status = '302 Moved Temporarily'
response_headers = [('Location','http://' + fully_qualified_domain_name + '/home'),
response_headers = [('Location','http://' + fully_qualified_domain_name + '{{ captiveportal_splash_page }}'),
('Content-type','text/html'),
('Content-Length',str(len(response_body)))]
start_response(status, response_headers)
logger.debug("redirect to home. Status: %s Headers: %s"%(status,repr(response_headers)))
return [response_body]
def android(environ, start_response):
global ANDROID_TRIGGERED
if environ.get('HTTP_X_FORWARDED_FOR'):
ip = environ['HTTP_X_FORWARDED_FOR'].strip()
else:
@ -211,16 +183,16 @@ def android(environ, start_response):
if system_version is None:
return put_302(environ, start_response)
if system_version[0:1] < '6':
logger.debug("system < 6:%s"%system_version)
logger.debug("system < 6:{}".format(system_version))
location = '/android_splash'
set_204after(ip,0)
elif system_version[:1] >= '7':
location = "http://" + fully_qualified_domain_name + "/home"
location = "http://" + fully_qualified_domain_name + '{{ captiveportal_splash_page }}'
else:
#set_204after(ip,20)
location = '/android_https'
agent = environ.get('HTTP_USER_AGENT','default_agent')
response_body = "hello"
response_body = b"hello"
status = '302 Moved Temporarily'
response_headers = [('Location',location)]
start_response(status, response_headers)
@ -229,10 +201,10 @@ def android(environ, start_response):
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", \
"FQDN": fully_qualified_domain_name, \
"FQDN": fully_qualified_domain_name + '{{ captiveportal_splash_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",\
"FQDN": fully_qualified_domain_name, \
"FQDN": fully_qualified_domain_name + '{{ captiveportal_splash_page }}', \
'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")}
txt = en_txt
if lang == "en":
@ -240,6 +212,7 @@ def android_splash(environ, start_response):
elif lang == "es":
txt = es_txt
response_body = str(j2_env.get_template("simple.template").render(**txt))
response_body = response_body.encode()
status = '200 OK'
response_headers = [('Content-type','text/html'),
('Content-Length',str(len(response_body)))]
@ -250,10 +223,10 @@ 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',\
"FQDN": fully_qualified_domain_name, \
"FQDN": fully_qualified_domain_name + '{{ captiveportal_splash_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",\
"FQDN": fully_qualified_domain_name, \
"FQDN": fully_qualified_domain_name + '{{ captiveportal_splash_page }}', \
'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")}
txt = en_txt
if lang == "en":
@ -261,6 +234,7 @@ def android_https(environ, start_response):
elif lang == "es":
txt = es_txt
response_body = str(j2_env.get_template("simple.template").render(**txt))
response_body = response_body.encode()
status = '200 OK'
response_headers = [('Content-type','text/html'),
('Content-Length',str(len(response_body)))]
@ -268,13 +242,14 @@ def android_https(environ, start_response):
return [response_body]
def mac_splash(environ,start_response):
logger.debug('in mac_splash')
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',
"FQDN": fully_qualified_domain_name, \
en_txt={ 'message': "Click on the button to go to the IIAB home page",\
'btn1': "GO TO IIAB HOME PAGE",'success_token': 'Success',
"FQDN": fully_qualified_domain_name + '{{ captiveportal_splash_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",\
"FQDN": fully_qualified_domain_name, \
"FQDN": fully_qualified_domain_name + '{{ captiveportal_splash_page }}', \
'btn1':"IIAB",'doc_root':get_iiab_env("WWWROOT")}
txt = en_txt
if lang == "en":
@ -283,6 +258,7 @@ def mac_splash(environ,start_response):
txt = es_txt
set_lasttimestamp(ip)
response_body = str(j2_env.get_template("mac.template").render(**txt))
response_body = response_body.encode()
status = '200 Success'
response_headers = [('Content-type','text/html'),
('Content-Length',str(len(response_body)))]
@ -290,6 +266,7 @@ def mac_splash(environ,start_response):
return [response_body]
def macintosh(environ, start_response):
logger.debug('in macintosh')
global ip
logger.debug("in function mcintosh")
#print >> sys.stderr , "Geo Print to stderr" + environ['HTTP_HOST']
@ -302,6 +279,7 @@ def macintosh(environ, start_response):
response_body = """<html><head><script>
window.location.reload(true)
</script></body></html>"""
response_body = response_body.encode()
status = '302 Moved Temporarily'
response_headers = [('content','text/html')]
start_response(status, response_headers)
@ -309,18 +287,12 @@ def macintosh(environ, start_response):
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/js-menu/menu-files/images/iiab_banner6.png"%doc_root, "rb").read()
image = open("{}/js-menu/menu-files/images/iiab_banner6.png".format(doc_root), "rb").read()
return [image]
def bootstrap(environ, start_response):
@ -328,7 +300,7 @@ def bootstrap(environ, start_response):
status = '200 OK'
headers = [('Content-type', 'text/javascript')]
start_response(status, headers)
boot = open("%s/common/js/bootstrap.min.js"%doc_root, "rb").read()
boot = open("{}/common/js/bootstrap.min.js".format(doc_root), "rb").read()
return [boot]
def jquery(environ, start_response):
@ -336,7 +308,7 @@ def jquery(environ, start_response):
status = '200 OK'
headers = [('Content-type', 'text/javascript')]
start_response(status, headers)
boot = open("%s/common/js/jquery.min.js"%doc_root, "rb").read()
boot = open("{}/common/js/jquery.min.js".format(doc_root), "rb").read()
return [boot]
def bootstrap_css(environ, start_response):
@ -344,25 +316,25 @@ def bootstrap_css(environ, start_response):
status = '200 OK'
headers = [('Content-type', 'text/css')]
start_response(status, headers)
boot = open("%s/common/css/bootstrap.min.css"%doc_root, "rb").read()
boot = open("{}/common/css/bootstrap.min.css".format(doc_root), "rb").read()
return [boot]
def null(environ, start_response):
status = '404 Not Found'
headers = [('Content-type', 'text/html')]
start_response(status, headers)
return [""]
return [b""]
def success(environ, start_response):
status = '200 ok'
html = '<html><head><title>Success</title></head><body>Success</body></html>'
html = b'<html><head><title>Success</title></head><body>Success</body></html>'
headers = [('Content-type', 'text/html')]
start_response(status, headers)
return [html]
def put_204(environ, start_response):
status = '204 No Data'
response_body = ''
response_body = b''
response_headers = [('Content-type','text/html'),
('Content-Length',str(len(response_body)))]
start_response(status, response_headers)
@ -371,8 +343,8 @@ def put_204(environ, start_response):
def put_302(environ, start_response):
status = '302 Moved Temporarily'
response_body = ''
location = "http://" + fully_qualified_domain_name + "/home"
response_body = b''
location = "http://" + fully_qualified_domain_name + '{{ captiveportal_splash_page }}'
response_headers = [('Content-type','text/html'),
('Location',location),
('Content-Length',str(len(response_body)))]
@ -412,23 +384,22 @@ def application (environ, start_response):
global CATCH
global LIST
global INACTIVITY_TO
global ANDROID_TRIGGERED
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)
data = ['{}: {}\n'.format(key, value) for key, value in sorted(environ.items()) ]
#logger.debug("need the correct ip:{}".format(data))
ip = environ['REMOTE_ADDR'].strip()
cmd="arp -an %s|gawk \'{print $4}\'" % ip
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)
data.append("host: {}\n".format(environ['HTTP_HOST']))
data.append("path: {}\n".format(environ['PATH_INFO']))
data.append("query: {}\n".format(environ['QUERY_STRING']))
data.append("ip: {}\n".format(ip))
agent = environ.get('HTTP_USER_AGENT','default_agent')
data.append("AGENT: %s\n"%agent)
data.append("AGENT: {}\n".format(agent))
logger.debug(data)
#print(data)
found = False
@ -441,7 +412,7 @@ def application (environ, start_response):
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,))
logger.debug("failed UPDATE users SET current_ts = {} WHERE ip = {}".format(ts,ip,))
conn.commit()
ymd=datetime.datetime.today().strftime("%y%m%d-%H%M")
@ -469,17 +440,18 @@ def application (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)
#data = ['{}: {}\n'.format(key, value) for key, value in sorted(environ.items()) ]
#logger.debug("need the correct ip:{}".format(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 [""]
response_body = b''
response_headers = [('Content-type','text/html'),
('Content-Length',str(len(response_body)))]
start_response(status, response_headers)
return [response_body]
#### parse OS platform based upon URL ##################
# mac
@ -514,7 +486,7 @@ def application (environ, start_response):
environ['PATH_INFO'] == "/gen_204" or\
environ['HTTP_HOST'] == "connectivitycheck.gstatic.com":
current_ts, last_ts, send204after = timeout_info(ip)
logger.debug("current_ts: %s last_ts: %s send204after: %s"%(current_ts, last_ts, send204after,))
logger.debug("current_ts: {} last_ts: {} send204after: {}".format(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):
@ -533,7 +505,7 @@ def application (environ, start_response):
environ['HTTP_HOST'] == "teredo.ipv6.microsoft.com.nsatc.net":
return microsoft(environ, start_response)
logger.debug("executing the default 302 response. [%s"%data)
logger.debug("executing the default 302 response. [{}".format(data))
return put_302(environ,start_response)
# Instantiate the server
@ -545,5 +517,5 @@ if __name__ == "__main__":
)
httpd.serve_forever()
#vim: tabstop=3 expandtab shiftwidth=3 softtabstop=3 background=dark
#vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 background=dark

View file

@ -15,8 +15,11 @@ 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
www.google.com
mtalk.google.com
alt4-mtalk.google.com
alt6-mtalk.google.com
alt7-mtalk.google.com
people-pa.googleapis.com
captive.lan

View file

@ -0,0 +1,4 @@
#!/bin/bash -x
awk '{print("address=/" $1 "/172.18.96.1")}' /opt/iiab/captiveportal/checkurls > /etc/dnsmasq.d/capture
echo "#following tells windows 7 that captive portal is active" >>/etc/dnsmasq.d/capture
echo "address=/dns.msftncsi.com/131.107.255.255" >> /etc/dnsmasq.d/capture

View file

@ -0,0 +1,24 @@
#!/usr/bin/env python3
# read list of online portal checkers, make nginx server blocks
import os
outstr = ''
#os.chdir('{{ iiab_dir }}/roles/captiveportal/templates')
os.chdir('/opt/iiab/iiab/roles/captiveportal/templates')
with open('checkurls','r') as urls:
for line in urls:
line = line.replace('*','.*')
outstr += 'server {\n'
outstr += ' listen 80;\n'
outstr += ' server_name {};\n'.format(line.strip())
outstr += ' location / {\n'
outstr += ' proxy_set_header X-Forwarded-For $remote_addr;\n'
outstr += ' proxy_set_header Host $http_host;\n'
outstr += ' proxy_pass "http://127.0.0.1:9090";\n'
outstr += ' }\n'
outstr += '}\n'
#print(outstr)
with open('/etc/nginx/sites-available/capture.conf','w') as config:
config.write(outstr)

View file

@ -0,0 +1,13 @@
[Unit]
Description=uWSGI Service
[Service]
ExecStart=/usr/bin/uwsgi --ini /opt/iiab/captiveportal/captiveportal.ini
Restart=always
RestartSec=5
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
[Install]
WantedBy=multi-user.target

View file

@ -8,7 +8,7 @@
# https://git.coolaj86.com/coolaj86/gitea-installer.sh
# Information needed to install Gitea
gitea_version: 1.10.0
gitea_version: 1.10.2
iset_suffixes:
i386: 386
x86_64: amd64

View file

@ -29,10 +29,10 @@
when: not test_kalite_installed.stat.exists
- include_tasks: setup-f18.yml
when: not test_kalite_installed.stat.exists and is_F18
when: not test_kalite_installed.stat.exists and is_F18 and kalite_install
- include_tasks: setup.yml
when: not test_kalite_installed.stat.exists and not is_F18
when: not test_kalite_installed.stat.exists and not is_F18 and kalite_install
- include_tasks: enable.yml
when: kalite_install or kalite_installed is defined

View file

@ -5,7 +5,7 @@
# If nec, change them by editing /etc/iiab/local_vars.yml prior to installing!
# Info needed to install Lokole
lokole_version: 0.5.3
lokole_version: 0.5.4
lokole_admin_user: admin # lowercase seems nec here (even though uppercase Admin/changeme is IIAB's OOB recommendation!)
lokole_admin_password: changeme
lokole_install_path: "{{ content_base }}/lokole" # /library/lokole

View file

@ -25,5 +25,5 @@ mediawiki_site_name: Community Wiki
mediawiki_install_path: "{{ content_base }}" # /library
mediawiki_abs_path: "{{ mediawiki_install_path }}/mediawiki-{{ mediawiki_version }}"
mediawiki_url: /mediawiki
mediawiki_full_url: "http://{{ iiab_hostname }}.{{ iiab_domain }}{{ mediawiki_url }}" # http://box.lan/mediawiki
mediawiki_url: /wiki
mediawiki_full_url: "http://{{ iiab_hostname }}.{{ iiab_domain }}{{ mediawiki_url }}" # http://box.lan/wiki

View file

@ -17,6 +17,24 @@
daemon_reload: yes
state: restarted
- name: Install {{ nginx_config_dir }}/mediawiki-nginx.conf from template, for http://box{{ mediawiki_url }}
template:
src: mediawiki-nginx.conf.j2
dest: "{{ nginx_config_dir }}/mediawiki-nginx.conf"
when: mediawiki_enabled
- name: Remove mediawiki-nginx.conf if not mediawiki_enabled (debuntu)
file:
path: "{{ nginx_config_dir }}/mediawiki-nginx.conf"
state: absent
when: not mediawiki_enabled and is_debuntu
- name: Restart nginx service to enable/disable http://box{{ mediawiki_url }}
systemd:
name: nginx
daemon_reload: yes
state: restarted
- name: Add 'mediawiki' variable values to {{ iiab_ini_file }}
ini_file:
path: "{{ iiab_ini_file }}"

View file

@ -25,6 +25,12 @@
mode: 0755
keep_newer: yes
- name: Create symlink mwlink from docroot to {{ mediawiki_abs_path }}
file:
src: "{{ mediawiki_abs_path }}"
dest: "{{ doc_root }}/mwlink"
state: link
- name: Start MySQL service, so we can create db
service:
state: started
@ -51,7 +57,7 @@
--installdbpass={{ mediawiki_db_user_password }}
--dbuser={{ mediawiki_db_user }}
--dbpass={{ mediawiki_db_user_password }}
--scriptpath=/mediawiki
--scriptpath=/mwlink
--lang=en
--pass={{ mediawiki_admin_user_password }}
"{{ mediawiki_site_name }}"
@ -60,11 +66,25 @@
chdir: "{{ mediawiki_abs_path }}"
creates: "{{ mediawiki_abs_path }}/LocalSettings.php"
- name: Configure wgArticlePath variable in {{ mediawiki_abs_path }}/LocalSettings.php
lineinfile:
dest: "{{ mediawiki_abs_path }}/LocalSettings.php"
line: '$wgArticlePath = "/wiki/$1";'
create: yes
- name: Configure wgUsePathInfo variable in {{ mediawiki_abs_path }}/LocalSettings.php
lineinfile:
dest: "{{ mediawiki_abs_path }}/LocalSettings.php"
line: '$wgUsePathInfo = true;'
create: yes
- name: Install /etc/{{ apache_config_dir }}/mediawiki.conf from template, for http://box{{ mediawiki_url }}
template:
src: mediawiki.conf.j2
dest: "/etc/{{ apache_config_dir }}/mediawiki.conf"
# Install {{ nginx_config_dir }}/mediawiki-nginx.conf from template in enable.yml
- name: Add 'mediawiki_installed' variable values to {{ iiab_state_file }}
lineinfile:
dest: "{{ iiab_state_file }}"

View file

@ -0,0 +1,54 @@
# this works if (docroot)/mwlink links to install
# and LocalSettings.php has
# $wgScriptPath = "/mwlink";
# $wgArticlePath = "/wiki/$1";
# $wgUsePathInfo = true;
location ~ ^/mwlink/(index|load|api|thumb|opensearch_desc)\.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass php; # or whatever port your PHP-FPM listens on
}
# Images
location /mwlink/images {
# Separate location for images/ so .php execution won't apply
}
location /mwlink/images/deleted {
# Deny access to deleted images folder
deny all;
}
# MediaWiki assets (usually images)
location ~ ^/mwlink/resources/(assets|lib|src) {
try_files $uri 404;
add_header Cache-Control "public";
expires 7d;
}
# Assets, scripts and styles from skins and extensions
location ~ ^/mwlink/(skins|extensions)/.+\.(css|js|gif|jpg|jpeg|png|svg)$ {
try_files $uri 404;
add_header Cache-Control "public";
expires 7d;
}
## Uncomment the following code if you wish to use the installer/updater
## installer/updater
#location /mwlink/mw-config/ {
# # Do this inside of a location so it can be negated
# location ~ \.php$ {
# include /etc/nginx/fastcgi_params;
# fastcgi_param SCRIPT_FILENAME $document_root/mwlink/mw-config/$fastcgi_script_name;
# fastcgi_pass 127.0.0.1:9000; # or whatever port your PHP-FPM listens on
# }
#}
# Handling for the article path (pretty URLs)
location {{ mediawiki_url }}/ {
rewrite ^{{ mediawiki_url }}/(?<pagename>.*)$ /mwlink/index.php;
}
# Explicit access to the root website, redirect to main page (adapt as needed)
location = {{ mediawiki_url }} {
return 301 {{ mediawiki_url }}/Main_Page;
}

View file

@ -7,7 +7,7 @@
# All above are set in: github.com/iiab/iiab/blob/master/vars/default_vars.yml
# If nec, change them by editing /etc/iiab/local_vars.yml prior to installing!
moodle_version: 37
moodle_version: 38
#moodle_repo_url: "https://github.com/moodle/moodle.git"
moodle_repo_url: "git://git.moodle.org/moodle.git"
moodle_base: "{{ iiab_base }}/moodle" # /opt/iiab

View file

@ -25,3 +25,11 @@
- { src: "roles/nginx/templates/server.conf", dest: "/etc/nginx/" }
- { src: "roles/nginx/templates/nginx.conf", dest: "/etc/nginx/" }
- { src: 'roles/nginx/templates/ports.conf', dest: '/etc/{{ apache_service }}/' , mode: '0644' }
- { src: 'roles/nginx/templates/uwsgi.service', dest: '/etc/systemd/system/' , mode: '0644' }
- name: Let uwsgi running as {{ apache_user }} write log files
file:
path: /var/log/uwsgi/app
state: directory
owner: "{{ apache_user }}"

View file

@ -25,14 +25,24 @@
dest: "/etc/nginx/conf.d/lokole-nginx.conf"
when: lokole_enabled
- name: Install MediaWiki's nginx conf.d file from template
template:
src: mediawiki-nginx.conf.j2
dest: /etc/nginx/conf.d/mediawiki-nginx.conf
when: mediawiki_enabled
# mediawiki and wordpress are no longer proxied
- name: Install WordPress's nginx conf.d file from template
template: src=nextcloud-nginx.conf dest=/etc/nginx/conf.d/nextcloud-nginx.conf
#- name: Install MediaWiki's nginx conf.d file from template
# template:
# src: mediawiki-nginx.conf.j2
# dest: /etc/nginx/conf.d/mediawiki-nginx.conf
# when: mediawiki_enabled
#- name: Install WordPress's nginx conf.d file from template
# template:
# src: wordpress-nginx.conf
# dest: /etc/nginx/conf.d/
# when: wordpress_enabled
- name: Install Nextcloud's nginx conf.d file from template
template:
src: nextcloud-nginx.conf
dest: /etc/nginx/conf.d/nextcloud-nginx.conf
when: nextcloud_enabled
- name: Install NodeRed's nginx conf.d file from template
@ -44,11 +54,5 @@
mode: 0666
when: nodered_enabled
- name: Install WordPress's nginx conf.d file from template
template:
src: wordpress-nginx.conf
dest: /etc/nginx/conf.d/
when: wordpress_enabled
#- name: Install proxpass to apache running on localhost

View file

@ -22,9 +22,10 @@ http {
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;

View file

@ -2,7 +2,7 @@
Description=uWSGI Service
[Service]
ExecStart=/usr/local/bin/uwsgi --ini /etc/uwsgi/admin_console_wsgi.ini
ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/apps-enabled/admin-console.ini
Restart=always
RestartSec=5
KillSignal=SIGQUIT

View file

@ -1,6 +1,6 @@
# For downloadable regional vector tilesets
location /maps {
rewrite ^/maps/(.*)$ /osm-vector-maps/$1;
rewrite ^/maps(.*)$ /osm-vector-maps$1;
}
location /osm-vector-maps {
alias /library/www/osm-vector-maps;

View file

@ -4,5 +4,5 @@
# All above are set in: github.com/iiab/iiab/blob/master/vars/default_vars.yml
# If nec, change them by editing /etc/iiab/local_vars.yml prior to installing!
phpmyadmin_name: "phpMyAdmin-4.9.2-all-languages"
phpmyadmin_name: "phpMyAdmin-5.0.0-all-languages"
phpmyadmin_name_zip: "{{ phpmyadmin_name }}.zip"

View file

@ -101,6 +101,12 @@
dest: "/etc/{{ apache_config_dir }}/wordpress.conf"
when: apache_enabled
- name: Install {{ nginx_config_dir }}/wordpress-nginx.conf from template, for http://box{{ wp_url }}
template:
src: wordpress-nginx.conf.j2
dest: "{{ nginx_config_dir }}/wordpress-nginx.conf"
when: nginx_enabled
- name: Add 'wordpress_installed' variable values to {{ iiab_state_file }}
lineinfile:
dest: "{{ iiab_state_file }}"

View file

@ -0,0 +1,19 @@
location {{ wp_url }} {
#rewrite_log on;
root {{ content_base }};
location ~ .*\.php$ {
include fastcgi_params;
fastcgi_pass php;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ ^({{ wp_url }})(/.*)/$ {
include fastcgi_params;
fastcgi_pass php;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME {{ wp_abs_path }}/index.php;
}
}

View file

@ -144,9 +144,10 @@ dns_jail_enabled: False
# Python-based Captive Portal, that @m-anish & @jvonau experimented with in
# July 2018 (https://github.com/iiab/iiab/pull/870) and that @georgejhunt
# extensively refined later in 2018 (PRs #1179, #1300, #1327).
captive_portal_install: False
captive_portal_enabled: False
captive_portal_port: 9090
captiveportal_install: False
captiveportal_enabled: False
captiveportal_port: 9090
captiveportal_splash_page: /
# In a pinch, disable Captive Portal using instructions in http://FAQ.IIAB.IO
# Bluetooth PAN access to IIAB server
@ -240,7 +241,7 @@ nginx_port: "80"
nginx_interface: "0.0.0.0"
nginx_install: True
nginx_enabled: True
nginx_config_dir: /etc/nginx/conf.d
# See also Apache vars {default_language, language_priority} @ top of this file
#
@ -338,7 +339,7 @@ azuracast_port_range_prefix: 10
dokuwiki_install: False
dokuwiki_enabled: False
dokuwiki_url: /wiki
dokuwiki_url: /dokuwiki
mediawiki_install: False
mediawiki_enabled: False

View file

@ -82,8 +82,9 @@ dns_jail_enabled: False
# Python-based Captive Portal, that @m-anish & @jvonau experimented with in
# July 2018 (https://github.com/iiab/iiab/pull/870) and that @georgejhunt
# extensively refined later in 2018 (PRs #1179, #1300, #1327).
captive_portal_install: False
captive_portal_enabled: False
captiveportal_install: False
captiveportal_enabled: False
captiveportal_splash_page: /
# In a pinch, disable Captive Portal using instructions in http://FAQ.IIAB.IO
# Bluetooth PAN access to IIAB server

View file

@ -82,8 +82,9 @@ dns_jail_enabled: False
# Python-based Captive Portal, that @m-anish & @jvonau experimented with in
# July 2018 (https://github.com/iiab/iiab/pull/870) and that @georgejhunt
# extensively refined later in 2018 (PRs #1179, #1300, #1327).
captive_portal_install: False
captive_portal_enabled: False
captiveportal_install: False
captiveportal_enabled: False
captiveportal_splash_page: /
# In a pinch, disable Captive Portal using instructions in http://FAQ.IIAB.IO
# Bluetooth PAN access to IIAB server

View file

@ -82,8 +82,9 @@ dns_jail_enabled: False
# Python-based Captive Portal, that @m-anish & @jvonau experimented with in
# July 2018 (https://github.com/iiab/iiab/pull/870) and that @georgejhunt
# extensively refined later in 2018 (PRs #1179, #1300, #1327).
captive_portal_install: False
captive_portal_enabled: False
captiveportal_install: False
captiveportal_enabled: False
captiveportal_splash_page: /
# In a pinch, disable Captive Portal using instructions in http://FAQ.IIAB.IO
# Bluetooth PAN access to IIAB server