proxychains-ng icon indicating copy to clipboard operation
proxychains-ng copied to clipboard

New requirement: Need all purpose ACL in configuration

Open robot-dot-win opened this issue 1 year ago • 10 comments

I've got this problem: my ISP blocks access to any destinations' port 25, so my SMTP delivery server doesn't work. With the help of proxychains-ng the server can work well via outside proxy servers, but I cannot precisely define that only non-localnet:25 should be proxied. In fact the current configuration's rule is "proxy_all" except the "localnet". For precise control, we need all purpose ACL rules like this: https://github.com/shadowsocks/shadowsocks-rust?tab=readme-ov-file#acl

That is:

  • Modes:
    • [bypass_all] - ACL runs in BlackList mode. Bypasses all addresses that didn't match any rules.
    • [proxy_all] - ACL runs in WhiteList mode. Proxies all addresses that didn't match any rules.
  • Rules:
    • [bypass_list] - Rules for connecting directly
    • [proxy_list] - Rules for connecting through proxies

-- Looking forward eagerly to this new upgrade! Thanks!

robot-dot-win avatar Jun 26 '24 03:06 robot-dot-win

we need all purpose ACL rules like this

you mean you need. the first user in my 13 years of maintaining this program that needs such functionality, and you expect i immediately implement it. i'd suggest you use an iptables rule that simply redirects all outgoing accesses to port 25 to a socks5 proxy you control, which in turn could be proxified to use your proxy in case it isn't socks5 already.

rofl0r avatar Jun 26 '24 08:06 rofl0r

use an iptables rule that simply redirects all outgoing accesses to port 25 to a socks5 proxy you control

Thank you so much for your immediate reply.

The usage conditions are:

  • I have three socks5 proxies in different countries outside the delivery server's ISP.
  • The delivery server's connections to the socks5 proxies are all NOT steady and reliable.
  • Every socks5 proxy might fail to deliver email because of the internet conditions. The failed email will stay in the delivery server's queue, waiting for the next try via another socks5 proxy.

So my proxychains.conf is like:

round_robin_chain
chain_len = 1

quiet_mode

remote_dns_subnet 224

# Some timeouts in milliseconds
tcp_read_time_out 15000
tcp_connect_time_out 8000

## Exclude connections to ANYwhere with port 80, 443
localnet 0.0.0.0:80/0.0.0.0
localnet [::]:80/0
localnet 0.0.0.0:443/0.0.0.0
localnet [::]:443/0

## RFC6890 Loopback address range
localnet 127.0.0.0/255.0.0.0
localnet ::1/128

## RFC1918 Private Address Ranges
localnet 10.0.0.0/255.0.0.0
localnet 172.16.0.0/255.240.0.0
localnet 192.168.0.0/255.255.0.0

[ProxyList]
socks5  x.x.x.x   51080  user1  passwd1
socks5  y.y.y.y   51080  user2  passwd2
socks5  z.z.z.z   51080  user3  passwd3

That's been working fine for year, but I hope to proxy access to only port 25 for the delivery server. I believe 'proxychains-ng` would be more comprehensive with the ACLs.

Thanks again!

robot-dot-win avatar Jun 27 '24 02:06 robot-dot-win

you can use exactly that config with the proxified socks5 server in the iptables-based solution i suggested. proxychains4 -f roundrobin.conf microsocks -i 127.0.0.1

rofl0r avatar Jun 27 '24 10:06 rofl0r

@rofl0r I'm sorry for my unclear description, which might've led to misunderstanding. I'm running an email server("the server"), which should deliver the users' email to dest addresses by accessing the dest servers' port 25. But the server is banned by its ISP from connections to any port 25, so I've had to set up 3 socks5 servers outside the ISP's network for email delivery. Suppose the server is postfix, then I'm running:

$ proxychains -f /etc/proxychains.conf postfix

This has been working fine for years.

I'm not a sophisticated iptables/nftables user, but how to redirect the outgoing connections(dest port 25), and to where or to what process that is listening and will act as the socks5 server's client?

robot-dot-win avatar Jun 28 '24 11:06 robot-dot-win

As my assumption, proxychains-ng's configure might change only a little, like:

### Examples for remotenet that will use a proxy to connect
## remotenet ranges except localnet ranges will use a proxy to connect.
## default(means all connections except localnet ranges will use a proxy):
##        remotenet ::/0
##        remotenet 0.0.0.0/0.0.0.0

## Connections to 31.13.94.36 with port 80 and 443 will use a proxy:
# remotenet 31.13.94.36:80/255.255.255.255
# remotenet 31.13.94.36:443/255.255.255.255

## Connections to anywhere with port 25 will use a proxy:
# remotenet 0.0.0.0:25/0.0.0.0
# remotenet [::]:25/0

And the source code might change like:

if (match localnet) {
    connect directly
} else if(match remotenet) {
   connect via proxy
} else {
   connect directly
}

Thus proxychains-ng will own an ALL PURPOSE ACL functionality.

robot-dot-win avatar Jun 28 '24 11:06 robot-dot-win

there's dozen of results searching for "iptables redirect outgoing port to socks5". the quintessence is that you need a transparent socks5 proxy like redsocks, iptables rules forwarding not all traffic, but only port 25 traffic there, and instruct redsocks to connect to a local socks5 proxy like microsocks which you run via proxychains, as mentioned in my last comment.

rofl0r avatar Jun 29 '24 18:06 rofl0r

there's dozen of results searching for "iptables redirect outgoing port to socks5". the quintessence is that you need a transparent socks5 proxy like redsocks, iptables rules forwarding not all traffic, but only port 25 traffic there, and instruct redsocks to connect to a local socks5 proxy like microsocks which you run via proxychains, as mentioned in my last comment.

I never knew there's something like redsocks/redsocks2/ipt2socks in the world! "In doing I learn." Thanks again!

I followed this, using nftables, ipt2socks and shadowsocks to achieve my requirement: https://unix.stackexchange.com/questions/501623/forward-all-traffic-to-a-socks5-proxy-port

Still I wish proxychains-ng would have this functionality, 'coz there are a lot to learn for an average user. I've created a fork, trying to make a contribution in weeks.

robot-dot-win avatar Jul 02 '24 01:07 robot-dot-win

Still I wish proxychains-ng would have this functionality, 'coz there are a lot to learn for a common user. I've created a fork, trying to make a contribution in weeks.

the main difficulty here is to create a design that's intuitive, covers all bases and is extensible. and lastly it should be possible to implement with a minimum of changes. adding an ad-hoc configuration for a single purpose like "proxify-only-connections-to-portX" is simple, a full general-purpose configuration for all kinds of usecases not so much.

rofl0r avatar Jul 02 '24 07:07 rofl0r

the main difficulty here is to create a design that's intuitive, covers all bases and is extensible. and lastly it should be possible to implement with a minimum of changes. adding an ad-hoc configuration for a single purpose like "proxify-only-connections-to-portX" is simple, a full general-purpose configuration for all kinds of usecases not so much.

Here we go.

robot-dot-win avatar Jul 03 '24 00:07 robot-dot-win

there's dozen of results searching for "iptables redirect outgoing port to socks5". the quintessence is that you need a transparent socks5 proxy like redsocks, iptables rules forwarding not all traffic, but only port 25 traffic there, and instruct redsocks to connect to a local socks5 proxy like microsocks which you run via proxychains, as mentioned in my last comment.

Inspired by the comment, I've found a graceful way to redirect outgoing port 25 to 3 outside proxy servers via nftables and shadowsocks-rust:

  1. Install ssserver on every outside proxy server to provide shadowsocks service:
    "servers": [
        {
            "server": "0.0.0.0",
            "server_port": 51080,
            "method": "aes-256-gcm",
            "password": "ssserver-passwd"
         }
    ]
  1. Install sslocal on the email server to provide transparent proxy LB service:
    "locals": [
        {
            "local_address": "127.0.0.1",
            "local_port": 1081,
            "protocol": "redir",
            "tcp_redir": "redirect"
        }
    ],

    "servers": [
        {
            "address": "<ssserver1-IP>",
            "port": 51080,
            "method": "aes-256-gcm",
            "password": "ssserver-passwd",
            "tcp_weight": 1.0
        },
        {
            "address": "<ssserver2-IP>",
            "port": 51080,
            "method": "aes-256-gcm",
            "password": "ssserver-passwd",
            "tcp_weight": 0.8
        },
        {
            "address": "<ssserver3-IP>",
            "port": 51080,
            "method": "aes-256-gcm",
            "password": "ssserver-passwd",
            "tcp_weight": 0.8
        }
    ]
  1. Set up nftables rules on the email server to redirect outgoing port 25 to the transparent proxy:
    chain nat_output {
        type nat hook output priority dstnat; policy accept;
        oifname {"ens192"} tcp dport {25} redirect to :1081
    }

It's working perfectly! By the way, have to say shadowsocks-rust is so powerful!

robot-dot-win avatar Jul 18 '24 13:07 robot-dot-win