Skip to content

Instantly share code, notes, and snippets.

@3m3x
Last active February 12, 2025 04:44
Show Gist options
  • Save 3m3x/f33b29c956730bab9710e3ac20017c83 to your computer and use it in GitHub Desktop.
Save 3m3x/f33b29c956730bab9710e3ac20017c83 to your computer and use it in GitHub Desktop.
Update proxy list in proxychains config

What?

A thin Python script to update the proxy list in proxychains.conf with output from proxybroker.

Why?

Well, the proxies pulled down by proxybroker are often stale or useless for our purposes.

And updating proxychains.conf with new proxies is a pain in the ass.

Ok

Just run it in the background and never be without usable proxies again (⌐■_■)

# proxychains.conf VER 4
#
# http, SOCKS4, SOCKS5 tunneling proxifier with DNS.
#
# The option below identifies how the ProxyList is treated.
# only one option should be uncommented at time,
# otherwise the last appearing option will be accepted
#dynamic_chain
#
# Dynamic - Each connection will be done via chained proxies
# all proxies chained in the order as they appear in the list
# at least one proxy must be online to play in chain
# (dead proxies are skipped)
# otherwise EINTR is returned to the app
#
#strict_chain
#
# Strict - Each connection will be done via chained proxies
# all proxies chained in the order as they appear in the list
# all proxies must be online to play in chain
# otherwise EINTR is returned to the app
#
random_chain
#
# Random - Each connection will be done via random proxy
# (or proxy chain, see chain_len) from the list.
# this option is good to test your IDS :)
# Make sense only if random_chain
chain_len = 5
# Quiet mode (no output from library)
#quiet_mode
# Proxy DNS requests - no leak for DNS data
#proxy_dns
# set the class A subnet number to usefor use of the internal remote DNS mapping
# we use the reserved 224.x.x.x range by default,
# if the proxified app does a DNS request, we will return an IP from that range.
# on further accesses to this ip we will send the saved DNS name to the proxy.
# in case some control-freak app checks the returned ip, and denies to
# connect, you can use another subnet, e.g. 10.x.x.x or 127.x.x.x.
# of course you should make sure that the proxified app does not need
# *real* access to this subnet.
# i.e. dont use the same subnet then in the localnet section
#remote_dns_subnet 127
#remote_dns_subnet 10
remote_dns_subnet 224
# Some timeouts in milliseconds
tcp_read_time_out 15000
tcp_connect_time_out 8000
# By default enable localnet for loopback address ranges
# RFC5735 Loopback address range
localnet 127.0.0.0/255.0.0.0
# 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
# Example for localnet exclusion
## Exclude connections to 192.168.1.0/24 with port 80
# localnet 192.168.1.0:80/255.255.255.0
## Exclude connections to 192.168.100.0/24
# localnet 192.168.100.0/255.255.255.0
## Exclude connections to ANYwhere with port 80
# localnet 0.0.0.0:80/0.0.0.0
# ProxyList format (values separated by 'tab' or 'blank')
# type host port [user pass]
[ProxyList]
http 118.171.217.46 3128
http 218.60.8.99 3129
http 206.189.45.191 80
#!/usr/bin/env python3
import argparse
import json
import os
import subprocess
import time
from pprint import pprint as pp
NUM_OF_PROXIES_TO_GRAB = 10
REFRESH_RATE = 15
HOME_DIR = os.environ['HOME']
PROXYCHAINS_CONF = f'{HOME_DIR}/.proxychains/proxychains.conf'
def get_proxy_entries(cmd):
proxies = subprocess.run(
cmd.split(),
stdout=subprocess.PIPE,
)
proxies = json.loads(proxies.stdout)
proxy_entries = []
for p in proxies:
proxy_type = p['types'][0]['type'].lower()
host = p['host']
port = p['port']
proxy_entries.append(f'{proxy_type} {host} {port}\n')
return proxy_entries
def update_config(proxy_entries):
# Extract our current config up until the proxies
new_config_lines = []
with open(PROXYCHAINS_CONF, 'r') as fd:
for line in fd.readlines():
new_config_lines.append(line)
if line.strip() == '[ProxyList]':
break
# Append our new proxy entries to the new config
new_config_lines.extend(proxy_entries)
# Write the config back out
with open(PROXYCHAINS_CONF, 'w') as fd:
fd.writelines(new_config_lines)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Get you some new proxies')
parser.add_argument(
'--total',
type=int,
default=NUM_OF_PROXIES_TO_GRAB,
dest='proxies_num',
help='How many proxies to pull down'
)
parser.add_argument(
'--refresh-rate',
type=int,
default=REFRESH_RATE,
dest='refresh_rate',
help='How often to refresh the list (in minutes)'
)
parser.add_argument(
'--types',
type=str,
default='HTTP',
dest='proxy_types',
help='Which types of proxies to scan for (see proxybroker types)'
)
args = parser.parse_args()
PROXYBROKER_CMD = f'proxybroker find --types {args.proxy_types} -l {args.proxies_num} -f json'
while True:
print('Getting proxies.. ', end='', flush=True)
update_config(
get_proxy_entries(PROXYBROKER_CMD)
)
print('done.', flush=True)
if 'refresh_rate' not in args:
break
print(f'Waiting {args.refresh_rate} minutes before refreshing list..\n', flush=True)
time.sleep(args.refresh_rate * 60)
@elie1316
Copy link

not working

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment