{"id":17048187,"url":"https://github.com/darkk/originas","last_synced_at":"2026-04-15T14:02:12.727Z","repository":{"id":66481309,"uuid":"134416316","full_name":"darkk/originas","owner":"darkk","description":"Пример получения AS для IP адреса по дампу originas","archived":false,"fork":false,"pushed_at":"2018-05-22T14:11:10.000Z","size":17,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-28T10:29:05.687Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/darkk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-22T13:06:16.000Z","updated_at":"2023-09-13T20:41:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"407fa526-74c0-4128-b1ea-80db78c7d8e4","html_url":"https://github.com/darkk/originas","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkk%2Foriginas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkk%2Foriginas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkk%2Foriginas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkk%2Foriginas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/darkk","download_url":"https://codeload.github.com/darkk/originas/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245052674,"owners_count":20553172,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-14T09:51:16.684Z","updated_at":"2026-04-15T14:02:07.700Z","avatar_url":"https://github.com/darkk.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Пример того, как можно сравнительно быстро преобразовывать IP-адрес в AS по дампу зоны originas с [routeviews.org](http://archive.routeviews.org/).\n\n- 30ms при использовании sqlite\n- 2ms при использовании posgresql\n\nNB: для одного адреса теоретически может быть несколько разных AS, если они указаны указаны как AS-SET для наименьшего покрывающего данный IP адрес префикса.\n\nIP в ASN\n========\n\nПодготовка БД:\n\n```\n# для sqlite\n$ make originas.bz2 \u0026\u0026 make originas.sqlite\n# для postgres\n$ make run-psql\n$ make originas.bz2 \u0026\u0026 make fill-psql\n```\n\nПоиск адресов:\n\n```\n$ time ./lookup_sqlite.py $(shuf -n 100 sample | sort -V) \n23.253.109.158\t23.253.64.0/18\tAS33070\n47.74.14.56\t47.74.0.0/18\tAS45102\n47.74.21.219\t47.74.0.0/18\tAS45102\n47.254.146.161\t47.254.128.0/18\tAS45102\n[...]\n212.71.237.224\t212.71.232.0/21\tAS63949\n212.111.42.144\t212.111.40.0/22\tAS63949\n213.52.128.13\t213.52.128.0/23\tAS63949\n\nreal\t0m3.732s\nuser\t0m2.908s\nsys\t0m0.824s\n```\n\n```\n$ shuf -n 100 sample \u003equery-ips\n$ time make lookup-psql \ndocker exec  --user postgres -i pg-originas psql --no-align --field-separator='\t' --set=\"qfile='/mnt/query-ips'\" -f /mnt/lookup_psql.sql\nCREATE TABLE\nCOPY 100\nip\torigin\tasn\n23.253.149.26\t23.253.128.0/19\t27357\n47.74.23.84\t47.74.0.0/18\t45102\n47.254.35.224\t47.254.32.0/21\t45102\n47.254.129.145\t47.254.128.0/18\t45102\n47.254.130.24\t47.254.128.0/18\t45102\n47.254.144.74\t47.254.128.0/18\t45102\n...\n213.168.250.173\t213.168.248.0/22\t63949\n(100 rows)\n\nreal\t0m0.312s\nuser\t0m0.020s\nsys\t0m0.012s\n```\n\nASN в имя AS\n============\n\nМожно использовать [JSON API от stat.ripe.net](https://stat.ripe.net/docs/data_api#AsOverview), например, для [AS8997](https://stat.ripe.net/data/as-overview/data.json?resource=AS8997).\n\nИли взять файл [asn.txt с ftp.ripe.net](https://ftp.ripe.net/ripe/asnames/asn.txt) и импортировать его в БД.\n\nПолнота данных\n==============\n\nДамп с routeviews на 22 мая 2018 г. включает в себя 60674 AS и 712961 префикс.\n\nДамп asn.txt содержит информацию о 87637, включая AS геокодированые США, странами Африки и т.п., т.е. он включает в себя не только европейские сети региона RIPE NCC.\n\nНа первый взгляд, полнота этих данных достаточна для практического применения \"примерно узнать, в какой сети очередной забаненный РКН IP адрес\".\n\nНо я кэширую whois!\n===================\n\n\u003e There are only two hard things in Computer Science: cache invalidation and naming things.\n\nКэширование whois вместо использования данных маршрутизации может привести к забавным багам.\n\nПредставим, что адрес `8.8.254.254` был забанен РКН. `whois` припишет ему префикс `8.0.0.0/9` и имя asn `Level 3 Parent, LLC`. В кэш эта информация будет сохранена и последующий поиск адреса `8.8.8.8` припишет его также `Level 3`, что неверно.\n\nПри поиске по данным маршрутизации, ответ будет более точный:\n\n```\n$ docker exec --user postgres -it pg-originas psql -c \"select * from originas join asn using(asn) where '8.8.254.254'::inet \u003c\u003c= origin\"\n asn  |   origin   |              asname\n------+------------+----------------------------------\n 3356 | 8.0.0.0/12 | LEVEL3 - Level 3 Parent, LLC, US\n(1 row)\n\n$ docker exec --user postgres -it pg-originas psql -c \"select * from originas join asn using(asn) where '8.8.8.8'::inet \u003c\u003c= origin\"\n  asn  |   origin   |              asname\n-------+------------+----------------------------------\n 15169 | 8.8.8.0/24 | GOOGLE - Google LLC, US\n  3356 | 8.0.0.0/12 | LEVEL3 - Level 3 Parent, LLC, US\n(2 rows)\n```\n\nНе всё так однозначно...\n========================\n\nК сожалению, использование AS-SET (группы автономных систем, объединенных для\nмаршрутизации) может порождать неоднозначности, когда один и тот же минимальный\nпокрывающий IP-адрес префикс может быть приписан разным AS. Например `20.134.1.42`:\n\n```\n$ docker exec --user postgres -it pg-originas psql -c \"select * from originas join asn using(asn) where '20.134.1.42'::inet \u003c\u003c= origin\"\n  asn  |    origin     |                      asname\n-------+---------------+---------------------------------------------------\n 17916 | 20.134.0.0/20 | CSC-IGN-AUNZ-AP Computer Sciences Corporation, AU\n  7474 | 20.134.0.0/20 | OPTUSCOM-AS01-AU SingTel Optus Pty Ltd, AU\n(2 rows)\n```\n\nХорошего рецепта для разрешения подобных неоднозначностей у меня нет.\n\nТакой адрес смущает и [RIPE Stat](https://stat.ripe.net/20.134.1.42#tabId=routing): какие-то из полей утверждают, что _168 peers announcing 20.134.0.0/20 originated by AS0_, а виджет _Prefix Routing Consistency_ показывает уровень бардака.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarkk%2Foriginas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdarkk%2Foriginas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarkk%2Foriginas/lists"}