I tried to use similar LD_PRELOAD solutions but I always ended up finding some programs that don't go through libc, so they bypassed the VPN.
badvpn-tun2socks works with everything I wanted, but it's not as easy to control the processes that go through the VPN. It should be possible with network namespaces or tagging packets with cgroups but it's a pain to get it all set up.