Dante's Socks-server or as one letter can "eat" a couple of days

    Whenever I encounter such a “working moment”, I wonder whether it is necessary to give his decision to the world or if it is petty for others, but this time I decided to post it. This article is more from the category of notes on cuffs and was written only because of the scarcity of information about setting up Dante on the net and limping on both legs of the official documentation.
    On Friday morning, the customer requested to raise the socks server for ~ 100 users, with authorization by login / password, IP binding and sending requests from the same IP to which the user is connecting. At the same time, the customer inquired about the timing of the work and, although I do not like to make forecasts on the installation / setup time, I assured him that in 3-4 hours the alpha version will be ready. Well, the truth is, by google selecting the appropriate socks server, installing, reading mana, tweaking the default config for yourself ... it should invest in 4 hours.
    OS FreeBSD 9.2, but everything described below is true for 10-ki.

    Oddly enough, there were only two matching socks-server requests: 3proxy 0.6.1 and Dante(in ports 1.3.2). Maybe, of course, I missed something, but either there is no authorization, or there is no int_ip -> ext_ip mode. Perhaps squid corresponds to these requests, but I did not want to put this monster for the sake of a simple task.
    I have nothing against 3proxy, I have been working with it for several years in portmapping mode, there are no special complaints, but it has been developing since 2009, the code is dirty and I heard repeated reviews about its voracity under heavy load.
    So, Dante.
    Prior to version 1.3, support for int_ip -> ext_ip Dante did not have, or rather there is a similar implementation in the paid version at a very undemocratic price of EUR400, however, Lysenko Konstantin added this functionality as a “same-same” patch in Dante 1.2.2 and it was included into release 1.3.0.
    I can’t pretend to say whether this construction worked in 1.3.0, but in 1.3.2 the requests persistently leave the first external-ip found in the config. Having shoveled a lean man, I turned to the developer page. There is a bit more information there, but to launch the same-same as I needed failed. However, since November 2013, the site has version 1.4, which for some reason is not included in the ports. Download, collect.
    It should be noted that the config in 1.4 has undergone cosmetic changes, although in the mans there are still examples with parameters of previous versions, which Dante swears as deprecated and, sometimes, prompts the correct new parameters.

    Test config:
    # cat /usr/local/etc/sockd.conf
    logoutput: /var/log/socks/socks.log
    debug: 0
    internal:          port = 1080
    internal:          port = 1080
    internal:          port = 1080
    external.rotation: same-same
    socksmethod: username
    user.privileged: root
    user.unprivileged: nobody
    user.libwrap: nobody
    compatibility: sameport
    client pass {
            from: port 1-65535 to:
    client block {
            from: to:
            log: connect error
    client block {
            from: to:
            log: connect error
    socks pass {
            from: to:
            log: connect error
            user: chaturanga
    socks block {
            from: to:
            log: connect error

    And ... contrary to expectations in 1.4, the same-same also did not work. This time, unlike 1.3, errors like

    warning: getoutaddr(): using external.rotation = same-same, local address was selected for forwarding from our local client to target, but that local address is not set on our external interface(s).  Configuration error in /usr/local/etc/sockd.conf?

    , where is the address of my local machine while here should be the internal-IP of the server to which the client is connecting. Confused by the phrase “Configuration error in /usr/local/etc/sockd.conf?” I’m kicking the config and studying mana, but, since there is not enough information in them, I’m climbing into the best mana - source. Smiling comments in the form of
        * Just return the first address of the appropriate type from our internal
        * list and hope the best.

    I find the source of the problems (./sockd/sockd_request.c, line 4173):
    / *
    * Find address to bind for client. First the ipaddress.
    * /
    if (getoutaddr (& io-> dst.laddr,
    & io-> src.raddr,
    emsglen) == NULL)
    return -1;

    Change & io-> src. r addr on & io-> src. l addr , rebuild, run, and finally see the desired:
    info: pass(1): tcp/connect [: username%chaturanga@ ->

    Quietly swearing, I draw up a bug report to the developers.
    As a result, instead of the stated 3-4 hours in reading, thinking out configs, trying to run Dante not in jail, tests on Centos instead of FreeBSD and digging in the source code I killed a couple of days ... So promise after that ...

    UPD1 : While writing the note, the developer replied:
    Hello, thank you for the bug-report. You are correct, there is an
    error here. Your proposed solution is basically correct, though
    we will probably implement the fix slightly differently.

    UPD2 : And in the course of further correspondence:
    Depending on the current workload, I doubt I will be able to provide
    you with our official patch for at least another month.

    Well, thanks for that.

    UPD3 (2014-09-03) :
    The developer reported that the bug has been fixed (v.1.4.1).
    Checked, everything works as expected.

    Also popular now: