1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/hotspot_ynh.git synced 2024-09-03 19:25:53 +02:00

DHCP with dnsmasq

This commit is contained in:
Julien VAUBOURG 2014-12-26 18:58:58 +01:00
parent aa2ae5853f
commit a72fcd29f8
12 changed files with 175 additions and 113 deletions

View file

@ -16,7 +16,7 @@ See the <a href="https://raw.githubusercontent.com/jvaubourg/hotspot_ynh/master/
* WPA2 encryption * WPA2 encryption
* 802.11n compliant * 802.11n compliant
* IPv6 compliant (with a delegated prefix) * IPv6 compliant (with a delegated prefix)
* Automatic clients configuration (IPv6 and IPv4) * Announce DNS resolvers (IPv6 with RDNSS/DHCPv6 and IPv4 with DHCPv4)
* Announce DNS resolvers (IPv6 and IPv4) * Automatic clients configuration (IPv6 with SLAAC/DHCPv6 and IPv4 with DHCPv4)
* Set an IPv6 from your delegated prefix (*prefix::42*) on the server, to use for the AAAA records * Set an IPv6 from your delegated prefix (*prefix::42*) on the server, to use for the AAAA records
* Web interface ([screenshot](https://raw.githubusercontent.com/jvaubourg/hotspot_ynh/master/screenshot.png)) * Web interface ([screenshot](https://raw.githubusercontent.com/jvaubourg/hotspot_ynh/master/screenshot.png))

View file

@ -1,15 +0,0 @@
option domain-name-servers <TPL:IP4_DNS0>, <TPL:IP4_DNS1>;
default-lease-time 14440;
ddns-update-style none;
deny bootp;
shared-network <TPL:WIFI_DEVICE> {
subnet <TPL:IP4_NAT_PREFIX>.0
netmask 255.255.255.0 {
option routers <TPL:IP4_NAT_PREFIX>.1;
option subnet-mask 255.255.255.0;
pool {
range <TPL:IP4_NAT_PREFIX>.2 <TPL:IP4_NAT_PREFIX>.254;
}
}
}

View file

@ -0,0 +1,30 @@
# Do DHCP for this subnet.
dhcp-range=interface:<TPL:WIFI_DEVICE>,<TPL:IP4_NAT_PREFIX>.2,<TPL:IP4_NAT_PREFIX>.254,4h
# Send DHCPv4 option.
dhcp-option=option:dns-server,<TPL:IP4_DNS0>,<TPL:IP4_DNS1>
# Set the DHCP server to authoritative mode. In this mode it will barge in
# and take over the lease for any client which broadcasts on the network,
# whether it has a record of the lease or not. This avoids long timeouts
# when a machine wakes up on a new network. DO NOT enable this if there's
# the slightest chance that you might end up accidentally configuring a DHCP
# server for your campus/company accidentally. The ISC server uses
# the same option, and this URL provides more information:
# http://www.isc.org/files/auth.html
dhcp-authoritative
# On systems which support it, dnsmasq binds the wildcard address,
# even when it is listening on only some interfaces. It then discards
# requests that it shouldn't reply to. This has the advantage of
# working even when interfaces come and go and change address. If you
# want dnsmasq to really bind only the interfaces it is listening on,
# uncomment this option. About the only time you may need this is when
# running another nameserver on the same machine.
bind-interfaces
# If this line is uncommented, dnsmasq will read /etc/ethers and act
# on the ethernet-address/IP pairs found there just as if they had
# been given as --dhcp-host options. Useful if you keep
# MAC-address/host mappings there for other purposes.
#read-ethers

View file

@ -0,0 +1,6 @@
# Do DHCP and Router Advertisements for this subnet. Set the A bit in the RA
# so that clients can use SLAAC addresses as well as DHCP ones.
dhcp-range=interface:<TPL:WIFI_DEVICE>,<TPL:IP6_NET>,slaac,64,4h
# Send DHCPv6 option. Note [] around IPv6 addresses.
dhcp-option=option6:dns-server,[<TPL:IP6_DNS0>],[<TPL:IP6_DNS1>]

View file

@ -46,22 +46,39 @@ is_forwarding_set() {
[ "${ip6}" -eq 1 -a "${ip4}" -eq 1 ] [ "${ip6}" -eq 1 -a "${ip4}" -eq 1 ]
} }
is_dhcpdv6_set() {
[ -e /etc/dnsmasq.d/dhcpdv6.conf ]
}
is_dhcpdv4_set() {
[ -e /etc/dnsmasq.d/dhcpdv4.conf ]
}
is_hostapd_running() { is_hostapd_running() {
service hostapd status &> /dev/null service hostapd status &> /dev/null
if [ $? -eq 0 ]; then
# If the wifi antenna was unplugged
if ip link show dev "${ynh_wifi_device}" | grep -q DOWN; then
service hostapd stop &> /dev/null
return 1
fi
return 0
fi
return 1
} }
is_radvd_running() { is_dnsmasq_running() {
service radvd status &> /dev/null service dnsmasq status &> /dev/null
}
is_dhcpd_running() {
service isc-dhcp-server status &> /dev/null
} }
is_running() { is_running() {
( has_ip6delegatedprefix && is_ip6addr_set && is_radvd_running && is_ndproxy_set || ! has_ip6delegatedprefix )\ ( has_ip6delegatedprefix && is_ip6addr_set && is_ndproxy_set && is_dhcpdv6_set || ! has_ip6delegatedprefix )\
&& is_nat_set "${new_internet_device}" && is_ip4nataddr_set && is_forwarding_set && is_hostapd_running\ && is_nat_set "${new_internet_device}" && is_ip4nataddr_set && is_forwarding_set && is_hostapd_running\
&& is_dhcpd_running && is_dhcpdv4_set && is_dnsmasq_running
} }
## Setters ## Setters
@ -90,6 +107,26 @@ set_forwarding() {
sysctl -w net.ipv4.conf.all.forwarding=1 > /dev/null sysctl -w net.ipv4.conf.all.forwarding=1 > /dev/null
} }
set_dhcpd() {
if has_ip6delegatedprefix; then
cp /etc/dnsmasq.d.tpl/dhcpdv6.conf.tpl /etc/dnsmasq.d/dhcpdv6.conf
sed "s|<TPL:WIFI_DEVICE>|${ynh_wifi_device}|g" -i /etc/dnsmasq.d/dhcpdv6.conf
sed "s|<TPL:IP6_NET>|${ynh_ip6_net}|g" -i /etc/dnsmasq.d/dhcpdv6.conf
sed "s|<TPL:IP6_DNS0>|${ynh_ip6_dns0}|g" -i /etc/dnsmasq.d/dhcpdv6.conf
sed "s|<TPL:IP6_DNS1>|${ynh_ip6_dns1}|g" -i /etc/dnsmasq.d/dhcpdv6.conf
fi
cp /etc/dnsmasq.d.tpl/dhcpdv4.conf.tpl /etc/dnsmasq.d/dhcpdv4.conf
sed "s|<TPL:IP4_DNS0>|${ynh_ip4_dns0}|g" -i /etc/dnsmasq.d/dhcpdv4.conf
sed "s|<TPL:IP4_DNS1>|${ynh_ip4_dns1}|g" -i /etc/dnsmasq.d/dhcpdv4.conf
sed "s|<TPL:WIFI_DEVICE>|${ynh_wifi_device}|g" -i /etc/dnsmasq.d/dhcpdv4.conf
sed "s|<TPL:IP4_NAT_PREFIX>|${ynh_ip4_nat_prefix}|g" -i /etc/dnsmasq.d/dhcpdv4.conf
service dnsmasq restart
}
start_hostapd() { start_hostapd() {
cp /etc/hostapd/hostapd.conf{.tpl,} cp /etc/hostapd/hostapd.conf{.tpl,}
@ -107,28 +144,6 @@ start_hostapd() {
service hostapd start service hostapd start
} }
start_radvd() {
cp /etc/radvd.conf{.tpl,}
sed "s|<TPL:WIFI_DEVICE>|${ynh_wifi_device}|g" -i /etc/radvd.conf
sed "s|<TPL:IP6_NET>|${ynh_ip6_net}|g" -i /etc/radvd.conf
sed "s|<TPL:IP6_DNS0>|${ynh_ip6_dns0}|g" -i /etc/radvd.conf
sed "s|<TPL:IP6_DNS1>|${ynh_ip6_dns1}|g" -i /etc/radvd.conf
service radvd start
}
start_dhcpd() {
cp /etc/dhcp/dhcpd.conf{.tpl,}
sed "s|<TPL:IP4_DNS0>|${ynh_ip4_dns0}|g" -i /etc/dhcp/dhcpd.conf
sed "s|<TPL:IP4_DNS1>|${ynh_ip4_dns1}|g" -i /etc/dhcp/dhcpd.conf
sed "s|<TPL:WIFI_DEVICE>|${ynh_wifi_device}|g" -i /etc/dhcp/dhcpd.conf
sed "s|<TPL:IP4_NAT_PREFIX>|${ynh_ip4_nat_prefix}|g" -i /etc/dhcp/dhcpd.conf
service isc-dhcp-server start
}
## Unsetters ## Unsetters
unset_ndproxy() { unset_ndproxy() {
@ -149,6 +164,11 @@ unset_ip6addr() {
ip address delete "${ynh_ip6_addr}/64" dev "${ynh_wifi_device}" ip address delete "${ynh_ip6_addr}/64" dev "${ynh_wifi_device}"
} }
unset_dhcpd() {
rm -f /etc/dnsmasq.d/dhcpdv?.conf
service dnsmasq restart
}
unset_forwarding() { unset_forwarding() {
sysctl -w net.ipv6.conf.all.forwarding=0 > /dev/null sysctl -w net.ipv6.conf.all.forwarding=0 > /dev/null
sysctl -w net.ipv4.conf.all.forwarding=0 > /dev/null sysctl -w net.ipv4.conf.all.forwarding=0 > /dev/null
@ -158,14 +178,6 @@ stop_hostapd() {
service hostapd stop service hostapd stop
} }
stop_radvd() {
service radvd stop
}
stop_dhcpd() {
service isc-dhcp-server stop
}
## Tools ## Tools
moulinette_get() { moulinette_get() {
@ -310,25 +322,16 @@ case "$1" in
set_forwarding set_forwarding
fi fi
# Run DHCP servers
if ( has_ip6delegatedprefix && ! is_dhcpdv6_set ) || ! is_dhcpdv4_set; then
echo "Set DHCP servers (dnsmasq)"
set_dhcpd
fi
# Run hostapd # Run hostapd
if ! is_hostapd_running; then if ! is_hostapd_running; then
echo "Run hostapd" echo "Run hostapd"
start_hostapd start_hostapd
sleep 1
fi
# Run radvd
# must be running after hostapd
if has_ip6delegatedprefix && ! is_radvd_running; then
echo "Run radvd"
start_radvd
fi
# Run dhcpd
# "options routers" addr (is_ip6addr_set) must be set before
if ! is_dhcpd_running; then
echo "Run dhcpd"
start_dhcpd
fi fi
# Update dynamic settings # Update dynamic settings
@ -337,7 +340,7 @@ case "$1" in
;; ;;
stop) stop)
echo "[hotspot] Stopping..." echo "[hotspot] Stopping..."
rm /tmp/.ynh-hotspot-started rm -f /tmp/.ynh-hotspot-started
if has_ip6delegatedprefix && is_ndproxy_set; then if has_ip6delegatedprefix && is_ndproxy_set; then
echo "Unset NDP proxy" echo "Unset NDP proxy"
@ -364,20 +367,15 @@ case "$1" in
unset_forwarding unset_forwarding
fi fi
if is_dhcpdv6_set || is_dhcpdv4_set; then
echo "Stop DHCP servers"
unset_dhcpd
fi
if is_hostapd_running; then if is_hostapd_running; then
echo "Stop hostapd" echo "Stop hostapd"
stop_hostapd stop_hostapd
fi fi
if has_ip6delegatedprefix && is_radvd_running; then
echo "Stop radvd"
stop_radvd
fi
if is_dhcpd_running; then
echo "Stop dhcpd"
stop_dhcpd
fi
if has_vpnclient_app; then if has_vpnclient_app; then
service ynh-vpnclient start service ynh-vpnclient start
@ -405,17 +403,24 @@ case "$1" in
echo "[ERR] No IPv6 address set" echo "[ERR] No IPv6 address set"
exitcode=1 exitcode=1
fi fi
if is_radvd_running; then if is_dhcpdv6_set; then
echo "[OK] Radvd is running" echo "[OK] SLAAC & DHCPv6 server set"
else else
echo "[ERR] Radvd is not running" echo "[ERR] No SLAAC & DHCPv6 server set"
exitcode=1 exitcode=1
fi fi
else else
echo "[INFO] No IPv6 delegated prefix found" echo "[INFO] No IPv6 delegated prefix found"
fi fi
if is_dhcpdv4_set; then
echo "[OK] DHCPv4 server set"
else
echo "[ERR] No DHCPv4 server set"
exitcode=1
fi
if is_nat_set "${new_internet_device}"; then if is_nat_set "${new_internet_device}"; then
echo "[OK] IPv4 NAT set" echo "[OK] IPv4 NAT set"
else else
@ -437,6 +442,13 @@ case "$1" in
exitcode=1 exitcode=1
fi fi
if is_dnsmasq_running; then
echo "[OK] Dnsmasq is running"
else
echo "[ERR] Dnsmasq is not running"
exitcode=1
fi
if is_hostapd_running; then if is_hostapd_running; then
echo "[OK] Hostapd is running" echo "[OK] Hostapd is running"
else else
@ -444,13 +456,6 @@ case "$1" in
exitcode=1 exitcode=1
fi fi
if is_dhcpd_running; then
echo "[OK] Dhcpd is running"
else
echo "[ERR] Dhcpd is not running"
exitcode=1
fi
exit ${exitcode} exit ${exitcode}
;; ;;
*) *)

View file

@ -1,6 +0,0 @@
interface <TPL:WIFI_DEVICE>
{
AdvSendAdvert on;
prefix <TPL:IP6_NET>/64 { };
RDNSS <TPL:IP6_DNS0> <TPL:IP6_DNS1> { };
};

View file

@ -38,9 +38,7 @@ if [ ! $? -eq 0 ]; then
fi fi
# Install packages # Install packages
# TODO: Replace isc-dhcp-server by dnsmasq (currently negotiating with the YunoHost team to packages='php5-fpm sipcalc hostapd iptables wireless-tools'
# also replace bind9 by dnsmasq)
packages='php5-fpm sipcalc hostapd radvd isc-dhcp-server iptables wireless-tools wireless-tools'
sudo apt-get --assume-yes --force-yes install ${packages} sudo apt-get --assume-yes --force-yes install ${packages}
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
@ -98,9 +96,12 @@ sudo install -o root -g root -m 0755 ../conf/ipv6_expanded /usr/local/bin/
sudo install -o root -g root -m 0755 ../conf/ipv6_compressed /usr/local/bin/ sudo install -o root -g root -m 0755 ../conf/ipv6_compressed /usr/local/bin/
# Copy confs # Copy confs
sudo mkdir -pm 0755 /etc/dnsmasq.d.tpl/
sudo chown root: /etc/dnsmasq.d.tpl/
sudo install -b -o root -g root -m 0644 ../conf/hostapd.conf.tpl /etc/hostapd/ sudo install -b -o root -g root -m 0644 ../conf/hostapd.conf.tpl /etc/hostapd/
sudo install -b -o root -g root -m 0644 ../conf/radvd.conf.tpl /etc/ sudo install -b -o root -g root -m 0644 ../conf/dnsmasq_dhcpdv6.conf.tpl /etc/dnsmasq.d.tpl/dhcpdv6.conf.tpl
sudo install -b -o root -g root -m 0644 ../conf/dhcpd.conf.tpl /etc/dhcp/ sudo install -b -o root -g root -m 0644 ../conf/dnsmasq_dhcpdv4.conf.tpl /etc/dnsmasq.d.tpl/dhcpdv4.conf.tpl
sudo install -b -o root -g root -m 0644 ../conf/nginx_wifiadmin.conf "/etc/nginx/conf.d/${domain}.d/wifiadmin.conf" sudo install -b -o root -g root -m 0644 ../conf/nginx_wifiadmin.conf "/etc/nginx/conf.d/${domain}.d/wifiadmin.conf"
sudo install -b -o root -g root -m 0644 ../conf/phpfpm_wifiadmin.conf /etc/php5/fpm/pool.d/wifiadmin.conf sudo install -b -o root -g root -m 0644 ../conf/phpfpm_wifiadmin.conf /etc/php5/fpm/pool.d/wifiadmin.conf
@ -134,18 +135,14 @@ sudo sed "s|<TPL:NGINX_LOCATION>|${url_path}|g" -i /var/www/wifiadmin/config.php
# Copy init script # Copy init script
sudo install -o root -g root -m 0755 ../conf/init_ynh-hotspot /etc/init.d/ynh-hotspot sudo install -o root -g root -m 0755 ../conf/init_ynh-hotspot /etc/init.d/ynh-hotspot
# Update firewall for DHCP
sudo yunohost firewall allow --no-upnp --ipv6 UDP 547
sudo yunohost firewall allow --no-upnp UDP 67
# Set default inits # Set default inits
# The boot order of these services are important, so they are disabled by default # The boot order of these services are important, so they are disabled by default
# and the ynh-hotspot service handles them. # and the ynh-hotspot service handles them.
# All services are registred by yunohost in order to prevent conflicts after the uninstall. # All services are registred by yunohost in order to prevent conflicts after the uninstall.
sudo yunohost service add isc-dhcp-server
sudo yunohost service stop isc-dhcp-server
sudo yunohost service disable isc-dhcp-server
sudo yunohost service add radvd
sudo yunohost service stop radvd
sudo yunohost service disable radvd
sudo yunohost service add hostapd sudo yunohost service add hostapd
sudo yunohost service stop hostapd sudo yunohost service stop hostapd
sudo yunohost service disable hostapd sudo yunohost service disable hostapd

View file

@ -9,7 +9,12 @@ sudo yunohost service remove ynh-hotspot
sudo rm -f /etc/init.d/ynh-hotspot sudo rm -f /etc/init.d/ynh-hotspot
sudo rm -f /tmp/.ynh-hotspot-* sudo rm -f /tmp/.ynh-hotspot-*
# Update firewall for DHCP
sudo yunohost firewall disallow --ipv6 UDP 547
sudo yunohost firewall disallow UDP 67
# Remove confs # Remove confs
sudo rm -fr /etc/dnsmasq.d.tpl/
sudo rm -f /etc/hostapd/hostapd.conf{.tpl,} /etc/radvd.conf{.tpl,} /etc/dhcp/dhcpd.conf{.tpl,} sudo rm -f /etc/hostapd/hostapd.conf{.tpl,} /etc/radvd.conf{.tpl,} /etc/dhcp/dhcpd.conf{.tpl,}
sudo rm -f /etc/nginx/conf.d/${domain}.d/wifiadmin.conf sudo rm -f /etc/nginx/conf.d/${domain}.d/wifiadmin.conf
sudo rm -f /etc/php5/fpm/pool.d/wifiadmin.conf sudo rm -f /etc/php5/fpm/pool.d/wifiadmin.conf
@ -24,6 +29,6 @@ sudo rm -rf /var/www/wifiadmin/
# Remove packets # Remove packets
# The yunohost policy is currently to not uninstall packets (dependency problems) # The yunohost policy is currently to not uninstall packets (dependency problems)
## sudo apt-get --assume-yes --force-yes remove hostapd radvd isc-dhcp-server iptables sipcalc wireless-tools ## sudo apt-get --assume-yes --force-yes remove hostapd iptables sipcalc wireless-tools
exit 0 exit 0

View file

@ -42,6 +42,14 @@ function ipv6_compressed($ip) {
return $output[0]; return $output[0];
} }
function is_connected_through_hotspot($ip6_net, $ip4_nat_prefix) {
$ip = $_SERVER['REMOTE_ADDR'];
$ip6_regex = '/^'.preg_quote(preg_replace('/::$/', '', $ip6_net)).':/';
$ip4_regex = '/^'.preg_quote($ip4_nat_prefix).'\./';
return (preg_match($ip6_regex, $ip) || preg_match($ip4_regex, $ip));
}
dispatch('/', function() { dispatch('/', function() {
exec('sudo iwconfig', $devs); exec('sudo iwconfig', $devs);
$wifi_device = moulinette_get('wifi_device'); $wifi_device = moulinette_get('wifi_device');
@ -59,6 +67,7 @@ dispatch('/', function() {
$ip6_net = moulinette_get('ip6_net'); $ip6_net = moulinette_get('ip6_net');
$ip6_net = ($ip6_net == 'none') ? '' : $ip6_net; $ip6_net = ($ip6_net == 'none') ? '' : $ip6_net;
$ip4_nat_prefix = moulinette_get('ip4_nat_prefix');
set('wifi_ssid', moulinette_get('wifi_ssid')); set('wifi_ssid', moulinette_get('wifi_ssid'));
set('wifi_passphrase', moulinette_get('wifi_passphrase')); set('wifi_passphrase', moulinette_get('wifi_passphrase'));
@ -69,10 +78,11 @@ dispatch('/', function() {
set('ip6_net', $ip6_net); set('ip6_net', $ip6_net);
set('ip6_dns0', moulinette_get('ip6_dns0')); set('ip6_dns0', moulinette_get('ip6_dns0'));
set('ip6_dns1', moulinette_get('ip6_dns1')); set('ip6_dns1', moulinette_get('ip6_dns1'));
set('ip4_nat_prefix', moulinette_get('ip4_nat_prefix')); set('ip4_nat_prefix', $ip4_nat_prefix);
set('ip4_dns0', moulinette_get('ip4_dns0')); set('ip4_dns0', moulinette_get('ip4_dns0'));
set('ip4_dns1', moulinette_get('ip4_dns1')); set('ip4_dns1', moulinette_get('ip4_dns1'));
set('faststatus', service_faststatus() == 0); set('faststatus', service_faststatus() == 0);
set('is_connected_through_hotspot', is_connected_through_hotspot($ip6_net, $ip4_nat_prefix));
return render('settings.html.php'); return render('settings.html.php');
}); });

View file

@ -43,3 +43,17 @@ div#github {
div#github a { div#github a {
margin-left: 17px; margin-left: 17px;
} }
div#saveconfirmation {
display: none;
padding-right: 15px;
width: 60%;
margin: 0 auto;
}
div#saveconfirmation div#confirm {
background-color: #fff;
padding: 10px;
margin: 15px 0 0 0;
border: 1px solid #F5E79E;
}

View file

@ -36,6 +36,11 @@ $(document).ready(function() {
$('#form').submit(); $('#form').submit();
}); });
$('#saveconfirm').click(function() {
$(this).hide();
$('#saveconfirmation').show();
});
$('#status .close').click(function() { $('#status .close').click(function() {
$(this).parent().hide(); $(this).parent().hide();
}); });

View file

@ -154,7 +154,18 @@
<div class="form-group"> <div class="form-group">
<div style="text-align: center"> <div style="text-align: center">
<?php if($is_connected_through_hotspot): ?>
<div class="alert alert-dismissible alert-warning fade in" role="alert" id="saveconfirmation">
<strong><?= T_('Notice') ?>:</strong> <?= T_("You are currently connected through the wifi hotspot. Please, confirm the reloading, wait for the wifi disconnect/reconnect and go back here to check that everything is okay.") ?>
<div id="confirm">
<button type="submit" class="btn btn-default" data-toggle="tooltip" id="save" data-title="<?= T_('Reloading may take a few minutes. Be patient.') ?>"><?= T_('Confirm') ?></button> <img src="public/img/loading.gif" id="save-loading" alt="Loading..." />
</div>
</div>
<button type="button" class="btn btn-default" id="saveconfirm"><?= T_('Save and reload') ?></button>
<?php else: ?>
<button type="submit" class="btn btn-default" data-toggle="tooltip" id="save" data-title="<?= T_('Reloading may take a few minutes. Be patient.') ?>"><?= T_('Save and reload') ?></button> <img src="public/img/loading.gif" id="save-loading" alt="Loading..." /> <button type="submit" class="btn btn-default" data-toggle="tooltip" id="save" data-title="<?= T_('Reloading may take a few minutes. Be patient.') ?>"><?= T_('Save and reload') ?></button> <img src="public/img/loading.gif" id="save-loading" alt="Loading..." />
<?php endif; ?>
</div> </div>
</div> </div>
</form> </form>