1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Help: Entware Mounting, init, wanup & firewall scripts

Discussion in 'Tomato Firmware' started by Sean Rhodes, Aug 24, 2014.

  1. Sean Rhodes

    Sean Rhodes Serious Server Member

    I have a Linksys E4200, with Shibby's latest firmware build tomato-E4200USB-NVRAM60K-1.28.RT-N5x-MIPSR2-121-AIO.bin. One thing I keep noticing in all the builds, is that parts of the entries in the scripts-->init gui simply disappear and also the same with the access restriction rules and on occasion, part of the scripts --> firewall and scripts --> wanup.

    In addition, sometimes my Entware would not always mount and I would also have an extra
    "LABEL=optware /opt ext2 rw,nodev,noatime 1 1" line in my /etc/fstab

    Performing a "nvram get" also shows they are not in the ram and also showed double lines in the /etc/fstab that had been loaded into the ram

    I followed Koitsu's advice and created a mount.autorun script:
    if /bin/grep -q /opt /proc/mounts
            /bin/umount /opt
            if [ $? -ne 0 ]; then
                    echo "umount failed, script not continuing"
                    exit 1
    /bin/mount -o bindable /tmp/mnt/usbflash /opt
    if [ -x /opt/sbin/fakeidentd ]
            kill `pidof fakeidentd` 2>/dev/null
            /opt/sbin/fakeidentd ident
    That, along with manually editing the /etc/fstab file and committing it to nvram, without entering anything in the gui, seem to fix the mounting issue.

    As for the scripts --> firewall and scripts --> wanup entries, it looked like they were not always being loaded.

    I made a couple of .wanup scripts, to be loaded from /opt/etc/configs, but don't really know the best way to load them or where to put them for them to load at the correct time in the boot sequence.

    I thought a good place would be in the mount.autorun that Koitsu provided easlier, but I messed that up playing around.

    Thanks to Koitsu, I have the following:

    if [ -f /var/notice/wan ]; then
      . /opt/etc/config/fire.wanup
      . /opt/etc/config/misc.wanup
      . /opt/etc/config/vpn.wanup
    But I don't really see a good place to load it from. Obviously the Entware has to be loaded first and stable, then the Wan has to be up and running.

    Can anyone give me pointers on the best place to put the scripts?

    As an fyi, here are the scripts themselves:
    iptables -I FORWARD -i `nvram get lan_ifname` -j wanout
    #Create whitelist 'function' script
    WOUT='iptables -I wanout  -j ACCEPT'
    MAC='-m mac --mac-source'
    # Exempt Machine MAC
    $WOUT $MAC xx:xx:xx:xx:xx:xx
    $WOUT $MAC xx:xx:xx:xx:xx:xx
    $WOUT $MAC xx:xx:xx:xx:xx:xx
    $WOUT $MAC xx:xx:xx:xx:xx:xx
    $WOUT $MAC xx:xx:xx:xx:xx:xx
    $WOUT $MAC xx:xx:xx:xx:xx:xx
    #Allow search access to all
    $WOUT -d www.google.com
    #Exempt Machine IP
    $WOUT -s
    $WOUT -s
    #Everything else gets blocked
    iptables -A wanout -j REJECT --reject-with icmp-proto-unreachable
    swapon /dev/sda2
    for i in /proc/sys/net/ipv4/conf/*/rp_filter ; do
      echo 0 > $i
    ip route flush table 100
    ip route del default table 100
    ip rule del fwmark 1 table 100
    ip route flush cache
    iptables -t mangle -F PREROUTING
    iface_lst=`route | awk ' {print $8}'`
    for tun_if in $iface_lst; do
        if [ $tun_if == "tun11" ] || [ $tun_if == "tun12" ] || [ $tun_if == "ppp0" ]; then
    ip route show table main | grep -Ev ^default | grep -Ev $tun_if \ | while read ROUTE ; do
       ip route add table 100 $ROUTE
    ip route add default table 100 via $(nvram get wan_gateway)
    ip rule add fwmark 1 table 100
    ip route flush cache
    iptables -t mangle -A PREROUTING -i br0 -j MARK --set-mark 1
    iptables -t mangle -A PREROUTING -i br0 -p tcp -m multiport --dport 80,443,8080,8088,2222 -j MARK --set-mark 1
    Thanks guys.
  2. jerrm

    jerrm Network Guru Member

    Hard to help in some respects, we have NEVER had any issues with losing any part of the GUI script entries, never use fstab, never use .autorun scripts.

    Not anything wrong necessarily, just a different approach.


    First, anything involving iptables rules should be in the gui fire script or a .fire event script. Many events will reset iptables that do not involve wanup at all.

    Second, I place responsibility for handling multiple calls to the script on the script itself. Your scripts look like they address the issue at some level, but I have given only the briefest of looks, with no real evaluation.

    Third, I shy away from any auto-run scripts in general, unless they are explicitly created somewhere visible. For me "visible" means in the GUI init script.

    Below assumes we are renaming the .wanup to .sh and placing in /opt/bin. The init script creates the event autorun links to the scripts, but I have made them into .fire links. This may or may not be appropriate for your environment.

    We only place code in the GUI init script, which becomes:
    mkdir $cfg
    # Create USB automount Script
    cat << EOF > $usb
    # wait for all partitions/drives we care about to auto-mount
    # then do whatever we need with them.
    # note there is no loop here - the script is called once at each mount
    if [ -d /mnt/partition1 -a -d /mnt/Data -a -d /mnt/Entware -a -d /mnt/partition2 ]; then
      # do whatever we need to after the drives are mounted
      logger automount start
      swapon \$(fdisk -l | grep swap | cut -d" " -f1)
      mount -obind /mnt/Entware /opt
      mkdir /mnt/data
      mount -obind /mnt/Data /mnt/data
      logger automount end
    chmod +x $usb
    # wait for system to come up
    while [ $A -gt 0 ] ; do
      echo `date` $A >> $log
      A=$(( $A - 1 ))
      if [ -f /var/notice/sysup -a -f /var/notice/wan -a -d /opt/bin ] ; then sleep 5 ; break; fi
      sleep 10
    # Now do something
    /opt/sbin/fakeidentd ident
    for s in fire.sh vpn.sh
    ln -s "/opt/bin/$s" "/etc/config/$s.fire"
    /opt/adblock/adblock.sh &
    Disclaimer: Above is a cut and paste assemblage, not tested. Edit to make sure all paths/files make since for your environment.
    Last edited: Aug 26, 2014
  3. Sean Rhodes

    Sean Rhodes Serious Server Member

    Thanks Jerrm. That's given me a lot to think about.
    What does this line do
    if [ -d /mnt/partition1 -a -d /mnt/Data -a -d /mnt/Entware -a -d /mnt/partition2]; then
    since I keep getting the following error
    [: missing ]

    I have 2 usb's mounted as follows:
    sda is 3 partitions:
    /dev/sda1 entware to /mnt/opt
    /dev/sda2 as swap
    /dev/sda3 data to /mnt/data

    and a spare usb /dev/sdb1 BKUP as /tmp/mnt/BKUP.

    I tried playing around with the above line but still get [: missing ] coming up and opt isn't mounting?

    btw I still have
    #device Mountpoint FStype Options Dump Pass#
    LABEL=swap none swap sw 0 0
    LABEL=entware /opt ext2 rw,nodev,noatime 1 1
    in etc/fstab and committed to nvram, if that makes a difference?
  4. ryzhov_al

    ryzhov_al Networkin' Nut Member

    Please add a space betweeen "partition2" and "]":
    if [ -d /mnt/partition1 -a -d /mnt/Data -a -d /mnt/Entware -a -d /mnt/partition2 ]; then
  5. Sean Rhodes

    Sean Rhodes Serious Server Member

    Thanks ryzhov_al,

    I figured out the space and that its saying if directory 1 and directory 2 and directory 3 etc..... are loaded then do the following.

    I think I have a mount issue that's causing the problem now:
    root@Tomato:/tmp/home/root# df -k
    Filesystem           1K-blocks      Used Available Use% Mounted on
    /dev/root                11008     11008         0 100% /
    tmpfs                    30620       460     30160   2% /tmp
    devfs                    30620         0     30620   0% /dev
    /dev/sda1               357797        13    339311   0% /opt
    /dev/sdb1              1996144     24556   1971588   1% /tmp/mnt/BKUP
    /dev/sda3               457904      3120    431140   1% /tmp/mnt/data
    root@Tomato:/tmp/home/root# mount -o bind /mnt/entware /opt
    mount: mounting /mnt/entware on /opt failed: No such file or directory
    it just doesn't see my entware anymore, although
    e2fsck -y -v -f /dev/sda1
    shows no errors.

    My thoughts are to reformat another USB and a clean flash and start again, since sometimes it says it can't find the entry in /etc/fstab,

    but its there, as shown above.

    Thanks for your help.
  6. jerrm

    jerrm Network Guru Member

    And also edit for your environment. "Entware" "partition1" "partition2" are all sample names. The whole thing is an untested sample. Read the disclaimer.

    My assumption is that automount is mounting any needed partitions. The script is just waiting for all partitions to be mounted before doing anything with them. It would be an alternative to using fstab or .autorun scripts.

    This approach allows us to take our standard usb drive, drop it into a new router, cut and paste the init script, and tweak a few lines in one place to enable/disable whatever scripts we need to run on the target router. With usb based autorun or event scripts you have to start looking in multiple folders and erase/rename/move files, etc.

    You may prefer to use nvram files, or usb based .autorun and event scripts. Whatever works for you is fine.
  7. koitsu

    koitsu Network Guru Member

    I don't know how your disk partitioning is layed out (it matters), but it looks to me like you have your sda device partitioned into at least 3 partitions (sda1 = presumably Entware? Not sure -- you tell me!), sda2 = ??? (maybe swap?), and sda3 = "data".

    If you look closely at my original line, you'll see it's this (and pay very close attention to the source -- it's /tmp/mnt/xxx not /mnt/xxx!):

    /bin/mount -o bindable /tmp/mnt/usbflash /opt
    What this does is essential create a "mount symlink" of /opt to the same place that /tmp/mnt/usbflash points to. The end result should look something like this on your router:

    root@gw:/tmp/home/root# df -k
    Filesystem           1K-blocks      Used Available Use% Mounted on
    /dev/root                 6528      6528         0 100% /
    tmpfs                   127976       260    127716   0% /tmp
    devfs                   127976         0    127976   0% /dev
    /dev/sda1             15599232    183000  14623828   1% /tmp/mnt/usbflash
    /dev/sda1             15599232    183000  14623828   1% /opt
    TomatoUSB itself manages the /tmp/mnt/* entries. The "usbflash" name comes from what I chose as the "partition label" (right now I am rushed for work and cannot remember if that's if a GPT label or an actual filesystem (ext2/ext3) label).
  8. Sean Rhodes

    Sean Rhodes Serious Server Member

    Thanks for all your help.

    Clearly I have a lot to learn and should not make assumptions
  9. Sean Rhodes

    Sean Rhodes Serious Server Member


    I have everything working for now, it turned out that my actual partition was empty, i don't understand how that could have happened.

    Basically my usb1 has 3 partitions:
    sda1 ext2 label=entware
    sda2 swap label=swap
    sda3 ext2 label=data

    usb2 has 1 partition
    sdb1 fat label=BKUP

    The data file was fine, but the entware partition was completely empty when I mounted it to a linux distro.

    I re-installed and everything is now fine, but I do have a question that is confusing me:

    If I let the router detect the usb on power-up, I see entware mounted as /tmp/mnt/entware mounted to /opt

    If I go to /tmp/mnt/ and look at the mounts, I only see data and BKUP, I don't see the opt mount.

    Can you explain how the opt mount is different than the data or BKUP mount?
  10. koitsu

    koitsu Network Guru Member

    The first two sentences are contradictory in a way, and also don't make full sense. Let me explain what is going on here. Please read what I write slowly, as it's going to be a lot to take in.

    When TomatoUSB starts up the storage subsystem layer for USB, it proceeds to mount all the filesystems on partitions it can find. (This is commonly called "tasting", e.g. "tasting the disk", by the way). This shows up in the GUI as well, under USB and NAS / USB Support, at the very bottom. I've included a screenshot of what I'm talking about.

    TomatoUSB does all of this itself. Where it mounts those filesystems is under /tmp/mnt/{label}, ex. /tmp/mnt/entware, /tmp/mnt/data, /tmp/mnt/BKUP. Those are "officially" where your filesystems are mounted.

    Now for how /opt and the bindable mount fits in:

    You can only have a single device/filesystem mounted once, in one single place. That's just how UNIX works. Normally the solution for this problem is to create a symbolic link (symlink) from the secondary place you desire to the original place, e.g. symlinking /opt to /tmp/mnt/entware.

    However, this can't be done on TomatoUSB because / (the root filesystem) is read-only and TomatoUSB comes pre-populated with a directory called /opt (there's nothing in it, but the directory is there). Thus you cannot do rm -fr /opt ; ln -s /tmp/mnt/entware /opt -- this will fail because / is read-only.

    So how do we work around this dilemma and somehow get the entware filesystem mounted in two places (TomatoUSB's default of /tmp/mnt/{label} and the desired /opt)?

    You use what's called a "bindable mount" or a "bind mount". This is a feature of Linux, similar to a loopback filesystem, which essentially allows multiple mounts to point to the same physical place (e.g. both /tmp/mnt/entware and /opt point to /dev/sda1). I'll save you the technical details of how this works.

    So by doing the following:

    /bin/mount -o bindable /tmp/mnt/entware /opt

    We effectively allow the /dev/sda1 filesystem to be mounted in two places, both /tmp/mnt/entware and /opt, without any ill-effects. Within the kernel they're actually both the exact same thing, there's never any "mismatch" of data, etc.. They both "point" to /dev/sda1 (this is badly phrased but you get my drift).

    TomatoUSB does not create bindable mounts on its own. That is what the mount.autorun script I mentioned is for, specifically these lines:

    if /bin/grep -q /opt /proc/mounts
            /bin/umount /opt
            if [ $? -ne 0 ]; then
                    echo "umount failed, script not continuing"
                    exit 1
    /bin/mount -o bindable /tmp/mnt/entware /opt
    The first "block" of script there works around a bug/quirk (I consider it a bug) in the Linux kernel where you can have indefinite numbers of bindable mounts with the same destination -- meaning without it, you could do df -k and see /opt mounted a hundred times. This would happen if you didn't have this code/script and clicked "Save" in the GUI under USB Support repeatedly (trust me, I speak the truth -- this is how I found the problem to begin with!). This DOES confuse part of the kernel, so basically you want to make sure you only have one /opt.

    The way it works is by looking at /proc/mounts (a special file per procfs that keeps track of all the mounted filesystems) and looks to see if /opt is already mounted. If it is, it unmounts it. (The syntax here is a little tricky and unintuitive, because Busybox grep -q returns 0 if a match was found, otherwise returns 1).

    The $? check ensure that the exit code of the previous /bin/umount command was successful (and if not bails out -- it's better to bail here than to blindly create another /opt mount).

    The next thing the script does is at the very bottom: the /bind/mount -o bindable /tmp/mnt/entware /opt creates the bindable mount, essentially pointing /opt to wherever /tmp/mnt/entware points to (i.e. /dev/sda1).

    Does this make sense now?

    Attached Files:

Share This Page