OpenWrt Forum Archive

Topic: NoDogSplash - missing config file (Chaos Calmer)

The content of this topic has been archived on 21 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Hi,

I tried to set up a captive portal using NoDogSplash on my Raspberry Pi with OpenWRT Chaos Calmer and I faced a problem. I installed nodogsplash package with opkg and wanted to change its configuration. Then I found that configuration file "/etc/nodogsplash/nodogsplash.conf" was missing so I made new configuration file by myself. Now, when I am trying to start nodogsplash with "/etc/init.d/nodogsplash start" command I get the message:

 nodogsplash: Configuration file '' doesn't exist" 

Also new, empty file "CONFIGFILE" in /etc/nodogsplash directory was created. I failed to find any cause and solution sad Can anyone help me with that problem? I am new to openWRT so it is possible that I did something wrong. Thank you for answers.

I think there is something wrong with the part of the code which reads the configuration file. It's in the /etc/init.d/nodogsplash:

  config_get val "$cfg" config
  if [ -n "$val" ] ; then
    if [ -f "$val" ] ; then
      nolog error "Configuration file '$file' doesn't exist"
      return 0
    fi
    cat $val > CONFIGFILE
  fi

(Last edited by marcosbontempo on 28 Jul 2015, 14:21)

Thank you marcosbontempo for your answer.  In line  with "nolog error" I changed '$file' to  '$val' and at least I get error with valid filename tongue  Now my question is: why does this error occur when configuration file exist?

This is my /etc/init.d/nodogsplash file:

#!/bin/sh /etc/rc.common
#
# description: Startup/shutdown script for nodogsplash captive portal
#
# Alexander Couzens <lynxis@fe80.eu> 2014
# P. Kube 2007
#
# (Based on wifidog startup script
# Date    : 2004-08-25
# Version : 1.0
# Comment by that author: Could be better, but it's working as expected)
#

START=95
STOP=95

USE_PROCD=1

IPT=/usr/sbin/iptables
WD_DIR=/usr/bin
# -s -d 5 runs in background, with level 5 (not so verbose) messages to syslog
# -f -d 7 runs in foreground, with level 7 (verbose) debug messages to terminal
OPTIONS="-s -f -d 7"
CONFIGFILE="/tmp/invalid_nodogsplash.conf"

# nolog(loglevel message ...)
nolog() {
  local level=$1
  shift
  logger -s -t nodogsplash -p daemon.$level $@
}

# append_config_option_map <cfgfile> <uci_cfg_obj> <option_name> <config_counterpart> [<optional default>]
# append "$config_counterpart $value" to cfgfile if option_name exists
# e.g. append_config_option "$CONFIGFILE" "$cfg" bind_address BindAddress 0.0.0.0
# will append "BindAddress 192.168.1.1" if uci bind_address is '192.168.1.1'
append_config_option_map() {
  local val=""
  local config_file="$1"
  local cfg="$2"
  local option_name="$3"
  local config_counterpart="$4"
  local default="$5"
  config_get val "$cfg" "$option_name" "$default"
  [ -n "$val" ] && echo "$config_counterpart $val" >> $config_file
}

# append_config_option <cfgfile> <uci_cfg_obj> <option_name> [<optional default>]
# append "$option_name $value" to cfgfile if option_name exists
# e.g. append_config_option "$CONFIGFILE" "$cfg" bind_address 0.0.0.0
# will append "bind_address 192.168.1.1" if uci bind_address is '192.168.1.1'
# if uci bind_address is unset append "bind_address 0.0.0.0"
append_config_option() {
  local val=""
  local config_file="$1"
  local cfg="$2"
  local option_name="$3"
  local default="$4"
  config_get val "$cfg" "$option_name" "$default"
  [ -n "$val" ] && echo "$option_name $val" >> $config_file
}

setup_user_authentication() {
  local cfg="$1"
  local val

  config_get_bool val "$cfg" authenticate_immediately 0
  [ $val -gt 0 ] && echo "AuthenticateImmediately yes" >> $CONFIGFILE

  config_get val "$cfg" username
  if [ -n "$val" ] ; then
    echo "UsernameAuthentication" >> $CONFIGFILE
    echo "Username $val" >> $CONFIGFILE
  fi

  config_get val "$cfg" password
  if [ -n "$val" ] ; then
    echo "PasswordAuthentication" >> $CONFIGFILE
    echo "Password $val" >> $CONFIGFILE
  fi
}

setup_mac_lists() {
  local cfg="$1"
  local MAC=""
  local val

  append_mac() {
    append MAC "$1" ","
  }

  config_get val "$cfg" macmechanism
  if [ -z "$val" ] ; then
    # check if we have AllowedMACList or BlockedMACList defined they will be ignored
    config_get val "$cfg" allowedmac
    if [ -n "$val" ] ; then
      echo "Ignoring allowedmac - macmechanism not \"allow\"" >&2
    fi

    config_get val "$cfg" blockedmac
    if [ -n "$val" ] ; then
      echo "Ignoring blockedmac - macmechanism not \"block\"" >&2
    fi
  elif [ "$val" == "allow" ] ; then
    MAC=""
    config_list_foreach "$cfg" allowedmac append_mac
    echo "AllowedMACList $MAC" >> $CONFIGFILE
  elif [ "$val" == "block" ] ; then
    MAC=""
    config_list_foreach "$cfg" blockedmac append_mac
    echo "BlockedMACList $MAC" >> $CONFIGFILE
  else
    nolog error "$cfg Invalid macmechanism '$val' - allow or block are valid."
    return 1
  fi
  MAC=""
  config_list_foreach "$cfg" trustedmac append_mac
  [ -n "$MAC" ] && echo "TrustedMACList $MAC" >> $CONFIGFILE
}

setup_firewall() {
  local cfg="$1"
  local uciname
  local val

  append_firewall() {
    echo "    FirewallRule $1" >> $CONFIGFILE
  }

  for rule in $(echo authenticated-users preauthenticated-users users-to-router trusted-users trusted-users-to-router)
  do
    uci_name=${rule//-/_}
    # uci does not allow - dashes
    echo "FirewallRuleSet $rule {" >> $CONFIGFILE
    config_list_foreach "$cfg" ${uci_name} append_firewall
    echo "}" >> $CONFIGFILE
    config_get val "$cfg" policy_${uci_name}
    [ -n "$val" ] && echo "EmptyRuleSetPolicy $rule $val" >> $CONFIGFILE
  done
}

generate_uci_config() {
  local cfg="$1"
  local val
  local ifname
  local download
  local upload

  CONFIGFILE="/tmp/etc/nodogsplash_$cfg.conf"

  echo "# auto-generated config file from /etc/config/nodogsplash" > $CONFIGFILE

  config_get val "$cfg" config
  if [ -n "$val" ] ; then
    if [ -f "$val" ] ; then
      nolog error "Configuration file '$val' doesn't exist"
      return 0
    fi
    cat $val > CONFIGFILE
  fi

  config_get val "$cfg" network
  if [ -n "$val" ] ; then
    if ! network_get_device ifname "$val" ; then
      nolog error "$cfg can not find ifname for network '$val'"
      return 1
    fi
  fi

  config_get val "$cfg" gatewayinterface
  if [ -n "$val" ] ; then
    if [ -n "$ifname" ] ; then
      nolog error "$cfg cannot use both option network and gatewayinterface"
      return 1
    fi
    ifname="$val"
  fi

  if [ -z "$ifname" ] ; then
      nolog error "$cfg option network or gatewayinterface missing"
      return 1
  fi

  echo "GatewayInterface $ifname" >> $CONFIGFILE

  append_config_option "$CONFIGFILE" "$cfg" gatewayname
  append_config_option "$CONFIGFILE" "$cfg" gatewayaddress
  append_config_option "$CONFIGFILE" "$cfg" gatewayport
  append_config_option "$CONFIGFILE" "$cfg" maxclients
  append_config_option "$CONFIGFILE" "$cfg" webroot
  append_config_option "$CONFIGFILE" "$cfg" debuglevel
  append_config_option "$CONFIGFILE" "$cfg" splashpage
  append_config_option "$CONFIGFILE" "$cfg" pagesdir
  append_config_option "$CONFIGFILE" "$cfg" checkinterval
  append_config_option "$CONFIGFILE" "$cfg" syslogfacility
  append_config_option "$CONFIGFILE" "$cfg" gatewayiprange
  append_config_option "$CONFIGFILE" "$cfg" imagedir
  append_config_option "$CONFIGFILE" "$cfg" redirecturl
  append_config_option "$CONFIGFILE" "$cfg" clientidletimeout
  append_config_option "$CONFIGFILE" "$cfg" clientforcetimeout
  append_config_option "$CONFIGFILE" "$cfg" gatewayiprange
  append_config_option "$CONFIGFILE" "$cfg" passwordattempts
  append_config_option "$CONFIGFILE" "$cfg" macmechanism
  append_config_option "$CONFIGFILE" "$cfg" uploadlimit
  append_config_option "$CONFIGFILE" "$cfg" downloadlimit
  append_config_option "$CONFIGFILE" "$cfg" remoteauthenticatoraction
  append_config_option "$CONFIGFILE" "$cfg" enablepreauth
  append_config_option "$CONFIGFILE" "$cfg" binvoucher
  append_config_option "$CONFIGFILE" "$cfg" forcevoucher
  append_config_option "$CONFIGFILE" "$cfg" passwordauthentication
  append_config_option "$CONFIGFILE" "$cfg" usernameauthentication
  append_config_option "$CONFIGFILE" "$cfg" passwordattempts
  append_config_option "$CONFIGFILE" "$cfg" username
  append_config_option "$CONFIGFILE" "$cfg" password
  append_config_option "$CONFIGFILE" "$cfg" authenticateimmediately
  append_config_option "$CONFIGFILE" "$cfg" decongesthttpdthreads
  append_config_option "$CONFIGFILE" "$cfg" httpdthreadthreshold
  append_config_option "$CONFIGFILE" "$cfg" httpdthreaddelayms
  append_config_option "$CONFIGFILE" "$cfg" fw_mark_authenticated
  append_config_option "$CONFIGFILE" "$cfg" fw_mark_trusted
  append_config_option "$CONFIGFILE" "$cfg" fw_mark_blocked

  config_get download "$cfg" downloadlimit
  config_get upload "$cfg" uploadlimit
  [ -n "$upload" -o -n "$download" ] && echo "TrafficControl yes" >> $CONFIGFILE

  setup_mac_lists "$cfg"
  setup_user_authentication "$cfg"
  setup_firewall "$cfg"
}

# setup configuration and start instance
create_instance() {
  local cfg="$1"
  local manual_config
  local val

  config_get_bool val "$cfg" enabled 0
  [ $val -gt 0 ] || return 0

  generate_uci_config "$cfg"

  if ! test_module ;  then
    logger -s -t nodogsplash -p daemon.error "nodogsplash is missing some kernel modules"
  fi

  procd_open_instance $cfg
  procd_set_param command /usr/bin/nodogsplash -c $CONFIGFILE $OPTIONS
  procd_set_param respawn
  procd_set_param file $CONFIGFILE
  procd_close_instance
}

start_service() {
  include /lib/functions

  mkdir -p /tmp/etc/
  config_load nodogsplash

  config_foreach create_instance instance
}

stop_service() {
  # nodogsplash doesn't exit fast enought, when procd terminates it.
  # otherwise procd will restart nodogsplash twice. first time starting nodogsplash fails, second time it succeeds
  sleep 1
}

status() {
  $WD_DIR/ndsctl status
}

# Test if we got all modules loaded
test_module() {
  ### Test ipt_mark with iptables
  test_ipt_mark () {
    ($IPT -A FORWARD -m mark --mark 2 -j ACCEPT 2>&1) > /dev/null
    IPTABLES_OK=$?
    if [ "$IPTABLES_OK" -eq 0 ]; then
      ($IPT -D FORWARD -m mark --mark 2 -j ACCEPT 2>&1) > /dev/null
      return 0
    else
      return 1
    fi
  }

  ### Test ipt_mac with iptables
  test_ipt_mac () {
    ($IPT -A INPUT -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT 2>&1) > /dev/null
    IPTABLES_OK=$?
    if [ "$IPTABLES_OK" -eq 0 ]; then
      ($IPT -D INPUT -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT 2>&1) > /dev/null
      return 0
    else
      return 1
    fi
  }

  ### Test ipt_IMQ with iptables
  test_ipt_IMQ () {
    ($IPT -t mangle -A PREROUTING -j IMQ --todev 0 2>&1) > /dev/null
    IPTABLES_OK=$?
    if [ "$IPTABLES_OK" -eq 0 ]; then
      ($IPT -t mangle -D PREROUTING -j IMQ --todev 0 2>&1) > /dev/null
      return 0
    else
      return 1
    fi
  }

  ### Test imq with ip
  test_imq () {
    (ip link set imq0 up 2>&1) > /dev/null
    IMQ0_OK=$?
    (ip link set imq1 up 2>&1) > /dev/null
    IMQ1_OK=$?
    if [ "$IMQ0_OK" -eq 0 -a "$IMQ1_OK" -eq 0 ]; then
      (ip link set imq0 down 2>&1) > /dev/null
      (ip link set imq1 down 2>&1) > /dev/null
      return 0
    else
      return 1
    fi
  }

  ### Test sch_htb with tc; requires imq0
  test_sch_htb () {
    (tc qdisc del dev imq0 root 2>&1) > /dev/null
    (tc qdisc add dev imq0 root htb 2>&1) > /dev/null
    TC_OK=$?
    if [ "$TC_OK" -eq 0 ]; then
      (tc qdisc del dev imq0 root 2>&1) > /dev/null
      return 0
    else
      return 1
    fi
  }

  ### Find a module on disk
  module_exists () {
    EXIST=$(find /lib/modules/`uname -r` -name $1.*o 2> /dev/null)
    if [ -n "$EXIST" ]; then
      return 0
    else
      return 1
    fi
  }

  ### Test if a module is in memory
  module_in_memory () {
    MODULE=$(lsmod | grep $1 | awk '{print $1}')
    if [ "$MODULE" = "$1" ]; then
      return 0
    else
      return 1
    fi
  }

  ### Test functionality of a module; load if necessary
  do_module_tests () {
    echo "  Testing module $1 $2"
    "test_$1"
    if [ $? -ne 0 ]; then
      echo "   Module $1 $2 needed"
      echo "   Scanning disk for $1 module"
      module_exists $1
      if [ $? -ne 0 ]; then
        echo "   $1 module missing: please install it"
        exit 1
      else
        echo "   $1 exists, trying to load"
        insmod $1 $2 > /dev/null
        if [ $? -ne 0 ]; then
          echo "   Error: insmod $1 $2 failed"
          exit 1
        else
          echo "   $1 $2 loaded successfully"
        fi
      fi
    else
      echo "   $1 is working"
    fi
  }

  echo " Testing required modules"

  do_module_tests "ipt_mac"
  do_module_tests "ipt_mark"

  # test for imq modules, only if TrafficControl is enabled in conf
  if ( grep -q -E '^[[:space:]]*TrafficControl[[:space:]]+(yes|true|1)' "$CONFIGFILE" ) ; then
    do_module_tests "imq" "numdevs=2"
    do_module_tests "ipt_IMQ"
    do_module_tests "sch_htb"
  fi
}

And it is /etc/config/nodogsplash file:

config instance
  # Set to 1 to enable nodogsplash
  option enabled 1

  # Use plain configuration file as well
  option config '/etc/nodogsplash/nodogsplash.conf'
  option network 'wlan'
  option gatewayname 'OpenWrt Nodogsplash'
  option maxclients '250'
  option idletimeout '1200'

  # Your router may have several interfaces, and you
  # probably want to keep them private from the network/gatewayinterface.
  # If so, you should block the entire subnets on those interfaces, e.g.:
  list authenticated_users 'block to 192.168.0.0/16'
  list authenticated_users 'block to 10.0.0.0/8'

  # Typical ports you will probably want to open up.
  list authenticated_users 'allow tcp port 22'
  list authenticated_users 'allow tcp port 53'
  list authenticated_users 'allow udp port 53'
  list authenticated_users 'allow tcp port 80'
  list authenticated_users 'allow tcp port 443'

  # For preauthenticated users to resolve IP addresses in their
  # initial request not using the router itself as a DNS server,
  list preauthenticated_users 'allow tcp port 53'
  list preauthenticated_users 'allow udp port 53'

  # Allow ports for SSH/Telnet/DNS/DHCP/HTTP/HTTPS
  list users_to_router 'allow tcp port 22'
  list users_to_router 'allow tcp port 23'
  list users_to_router 'allow tcp port 53'
  list users_to_router 'allow udp port 53'
  list users_to_router 'allow udp port 67'
  list users_to_router 'allow tcp port 80'
  list users_to_router 'allow tcp port 443'

  # See https://github.com/nodogsplash for a full list of available options.

Of course I have nodogsplash.conf file in /etc/nodogsplash. Does anyone know what is wrong with these files?

(Last edited by Charlie0 on 28 Jul 2015, 14:05)

This part of the code is strange... In the second condition, it returns a error if the file exists. I tried with an "else":

  if [ -n "$val" ] ; then                                            
    echo "$val"                                                               
    if [ -f $val ] ; then                                                       
        echo "Loading configuration file " $val                
    else                                                                        
      nolog error "Configuration file '$val' doesn't exist"                 
      return 0                                              
    fi                                                           
    cat $val > CONFIGFILE      
  fi            

                                                               
What do you think?

(Last edited by marcosbontempo on 28 Jul 2015, 14:21)

It is better. It recognises config file but i found another problem - values set in this file are not loaded to nodogsplash configuration. For example, in nodogsplash.conf I set GatewayName,  Traffic Control (to yes), blocked MAC addresses but all of these value remained default - checked with "ndsctl status". Something else must be wrong in init.d/nodogsplash, now i am trying to figure it out.

I think the configurations are loaded with this line:

 cat $val > CONFIGFILE 

Try fixing it:

 cat $val >> $CONFIGFILE 

Your configuration file will be at:

 CONFIGFILE="/tmp/etc/nodogsplash_$cfg.conf" 

Check if the configurations from /etc/config/nodogsplash and /etc/nodogsplash/nodogsplash.conf were copied.

(Last edited by marcosbontempo on 29 Jul 2015, 12:39)

I had the exact same issue with my TL-WR841ND v8 router, after installing nodogsplash there was no configuration file. I created one but it doesn't work.. I get no splash screen when surfing on the web sad

Any ideas?

Configuration is done through UCI in /etc/config/nodogsplash.

Where is the documentation update on this product for UCI.
LUCI webpage would be great since it is now running uci
and the GatewayName doesn't like spaces

(Last edited by graanco on 2 Nov 2015, 16:58)

You're editing the wrong file. Configuration is done in /etc/config/nodogsplash with UCI syntax, an example is provided which is very straight forward.

You can safely ignore and even comment out this part:

# Use plain configuration file as well
  option config '/etc/nodogsplash/nodogsplash.conf'

You don't need a nodogsplash.conf, a configuration file is generated from UCI by the init script.

EDIT: If you want documentation, make it smile

(Last edited by arokh on 2 Nov 2015, 17:02)

The discussion might have continued from here.