How to auto-execute a sh script on openwrt start

I think preinit will load it on a low runlevel, where it network / tcp/ip / iptables service is not available yet..?

new content:

#!/bin/sh /etc/rc.common
set -x && sleep 30 && rm ./public_ip.txt > /dev/null 2>&1
wget -qO- https://api.ipify.org > ./public_ip.txt
for IP in $(cat ./public_ip.txt); do iptables -t nat -A PREROUTING -d $IP -m tcp -p tcp --dport 80 $
iptables -t nat -A POSTROUTING -d 192.168.1.21 -s 192.168.1.0/24 -j SNAT --to-source 192.168.1.1
# rm -f ./public_ip.txt

i read here that i need the header "#!/bin/sh /etc/rc.common" for useing it as as service?
-> https://stackoverflow.com/questions/33340659/how-to-auto-start-an-application-in-openwrt

try to enable it as a service fails:

root@OpenWrt:/etc/init.d# /etc/init.d/iptables_custrules.sh enable
+ sleep 30
+ rm ./public_ip.txt
+ wget -qO- https://api.ipify.org
+ cat ./public_ip.txt
+ iptables -t nat -A PREROUTING -d x.x.x.x -m tcp -p tcp --dport 80 -j DNAT --to-destination 192.168.1.21
+ iptables -t nat -A POSTROUTING -d 192.168.1.21 -s 192.168.1.0/24 -j SNAT --to-source 192.168.1.1
+ '[' -n  ]
+ ALL_COMMANDS='start stop reload restart boot shutdown enable disable enabled depends '
+ list_contains ALL_COMMANDS enable
+ local 'var=ALL_COMMANDS'
+ local 'str=enable'
+ local val
+ eval 'val=" ${ALL_COMMANDS} "'
+ val=' start stop reload restart boot shutdown enable disable enabled depends  '
+ '[' ' start stop reload restart boot shutdown' '!=' ' start stop reload restart boot shutdown enable disable enabled depends  ' ]
+ enable
+ err=1
+ basename /etc/init.d/iptables_custrules.sh
+ name=iptables_custrules.sh
+ '['  ]
+ '['  ]
+ return 1
root@OpenWrt:/etc/init.d#
jeff@office:~$ cat /etc/rc.local 
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.

exit 0

As a side note, init scripts that "sleep" for any length of time are generally considered bad form

See also https://openwrt.org/docs/guide-developer/procd

do they block the execution of other scrips, our just itself?

i just need to wail until the internal iptables rules are processed...

now it works, with a start and stop function...

Depending on the "mother of all processes", they may block everything that follow. If you have to wait for something, it's good practice to either sequence until after that thing is "done", or to spawn a detached process to do the waiting.

"public_ip.txt" seems to exist after start, but it's empty... i think the networking subsystem is not avaialble at this time..?

...and the timestamp is ALWAYS Sep 11 01:02 - date is correct, but time is always the same... WTF?!?!?

When i execute manually in linux promt, time is correct and it contains my external ip..

Time sync has not happened yet, initial set is done to the latest file in /etc/ -- see /etc/init.d/sysfixtime

The whole thing it too crazy, nothing else...!!

Now i need some cigerettes and a coffe first!!!

1 Like

now i saw that alles entries in /etc/rc.d/ are numbered with Kx or Sx where x is a number...

Is that number the execution priority? What is the letter?

and it seems now i have 2 enties: K15iptables_custrules.sh S10iptables_custrules.sh

when i execute /etc/init.d/iptables_custrules.sh disable, both entries are gone...

Those are symlinks installed by enable/disable of services. One for system start, other for graceful shutdown. One typically leaves those to the process manager and sets dependencies in the service-definition files.

This is "normal" for "init"-based systems, before systemd became the rage.

i think i need to write a c or c++ application with an own thread and thread sleep for x secs, right?

Nope, you can do it with a shell script. procd will supervise it. You might want to trigger on network events rather than sleeping. See ubus documentation. I don't know a good reference for procd as the other site that once hosted a good description no longer does and it isn't on the Internet Archive.

1 Like

now i try it with ```

chkconfig: 5 9999 9999


https://serverfault.com/questions/176055/how-to-change-linux-services-startup-boot-order

Hold on -- OpenWrt isn't a desktop/server Linux-based distro. Most of what you read about "Linux" will not apply to OpenWrt startup and service management.

Think through what needs to be up and running for your script to work.

Think about what happens if, for example:

  • DNS for your download host fails
  • The download host doesn't respond
  • DNS is spoofed for the download host and you get a "list" from we-be-hackers.org

If you're doing this in startup scripts, the first two will cause OpenWrt (and most "sane" OSes) to fail to boot as the script fails and returns an error.

Edit:

Also look at mktemp as it's good practice to not be able to predict where temporary files are being written. You probably should put it under /tmp/ somewhere as well, since there's no reason to thrash flash for a temporary file.

I need a fast as possible to make my webserver public - that's currently the only one thing..

That seems to work:

#!/bin/sh /etc/rc.common
# chkconfig: 5 9999 9999

START=9999
STOP=9999

start() {
set -x
# sleep 30
rm /etc/init.d/public_ip.txt > /dev/null 2>&1
wget -qO- https://api.ipify.org > /etc/init.d/public_ip.txt
for IP in $(cat /etc/init.d/public_ip.txt); do iptables -t nat -A PREROUTING -d $IP -m tcp -p tcp --
dport 80 -j DNAT --to-destination 192.168.1.21; done
iptables -t nat -A POSTROUTING -d 192.168.1.21 -s 192.168.1.0/24 -j SNAT --to-source 192.168.1.1
# rm -f /etc/init.d/public_ip.txt
}

stop() {
rm /etc/init.d/public_ip.txt > /dev/null 2>&1
}

Thank you very much!!!

Best regards,
Jan

1 Like