summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorfelics@felics-tablet2016-11-12 20:40:12 +0100
committerfelics@felics-tablet2016-11-12 20:40:12 +0100
commita39f3eaec199d195c1faaf70e62d9ddec78d5060 (patch)
treea4b15f827b03995faf1390a97beb7a4d304a307c
parent72ebf4134d21e71fe6624e643d46163ab9012cf0 (diff)
downloadaur-a39f3eaec199d195c1faaf70e62d9ddec78d5060.tar.gz
Added configuration of network address translation and IP forwarding.
-rw-r--r--.SRCINFO7
-rw-r--r--PKGBUILD10
-rwxr-xr-xadhocspot.sh180
3 files changed, 177 insertions, 20 deletions
diff --git a/.SRCINFO b/.SRCINFO
index eda4f98109b8..b270cfede37b 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,20 +1,21 @@
pkgbase = adhocspot-script
pkgdesc = Bash script to easily configure your interface to share your internet connection and configure a DHCP and DNS and TFTP boot server to listen on it. IP, DHCP, DNS can be configured, and for WiFi interfaces also wireless mode and encryption.
- pkgver = 20161025.1
- pkgrel = 2
+ pkgver = 20161112.1
+ pkgrel = 1
epoch = 0
install = adhocspot-script.install
arch = any
license = custom: Public Domain
depends = bash
depends = dnsmasq
+ depends = iptables
depends = net-tools
depends = wireless_tools
depends = wpa_supplicant
source = adhocspot.sh
source = copying.txt
source = adhocspot-script.install
- sha256sums = 777d22e0def2e66613e42531c8d1a802bbdce7cd9cf90ec1acd5981f7a981476
+ sha256sums = d19a5c94f26f64b6da277ae501e6c6b9c8ebb72ecc60739b80540e2dc1d25651
sha256sums = c3cbff25307e905545788f5c74cc137d79706c60549092f2a37919b93cf55ee3
sha256sums = f05052583b9d7ba8215897bc621fea38d18fea20e1040fcbda4fd2ab76fc8867
diff --git a/PKGBUILD b/PKGBUILD
index d30007e9368a..f4658ffb41e7 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -3,8 +3,8 @@
_pkgname=adhocspot-script
pkgname="${_pkgname}"
epoch=0
-pkgver=20161025.1
-pkgrel=2
+pkgver=20161112.1
+pkgrel=1
pkgdesc="Bash script to easily configure your interface to share your internet connection and configure a DHCP and DNS and TFTP boot server to listen on it. IP, DHCP, DNS can be configured, and for WiFi interfaces also wireless mode and encryption."
arch=('any')
license=('custom: Public Domain')
@@ -15,6 +15,7 @@ groups=(
depends=(
"bash"
"dnsmasq"
+ "iptables"
"net-tools"
"wireless_tools"
"wpa_supplicant"
@@ -40,11 +41,14 @@ source=(
)
sha256sums=(
- "777d22e0def2e66613e42531c8d1a802bbdce7cd9cf90ec1acd5981f7a981476"
+ "d19a5c94f26f64b6da277ae501e6c6b9c8ebb72ecc60739b80540e2dc1d25651"
"c3cbff25307e905545788f5c74cc137d79706c60549092f2a37919b93cf55ee3"
"f05052583b9d7ba8215897bc621fea38d18fea20e1040fcbda4fd2ab76fc8867"
)
+pkgver() {
+ "${srcdir}/adhocspot.sh" --version
+}
package() {
_licdirbase="/usr/share/licenses/${pkgname}"
diff --git a/adhocspot.sh b/adhocspot.sh
index 69f38a58a2e4..06217b093ae7 100755
--- a/adhocspot.sh
+++ b/adhocspot.sh
@@ -1,13 +1,17 @@
#!/bin/bash
+_version=20161112.1
##### Dependencies. #####
#
# On Arch Linux, this script depends on the following packages (in brackets the bare commands it uses):
+# * bash: For running this script. ('bash')
# * dnsmasq: For DHCP and DNS. ('dnsmasq')
+# * iptables: For configuring NAT/ masquerading. ('iptables')
# * net-tools: For configuring IP information of the network interface. ('ifconfig')
# * wireless_tools: For configuration of wireless network interface. ('iwconfig')
# * wpa_supplicant: For WPA-encryption. ('wpa_supplicant', 'wpa_passphrase')
+# * ... and standard tools like grep, sed, awk ...
#
##### #####
@@ -20,6 +24,8 @@ _datetime="$(date +%Y-%m-%d_%H-%M-%S)"
_iface_default="wlan0"
_ip_default="192.168.101.3"
_netmask_default="255.255.255.0"
+_out_iface_all_default="true"
+_out_iface_default="<all>"
_dhcprange_lower_suffix_default="121"
_dhcprange_upper_suffix_default="199"
_macaddress_change_default="false"
@@ -29,9 +35,11 @@ _channel_default="8"
_encryption_default="off"
_enckey_default="please_specify_a_non_default_key"
_wifimode_default="ad-hoc"
-_no_wifi_default="false" # Set to true if we do not wifi-configure the interface (e.g. if already configured or it's not wifi).
-_no_ipconfig_default="false" # Set to true if we do not want to ip-configure the interface (e.g. if already configured).
+_no_wifi_default="false"
+_no_ipconfig_default="false"
+_no_nat_default="false"
_tftp_root_default="/tftpboot"
+_no_tftp_default="false"
_verbose_default="false"
_debug_default="false"
_rundir_base_default="/var/run/adhocspot"
@@ -193,6 +201,68 @@ get_ipconfig() {
echo "inet ${_ipaddr} ${_nmtext}${_updown}"
}
+get_nat_interfaces() {
+ # Returns a newline-separated list of interfaces to add masquerading to their postrouting queue. Examines $_out_iface_all: If $_out_iface_all is true, returns all available interfaces whose name does not start with 'lo'. Otherwise, returns ${_out_iface}.
+ _nat_ifaces=""
+ if "${_out_iface_all}"; then
+ _nat_ifaces="$(ifconfig -a | grep -E '^[^[[:space:]]]*' | awk '{print $1}' | sed 's|\:$||g')"
+ else
+ _nat_ifaces="${_out_iface}"
+ fi
+ echo "${_nat_ifaces}"
+}
+
+get_rp_filter_status() {
+ # Arguments: $1: Space-, tab- or newline-separated list of interfaces to check rp_filter value.
+ if [ $# -lt 1 ]; then
+ exiterror "$0: In function 'get_nat_status': Error: Need list of interfaces as option."
+ fi
+ for _nat_iface in $1; do
+ echo "${_nat_iface} $(cat "/proc/sys/net/ipv4/conf/${_nat_iface}/rp_filter")"
+ done
+}
+
+get_ipv4_forward_status() {
+ cat "/proc/sys/net/ipv4/ip_forward"
+}
+
+configure_nat() {
+ # Arguments:
+ # $1: Space-, tab- or newline-separated list of interfaces to add masquerading to their postrouting queue.
+ if [ $# -lt 1 ]; then
+ exiterror "$0: In function 'configure_nat': Error: Need list of interfaces as option."
+ fi
+ get_rp_filter_status "$1" > "${_rp_filter_statusfile}"
+ get_ipv4_forward_status > "${_ipv4_forward_statusfile}"
+ verbose "Configuring IPv4 forwarding"
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+ for _nat_iface in $1; do
+ verbose "Configuring masquerading and disabling rp_filter on ${_nat_iface}."
+ iptables -t nat -A POSTROUTING -j MASQUERADE -o "${_nat_iface}"
+ echo 0 > "/proc/sys/net/ipv4/conf/${_nat_iface}/rp_filter"
+ done
+}
+
+deconfigure_nat() {
+ if [ -e "${_rp_filter_statusfile}" ]; then
+ cat "${_rp_filter_statusfile}" | while read _line; do
+ _nat_iface="$(echo "${_line}" | awk '{print $1}')"
+ _rp_value="$(echo "${_line}" | awk '{print $2}')"
+ verbose "Setting rp_filter to ${_rp_value} on ${_nat_iface}."
+ echo "${_rp_value}" > "/proc/sys/net/ipv4/conf/${_nat_iface}/rp_filter"
+ done
+ rm -f "${_rp_filter_statusfile}"
+ fi
+ if [ -e "${_ipv4_forward_statusfile}" ]; then
+ _fwd="$(cat "${_ipv4_forward_statusfile}")"
+ verbose "Setting IPv4 forwarding to ${_fwd}."
+ echo "${_fwd}" > /proc/sys/net/ipv4/ip_forward
+ rm -f "${_ipv4_forward_statusfile}"
+ fi
+ verbose "Removing all entries from the 'nat' firewall table."
+ iptables -t nat -F
+}
+
configure_ip() {
# Configures the network interface $1. Expects as argument $2 a string acceptible to ifconfig (e.g. of the format 'inet <IP> netmask <netmask> [up/down]').
if [ $# -lt 2 ]; then
@@ -381,14 +451,21 @@ start_dnsmasq() {
# "--bind-interfaces"
"--dhcp-range=${_dhcprange_lower},${_dhcprange_upper},24h"
"--read-ethers"
- "--enable-tftp"
- "--tftp-root=${_dnsmasq_tftproot}"
- "--tftp-no-fail"
"--conf-file=/dev/null"
)
+ if "${_no_tftp}"; then
+ _dnsmasq_tftp_options=(
+ )
+ else
+ _dnsmasq_tftp_options=(
+ "--enable-tftp"
+ "--tftp-root=${_dnsmasq_tftproot}"
+ "--tftp-no-fail"
+ )
+ fi
verbose "Starting dnsmasq."
- dnsmasq "${_dnsmasq_debug_options[@]}" "${_dnsmasq_general_options[@]}" || {
+ dnsmasq "${_dnsmasq_debug_options[@]}" "${_dnsmasq_general_options[@]}" "${_dnsmasq_tftp_options[@]}" || {
_dnsmasq_error="$?"
exiterror "$0: Error: dnsmasq failed to start with exitcode ${_dnsmasq_error}. Aborting." "${_dnsmasq_error}"
}
@@ -447,6 +524,8 @@ string_whitelist() {
_iface="${_iface_default}"
_ip="${_ip_default}"
_netmask="${_netmask_default}"
+_out_iface_all="${_out_iface_all_default}"
+_out_iface="${_out_iface_default}"
# _dhcprange_lower is set after parsing the options.
# _dhcprange_upper is set after parsing the options.
_macaddress_change="${_macaddress_change_default}"
@@ -458,7 +537,9 @@ _enckey="${_enckey_default}"
_wifimode="${_wifimode_default}"
_no_wifi="${_no_wifi_default}"
_no_ipconfig="${_no_ipconfig_default}"
+_no_nat="${_no_nat_default}"
_tftp_root="${_tftp_root_default}"
+_no_tftp="${_no_tftp_default}"
_verbose="${_verbose_default}"
_debug="${_debug_default}"
_rundir_base="${_rundir_base_default}"
@@ -473,22 +554,34 @@ printusage() {
echo " down | stop Stop the thing."
echo " stat | status | state | show Show the status of the thing."
echo " -h | --help | help Print this message and exit."
+ echo " -V | --version Print version number and exit. (Version is: '${_version}'.)"
echo ""
echo "Arguments (all optional):"
echo " -h | --help | help Print this message and exit."
+ echo " -V | --version Print version number and exit. (Version is: '${_version}'.)"
echo " -v | --verbose Print information as we go on/ start daemons verbosely."
echo " -d | --debug Print debug output/ start daemons with debug output."
echo " Implies verbose."
- echo " -i | --iface <iface> Interface to use (default: ${_iface_default})."
+ echo " -i | --iface <iface> Interface on which the connection should be made available"
+ echo " (default: ${_iface_default})."
echo " Only characters out of the set [a-zA-Z0-9\._\-] are allowed."
- echo " -ip | --ip <ip> IPv4-address to set the interface to (default: ${_ip_default})."
- echo " -nm | --netmask <netmask> Netmask to use (default: ${_netmask_default})."
- echo " -m | --mac <MAC-address> Set the MAC-address of the interface (defaults to"
- echo " the interface's native MAC-address)."
- echo " -ni | --no-ipconfig If specified, do not configure IP information for the"
+ echo " -ip | --ip <ip> IPv4-address to configure this interface to (default: ${_ip_default})."
+ echo " -nm | --netmask <netmask> Netmask to use on this interface (default: ${_netmask_default})."
+ echo " -m | --mac <MAC-address> Set the MAC-address of this interface (defaults to the"
+ echo " interface's native MAC-address)."
+ echo " -ni | --no-ipconfig If specified, do not configure IP information for this"
echo " interface. Useful e.g. if already configured."
echo " Specifying this option, the following won't be configured:"
echo " IP-address, netmask, MAC-address."
+ echo " -o | --out-iface <iface> If specified, configure masquerading ('NAT') only for"
+ echo " packages leaving on this interface (usually this is your"
+ echo " interface which connects to the internet, not the one"
+ echo " specified by the option '-i' / '--iface')."
+ echo " Only characters out of the set [a-zA-Z0-9\._\-] are allowed."
+ echo " If not specified, NAT will be configured on all available non-"
+ echo " local interfaces (determined by name starting with 'lo')."
+ echo " -nn | --no-nat If specified, do not configure and deconfigure network address"
+ echo " translation, forwarding and masquerading."
echo " -dl | --dhcp-lower <dhcp-ip> Lower end of the range of IP-addresses to assign to"
echo " clients. The default is the first three numbers of our"
echo " IP-address, and then ${_dhcprange_lower_suffix_default}, e.g. ${_dhcprange_lower}"
@@ -510,8 +603,8 @@ printusage() {
echo " Specifying this option, the following won't be configured:"
echo " WiFi-mode, ESSID, channel, encryption type, encryption key."
echo " -tf | --tftp-root <dir> Directory where to serve files for TFTP network boot from"
- echo " (default: ${_tftp_root_default}). Set to something nonextisting"
- echo " to disable functionality."
+ echo " (default: ${_tftp_root_default})"
+ echo " -nt | --no-tftp If specified, do not provide a TFTP server."
echo " -r | --rundir <directory> Where to store and look for runtime information"
echo " (default: ${_rundir_base_default}). It get's created if nonextisting."
echo ""
@@ -544,6 +637,10 @@ case "${_action}" in
printusage
exit 0
;;
+ "-V"|"--version")
+ msg "${_version}"
+ exit 0
+ ;;
*)
errmsg "$0: Error: Invalid action '${_action}' specified."
errmsg ""
@@ -564,6 +661,12 @@ while [ $# -ge 1 ]; do
exit 0
;;
+ "-V"|"--version")
+ shift
+ msg "${_version}"
+ exit 0
+ ;;
+
"-i"|"--iface")
shift
if [ $# -ge 1 ]; then
@@ -611,6 +714,26 @@ while [ $# -ge 1 ]; do
_no_ipconfig='true'
;;
+ "-o"|"--out-iface")
+ shift
+ if [ $# -ge 1 ]; then
+ _out_iface_all="false"
+ _out_iface="$1"
+ else
+ errmsg "$0: Error: Too few arguments for option '-o' or '--out-iface': Need to specify an interface."
+ errmsg ""
+ errmsg "$(printusage)"
+ errmsg ""
+ exiterror "Aborting." 16
+ fi
+ shift
+ ;;
+
+ "-nn"|"--no-nat")
+ shift
+ _no_nat='true'
+ ;;
+
"-dl"|"--dhcp-lower")
shift
if [ $# -ge 1 ]; then
@@ -801,6 +924,11 @@ while [ $# -ge 1 ]; do
shift
;;
+ "-nt"|"--no-tftp")
+ shift
+ _no_tftp='true'
+ ;;
+
"-r"|"--rundir")
shift
if [ $# -ge 1 ]; then
@@ -855,6 +983,9 @@ _origmacfilebase='macaddress.orig'
_origifconfigfilebase='ifconfig.orig'
_wificonfiguredfilebase='wifi.orig'
_startedatfilebase='datetime.txt'
+_rp_filter_statusfilebase='rp_filter.orig'
+_ipv4_forward_statusfilebase='ipv4_forward.orig'
+_nat_configuredfilebase='nat_configured'
_wpa_ctrl="${_rundir}/${_wpa_ctrlfilebase}"
_wpa_pidfile="${_rundir}/${_wpa_pidfilebase}"
@@ -865,6 +996,9 @@ _origmacfile="${_rundir}/${_origmacfilebase}"
_origifconfigfile="${_rundir}/${_origifconfigfilebase}"
_wificonfiguredfile="${_rundir}/${_wificonfiguredfilebase}"
_startedatfile="${_rundir}/${_startedatfilebase}"
+_rp_filter_statusfile="${_rundir}/${_rp_filter_statusfilebase}"
+_ipv4_forward_statusfile="${_rundir}/${_ipv4_forward_statusfilebase}"
+_nat_configuredfile="${_rundir}/${_nat_configuredfilebase}"
if "${_verbose}"; then
@@ -898,6 +1032,12 @@ case "${_action}" in
configure_ip "${_iface}" "inet ${_ip} netmask ${_netmask} up"
fi
+ if ! "${_no_nat}"; then
+ _nat_interfaces="$(get_nat_interfaces | tr '\n' ' ')"
+ configure_nat "${_nat_interfaces}"
+ echo "${_nat_interfaces}" > "${_nat_configuredfile}"
+ fi
+
start_dnsmasq
;;
@@ -910,6 +1050,11 @@ case "${_action}" in
errmsg "$0: Cannot bring down, since specified runtime information directory ${_rundir} does not exist."
fi
+ if [ -e "${_nat_configuredfile}" ]; then
+ deconfigure_nat
+ rm -f "${_nat_configuredfile}"
+ fi
+
if [ -e "${_wpa_pidfile}" ]; then
kill_by_pidfile "${_wpa_pidfile}" "wpa_supplicant"
rm -f "${_wpa_pidfile}"
@@ -961,6 +1106,13 @@ case "${_action}" in
} || true
echo ""
+ [ -e "${_instdir}/${_nat_configuredfilebase}" ] && {
+ echo -n "NAT: Configured by us for interfaces $(cat "${_instdir}/${_nat_configuredfilebase}")."
+ } || {
+ echo -n "NAT: Not configured by us."
+ }
+ echo ""
+
[ -e "${_instdir}/${_wpa_pidfilebase}" ] && {
echo -n "wpa_supplicant: PID: $(cat "${_instdir}/${_wpa_pidfilebase}"), "; [ -d "/proc/$(cat "${_instdir}/${_wpa_pidfilebase}")" ] && echo -n "Running." || echo -n "Not running."
} || {