Closed robotiv closed 10 years ago
@robotiv Great question. You should be able to accomplish this using five separate listeners using a common table each with the source directive. I would rather not introduce an additional feature for this if it is already possible with existing configuration capabilities. I normally don't recommend using the source directive since the Linux kernel can make more efficient use of the outbound port range when a source address is not specified, but in this case sniproxy would need to bind to a source address before making the connection to the destination server.
Thanks for the fast response.
Wow, I didn't realize it could be that easy. So if I understand correctly to get client requests serviced over the same interface to the backend server I would need something like:
listen 192.168.0.10:80 { proto http table hosts }
listen 192.168.0.11:80 { proto http table hosts }
table hosts { host1.domain.com host2.domain.com }
So when a request comes in on 192.168.0.10, it will make the connection to host1.domain.com using the ip 192.168.0.10?
Thanks again!
You will need to add the source directive to each listener also:
listen 192.168.0.10:80 {
proto http
source 192.168.0.10
table hosts
}
listen 192.168.0.11:80 {
proto http
source 192.168.0.11
table hosts
}
table hosts {
host1.domain.com *
host2.domain.com *
}
Worked like a charm for IPv4, thank you.
I looked through the code a little bit and noticed the resolver function that calls libudns only looks up the A record even if the source directive specifies IPv6 address (correct me if I am wrong here please). I am specifically trying to accept connections on an IPv4 address and then resolve the AAAA record of the backend requested and connect to the backend using various IPv6 addresses assigned to me. Connecting out to a backend using various IPv6 addresses while listening on one IPv4 address also doesn't seem to be possible as the source directive is done in the listen?
Ideally I was trying to achieve something like this:
listen unix:/var/run/proxy.sock {
protocol http
# outgoing connections use any random IPv6 from this /32 range
source 2001:db8::/32
table ipv6hosts
}
listen 192.168.0.10:80 {
proto http
source 192.168.0.10
table hosts
}
table hosts {
host1.domain.com *
host2.domain.com *
# ipv6 hosts tunneled from IPv4
hostipv6a.domain.com unix:/var/run/server.sock
hostipv6b.domain.com unix:/var/run/server.sock
}
table ipv6hosts {
# anything that makes it here has already passed filtering from table above
.* *
}
Please let me know if my approach is completely wrong.
Thank you
I omitted IPv6 DNS look ups in the original non-blocking DNS resolver release, and no one has noticed until now. I just pushed a dual stack DNS resolver branch #136 to address this.
Thanks, built the branch :)
I think my other requirement of using multiple source IPv6 addresses can be resolved by enabling IPv6 privacy extensions on the system with a configured temp_prefered_lft for the address expiry.
I've been trying to get this to work and cannot. I manage to get sniproxy to 'bind' but it appears to still traffic everything through the linux kernels default gateway. I have the following scenario: -two different public IP addresses.
auto eth0 iface eth0 inet static hwaddress ether 00:00:d1:d0:1a:cc address 204.xxx.xxx.2 netmask 255.255.255.0 gateway 204.xxx.xxx.1 dns-nameservers 8.8.8.8 8.8.4.4 auto eth0:0 iface eth0:0 inet static address 104.xxx.xxx.3 netmask 255.255.254.0
OR with this style which puts all virtual IP's under eth0 and no sub virtuals:
auto eth0 iface eth0 inet static hwaddress ether 00:00:d1:d0:1a:cc address 204.xxx.xxx.2 netmask 255.255.255.0 gateway 204.xxx.xxx.1 dns-nameservers 8.8.8.8 8.8.4.4 iface eth0 inet static address 104.xxx.xxx.3 netmask 255.255.254.0
sniproxy appears to load OK with no errors in the error log with this configuration.
however when I use the following sniproxy conf file and test going to a webpage that shows public IP's. It always shows the 204.xxx.xxx.2 IP even though the request originated to 104.xxx.xxx.3 IP. the systems default gateway is the 204.xxx.xxx.1 gateway. It appears sniproxy is utilizing the systems default gateway/IP still and not the SOURCE IP I have provided in sniproxy conf:
user daemon
error_log { filename /tmp/sniproxy_error.log priority debug }
pidfile /var/tmp/sniproxy.pid listen 204.xxx.xxx.2:80 { proto http source 204.xxx.xxx.2 access_log { filename /tmp/sniproxy_access.log }
} listen 204.xxx.xxx.2:443 { proto tls source 204.xxx.xxx.2 access_log { filename /tmp/sniproxy_access.log }
}
listen 104.xxx.xxx.3:80 { proto http source 104.xxx.xxx.3 access_log { filename /tmp/sniproxy_access.log }
} listen 104.xxx.xxx.3:443 { proto tls source 104.xxx.xxx.3 access_log { filename /tmp/sniproxy_access.log } }
table { .. *
}
I have also enabled this sysctl function: net.ipv4.ip_nonlocal_bind = 1 as noted by users of HAProxy that had the same issue of HAProxy not binding. I thought it may work as a resolution for sniproxy but has not.
Any ideas?
UPDATE: I have figured out a way to make my above configuration work with the addition of other linux ip routing techniques. However I had thought that other users in previous posts stated they got it working with just mostly the sniproxy configurations. Please let us know if there is a certain procedural guide as to how you would recommend utilizing the bind source features.
Hi Dustin,
Great project, I've been following it for quite some time.
I was wondering if it would be possible to add an option to have incoming client requests serviced out using the same interface/address when going to the specified backend server in the table.
As an example, my server has 5 IP addresses and sniproxy listens on all of them and happily processes the client requests regardless of IP used. The problem is that the outgoing connections to the backend servers in the table (or the specified host when using *) is done through the default interface because of the routing rules on the machine. Would it be possible to have an option in sniproxy to have requests to the servers be done on the same interface they came in? I understand that this might be possible to do with some iproute2 commands but it would be much nicer if I could specify it as an option.
If this is already possible, I must have missed it. Thanks in advance.