openasn 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,589 @@
1
+ {
2
+ "schema_version": 1,
3
+ "_comment": "Tier B source specification, executed CLIENT-SIDE by OpenASN clients (the Ruby gem's update job). These sources have terms that permit fetching from the original authority but NOT third-party redistribution, or they change too fast for a nightly artifact (Tor exits) - so OpenASN publishes the recipe, never the data (the fetch-is-not-redistribute rule; see README Legal design). Clients: send a descriptive User-Agent, honor cadence_hours, keep stale data on failure, and skip source ids or parser ids you don't recognize (forward compatibility).",
4
+ "sources": [
5
+ {
6
+ "id": "apple_private_relay",
7
+ "url": "https://mask-api.icloud.com/egress-ip-ranges.csv",
8
+ "parser": "csv_cidr_first_column",
9
+ "maps_to": "relay",
10
+ "provider": "iCloud Private Relay",
11
+ "cadence_hours": 24,
12
+ "aggregate_cidrs": true,
13
+ "on_failure": "keep_stale",
14
+ "enabled_default": true,
15
+ "notes": "~280k rows; MUST aggregate (merges to a few tens of thousands of ranges). Apple posts this list publicly for recognition and says to treat Private Relay like carrier-grade NAT: recognize, don't block (https://developer.apple.com/icloud/prepare-your-network-for-icloud-private-relay/). Egress IPs live inside Cloudflare/Akamai space - relay MUST outrank hosting in client precedence."
16
+ },
17
+ {
18
+ "id": "tor_exits",
19
+ "url": "https://check.torproject.org/torbulkexitlist",
20
+ "parser": "plain_ip_per_line",
21
+ "maps_to": "tor_exit",
22
+ "provider": "Tor",
23
+ "cadence_hours": 12,
24
+ "on_failure": "keep_stale",
25
+ "enabled_default": true,
26
+ "notes": "Official Tor Project bulk exit list. Do NOT substitute dan.me.uk (bans fetchers for 30 min on over-fetch)."
27
+ },
28
+ {
29
+ "id": "aws",
30
+ "url": "https://ip-ranges.amazonaws.com/ip-ranges.json",
31
+ "parser": "aws_json",
32
+ "maps_to": "hosting",
33
+ "provider": "aws",
34
+ "cadence_hours": 24,
35
+ "on_failure": "keep_stale",
36
+ "enabled_default": true,
37
+ "notes": "Official. Parse prefixes[].ip_prefix and ipv6_prefixes[].ipv6_prefix."
38
+ },
39
+ {
40
+ "id": "gcp",
41
+ "url": "https://www.gstatic.com/ipranges/cloud.json",
42
+ "parser": "gcp_json",
43
+ "maps_to": "hosting",
44
+ "provider": "gcp",
45
+ "cadence_hours": 24,
46
+ "on_failure": "keep_stale",
47
+ "enabled_default": true,
48
+ "notes": "Customer ranges. goog.json (Google-owned infra) is deliberately not fetched: as-metadata already categorizes Google ASNs as hosting."
49
+ },
50
+ {
51
+ "id": "azure",
52
+ "resolver": "azure_download_page",
53
+ "page_url": "https://www.microsoft.com/en-us/download/details.aspx?id=56519",
54
+ "parser": "azure_servicetags_json",
55
+ "maps_to": "hosting",
56
+ "provider": "azure",
57
+ "cadence_hours": 168,
58
+ "on_failure": "keep_stale",
59
+ "enabled_default": true,
60
+ "notes": "The actual ServiceTags_Public_YYYYMMDD.json URL rotates weekly behind the download page; clients must scrape the page for the current link and keep stale data when the scrape breaks."
61
+ },
62
+ {
63
+ "id": "oracle",
64
+ "url": "https://docs.oracle.com/en-us/iaas/tools/public_ip_ranges.json",
65
+ "parser": "oci_json",
66
+ "maps_to": "hosting",
67
+ "provider": "oracle",
68
+ "cadence_hours": 168,
69
+ "on_failure": "keep_stale",
70
+ "enabled_default": true,
71
+ "notes": "Official OCI ranges: regions[].cidrs[].cidr."
72
+ },
73
+ {
74
+ "id": "digitalocean",
75
+ "url": "https://digitalocean.com/geo/google.csv",
76
+ "parser": "geofeed_csv",
77
+ "maps_to": "hosting",
78
+ "provider": "digitalocean",
79
+ "cadence_hours": 168,
80
+ "on_failure": "keep_stale",
81
+ "enabled_default": true,
82
+ "notes": "RFC 8805-style geofeed CSV; first column is the CIDR."
83
+ },
84
+ {
85
+ "id": "linode",
86
+ "url": "https://geoip.linode.com/",
87
+ "parser": "geofeed_csv",
88
+ "maps_to": "hosting",
89
+ "provider": "linode",
90
+ "cadence_hours": 168,
91
+ "on_failure": "keep_stale",
92
+ "enabled_default": true,
93
+ "notes": "RFC 8805 geofeed."
94
+ },
95
+ {
96
+ "id": "vultr",
97
+ "url": "https://geofeed.constant.com/",
98
+ "parser": "geofeed_csv",
99
+ "maps_to": "hosting",
100
+ "provider": "vultr",
101
+ "cadence_hours": 168,
102
+ "on_failure": "keep_stale",
103
+ "enabled_default": true,
104
+ "notes": "RFC 8805 geofeed (Constant = Vultr)."
105
+ },
106
+ {
107
+ "id": "cloudflare_ranges",
108
+ "url": "https://www.cloudflare.com/ips-v4",
109
+ "url_ipv6": "https://www.cloudflare.com/ips-v6",
110
+ "parser": "plain_cidr_per_line",
111
+ "maps_to": "flag:cloudflare_range",
112
+ "provider": "cloudflare",
113
+ "cadence_hours": 168,
114
+ "on_failure": "keep_stale",
115
+ "enabled_default": true,
116
+ "notes": "CONTEXT FLAG ONLY - never map to a blocking verdict. WARP and iCloud Private Relay egress live inside these ranges (that's why X4B excludes them from its dc list). Docs: https://developers.cloudflare.com/fundamentals/concepts/cloudflare-ip-addresses/"
117
+ },
118
+ {
119
+ "id": "protonvpn",
120
+ "url": "https://raw.githubusercontent.com/tn3w/ProtonVPN-IPs/master/protonvpn_ips.txt",
121
+ "parser": "plain_ip_per_line",
122
+ "maps_to": "vpn",
123
+ "provider": "ProtonVPN",
124
+ "cadence_hours": 24,
125
+ "on_failure": "keep_stale",
126
+ "enabled_default": true,
127
+ "license": "Apache-2.0",
128
+ "notes": "Exit IPs scraped from ProtonVPN's own API by tn3w/ProtonVPN-IPs (LICENSE verified Apache-2.0, default branch master). Proton's official API now requires app headers/session auth for anonymous callers (verified 2026-07-05), so this licensed feed remains the clean default until Proton publishes a stable public endpoint."
129
+ },
130
+ {
131
+ "id": "mullvad_relays",
132
+ "url": "https://api.mullvad.net/www/relays/all/",
133
+ "parser": "mullvad_relays_json",
134
+ "maps_to": "vpn",
135
+ "provider": "Mullvad",
136
+ "cadence_hours": 24,
137
+ "on_failure": "keep_stale",
138
+ "enabled_default": true,
139
+ "notes": "First-party public relay API used by Mullvad's server list (https://mullvad.net/en/servers). Parser keeps active exact relay IPs only (ipv4_addr_in/ipv6_addr_in); do NOT widen to /24. Mozilla VPN / Firefox VPN use Mullvad infrastructure (https://www.mozilla.org/en-US/products/vpn/resource-center/vpn-servers-around-the-world/), but the egress IP cannot distinguish Mozilla users from direct Mullvad users, so provider attribution stays 'Mullvad'."
140
+ },
141
+ {
142
+ "id": "ivpn_servers",
143
+ "url": "https://api.ivpn.net/v4/servers.json",
144
+ "parser": "ivpn_servers_json",
145
+ "maps_to": "vpn",
146
+ "provider": "IVPN",
147
+ "cadence_hours": 24,
148
+ "on_failure": "keep_stale",
149
+ "enabled_default": true,
150
+ "notes": "First-party IVPN server status JSON linked from/supporting https://www.ivpn.net/en/status/. Parser collects exact WireGuard hosts[].host and OpenVPN ip_addresses[]."
151
+ },
152
+ {
153
+ "id": "pia_servers",
154
+ "url": "https://serverlist.piaservers.net/vpninfo/servers/v7",
155
+ "parser": "pia_servers_json",
156
+ "maps_to": "vpn",
157
+ "provider": "Private Internet Access",
158
+ "cadence_hours": 24,
159
+ "on_failure": "keep_stale",
160
+ "enabled_default": true,
161
+ "notes": "First-party PIA client server list. Body is JSON on the first line followed by a detached signature; parser reads region server IPs for WireGuard/OpenVPN/IKEv2/meta groups and skips offline regions."
162
+ },
163
+ {
164
+ "id": "airvpn_status",
165
+ "url": "https://airvpn.org/api/status/",
166
+ "parser": "airvpn_status_json",
167
+ "maps_to": "vpn",
168
+ "provider": "AirVPN",
169
+ "cadence_hours": 24,
170
+ "on_failure": "keep_stale",
171
+ "enabled_default": true,
172
+ "notes": "First-party public status API (AirVPN forum confirms it lists all servers and entry IP addresses: https://airvpn.org/forums/topic/74903-servers-ips-list/). Parser collects ip_v4_in*/ip_v6_in* exact entry IPs; deprecated ip_entry fields are intentionally ignored."
173
+ },
174
+ {
175
+ "id": "windscribe_servers",
176
+ "url": "https://assets.windscribe.com/serverlist/mob-v2/1/0",
177
+ "parser": "windscribe_serverlist_json",
178
+ "maps_to": "vpn",
179
+ "provider": "Windscribe",
180
+ "cadence_hours": 24,
181
+ "on_failure": "keep_stale",
182
+ "enabled_default": true,
183
+ "notes": "First-party Windscribe mobile server list JSON. Parser collects active locations' ping_ip and node ip/ip2/ip3 exact IPs; hostnames are ignored because OpenASN does not do DNS expansion inside Tier B."
184
+ },
185
+ {
186
+ "id": "nordvpn_servers",
187
+ "url": "https://api.nordvpn.com/v2/servers?limit=0",
188
+ "parser": "nordvpn_servers_json",
189
+ "maps_to": "vpn",
190
+ "provider": "NordVPN",
191
+ "cadence_hours": 24,
192
+ "on_failure": "keep_stale",
193
+ "enabled_default": false,
194
+ "notes": "Opt-in: first-party NordVPN API returns exact station/ips[].ip.ip values. v2 is still large (~10MB live on 2026-07-05), so keep behind config.tier_b[:vpn_heavy]. Official server list docs: https://support.nordvpn.com/hc/en-us/articles/19383127694225-Where-can-I-find-the-NordVPN-server-list"
195
+ },
196
+ {
197
+ "id": "privadovpn",
198
+ "url": "https://privadovpn.com/apps/servers_export.json",
199
+ "parser": "privado_servers_json",
200
+ "maps_to": "vpn",
201
+ "provider": "PrivadoVPN",
202
+ "cadence_hours": 24,
203
+ "on_failure": "keep_stale",
204
+ "enabled_default": true,
205
+ "notes": "First-party PrivadoVPN app server export discovered via public client tooling and verified live 2026-07-05. Parser reads servers[].ip exact exit/server IPs and ignores hostname/load/location metadata."
206
+ },
207
+ {
208
+ "id": "riseup_vpn",
209
+ "url": "https://api.black.riseup.net/3/config/eip-service.json",
210
+ "parser": "leap_eip_service_json",
211
+ "maps_to": "vpn",
212
+ "provider": "RiseupVPN",
213
+ "cadence_hours": 24,
214
+ "on_failure": "keep_stale",
215
+ "enabled_default": true,
216
+ "notes": "First-party LEAP/Bitmask provider API for RiseupVPN. OONI's RiseupVPN test documents that this provider API returns VPN gateway IP addresses and capabilities (https://github.com/ooni/spec/blob/master/nettests/ts-026-riseupvpn.md). Parser reads gateways[].ip_address exact IPs."
217
+ },
218
+ {
219
+ "id": "wlvpn_server_list",
220
+ "url": "https://api.wlvpn.com/v2/list/wlvpnserverList.xml",
221
+ "parser": "wlvpn_server_list_xml",
222
+ "maps_to": "vpn",
223
+ "provider": "WLVPN",
224
+ "cadence_hours": 24,
225
+ "on_failure": "keep_stale",
226
+ "enabled_default": true,
227
+ "notes": "First-party WLVPN/IPVanish white-label server API. WLVPN's site says it is a white-label VPN solution powered by IPVanish and part of VIPRE Security Group, a Ziff Davis company (https://wlvpn.com/about-wlvpn/). Parser keeps only server elements with visible=1/status=1 and reads exact ip attributes. Provider attribution is intentionally WLVPN backend infrastructure, not a reseller brand such as Spaceship/FastVPN or Namecheap FastVPN."
228
+ },
229
+ {
230
+ "id": "worldvpn_servers",
231
+ "url": "https://worldvpn.net/servers",
232
+ "parser": "worldvpn_servers_html",
233
+ "maps_to": "vpn",
234
+ "provider": "WorldVPN",
235
+ "cadence_hours": 24,
236
+ "on_failure": "keep_stale",
237
+ "enabled_default": true,
238
+ "notes": "First-party WorldVPN public server table. The page publishes exact IPs beside *.ocservvpn.com hostnames and says all listed servers support multiple VPN protocols, with OpenVPN profiles linked per row. Parser reads only table rows whose host cell is *.ocservvpn.com and emits the exact IP cell; no DNS expansion or whole-page IP scraping."
239
+ },
240
+ {
241
+ "id": "ovpn_status_servers",
242
+ "url": "https://status.ovpn.com/datacenters/sydney/servers",
243
+ "urls": [
244
+ "https://status.ovpn.com/datacenters/vienna/servers",
245
+ "https://status.ovpn.com/datacenters/toronto/servers",
246
+ "https://status.ovpn.com/datacenters/copenhagen/servers",
247
+ "https://status.ovpn.com/datacenters/helsinki/servers",
248
+ "https://status.ovpn.com/datacenters/paris/servers",
249
+ "https://status.ovpn.com/datacenters/frankfurt/servers",
250
+ "https://status.ovpn.com/datacenters/erfurt/servers",
251
+ "https://status.ovpn.com/datacenters/offenbach/servers",
252
+ "https://status.ovpn.com/datacenters/milan/servers",
253
+ "https://status.ovpn.com/datacenters/tokyo/servers",
254
+ "https://status.ovpn.com/datacenters/amsterdam/servers",
255
+ "https://status.ovpn.com/datacenters/oslo/servers",
256
+ "https://status.ovpn.com/datacenters/warsaw/servers",
257
+ "https://status.ovpn.com/datacenters/bucharest/servers",
258
+ "https://status.ovpn.com/datacenters/singapore/servers",
259
+ "https://status.ovpn.com/datacenters/madrid/servers",
260
+ "https://status.ovpn.com/datacenters/sthlm/servers",
261
+ "https://status.ovpn.com/datacenters/malmo/servers",
262
+ "https://status.ovpn.com/datacenters/gothenburg/servers",
263
+ "https://status.ovpn.com/datacenters/sundsvall/servers",
264
+ "https://status.ovpn.com/datacenters/zurich/servers",
265
+ "https://status.ovpn.com/datacenters/kyiv/servers",
266
+ "https://status.ovpn.com/datacenters/london/servers",
267
+ "https://status.ovpn.com/datacenters/losangeles/servers",
268
+ "https://status.ovpn.com/datacenters/miami/servers",
269
+ "https://status.ovpn.com/datacenters/newyork/servers",
270
+ "https://status.ovpn.com/datacenters/chicago/servers",
271
+ "https://status.ovpn.com/datacenters/atlanta/servers",
272
+ "https://status.ovpn.com/datacenters/dallas/servers",
273
+ "https://status.ovpn.com/datacenters/seattle/servers",
274
+ "https://status.ovpn.com/datacenters/denver/servers"
275
+ ],
276
+ "parser": "ovpn_status_servers_json",
277
+ "maps_to": "vpn",
278
+ "provider": "OVPN",
279
+ "cadence_hours": 24,
280
+ "on_failure": "keep_stale",
281
+ "enabled_default": true,
282
+ "notes": "First-party OVPN status API used by https://status.ovpn.com's Servers-List Vue component (GET /datacenters/{slug}/servers). Parser keeps exact IPs for rows whose online flag is not false; no config-form CSRF workflow, hostname inference, DNS expansion, ASN widening, or status-page HTML scraping."
283
+ },
284
+ {
285
+ "id": "anonine_status",
286
+ "url": "https://anonine.com/www/server-status",
287
+ "parser": "anonine_status_json",
288
+ "maps_to": "vpn",
289
+ "provider": "Anonine",
290
+ "cadence_hours": 24,
291
+ "on_failure": "keep_stale",
292
+ "enabled_default": true,
293
+ "notes": "First-party JSON endpoint called by Anonine's public Network page Gatsby bundle (serverStatusUrl() -> /www/server-status). Parser reads exact primary_ip values and servers[].ips arrays. The endpoint also includes host aliases, but OpenASN uses exact IPs here so this can stay in the default exact-IP provider set."
294
+ },
295
+ {
296
+ "id": "azirevpn_locations",
297
+ "url": "https://api.azirevpn.com/v3/locations",
298
+ "parser": "azirevpn_locations_json",
299
+ "maps_to": "vpn",
300
+ "provider": "AzireVPN",
301
+ "cadence_hours": 24,
302
+ "on_failure": "keep_stale",
303
+ "enabled_default": false,
304
+ "resolve_hostnames": true,
305
+ "notes": "Opt-in DNS-expanded source: AzireVPN's official API docs publish the unauthenticated GET /v3/locations endpoint and describe the pool field as the hostname pool with IPs available for the location (https://www.azirevpn.com/docs/api/locations). Clients resolve those pool hostnames locally, so results stay behind config.tier_b[:vpn_dns]. AzireVPN's current site/legal footer redirects to Malwarebytes legal pages and says (c) 2012-2026 Malwarebytes."
306
+ },
307
+ {
308
+ "id": "vpnac_status",
309
+ "url": "https://vpn.ac/status",
310
+ "parser": "vpnac_status_html",
311
+ "maps_to": "vpn",
312
+ "provider": "VPN.AC",
313
+ "cadence_hours": 24,
314
+ "on_failure": "keep_stale",
315
+ "enabled_default": false,
316
+ "resolve_hostnames": true,
317
+ "notes": "Opt-in DNS-expanded source: VPN.AC's official VPN Nodes Status page publishes exact *.vpn.ac hostnames in the status table, and its official /ovpn/ directory publishes matching OpenVPN config bundles. Clients resolve the hostnames locally because the page publishes hostnames, not raw IPs."
318
+ },
319
+ {
320
+ "id": "trustzone_servers",
321
+ "url": "https://trust.zone/servers",
322
+ "parser": "trustzone_servers_html",
323
+ "maps_to": "vpn",
324
+ "provider": "Trust.Zone",
325
+ "cadence_hours": 24,
326
+ "on_failure": "keep_stale",
327
+ "enabled_default": false,
328
+ "resolve_hostnames": true,
329
+ "notes": "Opt-in DNS-expanded source: Trust.Zone's first-party Zones & Servers page publishes exact *.trust.zone zone hostnames. Manual OpenVPN setup pages keep the downloadable .ovpn files hidden behind login, so this source intentionally uses only the public server page and local DNS resolution."
330
+ },
331
+ {
332
+ "id": "surfshark_generic",
333
+ "url": "https://api.surfshark.com/v4/server/clusters/generic",
334
+ "parser": "surfshark_clusters_json",
335
+ "maps_to": "vpn",
336
+ "provider": "Surfshark",
337
+ "cadence_hours": 24,
338
+ "on_failure": "keep_stale",
339
+ "enabled_default": false,
340
+ "resolve_hostnames": true,
341
+ "notes": "Opt-in DNS-expanded source: first-party Surfshark cluster API publishes connectionName hostnames, not raw IPs. Clients resolve those hostnames locally at update time, so results can vary by DNS vantage and should stay behind config.tier_b[:vpn_dns]."
342
+ },
343
+ {
344
+ "id": "surfshark_static",
345
+ "url": "https://api.surfshark.com/v4/server/clusters/static",
346
+ "parser": "surfshark_clusters_json",
347
+ "maps_to": "vpn",
348
+ "provider": "Surfshark",
349
+ "cadence_hours": 24,
350
+ "on_failure": "keep_stale",
351
+ "enabled_default": false,
352
+ "resolve_hostnames": true,
353
+ "notes": "Opt-in DNS-expanded Surfshark static-IP cluster hostnames. See surfshark_generic for the DNS-vantage caveat."
354
+ },
355
+ {
356
+ "id": "surfshark_obfuscated",
357
+ "url": "https://api.surfshark.com/v4/server/clusters/obfuscated",
358
+ "parser": "surfshark_clusters_json",
359
+ "maps_to": "vpn",
360
+ "provider": "Surfshark",
361
+ "cadence_hours": 24,
362
+ "on_failure": "keep_stale",
363
+ "enabled_default": false,
364
+ "resolve_hostnames": true,
365
+ "notes": "Opt-in DNS-expanded Surfshark obfuscated cluster hostnames. The double-hop cluster endpoint returned an empty list live on 2026-07-05, so it is intentionally not included."
366
+ },
367
+ {
368
+ "id": "ipvanish_openvpn",
369
+ "url": "https://configs.ipvanish.com/openvpn/v2.6.0-0/configs.zip",
370
+ "parser": "ovpn_zip_remote_hosts",
371
+ "maps_to": "vpn",
372
+ "provider": "IPVanish",
373
+ "cadence_hours": 24,
374
+ "on_failure": "keep_stale",
375
+ "enabled_default": false,
376
+ "resolve_hostnames": true,
377
+ "dns_threads": 24,
378
+ "notes": "Opt-in DNS-expanded source: first-party IPVanish OpenVPN config archive linked by router/client documentation. Archive contains remote hostnames (thousands), so clients resolve locally and keep this behind config.tier_b[:vpn_dns]."
379
+ },
380
+ {
381
+ "id": "privatevpn_openvpn",
382
+ "url": "https://privatevpn.com/client/PrivateVPN-TUN.zip",
383
+ "parser": "ovpn_zip_remote_hosts",
384
+ "maps_to": "vpn",
385
+ "provider": "PrivateVPN",
386
+ "cadence_hours": 24,
387
+ "on_failure": "keep_stale",
388
+ "enabled_default": false,
389
+ "resolve_hostnames": true,
390
+ "notes": "Opt-in DNS-expanded source: first-party PrivateVPN OpenVPN TUN archive. Parser extracts remote hostnames and clients resolve them locally."
391
+ },
392
+ {
393
+ "id": "purevpn_openvpn",
394
+ "url": "https://d11a57lttb2ffq.cloudfront.net/heartbleed/router/Recommended-CA2.zip",
395
+ "parser": "ovpn_zip_remote_hosts",
396
+ "maps_to": "vpn",
397
+ "provider": "PureVPN",
398
+ "cadence_hours": 24,
399
+ "on_failure": "keep_stale",
400
+ "enabled_default": false,
401
+ "resolve_hostnames": true,
402
+ "notes": "Opt-in DNS-expanded source: first-party/PureVPN router OpenVPN archive used by client tooling. Parser extracts remote hostnames and clients resolve them locally."
403
+ },
404
+ {
405
+ "id": "torguard_openvpn_tcp",
406
+ "url": "https://torguard.net/downloads/OpenVPN-TCP-Linux.zip",
407
+ "parser": "ovpn_zip_remote_hosts",
408
+ "maps_to": "vpn",
409
+ "provider": "TorGuard",
410
+ "cadence_hours": 24,
411
+ "on_failure": "keep_stale",
412
+ "enabled_default": false,
413
+ "resolve_hostnames": true,
414
+ "notes": "Opt-in DNS-expanded source: first-party TorGuard TCP OpenVPN archive. The earlier servers.json endpoint hit a bot challenge, but these public config archives fetched cleanly live on 2026-07-05."
415
+ },
416
+ {
417
+ "id": "torguard_openvpn_udp",
418
+ "url": "https://torguard.net/downloads/OpenVPN-UDP-Linux.zip",
419
+ "parser": "ovpn_zip_remote_hosts",
420
+ "maps_to": "vpn",
421
+ "provider": "TorGuard",
422
+ "cadence_hours": 24,
423
+ "on_failure": "keep_stale",
424
+ "enabled_default": false,
425
+ "resolve_hostnames": true,
426
+ "notes": "Opt-in DNS-expanded source: first-party TorGuard UDP OpenVPN archive. Usually overlaps TCP, but keeping both avoids silent protocol-specific omissions."
427
+ },
428
+ {
429
+ "id": "fastestvpn_tcp",
430
+ "url": "https://support.fastestvpn.com/wp-admin/admin-ajax.php",
431
+ "method": "POST",
432
+ "form": { "action": "vpn_servers", "protocol": "tcp" },
433
+ "parser": "html_table_hostnames",
434
+ "maps_to": "vpn",
435
+ "provider": "FastestVPN",
436
+ "cadence_hours": 24,
437
+ "on_failure": "keep_stale",
438
+ "enabled_default": false,
439
+ "resolve_hostnames": true,
440
+ "notes": "Opt-in DNS-expanded source: first-party FastestVPN support page AJAX endpoint used by https://support.fastestvpn.com/vpn-servers/. Parser reads hostnames from the returned HTML table; clients resolve locally."
441
+ },
442
+ {
443
+ "id": "fastestvpn_udp",
444
+ "url": "https://support.fastestvpn.com/wp-admin/admin-ajax.php",
445
+ "method": "POST",
446
+ "form": { "action": "vpn_servers", "protocol": "udp" },
447
+ "parser": "html_table_hostnames",
448
+ "maps_to": "vpn",
449
+ "provider": "FastestVPN",
450
+ "cadence_hours": 24,
451
+ "on_failure": "keep_stale",
452
+ "enabled_default": false,
453
+ "resolve_hostnames": true,
454
+ "notes": "Opt-in DNS-expanded source: first-party FastestVPN UDP host table. Kept separate from TCP to avoid silent protocol-specific omissions."
455
+ },
456
+ {
457
+ "id": "vpnsecure_locations",
458
+ "url": "https://www.vpnsecure.me/vpn-locations/",
459
+ "parser": "vpnsecure_locations_html",
460
+ "maps_to": "vpn",
461
+ "provider": "VPNSecure",
462
+ "cadence_hours": 24,
463
+ "on_failure": "keep_stale",
464
+ "enabled_default": false,
465
+ "resolve_hostnames": true,
466
+ "notes": "Opt-in DNS-expanded source: VPNSecure's first-party locations page publishes per-server host labels and status. Parser keeps only hosts marked status--up and expands them to *.isponeder.com hostnames for local DNS resolution."
467
+ },
468
+ {
469
+ "id": "tunnelbear_openvpn",
470
+ "url": "https://tunnelbear.s3.amazonaws.com/support/linux/openvpn.zip",
471
+ "parser": "ovpn_zip_remote_hosts",
472
+ "maps_to": "vpn",
473
+ "provider": "TunnelBear",
474
+ "cadence_hours": 24,
475
+ "on_failure": "keep_stale",
476
+ "enabled_default": false,
477
+ "resolve_hostnames": true,
478
+ "notes": "Opt-in DNS-expanded source: TunnelBear's first-party Linux setup article links this public OpenVPN ZIP. Parser extracts exact remote hostnames, including provider files suffixed .ovpn.txt; clients resolve them locally."
479
+ },
480
+ {
481
+ "id": "strongvpn_locations",
482
+ "url": "https://strongtech.org/locations/",
483
+ "parser": "strongvpn_locations_html",
484
+ "maps_to": "vpn",
485
+ "provider": "StrongVPN",
486
+ "cadence_hours": 24,
487
+ "on_failure": "keep_stale",
488
+ "enabled_default": false,
489
+ "resolve_hostnames": true,
490
+ "dns_threads": 24,
491
+ "notes": "Opt-in DNS-expanded source: StrongVPN/StrongTech first-party locations page publishes exact vpn-*.reliablehosting.com server hostnames. Clients resolve locally because the page publishes hostnames, not raw IPs; live smoke on 2026-07-05 saw many stale DNS names, so keep behind config.tier_b[:vpn_dns]."
492
+ },
493
+ {
494
+ "id": "vyprvpn_openvpn",
495
+ "url": "https://support.vyprvpn.com/hc/article_attachments/46761120489229",
496
+ "parser": "ovpn_zip_remote_hosts",
497
+ "maps_to": "vpn",
498
+ "provider": "VyprVPN",
499
+ "cadence_hours": 24,
500
+ "on_failure": "keep_stale",
501
+ "enabled_default": false,
502
+ "resolve_hostnames": true,
503
+ "notes": "Opt-in DNS-expanded source: VyprVPN's first-party support article links this public OpenVPN ZIP (filename VyprVPN_OpenVPN_2026-03-06.zip; fetched 2026-07-05 with Last-Modified 2026-06-18). Parser extracts exact *.vyprvpn.com remote hostnames; clients resolve them locally. Some embedded cert metadata still names Golden Frog, which is legacy branding for the current Certida-operated service."
504
+ },
505
+ {
506
+ "id": "giganews_vyprvpn_hosts",
507
+ "url": "https://support.giganews.com/hc/en-us/articles/360039615432-What-are-the-VyprVPN-Server-Addresses",
508
+ "parser": "html_table_hostnames",
509
+ "maps_to": "vpn",
510
+ "provider": "Giganews VyprVPN",
511
+ "cadence_hours": 24,
512
+ "on_failure": "keep_stale",
513
+ "enabled_default": false,
514
+ "resolve_hostnames": true,
515
+ "notes": "Opt-in DNS-expanded source: Giganews first-party support page publishes exact *.vpn.giganews.com hostnames for VyprVPN bundled with Giganews accounts and says IP addresses are subject to change, so clients resolve hostnames locally."
516
+ },
517
+ {
518
+ "id": "slickvpn_locations",
519
+ "url": "https://www.slickvpn.com/locations/",
520
+ "parser": "slickvpn_locations_html",
521
+ "maps_to": "vpn",
522
+ "provider": "SlickVPN",
523
+ "cadence_hours": 24,
524
+ "on_failure": "keep_stale",
525
+ "enabled_default": false,
526
+ "resolve_hostnames": true,
527
+ "notes": "Opt-in DNS-expanded source: SlickVPN's first-party locations page says these are active VPN servers and links public 2025 OpenVPN configs under members.newsdemon.com. Parser extracts only the config-linked visible gw*.slickvpn.com hostnames from that page. In the 2026-07-05 smoke the Amsterdam page label resolved while the linked config's remote did not, so the active server page is the source of record and config files are corroboration only."
528
+ },
529
+ {
530
+ "id": "vpnbook_openvpn",
531
+ "url": "https://www.vpnbook.com/freevpn/openvpn",
532
+ "parser": "vpnbook_html_hosts",
533
+ "maps_to": "vpn",
534
+ "provider": "VPNBook",
535
+ "cadence_hours": 6,
536
+ "on_failure": "keep_stale",
537
+ "enabled_default": false,
538
+ "resolve_hostnames": true,
539
+ "notes": "Opt-in public/free VPN source: VPNBook publishes current OpenVPN server hostnames on this page; clients resolve them locally. Keep behind config.tier_b[:public_relays] because free public VPN endpoints are high-churn."
540
+ },
541
+ {
542
+ "id": "freevpn_us_servers",
543
+ "url": "https://www.freevpn.us/pages/server-status.html",
544
+ "parser": "freevpn_us_status_html",
545
+ "maps_to": "vpn",
546
+ "provider": "FreeVPN.us",
547
+ "cadence_hours": 6,
548
+ "on_failure": "keep_stale",
549
+ "enabled_default": false,
550
+ "resolve_hostnames": true,
551
+ "notes": "Opt-in public/free VPN source: FreeVPN.us (Roosterkid) publishes a live status table with data-type/data-host attributes. Parser keeps only OpenVPN, WireGuard, and PPTP/L2TP VPN rows and intentionally excludes SSH Tunnel and V2Ray rows from the VPN overlay. Clients resolve *.vpnv.cc locally; keep behind config.tier_b[:public_relays] because free public endpoints are high-churn."
552
+ },
553
+ {
554
+ "id": "vpngate",
555
+ "url": "http://www.vpngate.net/api/iphone/",
556
+ "parser": "vpngate_csv",
557
+ "maps_to": "vpn",
558
+ "provider": "VPN Gate",
559
+ "cadence_hours": 6,
560
+ "on_failure": "keep_stale",
561
+ "enabled_default": false,
562
+ "notes": "Opt-in: official VPN Gate Academic Experiment public relay API. These are volunteer relays, often residential/ISP IPs while actively serving VPN traffic; exact current hits are valuable but high-churn, so keep behind config.tier_b[:public_relays]. Parser reads the CSV IP column only and ignores embedded OpenVPN configs."
563
+ },
564
+ {
565
+ "id": "zscaler",
566
+ "url": "https://config.zscaler.com/api/zscaler.net/cenr/json",
567
+ "parser": "zscaler_json",
568
+ "maps_to": "enterprise_gateway",
569
+ "provider": "zscaler",
570
+ "cadence_hours": 168,
571
+ "on_failure": "keep_stale",
572
+ "enabled_default": false,
573
+ "notes": "Cloud Enforcement Node Ranges, published for allowlisting (verified live 2026-07-04: nested JSON, collect every 'range' value, both v4 and v6). Off by default: the ASN-level enterprise_gateway overrides already cover Zscaler; enable for finer range-level coverage."
574
+ },
575
+ {
576
+ "id": "nazgul_mixed",
577
+ "url": "https://raw.githubusercontent.com/NazgulCoder/IPLists/main/output/vpn-ipv4.txt",
578
+ "url_ipv6": "https://raw.githubusercontent.com/NazgulCoder/IPLists/main/output/vpn-ipv6.txt",
579
+ "parser": "plain_cidr_per_line",
580
+ "maps_to": "flag:mixed_high_risk",
581
+ "provider": "nazgul",
582
+ "cadence_hours": 24,
583
+ "on_failure": "keep_stale",
584
+ "enabled_default": false,
585
+ "license": "MIT",
586
+ "notes": "SEMANTIC WARNING (from their own README): includes ASNs of providers 'permissive toward pentesting, DDoS, bot operations' - broader than VPN. Never map to :vpn; exposed only as a flag. Off by default. Interim IPv6 VPN-ish signal for those who opt in."
587
+ }
588
+ ]
589
+ }