Я пытаюсь получить текущий публичный IPv6-адрес интерфейса в Python. При поиске я обнаружил пакет netifaces
, который может дать мне список всех ipv6-адресов устройства.
Это будет включать
- адрес локальной ссылки (который я мог бы отфильтровать простым взломом, что не очень хорошо, но хорошо ...)
- несколько глобальных адресов ipv6, один из которых является текущим
Теперь, что я имею в виду под током? Через расширения конфиденциальности (RFC 4941) новый адрес назначается интерфейсу через равные промежутки времени. Старые глобальные адреса ipv6 все еще действительны, но помечены как устаревшие. Я хочу этот самый последний.
Вот что я попробовал (запутанные части адресов по соображениям безопасности):
>>> import netifaces
>>> addrs = netifaces.ifaddresses('en0')
>>> for i in addrs[netifaces.AF_INET6]:
... print(i)
...
{'addr': 'fe80::caa:452a:b8cb:862e%en0', 'netmask': 'ffff:ffff:ffff:ffff::/64', 'flags': 1024}
{'addr': '2a02:____:____:9f1:cd8:e__e:e57b:eaa8', 'netmask': 'ffff:ffff:ffff:ffff::/64', 'flags': 1088}
{'addr': '2a02:____:____:9f1:3489:b__7:fb34:101', 'netmask': 'ffff:ffff:ffff:ffff::/64', 'flags': 192}
Очевидно, что первым является адрес локальной ссылки. Второй и третий глобальные, и у них есть флаг, о котором я понятия не имею, что он означает.
Есть ли способ (возможно, с помощью флага или другого метода в python) выяснить текущий (временный, не устаревший) глобальный адрес?
В Linux я знаю, что могу анализировать вывод ip -o -6 addr show dev interface
и анализировать этот вывод, но это не сработает, например. на Mac, и анализ выходных данных других инструментов - это то, что мне не нравится, если для него есть пакет python.
EDIT:
Флаги, похоже, присутствуют не на каждой ОС. Выход выше был на Mac. Вот вывод на Linux-машине в той же сети (гораздо больше времени безотказной работы):
{'addr': '2a02:____:____:9f1:940c:f__f:f9c0:c274', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': '2a02:____:____:9f1:395a:6__d:650a:3a11', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': '2a02:____:____:9f1:d08a:6__d:d967:d28a', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': '2a02:____:____:9f1:9d20:b__7:3edc:96a4', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': '2a02:____:____:9f1:b584:d__b:16bf:5dd2', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': '2a02:____:____:9f1:61ba:d__b:78d8:197f', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': '2a02:____:____:9f1:c1df:7__7:236d:4219', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': '2a02:____:____:9f1:d021:4__3:1a44:4947', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
{'addr': 'fe80::17ed:fbf5:a707:2a42%enp4s0', 'netmask': 'ffff:ffff:ffff:ffff::/64'}
РЕДАКТИРОВАТЬ 2:
Поскольку возникла путаница в том, что я имею в виду под «текущими» адресами, вот что я имею ввиду. На машине Linux предыдущего примера:
% ip -o -6 addr show dev enp4s0
2: enp4s0 inet6 2a02:____:____:9f1:940c:f__f:f9c0:c274/64 scope global temporary dynamic \ valid_lft 530760sec preferred_lft 12247sec
2: enp4s0 inet6 2a02:____:____:9f1:395a:6__d:650a:3a11/64 scope global temporary deprecated dynamic \ valid_lft 444473sec preferred_lft 0sec
2: enp4s0 inet6 2a02:____:____:9f1:d08a:6__d:d967:d28a/64 scope global temporary deprecated dynamic \ valid_lft 358187sec preferred_lft 0sec
2: enp4s0 inet6 2a02:____:____:9f1:9d20:b__7:3edc:96a4/64 scope global temporary deprecated dynamic \ valid_lft 271901sec preferred_lft 0sec
2: enp4s0 inet6 2a02:____:____:9f1:b584:d__b:16bf:5dd2/64 scope global temporary deprecated dynamic \ valid_lft 185616sec preferred_lft 0sec
2: enp4s0 inet6 2a02:____:____:9f1:61ba:d__b:78d8:197f/64 scope global temporary deprecated dynamic \ valid_lft 99330sec preferred_lft 0sec
2: enp4s0 inet6 2a02:____:____:9f1:c1df:7__7:236d:4219/64 scope global temporary deprecated dynamic \ valid_lft 13044sec preferred_lft 0sec
2: enp4s0 inet6 2a02:____:____:9f1:d021:4__3:1a44:4947/64 scope global dynamic mngtmpaddr noprefixroute \ valid_lft 2591735sec preferred_lft 604535sec
2: enp4s0 inet6 fe80::17ed:fbf5:a707:2a42/64 scope link noprefixroute \ valid_lft forever preferred_lft forever
Очевидно, что все «временные» адреса являются действительными адресами. Но только один не помечен как устаревший. Этот адрес будет использоваться для исходящих соединений. И это тот, который я хочу.