From 457f023e098d1ac2ec0f97ec5b5b8266ef0ce441 Mon Sep 17 00:00:00 2001 From: Julien VAUBOURG Date: Sun, 9 Nov 2014 00:40:40 +0100 Subject: [PATCH] The service is now based on yunohost settings, allowing to update the setup though the web interface with yunohost app setting commands --- conf/{dhcpd.conf => dhcpd.conf.tpl} | 0 conf/{hostapd.conf => hostapd.conf.tpl} | 0 conf/init_ynh-hotspot | 388 ++++++++++++++++++++++++ conf/{radvd.conf => radvd.conf.tpl} | 0 conf/ynh-hotspot | 227 -------------- scripts/install | 66 ++-- scripts/remove | 10 +- 7 files changed, 418 insertions(+), 273 deletions(-) rename conf/{dhcpd.conf => dhcpd.conf.tpl} (100%) rename conf/{hostapd.conf => hostapd.conf.tpl} (100%) create mode 100644 conf/init_ynh-hotspot rename conf/{radvd.conf => radvd.conf.tpl} (100%) delete mode 100644 conf/ynh-hotspot diff --git a/conf/dhcpd.conf b/conf/dhcpd.conf.tpl similarity index 100% rename from conf/dhcpd.conf rename to conf/dhcpd.conf.tpl diff --git a/conf/hostapd.conf b/conf/hostapd.conf.tpl similarity index 100% rename from conf/hostapd.conf rename to conf/hostapd.conf.tpl diff --git a/conf/init_ynh-hotspot b/conf/init_ynh-hotspot new file mode 100644 index 0000000..908acae --- /dev/null +++ b/conf/init_ynh-hotspot @@ -0,0 +1,388 @@ +#!/bin/bash +### BEGIN INIT INFO +# Provides: ynh-hotspot +# Required-Start: $network $remote_fs $syslog +# Required-Stop: $network $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Set prerequisites for wifi hotspot. +# Description: Set prerequisites for wifi hotspot. +### END INIT INFO + +# Functions +## State functions + +is_ndproxy_set() { + proxy=$(ip -6 neighbour show proxy) + [ ! -z "${proxy}" ] +} + +is_nat_set() { + internet_device=$1 + + iptables -nvt nat -L POSTROUTING | grep MASQUERADE | grep -q "${internet_device}" +} + +is_ip4nataddr_set() { + ip address show dev "${ynh_wifi_device}" 2> /dev/null | grep -q "${ynh_ip4_nat_prefix}.1/24" +} + +is_ip6addr_set() { + ip address show dev "${ynh_wifi_device}" 2> /dev/null | grep -q "${ynh_ip6_addr}/64" +} + +is_forwarding_set() { + ip6=$(sysctl net.ipv6.conf.all.forwarding | awk '{ print $NF; }') + ip4=$(sysctl net.ipv4.conf.all.forwarding | awk '{ print $NF; }') + + [ "${ip6}" -eq 1 -a "${ip4}" -eq 1 ] +} + +is_hostapd_running() { + service hostapd status &> /dev/null +} + +is_radvd_running() { + service radvd status &> /dev/null +} + +is_dhcpd_running() { + service isc-dhcp-server status &> /dev/null +} + +is_running() { + is_ndproxy_set && is_nat_set "${new_internet_device}" && is_ip4nataddr_set\ + && is_ip6addr_set && is_forwarding_set && is_hostapd_running\ + && is_radvd_running && is_dhcpd_running +} + +## Setters + +set_ndproxy() { + ip -6 neighbour add proxy "${ynh_ip6_addr}" dev "${ynh_wifi_device}" +} + +set_nat() { + internet_device=$1 + + iptables -t nat -A POSTROUTING -o "${internet_device}" -j MASQUERADE +} + +set_ip4nataddr() { + ip address add "${ynh_ip4_nat_prefix}.1/24" dev "${ynh_wifi_device}" +} + +set_ip6addr() { + ip address add "${ynh_ip6_addr}/64" dev "${ynh_wifi_device}" +} + +set_forwarding() { + sysctl -w net.ipv6.conf.all.forwarding=1 > /dev/null + sysctl -w net.ipv4.conf.all.forwarding=1 > /dev/null +} + +start_hostapd() { + cp /etc/hostapd/hostapd.conf{.tpl,} + + sed "s||${ynh_wifi_device}|g" -i /etc/hostapd/hostapd.conf + sed "s||${ynh_wifi_ssid}|g" -i /etc/hostapd/hostapd.conf + sed "s||${ynh_wifi_passphrase}|g" -i /etc/hostapd/hostapd.conf + + service hostapd start +} + +start_radvd() { + cp /etc/radvd.conf{.tpl,} + + sed "s||${ynh_wifi_device}|g" -i /etc/radvd.conf + sed "s||${ynh_ip6_net}|g" -i /etc/radvd.conf + sed "s||${ynh_ip6_dns0}|g" -i /etc/radvd.conf + sed "s||${ynh_ip6_dns1}|g" -i /etc/radvd.conf + + service radvd start +} + +start_dhcpd() { + cp /etc/dhcp/dhcpd.conf{.tpl,} + + sed "s||${ynh_ip4_dns0}|g" -i /etc/dhcp/dhcpd.conf + sed "s||${ynh_ip4_dns1}|g" -i /etc/dhcp/dhcpd.conf + sed "s||${ynh_wifi_device}|g" -i /etc/dhcp/dhcpd.conf + sed "s||${ynh_ip4_nat_prefix}|g" -i /etc/dhcp/dhcpd.conf + + service isc-dhcp-server start +} + +## Unsetters + +unset_ndproxy() { + ip -6 neighbour delete proxy "${ynh_ip6_addr}" dev "${ynh_wifi_device}" +} + +unset_nat() { + internet_device=$1 + + iptables -t nat -D POSTROUTING -o "${internet_device}" -j MASQUERADE +} + +unset_ip4nataddr() { + ip address delete "${ynh_ip4_nat_prefix}.1/24" dev "${ynh_wifi_device}" +} + +unset_ip6addr() { + ip address delete "${ynh_ip6_addr}/64" dev "${ynh_wifi_device}" +} + +unset_forwarding() { + sysctl -w net.ipv6.conf.all.forwarding=0 > /dev/null + sysctl -w net.ipv4.conf.all.forwarding=0 > /dev/null +} + +stop_hostapd() { + service hostapd stop +} + +stop_radvd() { + service radvd stop +} + +stop_dhcpd() { + service isc-dhcp-server stop +} + +## Tools + +moulinette_get() { + var=$1 + + value=$(yunohost app setting hotspot "${var}") + + if [[ "${value}" =~ "An instance is already running" ]]; then + echo "${value}" >&2 + exit 1 + fi + + echo "${value}" +} + +moulinette_set() { + var=$1 + value=$2 + + msg=$(yunohost app setting hotspot "${var}" -v "${value}") + + if [ ! $? -eq 0 ]; then + echo "${msg}" >&2 + exit 1 + fi +} + +# Variables + +echo -n "Retrieving Yunohost settings... " + +ynh_wifi_device=$(moulinette_get wifi_device) +ynh_wifi_ssid=$(moulinette_get wifi_ssid) +ynh_wifi_passphrase=$(moulinette_get wifi_passphrase) +ynh_ip6_addr=$(moulinette_get ip6_addr) +ynh_ip6_net=$(moulinette_get ip6_net) +ynh_ip6_dns0=$(moulinette_get ip6_dns0) +ynh_ip6_dns1=$(moulinette_get ip6_dns1) +ynh_ip4_dns0=$(moulinette_get ip4_dns0) +ynh_ip4_dns1=$(moulinette_get ip4_dns1) +ynh_ip4_nat_prefix=$(moulinette_get ip4_nat_prefix) + +old_internet_device=$(moulinette_get internet_device) +new_internet_device=$(ip route | awk '/default via/ { print $NF; }') + +# Switch the NAT interface if there is a VPN +ip link show dev tun0 &> /dev/null +if [ "$?" -eq 0 ]; then + new_internet_device=tun0 +fi + +echo "OK" + +# Script + +case "$1" in + start) + if is_running; then + echo "Already started" + else + echo "Starting..." + + # Set NDP proxy + if ! is_ndproxy_set; then + echo "Set NDP proxy" + set_ndproxy + fi + + # Check old state of the ipv4 NAT settings + if [ ! -z "${old_internet_device}" -a "${new_internet_device}" != "${old_internet_device}" ]\ + && is_nat_set "${old_internet_device}"; then + + unset_nat "${old_internet_device}" + fi + + # Set ipv4 NAT + if ! is_nat_set "${new_internet_device}"; then + echo "Set NAT" + set_nat "${new_internet_device}" + fi + + # Set ipv4 NAT address + if ! is_ip4nataddr_set; then + echo "Set IPv4 NAT address" + set_ip4nataddr + fi + + # Set the ipv6 address + if ! is_ip6addr_set; then + echo "Set IPv6 address" + set_ip6addr + fi + + # Set forwarding for ipv6 and ipv4 + if ! is_forwarding_set; then + echo "Set forwarding" + set_forwarding + fi + + # Run hostapd + if ! is_hostapd_running; then + echo "Run hostapd" + start_hostapd + sleep 1 + fi + + # Run radvd + # must be running after hostapd + if ! 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 + ;; + stop) + echo "Stopping..." + + if is_ndproxy_set; then + echo "Unset NDP proxy" + unset_ndproxy + fi + + if is_nat_set "${old_internet_device}"; then + echo "Unset NAT" + unset_nat "${old_internet_device}" + fi + + if is_ip4nataddr_set; then + echo "Unset IPv4 NAT address" + unset_ip4nataddr + fi + + if is_ip6addr_set; then + echo "Unset IPv6 address" + unset_ip6addr + fi + + if is_forwarding_set; then + echo "Unset forwarding" + unset_forwarding + fi + + if is_hostapd_running; then + echo "Stop hostapd" + stop_hostapd + fi + + if is_radvd_running; then + echo "Stop radvd" + stop_radvd + fi + + if is_dhcpd_running; then + echo "Stop dhcpd" + stop_dhcpd + fi + ;; + restart) + $0 stop + $0 start + ;; + status) + exitcode=0 + + if is_ndproxy_set; then + echo "NDP proxy is correctly set" + else + echo "NDP proxy is NOT set" + exitcode=1 + fi + + if is_nat_set "${new_internet_device}"; then + echo "NAT is correctly set" + else + echo "NAT is NOT set" + exitcode=1 + fi + + if is_ip4nataddr_set; then + echo "IPv4 NAT address is correctly set" + else + echo "IPv4 NAT address is NOT set" + exitcode=1 + fi + + if is_ip6addr_set; then + echo "IPv6 address is correctly set" + else + echo "IPv6 address is NOT set" + exitcode=1 + fi + + if is_forwarding_set; then + echo "Forwarding is correctly set" + else + echo "Forwarding is NOT set" + exitcode=1 + fi + + if is_hostapd_running; then + echo "Hostapd is running" + else + echo "Hostapd is NOT running" + exitcode=1 + fi + + if is_radvd_running; then + echo "Radvd is running" + else + echo "Radvd is NOT running" + exitcode=1 + fi + + if is_dhcpd_running; then + echo "Dhcpd is running" + else + echo "Dhcpd is NOT running" + exitcode=1 + fi + + exit ${exitcode} + ;; + *) + echo "Usage: $0 {start|stop|restart|status}" + exit 1 + ;; +esac + +exit 0 diff --git a/conf/radvd.conf b/conf/radvd.conf.tpl similarity index 100% rename from conf/radvd.conf rename to conf/radvd.conf.tpl diff --git a/conf/ynh-hotspot b/conf/ynh-hotspot deleted file mode 100644 index f22a77e..0000000 --- a/conf/ynh-hotspot +++ /dev/null @@ -1,227 +0,0 @@ -#!/bin/bash -### BEGIN INIT INFO -# Provides: ynh-hotspot -# Required-Start: $network $remote_fs $syslog -# Required-Stop: $network $remote_fs $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Set prerequisites for wifi hotspot. -# Description: Set prerequisites for wifi hotspot. -### END INIT INFO - -is_ndproxy_set() { - proxy=$(ip -6 neigh show proxy) - [ ! -z "${proxy}" ] -} - -is_nat_set() { - iptables -nt nat -L POSTROUTING | grep -q MASQUERADE -} - -is_ip4nataddr_set() { - ip a s dev | grep -q .1/24 -} - -is_ip6addr_set() { - ip a s dev | grep -q /64 -} - -is_forwarding_set() { - ip6=$(sysctl net.ipv6.conf.all.forwarding | awk '{ print $NF; }') - ip4=$(sysctl net.ipv4.conf.all.forwarding | awk '{ print $NF; }') - [ ${ip6} -eq 1 -a ${ip4} -eq 1 ] -} - -is_hostapd_running() { - service hostapd status &> /dev/null -} - -is_radvd_running() { - service radvd status &> /dev/null -} - -is_dhcpd_running() { - service isc-dhcp-server status &> /dev/null -} - -is_running() { - is_ndproxy_set && is_nat_set && is_forwarding_set\ - && is_hostapd_running && is_radvd_running && is_dhcpd_running -} - -internet_device=$(ip r | awk '/default via/ { print $NF; }') -internet_device_vpn=tun0 -internet_device_default=${internet_device} - -# Apply NAT on tun0 if IPv6 address if VPN is used -ip l sh dev tun0 &> /dev/null -if [ "$?" -eq 0 ]; then - internet_device_default=${internet_device_vpn} -fi - -case "$1" in - start) - if is_running; then - echo "Already correctly set" - else - if ! is_ndproxy_set; then - echo "Set NDP proxy" - ip -6 neigh add proxy dev - fi - - if ! is_nat_set; then - echo "Set NAT" - iptables -t nat -A POSTROUTING -o ${internet_device_default} -j MASQUERADE - fi - - if ! is_ip4nataddr_set; then - echo "Set IPv4 NAT address" - ip a a .1/24 dev - fi - - if ! is_ip6addr_set; then - echo "Set IPv6 address" - ip a a /64 dev - fi - - if ! is_forwarding_set; then - echo "Set forwarding" - sysctl -w net.ipv6.conf.all.forwarding=1 &> /dev/null - sysctl -w net.ipv4.conf.all.forwarding=1 &> /dev/null - fi - - if ! is_hostapd_running; then - echo "Run hostapd" - service hostapd start - fi - - # must be running after hostapd - if ! is_radvd_running; then - echo "Run radvd" - sleep 1 - service radvd start - fi - - # "options routers" addr (is_ip6addr_set) must be set before - if ! is_dhcpd_running; then - echo "Run dhcpd" - service isc-dhcp-server start - fi - fi - ;; - stop) - if is_ndproxy_set; then - echo "Unset NDP proxy" - ip -6 neigh del proxy dev - fi - - if is_nat_set; then - echo "Unset NAT" - # Depending on the presence or not of a VPN at the last startup, one of these 2 lines is unnecessary - iptables -t nat -D POSTROUTING -o ${internet_device} -j MASQUERADE 2> /dev/null - iptables -t nat -D POSTROUTING -o ${internet_device_vpn} -j MASQUERADE 2> /dev/null - fi - - if is_ip4nataddr_set; then - echo "Unset IPv4 NAT address" - ip a d .1/24 dev - fi - - if is_ip6addr_set; then - echo "Unset IPv6 address" - ip a d /64 dev - fi - - if is_forwarding_set; then - echo "Unset forwarding" - sysctl -w net.ipv6.conf.all.forwarding=0 &> /dev/null - sysctl -w net.ipv4.conf.all.forwarding=0 &> /dev/null - fi - - if is_hostapd_running; then - echo "Stop hostapd" - service hostapd stop - fi - - if is_radvd_running; then - echo "Stop radvd" - service radvd stop - fi - - if is_dhcpd_running; then - echo "Stop dhcpd" - service isc-dhcp-server stop - fi - ;; - restart) - $0 stop - $0 start - ;; - status) - exitcode=0 - - if is_ndproxy_set; then - echo "NDP proxy is correctly set" - else - echo "NDP proxy is NOT set" - exitcode=1 - fi - - if is_nat_set; then - echo "NAT is correctly set" - else - echo "NAT is NOT set" - exitcode=1 - fi - - if is_ip4nataddr_set; then - echo "IPv4 NAT address is correctly set" - else - echo "IPv4 NAT address is NOT set" - exitcode=1 - fi - - if is_ip6addr_set; then - echo "IPv6 address is correctly set" - else - echo "IPv6 address is NOT set" - exitcode=1 - fi - - if is_forwarding_set; then - echo "Forwarding is correctly set" - else - echo "Forwarding is NOT set" - exitcode=1 - fi - - if is_hostapd_running; then - echo "Hostapd is running" - else - echo "Hostapd is NOT running" - exitcode=1 - fi - - if is_radvd_running; then - echo "Radvd is running" - else - echo "Radvd is NOT running" - exitcode=1 - fi - - if is_dhcpd_running; then - echo "Dhcpd is running" - else - echo "Dhcpd is NOT running" - exitcode=1 - fi - - exit ${exitcode} - ;; - *) - echo "Usage: $0 {start|stop|restart|status}" - exit 1 - ;; -esac - -exit 0 diff --git a/scripts/install b/scripts/install index e19feba..785790c 100644 --- a/scripts/install +++ b/scripts/install @@ -22,55 +22,31 @@ sudo apt-get --assume-yes --force-yes install hostapd radvd isc-dhcp-server ipta sudo apt-get --assume-yes --force-yes install sipcalc # Compute extra arguments -ip6_expanded_net=$(sipcalc ${ip6_net} | grep Expanded | awk '{ print $NF; }') -ip6_net=$(sipcalc ${ip6_net} | grep Compressed | awk '{ print $NF; }') -ip6_addr=$(echo "$(echo ${ip6_expanded_net} | cut -d: -f1-7):1") -ip6_addr=$(sipcalc ${ip6_addr} | grep Compressed | awk '{ print $NF; }') +ip6_expanded_net=$(sipcalc "${ip6_net}" | grep Expanded | awk '{ print $NF; }') +ip6_net=$(sipcalc "${ip6_net}" | grep Compressed | awk '{ print $NF; }') +ip6_addr=$(echo "$(echo "${ip6_expanded_net}" | cut -d: -f1-7):1") +ip6_addr=$(sipcalc "${ip6_addr}" | grep Compressed | awk '{ print $NF; }') ip4_nat_prefix=10.0.242 # Save arguments for future upgrades -sudo yunohost app setting hotspot wifi_ssid -v ${wifi_ssid} -sudo yunohost app setting hotspot wifi_passphrase -v ${wifi_passphrase} -sudo yunohost app setting hotspot wifi_device -v ${wifi_device} -sudo yunohost app setting hotspot ip6_addr -v ${ip6_addr} -sudo yunohost app setting hotspot ip6_net -v ${ip6_net} -sudo yunohost app setting hotspot ip6_dns0 -v ${ip6_dns0} -sudo yunohost app setting hotspot ip6_dns1 -v ${ip6_dns1} -sudo yunohost app setting hotspot ip4_dns0 -v ${ip4_dns0} -sudo yunohost app setting hotspot ip4_dns1 -v ${ip4_dns1} -sudo yunohost app setting hotspot ip4_nat_prefix -v ${ip4_nat_prefix} +sudo yunohost app setting hotspot wifi_ssid -v "${wifi_ssid}" +sudo yunohost app setting hotspot wifi_passphrase -v "${wifi_passphrase}" +sudo yunohost app setting hotspot wifi_device -v "${wifi_device}" +sudo yunohost app setting hotspot ip6_addr -v "${ip6_addr}" +sudo yunohost app setting hotspot ip6_net -v "${ip6_net}" +sudo yunohost app setting hotspot ip6_dns0 -v "${ip6_dns0}" +sudo yunohost app setting hotspot ip6_dns1 -v "${ip6_dns1}" +sudo yunohost app setting hotspot ip4_dns0 -v "${ip4_dns0}" +sudo yunohost app setting hotspot ip4_dns1 -v "${ip4_dns1}" +sudo yunohost app setting hotspot ip4_nat_prefix -v "${ip4_nat_prefix}" # Copy confs -sudo install -b -o root -g root -m 0644 ../conf/hostapd.conf /etc/hostapd/ -sudo install -b -o root -g root -m 0644 ../conf/radvd.conf /etc/ -sudo install -b -o root -g root -m 0644 ../conf/dhcpd.conf /etc/dhcp/ - -# Fix confs -## hostapd -sudo sed "s||${wifi_device}|g" -i /etc/hostapd/hostapd.conf -sudo sed "s||${wifi_ssid}|g" -i /etc/hostapd/hostapd.conf -sudo sed "s||${wifi_passphrase}|g" -i /etc/hostapd/hostapd.conf - -## radvd -sudo sed "s||${wifi_device}|g" -i /etc/radvd.conf -sudo sed "s||${ip6_net}|g" -i /etc/radvd.conf -sudo sed "s||${ip6_dns0}|g" -i /etc/radvd.conf -sudo sed "s||${ip6_dns1}|g" -i /etc/radvd.conf - -## dhcpd -sudo sed "s||${ip4_dns0}|g" -i /etc/dhcp/dhcpd.conf -sudo sed "s||${ip4_dns1}|g" -i /etc/dhcp/dhcpd.conf -sudo sed "s||${wifi_device}|g" -i /etc/dhcp/dhcpd.conf -sudo sed "s||${ip4_nat_prefix}|g" -i /etc/dhcp/dhcpd.conf +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/dhcpd.conf.tpl /etc/dhcp/ # Copy init script -sudo install -b -o root -g root -m 0755 ../conf/ynh-hotspot /etc/init.d/ - -# Fix init script -## ynh-hostspot -sudo sed "s||${ip6_addr}|g" -i /etc/init.d/ynh-hotspot -sudo sed "s||${ip4_nat_prefix}|g" -i /etc/init.d/ynh-hotspot -sudo sed "s||${wifi_device}|g" -i /etc/init.d/ynh-hotspot +sudo install -b -o root -g root -m 0755 ../conf/init_ynh-hotspot /etc/init.d/ynh-hotspot ## hostapd sudo sed 's|^DAEMON_CONF=$|&/etc/hostapd/hostapd.conf|' -i /etc/init.d/hostapd @@ -89,10 +65,10 @@ sudo yunohost service add hostapd sudo yunohost service stop hostapd sudo yunohost service disable hostapd -# Remove IPv6 address if vpnclient is installed because from now this one is handle by this app -sudo yunohost app list -f vpnclient --json | grep -q '"installed": true' +# Remove IPv6 address set if there is a VPN installed +sudo ip -6 address show dev tun0 2> /dev/null | grep -q "${ip6_addr}/" if [ "$?" -eq 0 ]; then - ip a d ${ip6_addr}/128 dev tun0 &> /dev/null + sudo ip address delete "${ip6_addr}/128" dev tun0 &> /dev/null fi # Gooo diff --git a/scripts/remove b/scripts/remove index ce16f5e..95a2e5b 100644 --- a/scripts/remove +++ b/scripts/remove @@ -6,7 +6,15 @@ sudo yunohost service remove ynh-hotspot sudo rm -f /etc/init.d/ynh-hotspot # Remove confs -sudo rm -f /etc/hostapd/hostapd.conf /etc/radvd.conf /etc/dhcp/dhcpd.conf +sudo rm -f /etc/hostapd/hostapd.conf{.tpl,} /etc/radvd.conf{.tpl,} /etc/dhcp/dhcpd.conf{.tpl,} + +# Restart vpnclient service if installed to set the IPv6 address +# A new start will fix the address without unsetting all stuff +sudo yunohost app list -f vpnclient --json | grep -q '"installed": true' +if [ "$?" -eq 0 ]; then + sudo yunohost service start ynh-vpnclient +fi + # Remove packets # The yunohost policy is currently to not uninstall packets (dependency problems)