Re: hoststated(8): DNS Relay uses unexpected source IP address

2007-11-19 Thread Reyk Floeter
On Sat, Nov 17, 2007 at 04:01:51PM +0100, Rolf Sommerhalder wrote:
 relay dnsRelay {
  listen on $yellow port 53
  protocol dnsProto
  forward to $white port 53
  #forward to $dnsHost port 53
  timeout 60
 }
 

as theo mentioned, the problem is related to the use of the bind()
call for the outbound udp socket. the code currently uses the same
socket for inbound and outbound datagrams, and it will bind() to the
address specified in the listen on directive. there is no easy
support to support multi-homed interfaces yet, because i need to
extends the hoststated relay code to allow multiple listen on
directives per relay first (in contrast to TCP streams, we need to
listen for UDP replies).

please try to configure the following:

1. use 0.0.0.0 as the listen on address; the relay will listen
  on any IP address for incoming DNS requests and the kernel
  will select the primary IP address of the outgoing interface
  with the specified source port automatically

protocol dnsProto {
protocol dns
}
relay domain {
listen on 0.0.0.0 port 53
forward to $dnsHost port 53
protocol dnsProto
}

2. because we do not bind to an explicit address, restrict DNS in pf

pass in on { fxp2, fxp3 } inet proto udp to port 53

so the proposed solution is to always use listen on 0.0.0.0 port 53
with DNS relays for now.

 relay nfOracleRelay {
  listen on $yellow port 1521
  protocol nfOracleProto
  forward to $white port 1521
  #forward to $ospHost port 1521
  timeout 3600
 }
 
 relay x11Relay {
  listen on $yellow port 6000
  protocol x11Proto
  forward to $white port 6000
  #forward to $x11Host port 6000
  timeout 600
 }
 [EMAIL PROTECTED]:etc]#
 
 
 
 [EMAIL PROTECTED]:etc]# hoststated -v -d
 startup
 init_filter: filter init done
 init_tables: created 0 tables
 relay_init: adding relay x11Relay
 protocol 3: name x11Proto
 flags: 0x0004
 type: tcp
 relay_init: adding relay nfOracleRelay
 protocol 2: name nfOracleProto
 flags: 0x0004
 type: tcp
 relay_init: adding relay dnsRelay
 protocol 1: name dnsProto
 flags: 0x0004
 type: dns
 relay_init: adding relay sshRelay
 protocol 0: name sshProto
 flags: 0x0004
 type: tcp
 relay_launch: running relay x11Relay
 relay_launch: running relay nfOracleRelay
 relay_launch: running relay dnsRelay
 relay_launch: running relay sshRelay
 
 ---
 
 A) DNS/UDP Example
 
 Output of hoststated -v -d after issuing a DNS lookup on orange:
 
 relay_dns_log: session 1: request id 0xf4cc flags 0x1:0x0 qd 1 an 0 ns 0 ar 0
 relay dnsRelay, session 1 (1 active), 10.2.2.32 - 10.1.1.30:53, udp timeout
 relay_dns_log: session 2: request id 0xf4cc flags 0x1:0x0 qd 1 an 0 ns 0 ar 0
 relay dnsRelay, session 2 (1 active), 10.2.2.32 - 10.1.1.30:53, udp timeout
 
 
 hostated listens on the right NIC fxp3:
 
 [EMAIL PROTECTED]:root]# tcpdump -i fxp3 -n
 tcpdump: listening on fxp3, link-type EN10MB
 15:51:39.635373 10.2.2.32.32768  10.2.2.31.53: 51934+ A? orange. (24) (DF)
 15:51:44.636459 10.2.2.32.32768  10.2.2.31.53: 51934+ A? orange. (24) (DF)
 
 
 hostated passes on the proxied requets to the left NIC fxp2, using the
 unexpected/wrong(?) source address of (fxp3)=10.2.2.31, instead of
 (fxp2)=10.1.1.31 as in the TCP example below:
 
 [EMAIL PROTECTED]:root]# tcpdump -i fxp2 -n
 tcpdump: listening on fxp2, link-type EN10MB
 15:42:13.565810 10.2.2.31.53  10.1.1.30.53: 5744+ A? orange. (24)
 15:42:18.566692 10.2.2.31.53  10.1.1.30.53: 6135+ A? orange. (24)
 
 
 ---
 
 B) TCP Example
 
 Output of hoststated -v -d after orange opens and immediately
 closes again an X11 window on a remote X server to the left of
 white:
 
 relay x11Relay, session 5 (1 active), 10.2.2.32 - 10.1.1.30:6000, done
 
 
 hostated listens on the right NIC fxp3:
 
 [EMAIL PROTECTED]:root]# tcpdump -i fxp3 -n
 tcpdump: listening on fxp3, link-type EN10MB
 15:49:36.359944 10.2.2.32.32770  10.2.2.31.6000: S
 18518406:18518406(0) win 5840 mss 1460,sackOK,timestamp 74716745
 0,nop,wscale 2 (DF) [tos 0x10]
 15:49:36.360083 10.2.2.31.6000  10.2.2.32.32770: S
 2569303658:2569303658(0) ack 18518407 win 65535 mss
 1460,nop,nop,sackOK,nop,wscale 1,nop,nop,timestamp 2174965381
 74716745 (DF)
 15:49:36.360975 10.2.2.32.32770  10.2.2.31.6000: . ack 1 win 1460
 nop,nop,timestamp 74716746 2174965381 (DF) [tos 0x10]
 15:49:39.487031 10.2.2.32.32770  10.2.2.31.6000: P 1:3(2) ack 1 win
 1460 nop,nop,timestamp 74719873 2174965381 (DF) [tos 0x10]
 15:49:39.684656 10.2.2.31.6000  10.2.2.32.32770: . ack 3 win 33304
 nop,nop,timestamp 2174965388 74719873 (DF)
 15:49:43.873208 10.2.2.32.32770  10.2.2.31.6000: F 3:3(0) ack 1 win
 1460 nop,nop,timestamp 74724259 2174965388 (DF) [tos 0x10]
 15:49:43.873284 10.2.2.31.6000  10.2.2.32.32770: . ack 4 win 33304
 nop,nop,timestamp 2174965396 74724259 (DF)
 15:49:43.873720 10.2.2.31.6000  10.2.2.32.32770: F 1:1(0) ack 4 win
 33304 nop,nop,timestamp 2174965396 74724259 (DF)
 15:49:43.873928 10.2.2.32.1024  10.2.2.31.6000: . ack 2569303660 

Re: hoststated(8): DNS Relay uses unexpected source IP address

2007-11-19 Thread Rolf Sommerhalder
On Nov 19, 2007 6:35 PM, Reyk Floeter [EMAIL PROTECTED] wrote:
 please try to configure the following:
...
 so the proposed solution is to always use listen on 0.0.0.0 port 53
 with DNS relays for now.

Your proposal indeed solves the problem in my multi-homed setup, and
makes my work-around with source NAT rule obsolete! Thank you very
much.

In the long run, would it be feasible to extend relay_udp_bind() so
that its binds to the IP address of
the interface to which it will relay those DNS UDP packets (while also
observing the default route)?
Could this eliminate the implicit use of spoofed sender IP addresses
by the DNS relay on multi-homed hosts, without adding any knobs?

Rolf



Re: hoststated(8): DNS Relay uses unexpected source IP address

2007-11-17 Thread Rolf Sommerhalder
On Nov 17, 2007 4:01 PM, Rolf Sommerhalder
[EMAIL PROTECTED] wrote:

 This unexpected behaviuor of the DNS/UDP relay then causes routing
 problems as the white server is by default unaware of a route for
 the source address (yellow.fxp3). So DNS responses from white do not
 get routed back to yellow. Of course, I could add a route on white
 as a workaround. But it would be more elegant if the DNS/UDP relay
 would behave the same way as the TCP relays do. In order to figure out

As an alternate work-around, I just tried to insert a source NAT rule
in /etc/pf.conf on yellow, which masks/solves the routing problem
locally on the reverse proxy machine:

[EMAIL PROTECTED]:etc]# cat /etc/pf.conf
# source NAT for routing back from white for DNS only
nat log on fxp2 from 10.2.2.31 to 10.1.1.30 port 53 - (fxp2)

Probably, I should add at least static-port to the NAT rule above in
order to prevent white from modifying the source port 53 (see
tcpdump below).

Still, I am unsure if the DNS/UDP relay actually behaves correctly,
and if this work-around does make sense.

Rolf


A) DNS/UDP Example reloaded, now with source NAT on yellow

Output of hoststated -v -d after issuing a DNS lookup on orange:

relay_dns_log: session 1: request id 0xde7 flags 0x1:0x0 qd 1 an 0 ns 0 ar 0
relay_dns_log: session 1: response id 0x9cc flags 0x85:0x80 qd 1 an 1 ns 1 ar 0
relay dnsRelay, session 1 (1 active), 10.2.2.32 - 10.1.1.30:53, session closed

hostated listens on the right NIC fxp3:

[EMAIL PROTECTED]:root]# tcpdump -i fxp3 -n
tcpdump: listening on fxp3, link-type EN10MB
16:45:19.718243 arp who-has 10.2.2.31 tell 10.2.2.32
16:45:19.718274 arp reply 10.2.2.31 is-at 00:10:f3:0d:32:70
16:45:19.718461 10.2.2.32.32768  10.2.2.31.53: 3559+ A? orange. (36) (DF)
16:45:19.720859 10.2.2.31.53  10.2.2.32.32768: 3559* 1/1/0 A 172.16.70.32 (69)

hostated passes on the proxied requets to the left NIC fxp2, using the
source address (fxp2)=10.1.1.31, as forced by source NAT:

[EMAIL PROTECTED]:root]# tcpdump -i fxp2 -n
tcpdump: listening on fxp2, link-type EN10MB
16:48:57.815366 10.1.1.31.51245  10.1.1.30.53: 65223+ A? orange. (36)
16:48:57.816452 10.1.1.30.53  10.1.1.31.51245: 65223* 1/1/0 A 172.16.70.32 (69)



Re: hoststated(8): DNS Relay uses unexpected source IP address

2007-11-17 Thread Rolf Sommerhalder
On Nov 17, 2007 4:58 PM, Rolf Sommerhalder
[EMAIL PROTECTED] wrote:

 Still, I am unsure if the DNS/UDP relay actually behaves correctly,
 and if this work-around does make sense.

After a deep dive into the sources of hoststated, my current
understanding is that this is not a problem caused by hoststated
itself, but rather how the underlaying IP stack determines the source
IP address of a UDP packet when the server is multi-homed.

relay_dns_request() in src/usr.sbin/hoststated/relay_udp.c calls
sendto() with the correct destination IP. However, the source IP
address can not be passed to sendto().

Are there facilities to set the source address for UDP packets sent
from a multi-homed server?



Re: hoststated(8): DNS Relay uses unexpected source IP address

2007-11-17 Thread Theo de Raadt
 On Nov 17, 2007 4:58 PM, Rolf Sommerhalder
 [EMAIL PROTECTED] wrote:
 
  Still, I am unsure if the DNS/UDP relay actually behaves correctly,
  and if this work-around does make sense.
 
 After a deep dive into the sources of hoststated, my current
 understanding is that this is not a problem caused by hoststated
 itself, but rather how the underlaying IP stack determines the source
 IP address of a UDP packet when the server is multi-homed.
 
 relay_dns_request() in src/usr.sbin/hoststated/relay_udp.c calls
 sendto() with the correct destination IP. However, the source IP
 address can not be passed to sendto().
 
 Are there facilities to set the source address for UDP packets sent
 from a multi-homed server?

Oh, one does that by calling bind() beforehands, with the specific
local address one which uses use, instead of 0.0.0.0.  With udp this
works nicely because you can rebind a udp socket multiple times.  The
same thing does not work with tcp, for the obvious reasons.

However I don't know how this maps to the problem space inside
hoststated; I just wanted to mention that it is possible to solve the
specific problem you ask about.



Re: hoststated(8): DNS Relay uses unexpected source IP address

2007-11-17 Thread Rolf Sommerhalder
On Nov 18, 2007 8:04 AM, Theo de Raadt [EMAIL PROTECTED] wrote:
 Oh, one does that by calling bind() beforehands, with the specific
 local address one which uses use, instead of 0.0.0.0.  With udp this

Thanks Theo for your hint. I look into this in the context of hoststated.

What still puzzles me is that my multi-homed server sends out UDP
packets on interface fxp2=10.1.1.31 with source IP address of another
interface, e.g. fxp3=10.2.2.31.  Therefore, I'll take a look at
bind(2) and sendto(2) now, maybe this helps to solve my confusion
(poured too much Kirsch into the cheese fondue last night ;-).

By the way, googling with Set source address for UDP packets from
multihomed server brought up some interesting discussions in other
contexts, such as OpenVPN, bind or ntpd.