semigodking / redsocks

transparent redirector of any TCP/UDP connection to proxy
Apache License 2.0
1.16k stars 246 forks source link

FreeBSD 12.2 build issues #156

Closed v20z closed 3 years ago

v20z commented 3 years ago

Hello dear Semigodking.

Please take a look. Latest GIT repo cause failure building on FreeBSD 12.2:

base.c:149:34: error: no member named 'sin_port' in 'struct sockaddr_storage'
        natLookup.nl_inport = bindaddr->sin_port;
                              ~~~~~~~~  ^
base.c:150:33: error: no member named 'sin_port' in 'struct sockaddr_storage'
        natLookup.nl_outport = client->sin_port;
                               ~~~~~~  ^
base.c:151:32: error: no member named 'sin_addr' in 'struct sockaddr_storage'
        natLookup.nl_inip = bindaddr->sin_addr;
                            ~~~~~~~~  ^
base.c:152:31: error: no member named 'sin_addr' in 'struct sockaddr_storage'
        natLookup.nl_outip = client->sin_addr;
                             ~~~~~~  ^
base.c:176:13: error: no member named 'sin_family' in 'struct sockaddr_storage'; did you mean 'ss_family'?
                destaddr->sin_family = AF_INET;
                          ^~~~~~~~~~
                          ss_family
/usr/include/sys/_sockaddr_storage.h:50:14: note: 'ss_family' declared here
        sa_family_t     ss_family;      /* address family */
                        ^
base.c:177:13: error: no member named 'sin_port' in 'struct sockaddr_storage'
                destaddr->sin_port = natLookup.nl_realport;
                ~~~~~~~~  ^
base.c:178:13: error: no member named 'sin_addr' in 'struct sockaddr_storage'
                destaddr->sin_addr = natLookup.nl_realip;
                ~~~~~~~~  ^
base.c:201:11: error: no member named 'v4addr' in 'struct pf_addr'
        nl.saddr.v4addr.s_addr = client->sin_addr.s_addr;
        ~~~~~~~~ ^
base.c:203:11: error: no member named 'v4addr' in 'struct pf_addr'
        nl.daddr.v4addr.s_addr = bindaddr->sin_addr.s_addr;
        ~~~~~~~~ ^
base.c:222:33: error: no member named 'v4addr' in 'struct pf_addr'
        destaddr->sin_addr = nl.rdaddr.v4addr;
                             ~~~~~~~~~ ^
# uname -mrsv
FreeBSD 12.2-STABLE FreeBSD 12.2-STABLE GENERIC  amd64

Thank You.

semigodking commented 3 years ago

Here is the problem when compiling for FreeBSD: struct natLookup is for IPv4. bindaddr is defined as struct sockaddr_storage. To solve this problem, you need to statically cast bindaddr to struct sockaddr_in. Like:

natLookup.nl_inport = ((struct sockaddr_in *)bindaddr)->sin_port;

By changes like above, at least, you should be able to compile redsocks2 and make it work for IPv4 in FreeBSD.

v20z commented 3 years ago

Hello and thanks for rerply.

So I've pathed base.c file ike this:

--- base.c.bak  2020-07-05 14:40:16.000000000 +0500
+++ base.c  2020-10-26 17:56:13.239275000 +0500
@@ -146,10 +146,10 @@
    obj.ipfo_offset = 0;
 #endif

-   natLookup.nl_inport = bindaddr->sin_port;
-   natLookup.nl_outport = client->sin_port;
-   natLookup.nl_inip = bindaddr->sin_addr;
-   natLookup.nl_outip = client->sin_addr;
+   natLookup.nl_inport = ((struct sockaddr_in *)bindaddr)->sin_port;
+   natLookup.nl_outport = ((struct sockaddr_in *)client)->sin_port;
+   natLookup.nl_inip = ((struct sockaddr_in *)bindaddr)->sin_addr;
+   natLookup.nl_outip = ((struct sockaddr_in *)client)->sin_addr;
    natLookup.nl_flags = IPN_TCP;
 #if defined(IPFILTER_VERSION) && (IPFILTER_VERSION >= 4000027)
    x = ioctl(natfd, SIOCGNATL, &obj);
@@ -173,9 +173,9 @@
            log_errno(LOG_WARNING, "ioctl(SIOCGNATL)\n");
        return -1;
    } else {
-       destaddr->sin_family = AF_INET;
-       destaddr->sin_port = natLookup.nl_realport;
-       destaddr->sin_addr = natLookup.nl_realip;
+       ((struct sockaddr_in *)destaddr)->sin_family = AF_INET;
+       ((struct sockaddr_in *)destaddr)->sin_port = natLookup.nl_realport;
+       ((struct sockaddr_in *)destaddr)->sin_addr = natLookup.nl_realip;
        return 0;
    }
 }
@@ -198,9 +198,9 @@
    char clientaddr_str[INET6_ADDRSTRLEN], bindaddr_str[INET6_ADDRSTRLEN];

    memset(&nl, 0, sizeof(struct pfioc_natlook));
-   nl.saddr.v4addr.s_addr = client->sin_addr.s_addr;
+   nl.saddr.v4.s_addr = client->sin_addr.s_addr;
    nl.sport = client->sin_port;
-   nl.daddr.v4addr.s_addr = bindaddr->sin_addr.s_addr;
+   nl.daddr.v4.s_addr = bindaddr->sin_addr.s_addr;
    nl.dport = bindaddr->sin_port;
    nl.af = AF_INET;
    nl.proto = IPPROTO_TCP;
@@ -217,9 +217,9 @@
            goto fail;
        }
    }
-   destaddr->sin_family = AF_INET;
+   ((struct sockaddr_in *)destaddr)->sin_family = AF_INET;
    destaddr->sin_port = nl.rdport;
-   destaddr->sin_addr = nl.rdaddr.v4addr;
+   destaddr->sin_addr = nl.rdaddr.v4;
    return 0;

 fail:

And then it compiles but tsarting with simpliest config:

base {
    daemon = off;
    log_info = on;
    log_debug = on;
    log = stderr;
    redirector = generic;
}

redsocks {
    bind = "127.0.0.1:1080";
    relay = "127.0.0.1:11080";
    type = socks5;
    timeout = 10;
    autoproxy = 0;
}

Fails with message

err redsocks.c:1011 redsocks_init_instance(...) bind: Invalid argument
chromer030 commented 3 years ago

@semigodking same here , after compiling with modified base.c , it doesn't work redsocks_init_instance(...) bind: Invalid argument

semigodking commented 3 years ago

For quite a long time, i have been not using FreeBSD. I will try it out when i have time.

semigodking commented 3 years ago

I create a temporary fix. Could anyone try it out and report back? It is in freebsd branch. See commit 57296470b1c864c0c58e6170f2609f34c77d6323. If it does not work, try to config redsocks2 to use 'generic' as "redirector".

v20z commented 3 years ago

Hello Gentlemen.

Dear semigodking thanks for your attention.

Yes, I've downloaded freebsd branch and it now builds smoothly without patches and other fixes as it comes.

But when trying to start the result is the same, compiled executable exits immediately with the same message:

1606062984.453030 err redsocks.c:1011 redsocks_init_instance(...) bind: Invalid argument

The config still like mentioned earlier and redirector = generic;

semigodking commented 3 years ago

now it can start, but again,i do not know if it work.

v20z commented 3 years ago

Yes, it works now with specified config for 1-2 days.

Please commit those changes to the main branch or merge branches later so that we can download directly from the main.

Thanks for your attention.

semigodking commented 3 years ago

Great. I will merge those changes later. I appreciate if you could help me to update README for instructions to configure PF on FreeBSD for transparent proxy. Thank you.

v20z commented 3 years ago

I've used original redsocks on Mac in the past (before they retired ipfw in favor of pf) while visiting China to bypass GFW. Later I've switched to your version because you keep developing and additional features like autoproxy. Now I'm using it from time to time as a ready-made well configured solution. Then I usually redirect to stunnel to disguise requests to socks (name/password authorizing) server as plane https traffic.

I will also note that I'm building redsocks2 against LibreSSL because it is not compiling with OpenSSL 1.1 (maybe someday you will add support).

Configuration is trivial:

base {
    daemon = on;
    log_info = off;
    log_debug = off;
    user = redsocks;
    group = redsocks;
    redirector = generic;
}

redsocks {
    bind = "127.0.0.1:1080";
    relay = "127.0.0.1:11080";
    type = socks5;
    timeout = 10;
    autoproxy = 1;
}

IPFW rule:

ipfw add fwd 127.0.0.1,1080 tcp from any to any not uid redsocks out via ext0

Where ext0 is outgoing inteface. Username/uid is used to distinguish already redirected traffic. 1080 is listen port and 11080 is stunnel port (which wraps into https and unwraps back).

stunnel local side:

[forward-socks-server]
client = yes
sni = socks-server
accept = localhost:11080
connect =  IP.ADD.RE.SS:https

stunnel server side:

[TLS]
client = no
transparent = none
accept = IP.ADD.RE.SS:https
connect = localhost:http
...
[socks-server]
client = no
transparent = none
sni = TLS:socks-server
connect = localhost:socks

socks server (remote, dante with pam auth by name/pass):

debug: 0
errorlog: /var/opt/dante/sockd.err
logoutput: /var/opt/dante/sockd.log

internal: localhost port=1080
external: IP.ADD.RE.SS

user.privileged: root
user.notprivileged: nobody

clientmethod: none
socksmethod: pam.username

client pass {
    from: 0/0 to: 0/0
    log: error
}
socks pass {  
        from: 0/0 to: 0/0
    log: connect disconnect error
}
v20z commented 3 years ago

Thank you for your continued development and support.