Wifi Captive Portal

An implementation of a simple Captive Portal that allows
access to an IP network via forwarding on the same machine
running the GSM core network.

A Wifi AP could be connected to the ethernet port
specified in the hiera as wifi_if (default eth3)
Any Wifi AP can be used, and configured as desired.

In the future, maybe a RADIUS based solution could
supercede this.
This commit is contained in:
Keith Whyte 2023-08-21 03:43:20 +02:00
parent 3563a411fc
commit c749dd35f8
6 changed files with 170 additions and 1 deletions

View file

@ -0,0 +1,11 @@
[Unit]
Description=DNSMASQ for Wifi-Portal
[Service]
Type=simple
Restart=always
ExecStart=/usr/sbin/dnsmasq -C /etc/dnsmasq.wifi.conf
RestartSec=2
[Install]
WantedBy=multi-user.target

View file

@ -76,6 +76,10 @@ class rhizo_base {
$bsc_ip_address = hiera('rhizo::bsc_ip_address', '172.16.0.1') $bsc_ip_address = hiera('rhizo::bsc_ip_address', '172.16.0.1')
$vpn_ip_address = hiera('rhizo::vpn_ip_address') $vpn_ip_address = hiera('rhizo::vpn_ip_address')
$wan_ip_address = hiera('rhizo::wan_ip_address') $wan_ip_address = hiera('rhizo::wan_ip_address')
$wifi_ip_address = hiera('rhizo::wifi_ip_address', '172.24.0.1')
$wifi_net = hiera('rhizo::wifi_net', '172.24.0.0/16')
$wifi_dhcp_range = hiera('rhizo::wifi_dhcp_range', '172.24.0.1,172.24.100.254')
$wifi_dns = hiera('rhizo::wifi_dns', '1.1.1.1')
$sip_central_ip_address = hiera('rhizo::sip_central_ip_address') $sip_central_ip_address = hiera('rhizo::sip_central_ip_address')
$webphone_prefix = hiera('rhizo::webphone_prefix', '[]') $webphone_prefix = hiera('rhizo::webphone_prefix', '[]')
$latency_check_address = hiera('rhizo::latency_check_address','1.1.1.1') $latency_check_address = hiera('rhizo::latency_check_address','1.1.1.1')
@ -87,6 +91,8 @@ class rhizo_base {
$stats_disk = hiera('rhizo::stats_disk','sda1') $stats_disk = hiera('rhizo::stats_disk','sda1')
$stats_if = hiera('rhizo::stats_if','eth0') $stats_if = hiera('rhizo::stats_if','eth0')
$wifi_if = hiera('rhizo::wifi_if','eth3')
$has_wifi = hiera('rhizo::has_wifi', 0)
# SITE settings # SITE settings
# rate type can be "call" or "min" # rate type can be "call" or "min"
@ -200,6 +206,13 @@ class rhizo_base {
if $has_vsat == 1 { if $has_vsat == 1 {
include rhizo_base::sems include rhizo_base::sems
} }
if $has_wifi == 1 {
Firewall {
require => undef,
}
class { 'firewall': }
include rhizo_base::wifi
}
sysctl { 'net.ipv4.ip_forward': sysctl { 'net.ipv4.ip_forward':
value => '1' value => '1'
@ -333,6 +346,11 @@ schedule { 'never':
$rsched = "never" $rsched = "never"
} }
service { 'apache2':
require => [ Package['apache2'], Vcsrepo['/var/rhizomatica'] ],
ensure => running,
}
vcsrepo { '/var/rhizomatica': vcsrepo { '/var/rhizomatica':
schedule => $rsched, schedule => $rsched,
ensure => latest, ensure => latest,

View file

@ -0,0 +1,107 @@
# wifi.pp
#
# A basic Wifi service with
# captive portal and authentication via SMS OTP.
#
#
class rhizo_base::wifi {
$pub_if = $rhizo_base::stats_if
$wifi_if = $rhizo_base::wifi_if
$wifi_ip = $rhizo_base::wifi_ip_address
$wifi_net = $rhizo_base::wifi_net
$wifi_dhcp_range = $rhizo_base::wifi_dhcp_range
$wifi_dns = $rhizo_base::wifi_dns
file { '/etc/dnsmasq.wifi.conf':
content => template('rhizo_base/dnsmasq.conf.erb'),
notify => Service['dnsmasq-wifi']
}
file { '/lib/systemd/system/dnsmasq-wifi.service':
ensure => present,
source => 'puppet:///modules/rhizo_base/systemd/dnsmasq-wifi.service',
}
service { 'dnsmasq-wifi':
provider => 'systemd',
enable => true,
ensure => 'running'
}
python::pip { 'python-iptables':
schedule => 'onceweek',
ensure => '1.0.1',
pkgname => 'python-iptables',
}
file { '/etc/apache2/sites-available/001-portal.conf':
content => template('rhizo_base/portal.conf.erb'),
require => Package['apache2']
}
->file { '/etc/apache2/sites-enabled/001-portal.conf':
ensure => link,
target => '../sites-available/001-portal.conf',
require => Package['apache2'],
notify => Service['apache2']
}
firewall { '000 accept DHCP (udp port 67)':
proto => 'udp',
iniface => $wifi_if,
dport => [53, 67],
action => 'accept',
}
->firewall { '001 accept WWW Portal':
proto => 'tcp',
iniface => $wifi_if,
dport => 81,
action => 'accept',
}
->firewall { '002 accept ICMP':
proto => 'icmp',
iniface => $wifi_if,
destination => $wifi_ip,
action => 'accept',
}
->firewall { '003 drop mark 10':
iniface => $wifi_if,
match_mark => 0xa,
action => 'drop',
}
firewall { '005 accept related established':
chain => 'FORWARD',
proto => 'all',
iniface => $pub_if,
state => ['RELATED', 'ESTABLISHED'],
action => 'accept',
}
->firewall { '006 drop mark 10':
chain => 'FORWARD',
iniface => $wifi_if,
match_mark => 0xa,
action => 'drop',
}
firewall { '020 redirect to portal':
table => 'nat',
chain => 'PREROUTING',
proto => 'tcp',
dport => 80,
iniface => $wifi_if,
match_mark => 0xa,
jump => 'DNAT',
todest => "$wifi_ip:81"
}
firewall { '021 nat masq from Wifi':
table => 'nat',
chain => 'POSTROUTING',
source => $wifi_net,
outiface => $pub_if,
jump => 'MASQUERADE'
}
}

View file

@ -26,7 +26,7 @@ pgsql_db = '<%= @pgsql_db %>'
pgsql_user = '<%= @pgsql_user %>' pgsql_user = '<%= @pgsql_user %>'
pgsql_pwd = '<%= @pgsql_pwd %>' pgsql_pwd = '<%= @pgsql_pwd %>'
pgsql_host = '<%= @pgsql_host %>' pgsql_host = '<%= @pgsql_host %>'
db_revision = 16 db_revision = 18
# SITE # SITE
site_name = "<%= @site_name %>" site_name = "<%= @site_name %>"
@ -42,6 +42,8 @@ mncc_ip_address = "<%= @mncc_ip_address %>"
sip_central_ip_address = <%= @sip_central_ip_address %> sip_central_ip_address = <%= @sip_central_ip_address %>
webphone_prefix = <%= @webphone_prefix %> webphone_prefix = <%= @webphone_prefix %>
has_vsat = <%= @has_vsat %> has_vsat = <%= @has_vsat %>
has_wifi = <%= @has_wifi %>
wifi_if = "<%= @wifi_if %>"
site_routing = [ site_routing = [
<%= @site_routing %> <%= @site_routing %>

View file

@ -0,0 +1,9 @@
keep-in-foreground
interface=<%= @wifi_if %>
listen-address=<%= @wifi_ip %>
port=54
no-resolv
dhcp-range=<%= @wifi_dhcp_range %>
dhcp-option-force=114,http://<%= @wifi_ip %>
dhcp-option-force=6,<%= @wifi_dns %>
dhcp-leasefile=/var/lib/misc/dnsmasq-wifi.leases

View file

@ -0,0 +1,22 @@
<Directory /var/rhizomatica/portal>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ http://<%= @wifi_ip %>/index.php [R]
Require all granted
</Directory>
<VirtualHost <%= @wifi_ip %>:81>
#ServerName www.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/rhizomatica/portal
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/portal_error.log
CustomLog ${APACHE_LOG_DIR}/portal_access.log combined
</VirtualHost>