2 # Copyright (c) 2013-2017 The Bitcoin Core developers
3 # Distributed under the MIT software license, see the accompanying
4 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 # Generate seeds.txt from Pieter's DNS seeder
15 # These are hosts that have been observed to be behaving strangely (e.g.
16 # aggressively connecting to every node).
18 "130.211.129.106", "178.63.107.226",
19 "83.81.130.26", "88.198.17.7", "148.251.238.178", "176.9.46.6",
20 "54.173.72.127", "54.174.10.182", "54.183.64.54", "54.194.231.211",
21 "54.66.214.167", "54.66.220.137", "54.67.33.14", "54.77.251.214",
22 "54.94.195.96", "54.94.200.247"
30 PATTERN_IPV4
= re
.compile(r
"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):(\d+)$")
31 PATTERN_IPV6
= re
.compile(r
"^\[([0-9a-z:]+)\]:(\d+)$")
32 PATTERN_ONION
= re
.compile(r
"^([abcdefghijklmnopqrstuvwxyz234567]{16}\.onion):(\d+)$")
33 PATTERN_AGENT
= re
.compile(r
"^(/Satoshi:0.12.(0|1|99)/|/Satoshi:0.13.(0|1|2|99)/)$")
39 m
= PATTERN_IPV4
.match(sline
[0])
43 m
= PATTERN_IPV6
.match(sline
[0])
45 m
= PATTERN_ONION
.match(sline
[0])
50 ipstr
= sortkey
= m
.group(1)
51 port
= int(m
.group(2))
54 if m
.group(1) in ['::']: # Not interested in localhost
57 sortkey
= ipstr
# XXX parse IPv6 into number, could use name_to_ipv6 from generate-seeds
58 port
= int(m
.group(2))
60 # Do IPv4 sanity check
63 if int(m
.group(i
+2)) < 0 or int(m
.group(i
+2)) > 255:
65 ip
= ip
+ (int(m
.group(i
+2)) << (8*(3-i
)))
71 port
= int(m
.group(6))
76 uptime30
= float(sline
[7][:-1])
77 # Extract Unix timestamp of last success.
78 lastsuccess
= int(sline
[2])
79 # Extract protocol version.
80 version
= int(sline
[10])
82 agent
= sline
[11][1:-1]
83 # Extract service flags.
84 service
= int(sline
[9], 16)
86 blocks
= int(sline
[8])
94 'lastsuccess': lastsuccess
,
102 def filtermultiport(ips
):
103 '''Filter out hosts with more nodes per IP'''
104 hist
= collections
.defaultdict(list)
106 hist
[ip
['sortkey']].append(ip
)
107 return [value
[0] for (key
,value
) in list(hist
.items()) if len(value
)==1]
109 # Based on Greg Maxwell's seed_filter.py
110 def filterbyasn(ips
, max_per_asn
, max_total
):
111 # Sift out ips by type
112 ips_ipv4
= [ip
for ip
in ips
if ip
['net'] == 'ipv4']
113 ips_ipv6
= [ip
for ip
in ips
if ip
['net'] == 'ipv6']
114 ips_onion
= [ip
for ip
in ips
if ip
['net'] == 'onion']
120 if len(result
) == max_total
:
123 asn
= int([x
.to_text() for x
in dns
.resolver
.query('.'.join(reversed(ip
['ip'].split('.'))) + '.origin.asn.cymru.com', 'TXT').response
.answer
][0].split('\"')[1].split(' ')[0])
124 if asn
not in asn_count
:
126 if asn_count
[asn
] == max_per_asn
:
131 sys
.stderr
.write('ERR: Could not resolve ASN for "' + ip
['ip'] + '"\n')
133 # TODO: filter IPv6 by ASN
136 result
.extend(ips_ipv6
)
137 result
.extend(ips_onion
)
141 lines
= sys
.stdin
.readlines()
142 ips
= [parseline(line
) for line
in lines
]
144 # Skip entries with valid address.
145 ips
= [ip
for ip
in ips
if ip
is not None]
146 # Skip entries from suspicious hosts.
147 ips
= [ip
for ip
in ips
if ip
['ip'] not in SUSPICIOUS_HOSTS
]
148 # Enforce minimal number of blocks.
149 ips
= [ip
for ip
in ips
if ip
['blocks'] >= MIN_BLOCKS
]
150 # Require service bit 1.
151 ips
= [ip
for ip
in ips
if (ip
['service'] & 1) == 1]
152 # Require at least 50% 30-day uptime.
153 ips
= [ip
for ip
in ips
if ip
['uptime'] > 50]
154 # Require a known and recent user agent.
155 ips
= [ip
for ip
in ips
if PATTERN_AGENT
.match(ip
['agent'])]
156 # Sort by availability (and use last success as tie breaker)
157 ips
.sort(key
=lambda x
: (x
['uptime'], x
['lastsuccess'], x
['ip']), reverse
=True)
158 # Filter out hosts with multiple bitcoin ports, these are likely abusive
159 ips
= filtermultiport(ips
)
160 # Look up ASNs and limit results, both per ASN and globally.
161 ips
= filterbyasn(ips
, MAX_SEEDS_PER_ASN
, NSEEDS
)
162 # Sort the results by IP address (for deterministic output).
163 ips
.sort(key
=lambda x
: (x
['net'], x
['sortkey']))
166 if ip
['net'] == 'ipv6':
167 print('[%s]:%i' % (ip
['ip'], ip
['port']))
169 print('%s:%i' % (ip
['ip'], ip
['port']))
171 if __name__
== '__main__':