Skip to content

Commit 263324a

Browse files
committed
add vpn-ip-lookups (fix #9)
1 parent 82ac975 commit 263324a

File tree

9 files changed

+52
-1
lines changed

9 files changed

+52
-1
lines changed

src/riskdb/builder/config.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
REPORT_COOLDOWN = 10 # sec
1717
REPORT_DAYS = 30 # sliding window
1818
TOR_EXIT_NODE_LIST = 'https://check.torproject.org/torbulkexitlist'
19+
VPN_URLS = {
20+
'apple': 'https://mask-api.icloud.com/egress-ip-ranges.csv',
21+
'mullvad': 'https://api.mullvad.net/app/v1/relays',
22+
'pia': 'https://raw.githubusercontent.com/Lars-/PIA-servers/refs/heads/master/export.csv',
23+
}
24+
DOWNLOAD_TIMEOUT = 5 # do not wait forever if something changed (p.e. firewall blocks download)
1925

2026
PTR_LOOKUP_THREADS = 50
2127
PTR_CACHE_DAYS = 30

src/riskdb/builder/enrich_data.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212
from oxl_utils.ps import wait_for_threads
1313
from dns.resolver import Resolver, NoAnswer, NXDOMAIN, LifetimeTimeout, NoNameservers
1414
from dns.exception import SyntaxError as DNSSyntaxError
15+
from netaddr.ip import IPNetwork, cidr_merge
16+
from netaddr.core import AddrFormatError, AddrConversionError
1517

1618
from riskdb.builder.util import log
1719
from riskdb.config import KIND_FILES
1820
from riskdb.builder.load_reports import FileLoader
1921
from riskdb.builder.config import CACHE_FILE_PTR, ASN_JSON_FILE, TOR_EXIT_NODE_LIST, PTR_LOOKUP_THREADS, \
20-
PTR_CACHE_DAYS, PTR_STATUS_COUNT, PTR_NAMESERVERS, PTR_MAX_QUERY_RETRIES
22+
PTR_CACHE_DAYS, PTR_STATUS_COUNT, PTR_NAMESERVERS, PTR_MAX_QUERY_RETRIES, VPN_URLS, DOWNLOAD_TIMEOUT
2123

2224
now = int(time())
2325
ptr_cache_lock = Lock()
@@ -35,6 +37,35 @@ def load_lookup_list_asn() -> dict:
3537
return json_loads(f.read())
3638

3739

40+
def load_vpn_ips() -> list[IPNetwork]:
41+
vpn_file = '/tmp/vpns.txt'
42+
os_shell(
43+
f"wget -q --connect-timeout={DOWNLOAD_TIMEOUT} -O {vpn_file}.tmp {VPN_URLS['apple']} &&"
44+
f"tail -n +2 {vpn_file}.tmp | cut -d ',' -f1 | sort | uniq > {vpn_file}"
45+
)
46+
os_shell(
47+
f"wget -q --connect-timeout={DOWNLOAD_TIMEOUT} -O {vpn_file}.tmp {VPN_URLS['mullvad']} &&"
48+
f"jq -r '.[][] | try .[] | try .ipv4_addr_in' < {vpn_file}.tmp | sort | uniq >> {vpn_file} &&"
49+
f"jq -r '.[][] | try .[] | try .ipv6_addr_in' < {vpn_file}.tmp | sort | uniq >> {vpn_file}"
50+
)
51+
os_shell(
52+
f"wget -q --connect-timeout={DOWNLOAD_TIMEOUT} -O {vpn_file}.tmp {VPN_URLS['pia']} &&"
53+
f"tail -n +2 {vpn_file}.tmp | cut -d ',' -f1 | sort | uniq >> {vpn_file}"
54+
)
55+
56+
# NOTE: using netaddr to allow for subnet-merging where possible
57+
nets = []
58+
with open(vpn_file, 'r', encoding='utf-8') as f:
59+
for net in f.readlines():
60+
try:
61+
nets.append(IPNetwork(net.strip()))
62+
63+
except (AddrFormatError, AddrConversionError, ValueError):
64+
continue
65+
66+
return cidr_merge(nets)
67+
68+
3869
def load_lookup_lists() -> dict:
3970
lookup_lists = {}
4071
tor_exit_node_file = '/tmp/tor_exit_nodes.txt'
@@ -51,6 +82,7 @@ def load_lookup_lists() -> dict:
5182
except AddressValueError:
5283
continue
5384

85+
lookup_lists['vpns'] = load_vpn_ips()
5486
lookup_lists['asn'] = load_lookup_list_asn()
5587

5688
# creation of these files has yet to be automated

src/riskdb/builder/kind/crawler.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# for dynamic/full lists refer to: https://github.com/O-X-L/risk-db-lists/tree/main/asn
12
17858
23
18403
34
32934
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# for dynamic/full lists refer to: https://github.com/O-X-L/risk-db-lists/tree/main/asn
12
29484
23
680
34
137

src/riskdb/builder/kind/hosting.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# for dynamic/full lists refer to: https://github.com/O-X-L/risk-db-lists/tree/main/asn
12
559
23
834
34
917

src/riskdb/builder/kind/isp.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# for dynamic/full lists refer to: https://github.com/O-X-L/risk-db-lists/tree/main/asn
12
209
23
701
34
852

src/riskdb/builder/kind/scanner.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# for dynamic/full lists refer to: https://github.com/O-X-L/risk-db-lists/tree/main/asn
12
174
23
6939
34
10439

src/riskdb/builder/kind/vpn.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# for dynamic/full lists refer to: https://github.com/O-X-L/risk-db-lists/tree/main/asn
12
62371
23
141039
34
147049

src/riskdb/builder/obj/ip.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from netaddr import IPAddress as NetaddrIPAddress
2+
13
from riskdb.config import RISK_CATEGORIES
24

35
from riskdb.builder.obj.asn import ASN
@@ -84,6 +86,11 @@ def _init_kind(self, lookup_lists: dict) -> list[str]:
8486
if self.ip in lookup_lists['tor']:
8587
k.append('tor')
8688

89+
ip_obj = NetaddrIPAddress(self.ip)
90+
for net in lookup_lists['vpns']:
91+
if ip_obj in net:
92+
k.append('vpn')
93+
8794
if self.ptr is None:
8895
return k
8996

0 commit comments

Comments
 (0)