Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

external-check: Unable to check UNIX socket servers #101

Open
linuxdaemon opened this issue May 18, 2019 · 2 comments
Open

external-check: Unable to check UNIX socket servers #101

linuxdaemon opened this issue May 18, 2019 · 2 comments

Comments

@linuxdaemon
Copy link

@linuxdaemon linuxdaemon commented May 18, 2019

Output of haproxy -vv and uname -a

HA-Proxy version 1.6.3 2015/12/25
Copyright 2000-2015 Willy Tarreau <willy@haproxy.org>

Build options :
  TARGET  = linux2628
  CPU     = generic
  CC      = gcc
  CFLAGS  = -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2
  OPTIONS = USE_ZLIB=1 USE_REGPARM=1 USE_OPENSSL=1 USE_LUA=1 USE_PCRE=1

Default settings :
  maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200

Encrypted password support via crypt(3): yes
Built with zlib version : 1.2.8
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with OpenSSL version : OpenSSL 1.0.2g  1 Mar 2016
Running on OpenSSL version : OpenSSL 1.0.2g  1 Mar 2016
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports prefer-server-ciphers : yes
Built with PCRE version : 8.38 2015-11-23
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with Lua version : Lua 5.3.1
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND

Available polling systems :
      epoll : pref=300,  test result OK
       poll : pref=200,  test result OK
     select : pref=150,  test result OK
Total: 3 (3 usable), will use epoll.

Linux linuxdaemon-desktop 4.15.0-48-generic #51~16.04.1-Ubuntu SMP Fri Apr 5 12:01:12 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

What's the configuration?

global
    log /dev/log	local1
    log /dev/log	local1 notice
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user root
    group root
    daemon
    external-check

    # Default SSL material locations
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private
    # Default ciphers to use on SSL-enabled listening sockets.
    # For more information, see ciphers(1SSL). This list is from:
    #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
    ssl-default-bind-options no-sslv3

defaults
    log global
    mode http
    option httplog
    option dontlognull
    timeout connect 5000
    timeout client  50000
    timeout server  50000
    errorfile 400     /etc/haproxy/errors/400.http
    errorfile   403     /etc/haproxy/errors/403.http
    errorfile   408     /etc/haproxy/errors/408.http
    errorfile   500     /etc/haproxy/errors/500.http
    errorfile   502     /etc/haproxy/errors/502.http
    errorfile   503     /etc/haproxy/errors/503.http
    errorfile   504     /etc/haproxy/errors/504.http

frontend fe1
    bind /run/haproxy-fe1.sock
    mode tcp
    default_backend irc

backend irc
    mode tcp
    external-check path "/home/linuxdemon/Development/Snoonet/haproxy-inspircd-check/venv/bin"
    external-check command /home/linuxdemon/Development/Snoonet/haproxy-inspircd-check/check.py
    option external-check
    server irc1 /home/linuxdaemon/Development/C++/inspircd-master/run/haproxy.sock send-proxy-v2 check

Steps to reproduce the behavior

  1. Define a backend with a server using a UNIX socket
  2. Enable an external check script for the above server
  3. Check the script's parameters and environment variables, the UNIX socket path is not available to the script in any way

Actual behavior

The server address and port passed to the external check script are set to "unix" because

addr_to_str(&s->addr, buf, sizeof(buf));
uses

haproxy/src/standard.c

Lines 1276 to 1278 in 844028b

case AF_UNIX:
memcpy(str, "unix", 5);
return addr->ss_family;

Expected behavior

I think the server address parameter to external checks should be set to the unix socket path, to mimic the proxy address behavior

haproxy/src/checks.c

Lines 1722 to 1727 in 844028b

else if (listener->addr.ss_family == AF_UNIX) {
const struct sockaddr_un *un;
un = (struct sockaddr_un *)&listener->addr;
check->argv[1] = strdup(un->sun_path);
check->argv[2] = strdup("NOT_USED");

Do you have any idea what may have caused this?

As noted,

addr_to_str(&s->addr, buf, sizeof(buf));
uses addr_to_str() for all address families while

haproxy/src/checks.c

Lines 1711 to 1734 in 844028b

if (!listener) {
check->argv[1] = strdup("NOT_USED");
check->argv[2] = strdup("NOT_USED");
}
else if (listener->addr.ss_family == AF_INET ||
listener->addr.ss_family == AF_INET6) {
addr_to_str(&listener->addr, buf, sizeof(buf));
check->argv[1] = strdup(buf);
port_to_str(&listener->addr, buf, sizeof(buf));
check->argv[2] = strdup(buf);
}
else if (listener->addr.ss_family == AF_UNIX) {
const struct sockaddr_un *un;
un = (struct sockaddr_un *)&listener->addr;
check->argv[1] = strdup(un->sun_path);
check->argv[2] = strdup("NOT_USED");
}
else {
Alert("Starting [%s:%s] check: unsupported address family.\n", px->id, s->id);
goto err;
}
addr_to_str(&s->addr, buf, sizeof(buf));
uses special logic for unix sockets

Do you have an idea how to solve the issue?

Special casing unix sockets similar to how it is done for proxy addresses should work fine.

@wtarreau
Copy link
Member

@wtarreau wtarreau commented Jun 2, 2019

Feel free to propose a patch for this on the mailing list. Your analysis makes sense and I think the fix sounds reasonable. Possibly that over the long term we should have two sets of address-to-string resolve functions : remote_addr_to_str() (which cannot say more than "unix") and local_addr_to_str() which can actually retrieve more info such as the ones needed for the cases you suggest.

By the way, I'm seeing that your version is outdated and is affected by 252 known bugs. Please make your fix against latest master.

@capflam
Copy link
Member

@capflam capflam commented Aug 7, 2020

I remove 1.6, 1.7 and 1.9 labels. 1.9 is EOL and I doubt the fix will be backported to 1.6 and 1.7 that should now receives only critical fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants