On Tue, Aug 16, 2011 at 06:53:01AM -0500, Todd T. Fries wrote:
> 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.
ouch. and I think you mean imminent. :-)
.... Ken
>
> 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