FYI, you don't need a loop if the variable contains a CSV... i.e. you can simply add a single iptables rule using the
syntax.
Furthermore, for most situations, you really should not override the OpenVPN '
up/down' scripts provided by the firmware (see '
/usr/sbin/updown.sh') unless you fully understand the implications.
Instead, I suggest you use (as per the Wiki) a
RMerlin Wiki openvpn-event trigger script and
@john9527 kindly provided the
openvpn-event script template so you can
explicitly choose which
openvpn-event trigger script is executed by the
specific Server/Client.
e.g. create custom scripts
vpnclientX-route-up/vpnclientX-down without the need to add any directives in the VPN Client Custom GUI panel.
Thanks for the feedback. To be honest, I'm far less familiar w/ Merlin's implementation of OpenVPN than dd-wrt and tomato (although Merlin being a variant of tomato, I see many similarities). But the one big difference Merlin offers (for good or bad) is the addition of his own event driven model.
In principle, I get where you're coming from. It's considered the default, a standard if you will, for this environment. So I get it, and appreciate it.
After having examined more closely the inner workings of this firmware, it seems to me the openvpn-event script template from
@john9527 is almost a necessity, if only to eliminate the confusion of having to handle all your events, for all OpenVPN clients and servers, in one script. Not unless you intend to only support one of the OpenVPN clients or servers. So I wish the existence of that script was more well known. Seems it should be right up there w/ the Merlin documentation regarding use of the openvpn-event script.
I examined the OpenVPN config file for the client, and the only event directives I found were the following:
Code:
route-up vpnrouting.sh
route-pre-down vpnrouting.sh
I noticed these are *always* present, even if the user has configured the OpenVPN client to NOT using policy based routing (e.g., Redirect Internet traffic = All). And I see why. That's the script that calls the openvpn-event script in /jffs.
Code:
PARAM="$dev $tun_mtu $link_mtu $ifconfig_local $ifconfig_remote"
...
run_custom_script(){
if [ -f /jffs/scripts/openvpn-event ]
then
/usr/bin/logger -t "custom_script" "Running /jffs/scripts/openvpn-event (args: $PARAM)"
/bin/sh /jffs/scripts/openvpn-event $PARAM
fi
}
...
Wondering where the /usr/sbin/updown.sh fits into all this (to which I could find no reference in the OpenVPN client), I decided to configure the OpenVPN server, and voila, there it was in the server's config file.
Code:
up updown.sh
down updown.sh
So in fact, adding your own up/down directives via the Custom Config field of the OpenVPN *client* doesn't actually present an issue. It will work fine. (I know, I know, that's still not something we'd like to recommend, but I mention it just so everyone is clear about how it actually works).
Of course, the /usr/sbin/updown.sh script similarly calls the openvpn-event in /jffs, but for the OpenVPN server.
My concern with the Merlin approach is two-fold. First, it forces all user-defined OpenVPN event handling to necessarily be driven through the route-up and route-pre-down events. But what if I *want* to handle something via the up/down events of the OpenVPN client? Or numerous other events as well.
Code:
(from the OpenVPN documentation)
--up
Executed after TCP/UDP socket bind and TUN/TAP open.
--tls-verify
Executed when we have a still untrusted remote peer.
--ipchange
Executed after connection authentication, or remote IP address change.
--client-connect
Executed in --mode server mode immediately after client authentication.
--route-up
Executed after connection authentication, either immediately after, or some number of seconds after as defined by the --route-delay option.
--route-pre-down
Executed right before the routes are removed.
--client-disconnect
Executed in --mode server mode on client instance shutdown.
--down
Executed after TCP/UDP and TUN/TAP close.
--learn-address
Executed in --mode server mode whenever an IPv4 address/route or MAC address is added to OpenVPN's internal routing table.
--auth-user-pass-verify
Executed in --mode server mode on new client connections, when the client is still untrusted.
Granted, by far the most common events are route-up/route-pre-down, followed by up/down. But there are other events, and I don't see how these can be handled correctly via the Merlin openvpn-event, since the timing will be incorrect.
A secondary problem is that the Merlin openvpn-event only passes the command line arguments and environment variables from the route-up/route-pre-down events for the OpenVPN client, and up/down events of the OpenVPN server. But (and I'm not sure everyone is even aware of this) the environment variables provide *much* more information than the command line arguments to the OpenVPN event handler, and they are NOT necessarily the same variables from event to event! IOW, OpenVPN doesn't provide all possible variables to all possible events. It discriminates and limits those variables according to what the OpenVPN developers have deemed appropriate/relevant to the current event. So if every event I wish to handle has to be driven through the openvpn-event script, and that only executes in response to the route-up/route-pre-down or up/down scripts, that's a problem (or at least a limitation).
Now granted, I only skimmed these files/scripts to get a quick overview of how this all works. So I could easily be wrong about some things, or missed something. But assuming for the moment I'm right, it's clear to me that driving everything through those limited events is not going to work in all situations. An OpenVPN script developer who directly uses the OpenVPN event model is NOT going to have these problems. And needs to be aware of the limitations of having all OpenVPN events driven through a single Merlin openvpn-event script that only operates in response to a very limited number of OpenVPN events.
All that said, at least for this particular OP's needs, it doesn't really matter whether they use the Merlin or OpenVPN event driven model. Both will work just fine. But if you chose to use the former, you will need to change the event checking from up/down to route-up/route-pre-down.
Code:
...
route-up() {
...
}
route-pre-down() {
...
}
...
[ "$script_type" == "route-up" ] && route-up
[ "$script_type" == "route-pre-down" ] && route-pre-down
...
Sorry for the length of this post, but I'm just trying to understand the "Merlin way", so to speak. And it is different from other third-party firmware in this respect.
Btw, this thread is probably better suited to the VPN forum.