Re: rebound quantum entanglement

2016-10-03 Thread Theo de Raadt
+   return sysctl_int(oldp, oldlenp, newp, newlen, &dnsjacking);

+int dnsjacking = 0;

+   sin.sin_port = htons(dnsjacking);

How about using u_int16_t or in_port_t; and maybe error out if high
bits are set rather than ignoring them but still displaying them.



Re: rebound quantum entanglement

2016-10-03 Thread Ted Unangst
Ted Unangst wrote:
> Ted Unangst wrote:
> > So the plan is for rebound to be the 'system' resolver, with libc talking to
> > rbeound and rebound talking to the cloud. The main wrinkle is how does 
> > rebound
> > find the cloud? rebound.conf, but dhclient doesn't know anything about
> > rebound.conf, preferring to edit resolv.conf. But if rebound reads
> > resolv.conf, what does libc read? This has been a bit of a tangle until now,
> > especially in scenarios like upgrades where rebound may not even be running.
> 
> Move the hijacking into the kernel. rebound sets a sysctl, and then the kernel
> gives it all the dns connections. libc knows nothing. if rebound dies, dns
> dies. still listening on :53 because it has to listen somewhere.

configurable jack port, rebound uses 54.


Index: sys/kern/kern_sysctl.c
===
RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.311
diff -u -p -r1.311 kern_sysctl.c
--- sys/kern/kern_sysctl.c  21 Sep 2016 14:06:50 -  1.311
+++ sys/kern/kern_sysctl.c  21 Sep 2016 16:06:16 -
@@ -598,6 +598,10 @@ kern_sysctl(int *name, u_int namelen, vo
return sysctl_int(oldp, oldlenp, newp, newlen, &global_ptrace);
}
 #endif
+   case KERN_DNSJACKING: {
+   extern int dnsjacking;
+   return sysctl_int(oldp, oldlenp, newp, newlen, &dnsjacking);
+   }
default:
return (EOPNOTSUPP);
}
Index: sys/kern/uipc_syscalls.c
===
RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.133
diff -u -p -r1.133 uipc_syscalls.c
--- sys/kern/uipc_syscalls.c9 Aug 2016 02:25:35 -   1.133
+++ sys/kern/uipc_syscalls.c15 Sep 2016 22:32:55 -
@@ -67,6 +67,8 @@ externstruct fileops socketops;
 intcopyaddrout(struct proc *, struct mbuf *, struct sockaddr *, socklen_t,
socklen_t *);
 
+int dnsjacking = 0;
+
 int
 sys_socket(struct proc *p, void *v, register_t *retval)
 {
@@ -395,6 +397,16 @@ sys_connect(struct proc *p, void *v, reg
FRELE(fp, p);
m_freem(nam);
return (error);
+   }
+   if (dnsjacking) {
+   struct sockaddr_in sin;
+   memset(&sin, 0, sizeof(sin));
+   sin.sin_len = sizeof(sin);
+   sin.sin_family = AF_INET;
+   sin.sin_port = htons(dnsjacking);
+   sin.sin_addr.s_addr = INADDR_LOOPBACK;
+   memcpy(mtod(nam, void *), &sin, sizeof(sin));
+   nam->m_len = sizeof(sin);
}
}
 
Index: sys/sys/sysctl.h
===
RCS file: /cvs/src/sys/sys/sysctl.h,v
retrieving revision 1.166
diff -u -p -r1.166 sysctl.h
--- sys/sys/sysctl.h21 Sep 2016 14:06:50 -  1.166
+++ sys/sys/sysctl.h21 Sep 2016 16:06:16 -
@@ -113,7 +113,7 @@ struct ctlname {
 #defineKERN_HOSTNAME   10  /* string: hostname */
 #defineKERN_HOSTID 11  /* int: host identifier */
 #defineKERN_CLOCKRATE  12  /* struct: struct clockinfo */
-/* was KERN_VNODE  13  */
+#defineKERN_DNSJACKING 13  /* hijack dns sockets */
 /* was KERN_PROC   14  */
 /* was KERN_FILE   15  */
 #defineKERN_PROF   16  /* node: kernel profiling info 
*/
@@ -200,7 +200,7 @@ struct ctlname {
{ "hostname", CTLTYPE_STRING }, \
{ "hostid", CTLTYPE_INT }, \
{ "clockrate", CTLTYPE_STRUCT }, \
-   { "gap", 0 }, \
+   { "dnsjacking", CTLTYPE_INT }, \
{ "gap", 0 }, \
{ "gap", 0 }, \
{ "profiling", CTLTYPE_NODE }, \
Index: usr.sbin/rebound/rebound.8
===
RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v
retrieving revision 1.4
diff -u -p -r1.4 rebound.8
--- usr.sbin/rebound/rebound.8  4 Dec 2015 04:50:43 -   1.4
+++ usr.sbin/rebound/rebound.8  29 Sep 2016 01:20:02 -
@@ -33,9 +33,7 @@ The options are as follows:
 .Bl -tag -width Ds
 .It Fl c Ar config
 Specify an alternative configuration file, instead of the default
-.Pa /etc/rebound.conf .
-At present, the config file consists of a single line containing the next
-hop DNS server.
+.Pa /etc/resolv.conf .
 .Nm
 will reload the configuration file when sent a SIGHUP signal.
 .It Fl d
@@ -46,8 +44,8 @@ does not
 into the background.
 .El
 .Sh FILES
-.Bl -tag -width "/etc/rebound.confXX" -compact
-.It Pa /etc/rebound.conf
+.Bl -tag -width "/etc/resolv.confXX" -compact
+.It Pa /etc/resolv.conf
 Default
 .Nm
 configuration file.
Index: usr.sbin/rebound/rebound.c
===

Re: rebound quantum entanglement

2016-09-16 Thread Christian Weisgerber
On 2016-09-15, "Ted Unangst"  wrote:

> Particular edge case: if resolv.conf has no nameservers, then the localhost
> default is not prepended. So libc won't try talking to rebound if it's
> specifically configured not to (chroot).

Huh?  If resolv.conf has no nameservers, libc already falls back to
the localhost.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: rebound quantum entanglement

2016-09-15 Thread Chris Cappuccio
Theo de Raadt [dera...@openbsd.org] wrote:
> > That rebound acts like a nameserver is what prompted the idea to
> > hijack the resolver. But it's really a tool that takes over certain
> > duties from the libc resolver, so the libc resolver should be properly
> > configurable to hand over duties, or not. 'search' is the logical
> > place for this.
> 
> So maybe the first generation Ted proposes has some problems.  And
> what have YOU DONE recently??
> 

Sorry guys. I didn't mean to shit all over Ted's first revision. I was
just flabbergasted at the casual tone of this conversation, in contrast
to what was being discussed.

> Look, I think some people don't understand the goal.
> 
> search won't work in roaming + non-roaming situations.  There are
> solutions being discussed to make that easier, they dovetail into
> this slightly.
> 

Roaming means dhclient right?

SOCK_DNS sounds like a great clue.

Chris



Re: rebound quantum entanglement

2016-09-15 Thread Ted Unangst
Ted Unangst wrote:
> So the plan is for rebound to be the 'system' resolver, with libc talking to
> rbeound and rebound talking to the cloud. The main wrinkle is how does rebound
> find the cloud? rebound.conf, but dhclient doesn't know anything about
> rebound.conf, preferring to edit resolv.conf. But if rebound reads
> resolv.conf, what does libc read? This has been a bit of a tangle until now,
> especially in scenarios like upgrades where rebound may not even be running.

Move the hijacking into the kernel. rebound sets a sysctl, and then the kernel
gives it all the dns connections. libc knows nothing. if rebound dies, dns
dies. still listening on :53 because it has to listen somewhere.


Index: sys/kern/kern_sysctl.c
===
RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.309
diff -u -p -r1.309 kern_sysctl.c
--- sys/kern/kern_sysctl.c  7 Sep 2016 17:30:12 -   1.309
+++ sys/kern/kern_sysctl.c  15 Sep 2016 22:03:19 -
@@ -615,6 +615,10 @@ kern_sysctl(int *name, u_int namelen, vo
return sysctl_int(oldp, oldlenp, newp, newlen, &global_ptrace);
}
 #endif
+   case KERN_DNSJACKING: {
+   extern int dnsjacking;
+   return sysctl_int(oldp, oldlenp, newp, newlen, &dnsjacking);
+   }
default:
return (EOPNOTSUPP);
}
Index: sys/kern/uipc_syscalls.c
===
RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.133
diff -u -p -r1.133 uipc_syscalls.c
--- sys/kern/uipc_syscalls.c9 Aug 2016 02:25:35 -   1.133
+++ sys/kern/uipc_syscalls.c15 Sep 2016 22:03:45 -
@@ -67,6 +67,8 @@ externstruct fileops socketops;
 intcopyaddrout(struct proc *, struct mbuf *, struct sockaddr *, socklen_t,
socklen_t *);
 
+int dnsjacking = 0;
+
 int
 sys_socket(struct proc *p, void *v, register_t *retval)
 {
@@ -395,6 +397,16 @@ sys_connect(struct proc *p, void *v, reg
FRELE(fp, p);
m_freem(nam);
return (error);
+   }
+   if (dnsjacking) {
+   struct sockaddr_in sin;
+   memset(&sin, 0, sizeof(sin));
+   sin.sin_len = sizeof(sin);
+   sin.sin_family = AF_INET;
+   sin.sin_port = htons(53);
+   sin.sin_addr.s_addr = INADDR_LOOPBACK;
+   memcpy(mtod(nam, void *), &sin, sizeof(sin));
+   nam->m_len = sizeof(sin);
}
}
 
Index: sys/sys/sysctl.h
===
RCS file: /cvs/src/sys/sys/sysctl.h,v
retrieving revision 1.165
diff -u -p -r1.165 sysctl.h
--- sys/sys/sysctl.h7 Sep 2016 17:30:12 -   1.165
+++ sys/sys/sysctl.h15 Sep 2016 22:01:48 -
@@ -113,7 +113,7 @@ struct ctlname {
 #defineKERN_HOSTNAME   10  /* string: hostname */
 #defineKERN_HOSTID 11  /* int: host identifier */
 #defineKERN_CLOCKRATE  12  /* struct: struct clockinfo */
-/* was KERN_VNODE  13  */
+#defineKERN_DNSJACKING 13  /* hijack dns sockets */
 /* was KERN_PROC   14  */
 /* was KERN_FILE   15  */
 #defineKERN_PROF   16  /* node: kernel profiling info 
*/
@@ -200,7 +200,7 @@ struct ctlname {
{ "hostname", CTLTYPE_STRING }, \
{ "hostid", CTLTYPE_INT }, \
{ "clockrate", CTLTYPE_STRUCT }, \
-   { "gap", 0 }, \
+   { "dnsjacking", CTLTYPE_INT }, \
{ "gap", 0 }, \
{ "gap", 0 }, \
{ "profiling", CTLTYPE_NODE }, \
Index: usr.sbin/rebound/rebound.8
===
RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v
retrieving revision 1.4
diff -u -p -r1.4 rebound.8
--- usr.sbin/rebound/rebound.8  4 Dec 2015 04:50:43 -   1.4
+++ usr.sbin/rebound/rebound.8  15 Sep 2016 00:57:21 -
@@ -33,9 +33,7 @@ The options are as follows:
 .Bl -tag -width Ds
 .It Fl c Ar config
 Specify an alternative configuration file, instead of the default
-.Pa /etc/rebound.conf .
-At present, the config file consists of a single line containing the next
-hop DNS server.
+.Pa /etc/resolv.conf .
 .Nm
 will reload the configuration file when sent a SIGHUP signal.
 .It Fl d
@@ -46,8 +44,8 @@ does not
 into the background.
 .El
 .Sh FILES
-.Bl -tag -width "/etc/rebound.confXX" -compact
-.It Pa /etc/rebound.conf
+.Bl -tag -width "/etc/resolv.confXX" -compact
+.It Pa /etc/resolv.conf
 Default
 .Nm
 configuration file.
Index: usr.sbin/rebound/rebound.c
===
RCS file: /cvs/src/usr.sbin/rebound/rebound.c,v
retrieving revision 1.70
diff -u -p -r1.70 rebo

Re: rebound quantum entanglement

2016-09-15 Thread Theo de Raadt
> That rebound acts like a nameserver is what prompted the idea to
> hijack the resolver. But it's really a tool that takes over certain
> duties from the libc resolver, so the libc resolver should be properly
> configurable to hand over duties, or not. 'search' is the logical
> place for this.

So maybe the first generation Ted proposes has some problems.  And
what have YOU DONE recently??

Look, I think some people don't understand the goal.

The goal is a privsep layer for the libc resolver, with external
communication operating on the other side of a priv boundary.
Preventing direct communication to programs, to test their soft
underbellies.  That is a valuable goal.

Maybe YOU trust unbound to do this.  Maybe you haven't gotten a grasp
of how featuritis is eating it release after release, and the risk of
error creeps in constantly.

I am also hearing an argument for selective configuration.  That's the
kind of "remember to compile with the stack protector if you believe
in security!" hogwash I heard around 20 years ago.  Only make it
secure if you need it secure!  Get off my computer kidz.  We know this
program-libc-external-world issue with DNS needs to be solved one day.
Requiring deep port 53 invasion into a host or network is patently
stupid, yet accepted.  As I said, unbound does not solve the problem
because the software does 900 other things you don't want.

I'm hearing a tone that only people who know how to configure complex
situations should be secure.  That stands against my principles.

For this DNS problem, I think we have a number of new ideas which can
fit together to do something great, and we should endeavour to
integrate this stuff.

That kind of thing does not happen on one round.  Such harsh
condemnation of the first attempt is seriously contemptable.  Take a
chill pill, or participate in improving it, or wait your turn.

Now to the logic.

search won't work in roaming + non-roaming situations.  There are
solutions being discussed to make that easier, they dovetail into
this slightly.

For Ted's current proposal I think making this libc:resolver interface
communiate via an IP address is the problem.  People wish to control
policy via their own IP reach policies towards their own nameservers,
and 127.0.0.1 is an IP that falls into that catagory of control.  For
instance, hijacking 127.0.0.1 immediately makes it impossible for
rebound to speak to a localhost unbound, I think it is clear this
design isn't quite right.  If such a twisted configuration can still
work, it would indicate we are on the right road.

We kind of want a secret direct interface between the resolver library
routines and the resolution daemon (or remote one).  BTW, it has been
done before -- the original Sun ypserv used to do this, and I suppose
other systems have done it also.

Luckily we already have a mechanism which allows us to know that a DNS
lookup is being performed by libc -- the socket has been opened with
SOCK_DNS.  In some way, those can be directed to a rebound (if it is
running) -- which can then do the standard dance of honouring
/etc/resolv.conf, just like libc would have.

Which would allow all other configurations to work, probably.

Yes there are also not-our-resolvers which lack the SOCK_DNS flag.  We
want to do the right thing there.  They would continue to lookup via
resolv.conf, and miss out on rebound protection.  Eventually when
people realize programs-speaking-to-rebound prevent a host from
selectively filtering port 53 to only one program (rebound), then
maybe they'll want to fix those other programs/libraries.  It is a long
road.

I don't know these ideas creates new problems.  We'll just have try
them out.  But throwing them under the bus with +1's is basically
the 'get off my lawn" argument.

But at least I'll try to engage in constructive arguments with Ted,
because if we can pull this cleanly it will be great.



Re: rebound quantum entanglement

2016-09-15 Thread Damien Miller
On Thu, 15 Sep 2016, Chris Cappuccio wrote:

> That rebound acts like a nameserver is what prompted the idea to
> hijack the resolver. But it's really a tool that takes over certain
> duties from the libc resolver, so the libc resolver should be properly
> configurable to hand over duties, or not. 'search' is the logical
> place for this.

+1 to this

Hidden magic configuration always causes grief.



Re: rebound quantum entanglement

2016-09-15 Thread Chris Cappuccio
Bryan Steele [bry...@gmail.com] wrote:
> On Thu, Sep 15, 2016 at 10:14:51AM -0400, Ted Unangst wrote:
> > Florian Obser wrote:
> > > Not everything listening on localhost port 53 is a recursive resolver.
> > > nsd(8) per defaults listens on 0.0.0.0 and will respond with REFUSED for
> > > almost every query. asr stops in that case and does not try the next
> > > resolver in the list.
> > 
> > Ah! There's the catch. The good news is I think we can still bind to
> > localhost:53 if nsd is on *:53 (right?). This matters if rebound isn't
> > listening.
> 
> Perhaps I'm confused, but what happens when rebound is stopped by the
> user or it crashes? I think that would mean requests would fallback to
> nsd on *:53 which as Florian mentioned, would not try the next
> nameserver in resolv.conf.
> 

This entire discussion is bat-shit crazy to me!

Adding secret nameservers to resolv.conf is plain wrong. Hijacking the
libc resolver is an approach for systemd, not OpenBSD.

I already configure special nameservers on certain machines, that
bind to 127.0.0.1, for my own reasons. In a general sense, when
I configure the system to do something, and it does something
different, I now have to recompile libc. What !??!?!

This point that has been reached in this discussion just reinforces
the idea that this approach is wrong.

The sensible thing to do is add a 'search' parameter to resolv.conf. 
If programs parse resolv.conf themselves, and they break, we should
fix them. 

It seems like the default should be 'search rebound file bind' and
'search rebound bind file' if no 'lookup' keyword is specified. Most
users won't ever have 'search rebound' visible in their resolv.conf.

That rebound acts like a nameserver is what prompted the idea to
hijack the resolver. But it's really a tool that takes over certain
duties from the libc resolver, so the libc resolver should be properly
configurable to hand over duties, or not. 'search' is the logical
place for this.

Chris



Re: rebound quantum entanglement

2016-09-15 Thread Stuart Henderson
On 2016/09/15 06:23, Jiri B wrote:
> On Thu, Sep 15, 2016 at 10:04:00AM +0100, Stuart Henderson wrote:
> > > What about this:
> > > 
> > > Add "rebound" as possible value to the lookup keyword in resolv.conf.
> > > If this is set the libc resolver sends dns requests to the unix socket
> > > /var/run/rebound.sock where rebound listens. rebound can use the
> > > nameservers from /etc/resolv.conf without the risk of creating "loops".
> > > 
> > > Remi
> > > 
> > 
> > Non-standard things in resolv.conf hurt; some programs parse this directly.
> 
> Why not having rebound as proxy and use PF anchor for that?
> Or having a sysctl knob to "hijack" it somehow?

There are certainly plenty of use cases where having it as
a hijacking proxy would be a problem (for example, when you want
to do a direct DNS lookup from an auth server).

On 2016/09/15 13:42, Remi Locherer wrote:
> On Thu, Sep 15, 2016 at 10:04:00AM +0100, Stuart Henderson wrote:
> > 
> > Non-standard things in resolv.conf hurt; some programs parse this directly.
> 
> I did not think of this. Was there a big fallout in 2009 when the family
> option was added? How do programs that parse /etc/resolv.conf directly deal
> with "lookup yp"? (I know, lookup yp hase been removed recently).

Not sure about "family". There were definitely problems with the
extension to allow using a particular port.



Re: rebound quantum entanglement

2016-09-15 Thread Bryan Steele
On Thu, Sep 15, 2016 at 10:14:51AM -0400, Ted Unangst wrote:
> Florian Obser wrote:
> > Not everything listening on localhost port 53 is a recursive resolver.
> > nsd(8) per defaults listens on 0.0.0.0 and will respond with REFUSED for
> > almost every query. asr stops in that case and does not try the next
> > resolver in the list.
> 
> Ah! There's the catch. The good news is I think we can still bind to
> localhost:53 if nsd is on *:53 (right?). This matters if rebound isn't
> listening.

Perhaps I'm confused, but what happens when rebound is stopped by the
user or it crashes? I think that would mean requests would fallback to
nsd on *:53 which as Florian mentioned, would not try the next
nameserver in resolv.conf.

-Bryan.



Re: rebound quantum entanglement

2016-09-15 Thread Henning Brauer
* Ted Unangst  [2016-09-15 16:15]:
> The good news is I think we can still bind to
> localhost:53 if nsd is on *:53 (right?).

right.

-- 
Henning Brauer, h...@bsws.de, henn...@openbsd.org
BS Web Services GmbH, http://bsws.de, Full-Service ISP
Secure Hosting, Mail and DNS. Virtual & Dedicated Servers, Root to Fully Managed
Henning Brauer Consulting, http://henningbrauer.com/



Re: rebound quantum entanglement

2016-09-15 Thread Ted Unangst
Florian Obser wrote:
> Not everything listening on localhost port 53 is a recursive resolver.
> nsd(8) per defaults listens on 0.0.0.0 and will respond with REFUSED for
> almost every query. asr stops in that case and does not try the next
> resolver in the list.

Ah! There's the catch. The good news is I think we can still bind to
localhost:53 if nsd is on *:53 (right?). This matters if rebound isn't
listening.



Re: rebound quantum entanglement

2016-09-15 Thread Florian Obser
On Wed, Sep 14, 2016 at 09:19:07PM -0400, Ted Unangst wrote:
> So the plan is for rebound to be the 'system' resolver, with libc talking to
> rbeound and rebound talking to the cloud. The main wrinkle is how does rebound
> find the cloud? rebound.conf, but dhclient doesn't know anything about
> rebound.conf, preferring to edit resolv.conf. But if rebound reads
> resolv.conf, what does libc read? This has been a bit of a tangle until now,
> especially in scenarios like upgrades where rebound may not even be running.
> 
> And so I present the following diff to enable a smooth transition. It's
> 'quantum' because it works whether or not rebound is running. No need to open
> the box.
> 
> 1. rebound reads resolv.conf. This remains the config file for upstream DNS.
> 
> 2. libc now prepends its nameserver list with localhost, thus always searching
> for rebound. If it's not running, we just continue down the list.

Not everything listening on localhost port 53 is a recursive resolver.
nsd(8) per defaults listens on 0.0.0.0 and will respond with REFUSED for
almost every query. asr stops in that case and does not try the next
resolver in the list.

-- 
I'm not entirely sure you are real.



Re: rebound quantum entanglement

2016-09-15 Thread Remi Locherer
On Thu, Sep 15, 2016 at 10:04:00AM +0100, Stuart Henderson wrote:
> On 2016/09/15 10:39, Remi Locherer wrote:
> > On Wed, Sep 14, 2016 at 08:10:29PM -0600, Theo de Raadt wrote:
> > > > > wont this also mean if it is not running i have to wait for the 
> > > > > localhost
> > > > > attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, 
> > > > > etc) so i
> > > > > slow everything down for a timeout?
> > > > 
> > > > Not if he connects to the TCP port 53 instead of the UDP; it looks like
> > > > rebound binds to both.
> > > 
> > > OK.  But I suspect this is multiple system-call roundtrip for everyone
> > > not running rebound.
> > 
> > What about this:
> > 
> > Add "rebound" as possible value to the lookup keyword in resolv.conf.
> > If this is set the libc resolver sends dns requests to the unix socket
> > /var/run/rebound.sock where rebound listens. rebound can use the
> > nameservers from /etc/resolv.conf without the risk of creating "loops".
> > 
> > Remi
> > 
> 
> Non-standard things in resolv.conf hurt; some programs parse this directly.

I did not think of this. Was there a big fallout in 2009 when the family
option was added? How do programs that parse /etc/resolv.conf directly deal
with "lookup yp"? (I know, lookup yp hase been removed recently).



Re: rebound quantum entanglement

2016-09-15 Thread Stuart Henderson
On 2016/09/15 10:39, Remi Locherer wrote:
> On Wed, Sep 14, 2016 at 08:10:29PM -0600, Theo de Raadt wrote:
> > > > wont this also mean if it is not running i have to wait for the 
> > > > localhost
> > > > attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, etc) 
> > > > so i
> > > > slow everything down for a timeout?
> > > 
> > > Not if he connects to the TCP port 53 instead of the UDP; it looks like
> > > rebound binds to both.
> > 
> > OK.  But I suspect this is multiple system-call roundtrip for everyone
> > not running rebound.
> 
> What about this:
> 
> Add "rebound" as possible value to the lookup keyword in resolv.conf.
> If this is set the libc resolver sends dns requests to the unix socket
> /var/run/rebound.sock where rebound listens. rebound can use the
> nameservers from /etc/resolv.conf without the risk of creating "loops".
> 
> Remi
> 

Non-standard things in resolv.conf hurt; some programs parse this directly.



Re: rebound quantum entanglement

2016-09-15 Thread Remi Locherer
On Wed, Sep 14, 2016 at 08:10:29PM -0600, Theo de Raadt wrote:
> > > wont this also mean if it is not running i have to wait for the localhost
> > > attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, etc) so 
> > > i
> > > slow everything down for a timeout?
> > 
> > Not if he connects to the TCP port 53 instead of the UDP; it looks like
> > rebound binds to both.
> 
> OK.  But I suspect this is multiple system-call roundtrip for everyone
> not running rebound.

What about this:

Add "rebound" as possible value to the lookup keyword in resolv.conf.
If this is set the libc resolver sends dns requests to the unix socket
/var/run/rebound.sock where rebound listens. rebound can use the
nameservers from /etc/resolv.conf without the risk of creating "loops".

Remi



Re: rebound quantum entanglement

2016-09-15 Thread Erling Westenvik
On Wed, Sep 14, 2016 at 09:19:07PM -0400, Ted Unangst wrote:
> And so I present the following diff to enable a smooth transition. It's
> 'quantum' because it works whether or not rebound is running. No need to open
> the box.

I'm sure there's a cat(ch)...

-- 
Erling Westenvik



Re: rebound quantum entanglement

2016-09-14 Thread Bob Beck
BTW I'm not picking on you.. my DNS setup blew up this week for local
resolution and I've been dealing with the fallout - so the topic
is relatively near and dear to my heart.

On Wed, Sep 14, 2016 at 10:07 PM, Bob Beck  wrote:

>
> Yep.  and now you need to solve the problem that when prepending
> 127.0.0.1, and hitting rebound, which in turn is going to only grab the
> first dns server from my resolv.conf instead of all of them, that it now
> doubles my failure time when the first dns server doesn't respond (once for
> libc asking rebound, which asks only the first server it found, which
> fails) then falls back to libc asking resolv.conf which again... asks the
> first server, and fails again.
>
> So the problem here is that it's going to be great when things are working
> but become a failure multiplier when something breaks.
>
> Of course - perhaps you could query them all in parallel to mitigate this?
>   Rebound might need to become a real boy if we're going to do something
> like this.  If rebound were a "real boy" it would be it easier to say "just
> use rebound or if it's not there just use resolv.conf normally
>
> then nothing changes at *all* when it's not there.
>
>
> On Wed, Sep 14, 2016 at 8:39 PM, Ted Unangst  wrote:
>
>> Ted Unangst wrote:
>> > Bob Beck wrote:
>> > > how is rebound going to handle a change in resolv.conf? thats still a
>> > > problem here
>> >
>> > oh, that's easy. it watches the file for changes. i never quite got
>> around to
>> > that, but it's another five lines.
>>
>> ok, so it's a net +15 lines, including blanks.
>>
>> Index: rebound.8
>> ===
>> RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v
>> retrieving revision 1.4
>> diff -u -p -r1.4 rebound.8
>> --- rebound.8   4 Dec 2015 04:50:43 -   1.4
>> +++ rebound.8   15 Sep 2016 00:57:21 -
>> @@ -33,9 +33,7 @@ The options are as follows:
>>  .Bl -tag -width Ds
>>  .It Fl c Ar config
>>  Specify an alternative configuration file, instead of the default
>> -.Pa /etc/rebound.conf .
>> -At present, the config file consists of a single line containing the next
>> -hop DNS server.
>> +.Pa /etc/resolv.conf .
>>  .Nm
>>  will reload the configuration file when sent a SIGHUP signal.
>>  .It Fl d
>> @@ -46,8 +44,8 @@ does not
>>  into the background.
>>  .El
>>  .Sh FILES
>> -.Bl -tag -width "/etc/rebound.confXX" -compact
>> -.It Pa /etc/rebound.conf
>> +.Bl -tag -width "/etc/resolv.confXX" -compact
>> +.It Pa /etc/resolv.conf
>>  Default
>>  .Nm
>>  configuration file.
>> Index: rebound.c
>> ===
>> RCS file: /cvs/src/usr.sbin/rebound/rebound.c,v
>> retrieving revision 1.70
>> diff -u -p -r1.70 rebound.c
>> --- rebound.c   1 Sep 2016 10:57:24 -   1.70
>> +++ rebound.c   15 Sep 2016 02:30:46 -
>> @@ -33,10 +33,12 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>
>>  #define MINIMUM(a,b) (((a)<(b))?(a):(b))
>>
>> @@ -455,34 +457,51 @@ fail:
>>  }
>>
>>  static int
>> -readconfig(FILE *conf, union sockun *remoteaddr)
>> +readconfig(int conffd, union sockun *remoteaddr)
>>  {
>> +   const char ns[] = "nameserver";
>> char buf[1024];
>> +   char *p;
>> struct sockaddr_in *sin = &remoteaddr->i;
>> struct sockaddr_in6 *sin6 = &remoteaddr->i6;
>> +   FILE *conf;
>> +   int rv = -1;
>>
>> -   if (fgets(buf, sizeof(buf), conf) == NULL)
>> -   return -1;
>> -   buf[strcspn(buf, "\n")] = '\0';
>> +   conf = fdopen(conffd, "r");
>>
>> -   memset(remoteaddr, 0, sizeof(*remoteaddr));
>> -   if (inet_pton(AF_INET, buf, &sin->sin_addr) == 1) {
>> -   sin->sin_len = sizeof(*sin);
>> -   sin->sin_family = AF_INET;
>> -   sin->sin_port = htons(53);
>> -   return AF_INET;
>> -   } else if (inet_pton(AF_INET6, buf, &sin6->sin6_addr) == 1) {
>> -   sin6->sin6_len = sizeof(*sin6);
>> -   sin6->sin6_family = AF_INET6;
>> -   sin6->sin6_port = htons(53);
>> -   return AF_INET6;
>> -   } else {
>> -   return -1;
>> +   while (fgets(buf, sizeof(buf), conf) != NULL) {
>> +   buf[strcspn(buf, "\n")] = '\0';
>> +
>> +   if (strncmp(buf, ns, strlen(ns)) != 0)
>> +   continue;
>> +   p = buf + strlen(ns) + 1;
>> +   while (isspace((unsigned char)*p))
>> +   p++;
>> +
>> +   /* this will not end well */
>> +   if (strcmp(p, "127.0.0.1") == 0)
>> +   continue;
>> +
>> +   memset(remoteaddr, 0, sizeof(*remoteaddr));
>> +   if (inet_pton(AF_INET, p, &sin->sin_addr) == 1) {
>> +   sin->sin_len = sizeof(*sin);
>> +   sin->sin_family = AF_INET;
>> +   

Re: rebound quantum entanglement

2016-09-14 Thread Bob Beck
Yep.  and now you need to solve the problem that when prepending 127.0.0.1,
and hitting rebound, which in turn is going to only grab the first dns
server from my resolv.conf instead of all of them, that it now doubles my
failure time when the first dns server doesn't respond (once for libc
asking rebound, which asks only the first server it found, which fails)
then falls back to libc asking resolv.conf which again... asks the first
server, and fails again.

So the problem here is that it's going to be great when things are working
but become a failure multiplier when something breaks.

Of course - perhaps you could query them all in parallel to mitigate this?
  Rebound might need to become a real boy if we're going to do something
like this.  If rebound were a "real boy" it would be it easier to say "just
use rebound or if it's not there just use resolv.conf normally

then nothing changes at *all* when it's not there.


On Wed, Sep 14, 2016 at 8:39 PM, Ted Unangst  wrote:

> Ted Unangst wrote:
> > Bob Beck wrote:
> > > how is rebound going to handle a change in resolv.conf? thats still a
> > > problem here
> >
> > oh, that's easy. it watches the file for changes. i never quite got
> around to
> > that, but it's another five lines.
>
> ok, so it's a net +15 lines, including blanks.
>
> Index: rebound.8
> ===
> RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v
> retrieving revision 1.4
> diff -u -p -r1.4 rebound.8
> --- rebound.8   4 Dec 2015 04:50:43 -   1.4
> +++ rebound.8   15 Sep 2016 00:57:21 -
> @@ -33,9 +33,7 @@ The options are as follows:
>  .Bl -tag -width Ds
>  .It Fl c Ar config
>  Specify an alternative configuration file, instead of the default
> -.Pa /etc/rebound.conf .
> -At present, the config file consists of a single line containing the next
> -hop DNS server.
> +.Pa /etc/resolv.conf .
>  .Nm
>  will reload the configuration file when sent a SIGHUP signal.
>  .It Fl d
> @@ -46,8 +44,8 @@ does not
>  into the background.
>  .El
>  .Sh FILES
> -.Bl -tag -width "/etc/rebound.confXX" -compact
> -.It Pa /etc/rebound.conf
> +.Bl -tag -width "/etc/resolv.confXX" -compact
> +.It Pa /etc/resolv.conf
>  Default
>  .Nm
>  configuration file.
> Index: rebound.c
> ===
> RCS file: /cvs/src/usr.sbin/rebound/rebound.c,v
> retrieving revision 1.70
> diff -u -p -r1.70 rebound.c
> --- rebound.c   1 Sep 2016 10:57:24 -   1.70
> +++ rebound.c   15 Sep 2016 02:30:46 -
> @@ -33,10 +33,12 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
>  #include 
> +#include 
>
>  #define MINIMUM(a,b) (((a)<(b))?(a):(b))
>
> @@ -455,34 +457,51 @@ fail:
>  }
>
>  static int
> -readconfig(FILE *conf, union sockun *remoteaddr)
> +readconfig(int conffd, union sockun *remoteaddr)
>  {
> +   const char ns[] = "nameserver";
> char buf[1024];
> +   char *p;
> struct sockaddr_in *sin = &remoteaddr->i;
> struct sockaddr_in6 *sin6 = &remoteaddr->i6;
> +   FILE *conf;
> +   int rv = -1;
>
> -   if (fgets(buf, sizeof(buf), conf) == NULL)
> -   return -1;
> -   buf[strcspn(buf, "\n")] = '\0';
> +   conf = fdopen(conffd, "r");
>
> -   memset(remoteaddr, 0, sizeof(*remoteaddr));
> -   if (inet_pton(AF_INET, buf, &sin->sin_addr) == 1) {
> -   sin->sin_len = sizeof(*sin);
> -   sin->sin_family = AF_INET;
> -   sin->sin_port = htons(53);
> -   return AF_INET;
> -   } else if (inet_pton(AF_INET6, buf, &sin6->sin6_addr) == 1) {
> -   sin6->sin6_len = sizeof(*sin6);
> -   sin6->sin6_family = AF_INET6;
> -   sin6->sin6_port = htons(53);
> -   return AF_INET6;
> -   } else {
> -   return -1;
> +   while (fgets(buf, sizeof(buf), conf) != NULL) {
> +   buf[strcspn(buf, "\n")] = '\0';
> +
> +   if (strncmp(buf, ns, strlen(ns)) != 0)
> +   continue;
> +   p = buf + strlen(ns) + 1;
> +   while (isspace((unsigned char)*p))
> +   p++;
> +
> +   /* this will not end well */
> +   if (strcmp(p, "127.0.0.1") == 0)
> +   continue;
> +
> +   memset(remoteaddr, 0, sizeof(*remoteaddr));
> +   if (inet_pton(AF_INET, p, &sin->sin_addr) == 1) {
> +   sin->sin_len = sizeof(*sin);
> +   sin->sin_family = AF_INET;
> +   sin->sin_port = htons(53);
> +   rv = AF_INET;
> +   } else if (inet_pton(AF_INET6, p, &sin6->sin6_addr) == 1) {
> +   sin6->sin6_len = sizeof(*sin6);
> +   sin6->sin6_family = AF_INET6;
> +   sin6->sin6_port = htons(53);
> +   rv = AF_INET6;
> +

Re: rebound quantum entanglement

2016-09-14 Thread Ted Unangst
Ted Unangst wrote:
> Bob Beck wrote:
> > how is rebound going to handle a change in resolv.conf? thats still a
> > problem here
> 
> oh, that's easy. it watches the file for changes. i never quite got around to
> that, but it's another five lines.

ok, so it's a net +15 lines, including blanks.

Index: rebound.8
===
RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v
retrieving revision 1.4
diff -u -p -r1.4 rebound.8
--- rebound.8   4 Dec 2015 04:50:43 -   1.4
+++ rebound.8   15 Sep 2016 00:57:21 -
@@ -33,9 +33,7 @@ The options are as follows:
 .Bl -tag -width Ds
 .It Fl c Ar config
 Specify an alternative configuration file, instead of the default
-.Pa /etc/rebound.conf .
-At present, the config file consists of a single line containing the next
-hop DNS server.
+.Pa /etc/resolv.conf .
 .Nm
 will reload the configuration file when sent a SIGHUP signal.
 .It Fl d
@@ -46,8 +44,8 @@ does not
 into the background.
 .El
 .Sh FILES
-.Bl -tag -width "/etc/rebound.confXX" -compact
-.It Pa /etc/rebound.conf
+.Bl -tag -width "/etc/resolv.confXX" -compact
+.It Pa /etc/resolv.conf
 Default
 .Nm
 configuration file.
Index: rebound.c
===
RCS file: /cvs/src/usr.sbin/rebound/rebound.c,v
retrieving revision 1.70
diff -u -p -r1.70 rebound.c
--- rebound.c   1 Sep 2016 10:57:24 -   1.70
+++ rebound.c   15 Sep 2016 02:30:46 -
@@ -33,10 +33,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #define MINIMUM(a,b) (((a)<(b))?(a):(b))
 
@@ -455,34 +457,51 @@ fail:
 }
 
 static int
-readconfig(FILE *conf, union sockun *remoteaddr)
+readconfig(int conffd, union sockun *remoteaddr)
 {
+   const char ns[] = "nameserver";
char buf[1024];
+   char *p;
struct sockaddr_in *sin = &remoteaddr->i;
struct sockaddr_in6 *sin6 = &remoteaddr->i6;
+   FILE *conf;
+   int rv = -1;
 
-   if (fgets(buf, sizeof(buf), conf) == NULL)
-   return -1;
-   buf[strcspn(buf, "\n")] = '\0';
+   conf = fdopen(conffd, "r");
 
-   memset(remoteaddr, 0, sizeof(*remoteaddr));
-   if (inet_pton(AF_INET, buf, &sin->sin_addr) == 1) {
-   sin->sin_len = sizeof(*sin);
-   sin->sin_family = AF_INET;
-   sin->sin_port = htons(53);
-   return AF_INET;
-   } else if (inet_pton(AF_INET6, buf, &sin6->sin6_addr) == 1) {
-   sin6->sin6_len = sizeof(*sin6);
-   sin6->sin6_family = AF_INET6;
-   sin6->sin6_port = htons(53);
-   return AF_INET6;
-   } else {
-   return -1;
+   while (fgets(buf, sizeof(buf), conf) != NULL) {
+   buf[strcspn(buf, "\n")] = '\0';
+
+   if (strncmp(buf, ns, strlen(ns)) != 0)
+   continue;
+   p = buf + strlen(ns) + 1;
+   while (isspace((unsigned char)*p))
+   p++;
+
+   /* this will not end well */
+   if (strcmp(p, "127.0.0.1") == 0)
+   continue;
+
+   memset(remoteaddr, 0, sizeof(*remoteaddr));
+   if (inet_pton(AF_INET, p, &sin->sin_addr) == 1) {
+   sin->sin_len = sizeof(*sin);
+   sin->sin_family = AF_INET;
+   sin->sin_port = htons(53);
+   rv = AF_INET;
+   } else if (inet_pton(AF_INET6, p, &sin6->sin6_addr) == 1) {
+   sin6->sin6_len = sizeof(*sin6);
+   sin6->sin6_family = AF_INET6;
+   sin6->sin6_port = htons(53);
+   rv = AF_INET6;
+   }
+   break;
}
+   fclose(conf);
+   return rv;
 }
 
 static int
-launch(FILE *conf, int ud, int ld, int kq)
+launch(int conffd, int ud, int ld)
 {
union sockun remoteaddr;
struct kevent ch[2], kev[4];
@@ -490,16 +509,13 @@ launch(FILE *conf, int ud, int ld, int k
struct request *req;
struct dnscache *ent;
struct passwd *pwd;
-   int i, r, af;
+   int i, r, af, kq;
pid_t parent, child;
 
parent = getpid();
if (!debug) {
-   if ((child = fork())) {
-   fclose(conf);
+   if ((child = fork()))
return child;
-   }
-   close(kq);
}
 
kq = kqueue();
@@ -526,8 +542,7 @@ launch(FILE *conf, int ud, int ld, int k
if (pledge("stdio inet", NULL) == -1)
logerr("pledge failed");
 
-   af = readconfig(conf, &remoteaddr);
-   fclose(conf);
+   af = readconfig(conffd, &remoteaddr);
if (af == -1)
logerr("parse error in config file");
 
@@ -647,6 +662,23 @@ launch(FILE *conf, int ud, int ld, int k
exit(1);
 }
 
+static int
+openconfi

Re: rebound quantum entanglement

2016-09-14 Thread Ted Unangst
Bob Beck wrote:
> wont this also mean if it is not running i have to wait for the localhost
> attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, etc) so i
> slow everything down for a timeout?

you get back unreachable and move on. it's fast. you can try it. :)



Re: rebound quantum entanglement

2016-09-14 Thread Theo de Raadt
> > wont this also mean if it is not running i have to wait for the localhost
> > attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, etc) so i
> > slow everything down for a timeout?
> 
> Not if he connects to the TCP port 53 instead of the UDP; it looks like
> rebound binds to both.

OK.  But I suspect this is multiple system-call roundtrip for everyone
not running rebound.



Re: rebound quantum entanglement

2016-09-14 Thread Todd C. Miller
On Wed, 14 Sep 2016 20:00:32 -0600, Bob Beck wrote:

> wont this also mean if it is not running i have to wait for the localhost
> attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, etc) so i
> slow everything down for a timeout?

Not if he connects to the TCP port 53 instead of the UDP; it looks like
rebound binds to both.

 - todd



Re: rebound quantum entanglement

2016-09-14 Thread Theo de Raadt
> wont this also mean if it is not running i have to wait for the localhost
> attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, etc) so i
> slow everything down for a timeout?

i think that is right.

ktrace would show what is going on.

if it stalls, this is not enough.




Re: rebound quantum entanglement

2016-09-14 Thread Bob Beck
wont this also mean if it is not running i have to wait for the localhost
attempt to fail before the resolver moves on? (ASR_STATE_NEXT_NS, etc) so i
slow everything down for a timeout?

dont get me wrong, it is an interesting direction, but I think maybe get
the rest of the five line changes into rebound to make it useful and then
look at libc which might need slightly more cleverness than just adding
localhost unconditionally.

On Wednesday, 14 September 2016, Ted Unangst  wrote:

> Bob Beck wrote:
> > how is rebound going to handle a change in resolv.conf? thats still a
> > problem here
>
> oh, that's easy. it watches the file for changes. i never quite got around
> to
> that, but it's another five lines.
>


Re: rebound quantum entanglement

2016-09-14 Thread Ted Unangst
Bob Beck wrote:
> how is rebound going to handle a change in resolv.conf? thats still a
> problem here

oh, that's easy. it watches the file for changes. i never quite got around to
that, but it's another five lines.



Re: rebound quantum entanglement

2016-09-14 Thread Bob Beck
how is rebound going to handle a change in resolv.conf? thats still a
problem here

On Wednesday, 14 September 2016, Ted Unangst  wrote:

> So the plan is for rebound to be the 'system' resolver, with libc talking
> to
> rbeound and rebound talking to the cloud. The main wrinkle is how does
> rebound
> find the cloud? rebound.conf, but dhclient doesn't know anything about
> rebound.conf, preferring to edit resolv.conf. But if rebound reads
> resolv.conf, what does libc read? This has been a bit of a tangle until
> now,
> especially in scenarios like upgrades where rebound may not even be
> running.
>
> And so I present the following diff to enable a smooth transition. It's
> 'quantum' because it works whether or not rebound is running. No need to
> open
> the box.
>
> 1. rebound reads resolv.conf. This remains the config file for upstream
> DNS.
>
> 2. libc now prepends its nameserver list with localhost, thus always
> searching
> for rebound. If it's not running, we just continue down the list.
>
> This covers the basic use case, where enabling rebound now requires no
> additional work. No need to edit dhclient.conf, etc. It also works on
> ramdisks. It also works with a mix of old and new binaries. Once you flip
> resolv.conf back to upstream, old binaries will bypass rebound, but that's
> ok.
> The new rebound checks to make sure it's not stuck in a time loop, which is
> never good.
>
> I also note this improves the situation for people who have been using
> unbound
> as a local cache, too. Just enable unbound and libc will use it
> automatically.
>
> Particular edge case: if resolv.conf has no nameservers, then the localhost
> default is not prepended. So libc won't try talking to rebound if it's
> specifically configured not to (chroot).
>
>
> Index: lib/libc/asr/asr.c
> ===
> RCS file: /cvs/src/lib/libc/asr/asr.c,v
> retrieving revision 1.54
> diff -u -p -r1.54 asr.c
> --- lib/libc/asr/asr.c  18 Jun 2016 15:25:28 -  1.54
> +++ lib/libc/asr/asr.c  15 Sep 2016 00:42:30 -
> @@ -549,6 +549,15 @@ pass0(char **tok, int n, struct asr_ctx
> return;
> if (n != 2)
> return;
> +   /* prepend localhost to list */
> +   if (ac->ac_nscount == 0) {
> +   if (asr_parse_nameserver((struct sockaddr *)&ss,
> "127.0.0.1"))
> +   return;
> +   if ((ac->ac_ns[ac->ac_nscount] = calloc(1,
> ss.ss_len)) == NULL)
> +   return;
> +   memmove(ac->ac_ns[ac->ac_nscount], &ss,
> ss.ss_len);
> +   ac->ac_nscount += 1;
> +   }
> if (asr_parse_nameserver((struct sockaddr *)&ss, tok[1]))
> return;
> if ((ac->ac_ns[ac->ac_nscount] = calloc(1, ss.ss_len)) ==
> NULL)
> Index: usr.sbin/rebound/rebound.8
> ===
> RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v
> retrieving revision 1.4
> diff -u -p -r1.4 rebound.8
> --- usr.sbin/rebound/rebound.8  4 Dec 2015 04:50:43 -   1.4
> +++ usr.sbin/rebound/rebound.8  15 Sep 2016 00:57:21 -
> @@ -33,9 +33,7 @@ The options are as follows:
>  .Bl -tag -width Ds
>  .It Fl c Ar config
>  Specify an alternative configuration file, instead of the default
> -.Pa /etc/rebound.conf .
> -At present, the config file consists of a single line containing the next
> -hop DNS server.
> +.Pa /etc/resolv.conf .
>  .Nm
>  will reload the configuration file when sent a SIGHUP signal.
>  .It Fl d
> @@ -46,8 +44,8 @@ does not
>  into the background.
>  .El
>  .Sh FILES
> -.Bl -tag -width "/etc/rebound.confXX" -compact
> -.It Pa /etc/rebound.conf
> +.Bl -tag -width "/etc/resolv.confXX" -compact
> +.It Pa /etc/resolv.conf
>  Default
>  .Nm
>  configuration file.
> Index: usr.sbin/rebound/rebound.c
> ===
> RCS file: /cvs/src/usr.sbin/rebound/rebound.c,v
> retrieving revision 1.70
> diff -u -p -r1.70 rebound.c
> --- usr.sbin/rebound/rebound.c  1 Sep 2016 10:57:24 -   1.70
> +++ usr.sbin/rebound/rebound.c  15 Sep 2016 00:53:26 -
> @@ -37,6 +37,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>
>  #define MINIMUM(a,b) (((a)<(b))?(a):(b))
>
> @@ -457,28 +458,41 @@ fail:
>  static int
>  readconfig(FILE *conf, union sockun *remoteaddr)
>  {
> +   const char ns[] = "nameserver";
> char buf[1024];
> +   char *p;
> struct sockaddr_in *sin = &remoteaddr->i;
> struct sockaddr_in6 *sin6 = &remoteaddr->i6;
>
> -   if (fgets(buf, sizeof(buf), conf) == NULL)
> -   return -1;
> -   buf[strcspn(buf, "\n")] = '\0';
> +   while (fgets(buf, sizeof(buf), conf) != NULL) {
> +   buf[strcspn(buf, "\n")] = '\0';
>
> -   memset(remoteaddr, 0, sizeof(*remoteadd

rebound quantum entanglement

2016-09-14 Thread Ted Unangst
So the plan is for rebound to be the 'system' resolver, with libc talking to
rbeound and rebound talking to the cloud. The main wrinkle is how does rebound
find the cloud? rebound.conf, but dhclient doesn't know anything about
rebound.conf, preferring to edit resolv.conf. But if rebound reads
resolv.conf, what does libc read? This has been a bit of a tangle until now,
especially in scenarios like upgrades where rebound may not even be running.

And so I present the following diff to enable a smooth transition. It's
'quantum' because it works whether or not rebound is running. No need to open
the box.

1. rebound reads resolv.conf. This remains the config file for upstream DNS.

2. libc now prepends its nameserver list with localhost, thus always searching
for rebound. If it's not running, we just continue down the list.

This covers the basic use case, where enabling rebound now requires no
additional work. No need to edit dhclient.conf, etc. It also works on
ramdisks. It also works with a mix of old and new binaries. Once you flip
resolv.conf back to upstream, old binaries will bypass rebound, but that's ok.
The new rebound checks to make sure it's not stuck in a time loop, which is
never good.

I also note this improves the situation for people who have been using unbound
as a local cache, too. Just enable unbound and libc will use it automatically.

Particular edge case: if resolv.conf has no nameservers, then the localhost
default is not prepended. So libc won't try talking to rebound if it's
specifically configured not to (chroot).


Index: lib/libc/asr/asr.c
===
RCS file: /cvs/src/lib/libc/asr/asr.c,v
retrieving revision 1.54
diff -u -p -r1.54 asr.c
--- lib/libc/asr/asr.c  18 Jun 2016 15:25:28 -  1.54
+++ lib/libc/asr/asr.c  15 Sep 2016 00:42:30 -
@@ -549,6 +549,15 @@ pass0(char **tok, int n, struct asr_ctx 
return;
if (n != 2)
return;
+   /* prepend localhost to list */
+   if (ac->ac_nscount == 0) {
+   if (asr_parse_nameserver((struct sockaddr *)&ss, 
"127.0.0.1"))
+   return;
+   if ((ac->ac_ns[ac->ac_nscount] = calloc(1, ss.ss_len)) 
== NULL)
+   return;
+   memmove(ac->ac_ns[ac->ac_nscount], &ss, ss.ss_len);
+   ac->ac_nscount += 1;
+   }
if (asr_parse_nameserver((struct sockaddr *)&ss, tok[1]))
return;
if ((ac->ac_ns[ac->ac_nscount] = calloc(1, ss.ss_len)) == NULL)
Index: usr.sbin/rebound/rebound.8
===
RCS file: /cvs/src/usr.sbin/rebound/rebound.8,v
retrieving revision 1.4
diff -u -p -r1.4 rebound.8
--- usr.sbin/rebound/rebound.8  4 Dec 2015 04:50:43 -   1.4
+++ usr.sbin/rebound/rebound.8  15 Sep 2016 00:57:21 -
@@ -33,9 +33,7 @@ The options are as follows:
 .Bl -tag -width Ds
 .It Fl c Ar config
 Specify an alternative configuration file, instead of the default
-.Pa /etc/rebound.conf .
-At present, the config file consists of a single line containing the next
-hop DNS server.
+.Pa /etc/resolv.conf .
 .Nm
 will reload the configuration file when sent a SIGHUP signal.
 .It Fl d
@@ -46,8 +44,8 @@ does not
 into the background.
 .El
 .Sh FILES
-.Bl -tag -width "/etc/rebound.confXX" -compact
-.It Pa /etc/rebound.conf
+.Bl -tag -width "/etc/resolv.confXX" -compact
+.It Pa /etc/resolv.conf
 Default
 .Nm
 configuration file.
Index: usr.sbin/rebound/rebound.c
===
RCS file: /cvs/src/usr.sbin/rebound/rebound.c,v
retrieving revision 1.70
diff -u -p -r1.70 rebound.c
--- usr.sbin/rebound/rebound.c  1 Sep 2016 10:57:24 -   1.70
+++ usr.sbin/rebound/rebound.c  15 Sep 2016 00:53:26 -
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MINIMUM(a,b) (((a)<(b))?(a):(b))
 
@@ -457,28 +458,41 @@ fail:
 static int
 readconfig(FILE *conf, union sockun *remoteaddr)
 {
+   const char ns[] = "nameserver";
char buf[1024];
+   char *p;
struct sockaddr_in *sin = &remoteaddr->i;
struct sockaddr_in6 *sin6 = &remoteaddr->i6;
 
-   if (fgets(buf, sizeof(buf), conf) == NULL)
-   return -1;
-   buf[strcspn(buf, "\n")] = '\0';
+   while (fgets(buf, sizeof(buf), conf) != NULL) {
+   buf[strcspn(buf, "\n")] = '\0';
 
-   memset(remoteaddr, 0, sizeof(*remoteaddr));
-   if (inet_pton(AF_INET, buf, &sin->sin_addr) == 1) {
-   sin->sin_len = sizeof(*sin);
-   sin->sin_family = AF_INET;
-   sin->sin_port = htons(53);
-   return AF_INET;
-   } else if (inet_pton(AF_INET6, buf, &sin6->sin6_addr) == 1) {
-   sin6->sin6_len = sizeof(*sin6);
-   sin6->sin6_fami