Re: hoststated(8): DNS Relay uses unexpected source IP address
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
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
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
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
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
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.