I have done this in a different way, namely by 'filtering' the variables
that are passed to /sbin/dhclient-script by using the
'script "/path/to/my/script"' option to run my own script, act on variables
I care about (dns and default gateway) and then calling /sbin/dhclient-script
in the event it still has something to do.
Honestly I think your approach is cleaner, and more likely to survive the
ever eminent promise from krw@ to remove the script entirely.
Thanks,
Penned by Stefan Sperling on 20110816 5:08.37, we have:
| In some networks (e.g. at public events using open wifi) I want
| traffic not destined for the local network to go through a VPN.
|
| If the local network uses DHCP, I usually end up killing dhclient
| because it's impossible to renew the lease without changing the
| default route.
|
| To be clear, I end up with a command sequence like:
|
| dhclient wpi0 # get a local address
| netstat -rn -finet | grep ^default # figure out local router
| route delete default # don't use local router for everything
| route add -host $VPN_SERVER_IP $LOCAL_ROUTER # just for this host
| openvpn config-file # start VPN, i am too dumb for ipsec
| route add default $ROUTER_BEHIND_VPN # use my trusted router as default
| pkill -x dhclient # kill dhclient to avoid default route change later
|
| The problem is that the lease expires at some point and things
| usually stop working until I perform the same tedious configuration
| dance again.
|
| The patch below adds a new option to dhclient.conf (the VPN server is
| at 10.1.1.1 in this example):
|
| interface "wpi0" {
| host-route 10.1.1.1;
| }
|
| Instead of adding a default route dhclient will add a host route
| to the specified address. So the above sequence becomes:
|
| dhclient wpi0 # get a local address, add route to VPN server
| openvpn config-file # start VPN
| route add default $ROUTER_BEHIND_VPN # use my trusted router as default
|
| And the configuration remains stable.
|
| Is this a good approach?
| Does anyone else think this is useful?
|
|
| Index: clparse.c
| ===================================================================
| RCS file: /cvs/src/sbin/dhclient/clparse.c,v
| retrieving revision 1.37
| diff -u -p -r1.37 clparse.c
| --- clparse.c 4 Apr 2011 11:14:52 -0000 1.37
| +++ clparse.c 12 Aug 2011 18:04:02 -0000
| @@ -151,7 +151,8 @@ read_client_leases(void)
| * interface-declaration |
| * TOK_LEASE client-lease-statement |
| * TOK_ALIAS client-lease-statement |
| - * TOK_REJECT reject-statement
| + * TOK_REJECT reject-statement |
| + * TOK_HOST_ROUTE host-route-statement
| */
| void
| parse_client_statement(FILE *cfile)
| @@ -234,6 +235,9 @@ parse_client_statement(FILE *cfile)
| case TOK_REJECT:
| parse_reject_statement(cfile);
| return;
| + case TOK_HOST_ROUTE:
| + parse_host_route_statement(cfile);
| + return;
| default:
| parse_warn("expecting a statement.");
| skip_to_semi(cfile);
| @@ -739,6 +743,25 @@ parse_reject_statement(FILE *cfile)
| token = next_token(&val, cfile);
| } while (token == ',');
|
| + if (token != ';') {
| + parse_warn("expecting semicolon.");
| + skip_to_semi(cfile);
| + }
| +}
| +
| +void
| +parse_host_route_statement(FILE *cfile)
| +{
| + char *val;
| + int token;
| +
| + if (!parse_ip_addr(cfile, &config->host_route)) {
| + parse_warn("expecting IP address.");
| + skip_to_semi(cfile);
| + return;
| + }
| +
| + token = next_token(&val, cfile);
| if (token != ';') {
| parse_warn("expecting semicolon.");
| skip_to_semi(cfile);
| Index: conflex.c
| ===================================================================
| RCS file: /cvs/src/sbin/dhclient/conflex.c,v
| retrieving revision 1.13
| diff -u -p -r1.13 conflex.c
| --- conflex.c 17 Dec 2006 17:41:56 -0000 1.13
| +++ conflex.c 12 Aug 2011 18:00:51 -0000
| @@ -324,6 +324,7 @@ static const struct keywords {
| { "filename", TOK_FILENAME },
| { "fixed-address", TOK_FIXED_ADDR },
| { "hardware", TOK_HARDWARE },
| + { "host-route", TOK_HOST_ROUTE },
| { "initial-interval", TOK_INITIAL_INTERVAL },
| { "interface", TOK_INTERFACE },
| { "lease", TOK_LEASE },
| Index: dhclient-script
| ===================================================================
| RCS file: /cvs/src/sbin/dhclient/dhclient-script,v
| retrieving revision 1.22
| diff -u -p -r1.22 dhclient-script
| --- dhclient-script 9 Apr 2011 19:53:00 -0000 1.22
| +++ dhclient-script 12 Aug 2011 18:06:00 -0000
| @@ -60,11 +60,16 @@ delete_old_routes() {
| add_new_routes() {
| route -q $rdomain -n flush -inet -iface $interface
| for router in $new_routers; do
| - if [ "$new_ip_address" = "$router" ]; then
| - route -q $rdomain add default -iface $router
| + if [ -n "$host_route" -a "$host_route" != "0.0.0.0" ]; then
| + new_route="-host $host_route $router"
| else
| - route -q $rdomain add default $router
| + if [ "$new_ip_address" = "$router" ]; then
| + new_route="default -iface $router"
| + else
| + new_route="default $router"
| + fi
| fi
| + route -q $rdomain add $new_route
| # 2nd and subsequent default routers error out, so explicitly
| # stop processing the list after the first one.
| break
| Index: dhclient.c
| ===================================================================
| RCS file: /cvs/src/sbin/dhclient/dhclient.c,v
| retrieving revision 1.141
| diff -u -p -r1.141 dhclient.c
| --- dhclient.c 11 May 2011 14:38:36 -0000 1.141
| +++ dhclient.c 12 Aug 2011 18:06:57 -0000
| @@ -1604,6 +1604,9 @@ supersede:
| }
| snprintf(tbuf, sizeof(tbuf), "%d", (int)lease->expiry);
| script_set_env(prefix, "expiry", tbuf);
| +
| + if (config->host_route.len)
| + script_set_env("", "host_route", piaddr(config->host_route));
| }
|
| void
| Index: dhclient.conf.5
| ===================================================================
| RCS file: /cvs/src/sbin/dhclient/dhclient.conf.5,v
| retrieving revision 1.21
| diff -u -p -r1.21 dhclient.conf.5
| --- dhclient.conf.5 9 Apr 2011 19:53:00 -0000 1.21
| +++ dhclient.conf.5 13 Aug 2011 19:18:56 -0000
| @@ -430,6 +430,13 @@ If no lease is acquired, the script is u
| any, and also called once if no valid lease can be identified.
| For more information, see
| .Xr dhclient.leases 5 .
| +.It Ic host-route Ar ip-address ;
| +The
| +.Ic host-route
| +statement causes the DHCP client to install a host route to the specified
| +IP address instead of installing a default route.
| +This is useful if the default route points to a VPN tunnel terminated
| +at the specified IP address instead of a router on the local network.
| .El
| .Sh EXAMPLES
| The following configuration file is used on a laptop
| Index: dhcpd.h
| ===================================================================
| RCS file: /cvs/src/sbin/dhclient/dhcpd.h,v
| retrieving revision 1.73
| diff -u -p -r1.73 dhcpd.h
| --- dhcpd.h 11 May 2011 14:38:36 -0000 1.73
| +++ dhcpd.h 12 Aug 2011 18:03:23 -0000
| @@ -150,6 +150,7 @@ struct client_config {
| enum { IGNORE, ACCEPT, PREFER }
| bootp_policy;
| struct iaddrlist *reject_list;
| + struct iaddr host_route;
| };
|
| struct client_state {
| @@ -344,3 +345,4 @@ void parse_client_lease_declaration(FILE
| int parse_option_decl(FILE *, struct option_data *);
| void parse_string_list(FILE *, struct string_list **, int);
| void parse_reject_statement(FILE *);
| +void parse_host_route_statement(FILE *);
| Index: dhctoken.h
| ===================================================================
| RCS file: /cvs/src/sbin/dhclient/dhctoken.h,v
| retrieving revision 1.5
| diff -u -p -r1.5 dhctoken.h
| --- dhctoken.h 15 May 2006 08:10:57 -0000 1.5
| +++ dhctoken.h 12 Aug 2011 18:03:38 -0000
| @@ -79,6 +79,7 @@
| #define TOK_REJECT 292
| #define TOK_FDDI 293
| #define TOK_LINK_TIMEOUT 294
| +#define TOK_HOST_ROUTE 295
|
| #define is_identifier(x) ((x) >= TOK_FIRST_TOKEN && \
| (x) != TOK_STRING && \
--
Todd Fries .. [email protected]
_____________________________________________
| \ 1.636.410.0632 (voice)
| Free Daemon Consulting, LLC \ 1.405.227.9094 (voice)
| http://FreeDaemonConsulting.com \ 1.866.792.3418 (FAX)
| 2525 NW Expy #525, Oklahoma City, OK 73112 \ sip:[email protected]
| "..in support of free software solutions." \ sip:[email protected]
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
37E7 D3EB 74D0 8D66 A68D B866 0326 204E 3F42 004A
http://todd.fries.net/pgp.txt