wknapik / vpnfailsafe

IP leak prevention for OpenVPN
MIT License
150 stars 18 forks source link

Not working on musl #32

Open travankor opened 6 years ago

travankor commented 6 years ago

First of all, thank you first for this script. I've been using it successfully on Void Linux with glibc for several months now.

However, when I try to use vpnfailsafe on Void Linux musl libc, openvpn will not connect. I double checked the provided AUR PKGBUILD to make sure that all dependencies are installed.

The separate project update-resolv-conf.sh works fine though. Any idea what this problem could be? The openvpn output seems to be almost the same on glibc and musl, but I can upload some logs later if that helps.

travankor commented 6 years ago

Here is the output if it is of any help. Anything inside ${} is what I edited out.

Attempting to connect with vpnfailsafe:

${timestamp} OpenVPN 2.4.6 x86_64-unknown-linux-musl [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Jun 17 2018
${timestamp} library versions: LibreSSL 2.7.4, LZO 2.10
${timestamp} WARNING: --ping should normally be used with --ping-restart or --ping-exit
${timestamp} NOTE: the current --script-security setting may allow this configuration to call user-defined scripts
${timestamp} Outgoing Control Channel Authentication: Using 512 bit message hash 'SHA512' for HMAC authentication
${timestamp} Incoming Control Channel Authentication: Using 512 bit message hash 'SHA512' for HMAC authentication
${timestamp} RESOLVE: Cannot resolve host address: ${vpn}:1194 (Try again)
${timestamp} Socket Buffers: R=[212992->212992] S=[212992->212992]
${timestamp} UDP link local: (not bound)
${timestamp} UDP link remote: [AF_INET]${IP}:1194
${timestamp} TLS: Initial packet from [AF_INET]${IP}:1194, sid=${sid}
${timestamp} WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
${timestamp} VERIFY OK: depth=2, C=${country code}, O=${vpn}, CN=${vpn} Root CA
${timestamp} VERIFY OK: depth=1, C=${country code}, O=${vpn}, CN=${vpn} Intermediate CA 1
${timestamp} VERIFY KU OK
${timestamp} Validating certificate extended key usage
${timestamp} ++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication
${timestamp} VERIFY EKU OK
${timestamp} VERIFY OK: depth=0, CN=${vpn}
${timestamp} Control Channel: TLSv1.2, cipher TLSv1/SSLv3 ECDHE-RSA-AES256-GCM-SHA384, 2048 bit RSA
${timestamp} [${vpn}] Peer Connection Initiated with [AF_INET]${IP}:1194
${timestamp} SENT CONTROL [${vpn}]: 'PUSH_REQUEST' (status=1)
${timestamp} AUTH: Received control message: AUTH_FAILED
${timestamp} SIGTERM[soft,auth-failure] received, process exiting

Connecting with update resolv conf:

${timestamp} OpenVPN 2.4.6 x86_64-unknown-linux-musl [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Jun 17 2018
${timestamp} library versions: LibreSSL 2.7.4, LZO 2.10
${timestamp} WARNING: --ping should normally be used with --ping-restart or --ping-exit
${timestamp} NOTE: the current --script-security setting may allow this configuration to call user-defined scripts
${timestamp} Outgoing Control Channel Authentication: Using 512 bit message hash 'SHA512' for HMAC authentication
${timestamp} Incoming Control Channel Authentication: Using 512 bit message hash 'SHA512' for HMAC authentication
${timestamp} TCP/UDP: Preserving recently used remote address: [AF_INET]${IP}:1194
${timestamp} Socket Buffers: R=[212992->212992] S=[212992->212992]
${timestamp} UDP link local: (not bound)
${timestamp} UDP link remote: [AF_INET]${IP}:1194
${timestamp} TLS: Initial packet from [AF_INET]${IP}, sid=${sid}
${timestamp} WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
${timestamp} VERIFY OK: depth=2, C=${country code}, O=${vpn}, CN=${vpn} Root CA
${timestamp} VERIFY OK: depth=1, C=${country code}, O=${vpn}, CN=${vpn} Intermediate CA 1
${timestamp} VERIFY KU OK
${timestamp} Validating certificate extended key usage
${timestamp} ++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication
${timestamp} VERIFY EKU OK
${timestamp} VERIFY OK: depth=0, CN=${vpn}

When I tried vpnfailsafe again, I got a slightly different output:

${first few lines exactly the same as above}
${timestamp} TLS: Initial packet from [AF_INET]${IP}:1194, sid=${sid}
${timestamp} WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
${timestamp} VERIFY OK: depth=2, C=${country code}, O=${vpn}, CN=${vpn} Root CA
${timestamp} VERIFY OK: depth=1, C=${country code}, O=${vpn}, CN=${vpn} Intermediate CA 1
${timestamp} VERIFY KU OK
${timestamp} Validating certificate extended key usage
${timestamp} ++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication
${timestamp} VERIFY EKU OK
${timestamp} VERIFY OK: depth=0, CN=${vpn}
${timestamp} Control Channel: TLSv1.2, cipher TLSv1/SSLv3 ECDHE-RSA-AES256-GCM-SHA384, 2048 bit RSA
${timestamp} [${vpn}] Peer Connection Initiated with [AF_INET]${IP}:1194
${timestamp} SENT CONTROL [${vpn}]: 'PUSH_REQUEST' (status=1)
${timestamp} PUSH: Received control message: 'PUSH_REPLY,redirect-gateway def1,dhcp-option DNS 10.8.8.1,sndbuf 524288,rcvbuf 524288,explicit-exit-notify,comp-lzo no,route-gateway 10.8.8.1,topology subnet,ping 10,ping-restart 60,ifconfig 10.8.8.14 255.255.255.0,peer-id 10,cipher AES-256-GCM'
${timestamp} OPTIONS IMPORT: timers and/or timeouts modified
${timestamp} OPTIONS IMPORT: explicit notify parm(s) modified
${timestamp} OPTIONS IMPORT: compression parms modified
${timestamp} OPTIONS IMPORT: --sndbuf/--rcvbuf options modified
${timestamp} Socket Buffers: R=[212992->425984] S=[212992->425984]
${timestamp} OPTIONS IMPORT: --ifconfig/up options modified
${timestamp} OPTIONS IMPORT: route options modified
${timestamp} OPTIONS IMPORT: route-related options modified
${timestamp} OPTIONS IMPORT: --ip-win32 and/or --dhcp-option options modified
${timestamp} OPTIONS IMPORT: peer-id set
${timestamp} OPTIONS IMPORT: adjusting link_mtu to 1657
${timestamp} OPTIONS IMPORT: data channel crypto options modified
${timestamp} Data Channel: using negotiated cipher 'AES-256-GCM'
${timestamp} Outgoing Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key
${timestamp} Incoming Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key
${timestamp} ROUTE_GATEWAY 192.168.29.1/255.255.255.0 IFACE=wlp3s0 HWADDR=${mac id?}
${timestamp} TUN/TAP device tun1 opened
${timestamp} TUN/TAP TX queue length set to 100
${timestamp} do_ifconfig, tt->did_ifconfig_ipv6_setup=0
${timestamp} /usr/bin/ip link set dev tun1 up mtu 1500
${timestamp} /usr/bin/ip addr add dev tun1 10.8.8.14/24 broadcast 10.8.8.255
${timestamp} /etc/openvpn/vpnfailsafe.sh tun1 1500 1585 10.8.8.14 255.255.255.0 init
getent: Unknown database `-s': No error information
Usage: getent database [key ...]
        database may be one of:
                ethers group hosts networks passwd protocols services
                shells
getent: Unknown database `-s': No error information
Usage: getent database [key ...]
        database may be one of:
                ethers group hosts networks passwd protocols services
                shells
${timestamp} /usr/bin/ip route add ${IP}/32 via 192.168.29.1
RTNETLINK answers: File exists
${timestamp} ERROR: Linux route add command failed: external program exited with error status: 2
${timestamp} /usr/bin/ip route add 0.0.0.0/1 via 10.8.8.1
RTNETLINK answers: File exists
${timestamp}ERROR: Linux route add command failed: external program exited with error status: 2
${timestamp} /usr/bin/ip route add ${static IP?}/1 via 10.8.8.1
RTNETLINK answers: File exists
${timestamp} ERROR: Linux route add command failed: external program exited with error status: 2
${timestamp} Initialization Sequence Completed
${timestamp} write UDP: Operation not permitted (code=1)
${forcefully kill process}

Is the problem related to glibc's getent?

wknapik commented 6 years ago

Hi @travankor,

Is the problem related to glibc's getent?

Indeed. The glibc variant supports the -s option, while the musl variant does not.

I opened issues against Void and Alpine to see if it can be fixed at the source.

Let's wait for feedback from @fabled, who's the current maintainer of getent.c.

PS. The first log you pasted - that's unrelated to vpnfailsafe, you got AUTH_FAILED before any --up script had a chance to run.

fabled commented 6 years ago

getent is not really specified by POSIX. It is mostly glibc invention, but also supported by some BSDs and other Unixes. The -s option seems to be implemented only in glibc. So usage of it works only with glibc. We ship getent in Alpine mainly to allow building of certain software projects and it is not part of musl. Even if we at Alpine would support this, it might not be present in any other musl based distribution, or any other Unix. It would be recommendable to use something more portable in this use case.

wknapik commented 6 years ago

Hey @fabled! Thanks for your response.

Given the lack of specification, I think following glibc makes the most sense. I've only seen two implementations on Linux so far - the glibc one and the one you're maintaining, so if you added support for -s, I'd be covered, since vpnfailsafe only runs on Linux anyway.

It seems like it would be simple to implement, but I'm not much of a C coder, so I can't contribute a patch...

What do you think ?

PS. This is unrelated, but I'd suggest setting up a dedicated repo for getent. Everyone seems to just copy getent.c to distro repos - would be good to have one authoritative upstream, to keep up-to-date with any updates you make.

travankor commented 6 years ago

I don't know why musl can't bundle getent along with some extras under some sort of auxiliary repository. Maybe a good question for the mailing list, but since I'm a newbie I would rather not ask.

The current getent from NetBSD (used on Alpine/Void) is ~500 sloc, compared to ~1000 sloc for glibc's getent, so there isn't a lot of extra bloat.

However, if the current getent is considered feature complete, bind-utils is a relatively heavy dependency to add. Hopefully, something more lightweight and secure can be used instead (like drill).