Jump to content
ankar84

Защищаем DNS запросы с помощью dnscrypt-proxy2. Бонусом блокировка рекламы.

Recommended Posts

2 часа назад, shadowy сказал:

Подскажите как накатить его на KeeneticOS: 3.3.10 ?....

А зачем, если в 3.x версиях есть DoT/DoH в прошивке?

Читали?

Share this post


Link to post
Share on other sites
2 часа назад, shadowy сказал:

Подскажите как накатить его на KeeneticOS: 3.3.10 ?....

спасибо...

В настоящие время есть альтернатива

Так как в нем есть поддержка - DNSCrypt / DNS-over-HTTPS / DNS-поверх-TLS плюс так же фильтры на базе host (готовые или свои) и другие фильтры => блокировщик рекламы.

 

Если не нужно, то ни каких изменений по установки пакетов от Entware не происходило.

/ # opkg list | grep dnscrypt
dnscrypt-proxy - 2019-08-20-07ac3825-1 - dnscrypt-proxy provides local service which can be used directly as your local resolver or as a DNS forwarder, encrypting and authenticating requests using the DNSCrypt protocol and passing them to an upstream server. The DNSCrypt protocol uses high-speed high-security elliptic-curve cryptography and is very similar to DNSCurve, but focuses on securing communications between a client and its first-level resolver.
dnscrypt-proxy-resolvers - 2019-08-20-07ac3825-1 - Package with current list of dnscrypt-proxy resolvers.
dnscrypt-proxy2 - 2.0.36-1 - DNSCrypt is a network protocol designed by Frank Denis and Yecheng Fu, which authenticates Domain Name System (DNS) traffic between the user's computer and recursive name servers.
/ # 

Набрать "opkg install dnscrypt-proxy2"

 

 

Share this post


Link to post
Share on other sites
2 hours ago, vasek00 said:

В настоящие время есть альтернатива

Так как в нем есть поддержка - DNSCrypt / DNS-over-HTTPS / DNS-поверх-TLS плюс так же фильтры на базе host (готовые или свои) и другие фильтры => блокировщик рекламы.

 

Если не нужно, то ни каких изменений по установки пакетов от Entware не происходило.


/ # opkg list | grep dnscrypt
dnscrypt-proxy - 2019-08-20-07ac3825-1 - dnscrypt-proxy provides local service which can be used directly as your local resolver or as a DNS forwarder, encrypting and authenticating requests using the DNSCrypt protocol and passing them to an upstream server. The DNSCrypt protocol uses high-speed high-security elliptic-curve cryptography and is very similar to DNSCurve, but focuses on securing communications between a client and its first-level resolver.
dnscrypt-proxy-resolvers - 2019-08-20-07ac3825-1 - Package with current list of dnscrypt-proxy resolvers.
dnscrypt-proxy2 - 2.0.36-1 - DNSCrypt is a network protocol designed by Frank Denis and Yecheng Fu, which authenticates Domain Name System (DNS) traffic between the user's computer and recursive name servers.
/ # 

Набрать "opkg install dnscrypt-proxy2"

 

 

Спасибо, но есть необходимость именно в dnscrypt. Не понятно только одно: Через какой интерфейс устанавливать... Через путти ошибки только http://prntscr.com/r5svpi

Share this post


Link to post
Share on other sites
2 часа назад, shadowy сказал:

Спасибо, но есть необходимость именно в dnscrypt. Не понятно только одно: Через какой интерфейс устанавливать... Через путти ошибки только http://prntscr.com/r5svpi

Вы вводите команды в CLI, а эта статья про установку dnscrypt в Entware.

Если у вас ещё не установлен Entware, то начинать нужно отсюда.

Share this post


Link to post
Share on other sites
В 10.02.2020 в 19:14, Albram сказал:

Сегодня нашел причину "дыры" описанной мной в этой теме ранее

Напомню: DNS сервер откликался на запросы снаружи на udp/53 на внешний адрес кинетика. Firewall включен, nmap не показывал этот порт открытым. Обходным решением тогда оказалось, как ни странно, указание в настройках dnscrypt-proxy2 слушать на любом порту, вместо 127.0.0.1:53 и 192.168.1.1:53, как было у меня раньше. При этом, при внешних запросах, ответов от dns сервера не было (на внешнем клиенте был таймаут ответа от сервера), но в активных подключениях кинетика всё равно появлялось это соединение.

Обнаружил у себя аналогичную проблему - огромный исходящий трафик, видимый в странице "Системный монитор" в WEB-интерфейсе. Методом исключения нашёл виновника: dnscrypt-proxy2. Нашел эту ветку на форме. Никакие указанные здесь команды типа "tcpdump port 53 -n -nn -v" никакого ненормального трафика не показывают, показывает только "Системный монитор". После чтения темы добавил через WEB-интерфейс "первыми" два правила запрета входящих пакетов на 53-й порт: 1) для TCP и 2) для UDP. Исходящий трафик исчез.

Share this post


Link to post
Share on other sites
4 часа назад, HuduGuru сказал:

Обнаружил у себя аналогичную проблему - огромный исходящий трафик, видимый в странице "Системный монитор" в WEB-интерфейсе. Методом исключения нашёл виновника: dnscrypt-proxy2. Нашел эту ветку на форме. Никакие указанные здесь команды типа "tcpdump port 53 -n -nn -v" никакого ненормального трафика не показывают, показывает только "Системный монитор". После чтения темы добавил через WEB-интерфейс "первыми" два правила запрета входящих пакетов на 53-й порт: 1) для TCP и 2) для UDP. Исходящий трафик исчез.

Включил dnscrypt-proxy2 проверку на "счет виновника" и не нашел нечего :

/opt/etc/init.d # netstat -ntulp | grep dnscrypt-proxy
tcp        0      0 192.168.1.1:53          0.0.0.0:*               LISTEN      2355/dnscrypt-proxy
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      2355/dnscrypt-proxy
udp        0      0 192.168.1.1:53          0.0.0.0:*                           2355/dnscrypt-proxy
udp        0      0 127.0.0.1:53            0.0.0.0:*                           2355/dnscrypt-proxy
/opt/etc/init.d # 

Ни каких блокировок дополнительно нет. По системному монитору нет ни чего на что следовало бы обратить внимание - огромный трафик.

 

При выключенной опции "server_names"

######## server_names = ['cloudflare', 'google', 'yandex']

в итоге  согласно скаченных файлов "relays.md" и "public-resolvers.md" и например так же "quard9-resolvers.md" (в конфиге они включены)

[sources.'public-resolvers']
urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v2/public-resolvers.md', 'https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md']
cache_file = 'public-resolvers.md'
minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
refresh_delay = 72
prefix = ''

## Anonymized DNS relays

[sources.'relays']
urls = ['https://github.com/DNSCrypt/dnscrypt-resolvers/raw/master/v2/relays.md', 'https://download.dnscrypt.info/resolvers-list/v2/relays.md']
cache_file = 'relays.md'
minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
refresh_delay = 72
prefix = ''

## Quad9 over DNSCrypt - https://quad9.net/

[sources.quad9-resolvers]
urls = ['https://www.quad9.net/quad9-resolvers.md']
minisign_key = 'RWQBphd2+f6eiAqBsvDZEBXBGHQBJfeG6G+wJPPKxCZMoEQYpmoysKUN'
cache_file = 'quad9-resolvers.md'
prefix = 'quad9-'

и переменной "refresh_delay = 72" будет происходить тестирование всех серверов согласно списка в этих файлов, да еще потом refresh_delay

Скрытый текст

[2020-05-13 13:30:35] [NOTICE] dnscrypt-proxy 2.0.39
[2020-05-13 13:30:35] [NOTICE] Network connectivity detected
[2020-05-13 13:30:35] [NOTICE] Source [public-resolvers] loaded
[2020-05-13 13:30:35] [NOTICE] Source [relays] loaded
[2020-05-13 13:30:35] [NOTICE] Source [quad9-resolvers] loaded
[2020-05-13 13:30:35] [NOTICE] Firefox workaround initialized
[2020-05-13 13:30:35] [NOTICE] Now listening to 127.0.0.1:53 [UDP]
[2020-05-13 13:30:35] [NOTICE] Now listening to 127.0.0.1:53 [TCP]
[2020-05-13 13:30:35] [NOTICE] Now listening to 192.168.1.1:53 [UDP]
[2020-05-13 13:30:35] [NOTICE] Now listening to 192.168.1.1:53 [TCP]
[2020-05-13 13:30:36] [NOTICE] [sth-dnscrypt-se] OK (DNSCrypt) - rtt: 102ms
[2020-05-13 13:30:37] [NOTICE] [dnslify-doh] OK (DoH) - rtt: 72ms
[2020-05-13 13:30:37] [NOTICE] [nextdns] OK (DoH) - rtt: 126ms
[2020-05-13 13:30:41] [NOTICE] [publicarray-au-doh] OK (DoH) - rtt: 379ms
[2020-05-13 13:30:41] [NOTICE] [charis] TIMEOUT
[2020-05-13 13:30:42] [NOTICE] [opennic-rico4514] OK (DNSCrypt) - rtt: 294ms
[2020-05-13 13:30:42] [NOTICE] [dnscrypt.ca-2] OK (DNSCrypt) - rtt: 319ms
[2020-05-13 13:30:42] [NOTICE] [quad9-dnscrypt-ip4-nofilter-alt] OK (DNSCrypt) - rtt: 142ms
[2020-05-13 13:30:42] [NOTICE] [quad9-dnscrypt-ip4-nofilter-alt] OK (DNSCrypt) - rtt: 142ms - additional certificate
[2020-05-13 13:30:43] [NOTICE] [cz.nic] OK (DoH) - rtt: 74ms
[2020-05-13 13:30:43] [NOTICE] [ibksturm] OK (DNSCrypt) - rtt: 165ms
[2020-05-13 13:32:52] [NOTICE] [arvind-io] TIMEOUT
[2020-05-13 13:32:53] [NOTICE] [lelux.fi] OK (DoH) - rtt: 83ms
[2020-05-13 13:32:56] [NOTICE] System DNS configuration not usable yet, exceptionally resolving [i.233py.com] using fallback resolvers over udp
[2020-05-13 13:35:12] [NOTICE] [edoardo] TIMEOUT
[2020-05-13 13:35:12] [NOTICE] [rumpelsepp.org] OK (DoH) - rtt: 78ms
[2020-05-13 13:35:12] [NOTICE] [scaleway-fr] OK (DNSCrypt) - rtt: 147ms
[2020-05-13 13:35:13] [NOTICE] [cloudflare] OK (DoH) - rtt: 68ms
[2020-05-13 13:35:16] [NOTICE] [quad9-doh-ip4-nofilter-alt] OK (DoH) - rtt: 77ms
[2020-05-13 13:35:18] [NOTICE] [dnscrypt.ca-1-doh] OK (DoH) - rtt: 164ms
[2020-05-13 13:35:18] [NOTICE] [ffmuc.net] OK (DNSCrypt) - rtt: 162ms
[2020-05-13 13:35:19] [NOTICE] [faelix] OK (DoH) - rtt: 210ms
[2020-05-13 13:35:20] [NOTICE] [ams-doh-nl] OK (DoH) - rtt: 79ms
[2020-05-13 13:35:21] [NOTICE] [opennic-luggs] OK (DNSCrypt) - rtt: 301ms
[2020-05-13 13:35:23] [NOTICE] System DNS configuration not usable yet, exceptionally resolving [doh.233py.com] using fallback resolvers over udp
[2020-05-13 13:35:24] [NOTICE] System DNS configuration not usable yet, exceptionally resolving [doh.233py.com] using fallback resolvers over udp
[2020-05-13 13:35:26] [NOTICE] [dnscrypt.ca-1] OK (DNSCrypt) - rtt: 300ms
[2020-05-13 13:35:26] [NOTICE] [dns.digitale-gesellschaft.ch] OK (DoH) - rtt: 78ms
[2020-05-13 13:37:37] [NOTICE] [suami] TIMEOUT
[2020-05-13 13:37:40] [NOTICE] [doh.appliedprivacy.net] OK (DoH) - rtt: 72ms
[2020-05-13 13:37:42] [NOTICE] [sth-doh-se] OK (DoH) - rtt: 46ms
[2020-05-13 13:37:43] [NOTICE] [gridns-jp] OK (DoH) - rtt: 238ms
[2020-05-13 13:37:44] [NOTICE] [jp.tiarap.org] OK (DoH) - rtt: 84ms
[2020-05-13 13:37:44] [NOTICE] [qag.me] OK (DNSCrypt) - rtt: 427ms
[2020-05-13 13:37:47] [NOTICE] [quad101] OK (DoH) - rtt: 347ms
[2020-05-13 13:37:48] [NOTICE] [opennic-luggs2] OK (DNSCrypt) - rtt: 331ms
[2020-05-13 13:37:48] [NOTICE] [quad9-dnscrypt-ip4-nofilter-pri] OK (DNSCrypt) - rtt: 147ms
[2020-05-13 13:37:48] [NOTICE] [quad9-dnscrypt-ip4-nofilter-pri] OK (DNSCrypt) - rtt: 147ms - additional certificate
[2020-05-13 13:37:48] [NOTICE] [meganerd] OK (DNSCrypt) - rtt: 174ms
[2020-05-13 13:37:49] [NOTICE] [freetsa.org] OK (DNSCrypt) - rtt: 583ms
[2020-05-13 13:37:49] [NOTICE] [soltysiak] OK (DNSCrypt) - rtt: 189ms
[2020-05-13 13:37:49] [NOTICE] [ventricle.us] OK (DNSCrypt) - rtt: 275ms
[2020-05-13 13:37:50] [NOTICE] [publicarray-au2] OK (DNSCrypt) - rtt: 683ms
[2020-05-13 13:37:50] [NOTICE] [a-and-a] OK (DoH) - rtt: 79ms
[2020-05-13 13:37:50] [NOTICE] [ams-dnscrypt-nl] OK (DNSCrypt) - rtt: 181ms
[2020-05-13 13:37:52] [NOTICE] [libredns] OK (DoH) - rtt: 75ms
[2020-05-13 13:37:52] [NOTICE] [ev-to] OK (DNSCrypt) - rtt: 315ms
[2020-05-13 13:37:53] [NOTICE] [qualityology.com] OK (DNSCrypt) - rtt: 458ms
[2020-05-13 13:37:54] [NOTICE] [dnscrypt.ca-2-doh] OK (DoH) - rtt: 150ms
[2020-05-13 13:37:55] [NOTICE] [d0wn-is-ns2] OK (DNSCrypt) - rtt: 256ms
[2020-05-13 13:37:55] [NOTICE] [dns.digitale-gesellschaft.ch-2] OK (DoH) - rtt: 91ms
[2020-05-13 13:37:55] [NOTICE] [dnscrypt.eu-nl] OK (DNSCrypt) - rtt: 171ms
[2020-05-13 13:38:01] [NOTICE] [jp.tiar.app-doh] OK (DoH) - rtt: 240ms
[2020-05-13 13:38:02] [NOTICE] [ev-va] OK (DNSCrypt) - rtt: 464ms
[2020-05-13 13:38:03] [NOTICE] [quad9-doh-ip4-nofilter-pri] OK (DoH) - rtt: 77ms
[2020-05-13 13:38:03] [NOTICE] [dnscrypt.eu-dk] OK (DNSCrypt) - rtt: 116ms
[2020-05-13 13:38:03] [NOTICE] [opennic-bongobow] OK (DNSCrypt) - rtt: 133ms
[2020-05-13 13:38:04] [NOTICE] [publicarray-au] OK (DNSCrypt) - rtt: 776ms
[2020-05-13 13:38:05] [NOTICE] [doh.ffmuc.net] OK (DoH) - rtt: 207ms
[2020-05-13 13:38:05] [NOTICE] [jp.tiar.app] OK (DNSCrypt) - rtt: 471ms
[2020-05-13 13:38:06] [NOTICE] [dnscrypt.uk-ipv4] OK (DNSCrypt) - rtt: 162ms
[2020-05-13 13:38:06] [NOTICE] [d0wn-tz-ns1] OK (DNSCrypt) - rtt: 416ms
[2020-05-13 13:38:09] [NOTICE] [powerdns-doh] OK (DoH) - rtt: 95ms
[2020-05-13 13:38:11] [NOTICE] [doh-crypto-sx] OK (DoH) - rtt: 1033ms
[2020-05-13 13:38:16] [NOTICE] [opennic-R4SAS] OK (DNSCrypt) - rtt: 131ms
[2020-05-13 13:38:16] [NOTICE] [v.dnscrypt.uk-ipv4] OK (DNSCrypt) - rtt: 172ms
[2020-05-13 13:38:17] [NOTICE] [doh-fi-snopyta] OK (DoH) - rtt: 68ms
[2020-05-13 13:38:17] [NOTICE] [scaleway-ams] OK (DNSCrypt) - rtt: 182ms
[2020-05-13 13:38:17] [NOTICE] [skyfighter-dns] OK (DNSCrypt) - rtt: 157ms
[2020-05-13 13:38:17] [NOTICE] Sorted latencies:
[2020-05-13 13:38:17] [NOTICE] -    46ms sth-doh-se
[2020-05-13 13:38:17] [NOTICE] -    68ms cloudflare
[2020-05-13 13:38:17] [NOTICE] -    68ms doh-fi-snopyta
[2020-05-13 13:38:17] [NOTICE] -    72ms doh.appliedprivacy.net
[2020-05-13 13:38:17] [NOTICE] -    72ms dnslify-doh
[2020-05-13 13:38:17] [NOTICE] -    74ms cz.nic
[2020-05-13 13:38:17] [NOTICE] -    75ms libredns
[2020-05-13 13:38:17] [NOTICE] -    77ms quad9-doh-ip4-nofilter-alt
[2020-05-13 13:38:17] [NOTICE] -    77ms quad9-doh-ip4-nofilter-pri
[2020-05-13 13:38:17] [NOTICE] -    78ms rumpelsepp.org
[2020-05-13 13:38:17] [NOTICE] -    78ms dns.digitale-gesellschaft.ch
[2020-05-13 13:38:17] [NOTICE] -    79ms ams-doh-nl
[2020-05-13 13:38:17] [NOTICE] -    79ms a-and-a
[2020-05-13 13:38:17] [NOTICE] -    83ms lelux.fi
[2020-05-13 13:38:17] [NOTICE] -    84ms jp.tiarap.org
[2020-05-13 13:38:17] [NOTICE] -    91ms dns.digitale-gesellschaft.ch-2
[2020-05-13 13:38:17] [NOTICE] -    95ms powerdns-doh
[2020-05-13 13:38:17] [NOTICE] -   102ms sth-dnscrypt-se
[2020-05-13 13:38:17] [NOTICE] -   116ms dnscrypt.eu-dk
[2020-05-13 13:38:17] [NOTICE] -   126ms nextdns
[2020-05-13 13:38:17] [NOTICE] -   131ms opennic-R4SAS
[2020-05-13 13:38:17] [NOTICE] -   133ms opennic-bongobow
[2020-05-13 13:38:17] [NOTICE] -   142ms quad9-dnscrypt-ip4-nofilter-alt
[2020-05-13 13:38:17] [NOTICE] -   147ms scaleway-fr
[2020-05-13 13:38:17] [NOTICE] -   147ms quad9-dnscrypt-ip4-nofilter-pri
[2020-05-13 13:38:17] [NOTICE] -   150ms dnscrypt.ca-2-doh
[2020-05-13 13:38:17] [NOTICE] -   157ms skyfighter-dns
[2020-05-13 13:38:17] [NOTICE] -   162ms ffmuc.net
[2020-05-13 13:38:17] [NOTICE] -   162ms dnscrypt.uk-ipv4
[2020-05-13 13:38:17] [NOTICE] -   164ms dnscrypt.ca-1-doh
[2020-05-13 13:38:17] [NOTICE] -   165ms ibksturm
[2020-05-13 13:38:17] [NOTICE] -   171ms dnscrypt.eu-nl
[2020-05-13 13:38:17] [NOTICE] -   172ms v.dnscrypt.uk-ipv4
[2020-05-13 13:38:17] [NOTICE] -   174ms meganerd
[2020-05-13 13:38:17] [NOTICE] -   181ms ams-dnscrypt-nl
[2020-05-13 13:38:17] [NOTICE] -   182ms scaleway-ams
[2020-05-13 13:38:17] [NOTICE] -   189ms soltysiak
[2020-05-13 13:38:17] [NOTICE] -   207ms doh.ffmuc.net
[2020-05-13 13:38:17] [NOTICE] -   210ms faelix
[2020-05-13 13:38:17] [NOTICE] -   238ms gridns-jp
[2020-05-13 13:38:17] [NOTICE] -   240ms jp.tiar.app-doh
[2020-05-13 13:38:17] [NOTICE] -   256ms d0wn-is-ns2
[2020-05-13 13:38:17] [NOTICE] -   275ms ventricle.us
[2020-05-13 13:38:17] [NOTICE] -   294ms opennic-rico4514
[2020-05-13 13:38:17] [NOTICE] -   300ms dnscrypt.ca-1
[2020-05-13 13:38:17] [NOTICE] -   301ms opennic-luggs
[2020-05-13 13:38:17] [NOTICE] -   315ms ev-to
[2020-05-13 13:38:17] [NOTICE] -   319ms dnscrypt.ca-2
[2020-05-13 13:38:17] [NOTICE] -   331ms opennic-luggs2
[2020-05-13 13:38:17] [NOTICE] -   347ms quad101
[2020-05-13 13:38:17] [NOTICE] -   379ms publicarray-au-doh
[2020-05-13 13:38:17] [NOTICE] -   416ms d0wn-tz-ns1
[2020-05-13 13:38:17] [NOTICE] -   427ms qag.me
[2020-05-13 13:38:17] [NOTICE] -   458ms qualityology.com
[2020-05-13 13:38:17] [NOTICE] -   464ms ev-va
[2020-05-13 13:38:17] [NOTICE] -   471ms jp.tiar.app
[2020-05-13 13:38:17] [NOTICE] -   583ms freetsa.org
[2020-05-13 13:38:17] [NOTICE] -   683ms publicarray-au2
[2020-05-13 13:38:17] [NOTICE] -   776ms publicarray-au
[2020-05-13 13:38:17] [NOTICE] -  1033ms doh-crypto-sx
[2020-05-13 13:38:17] [NOTICE] Server with the lowest initial latency: sth-doh-se (rtt: 46ms)
[2020-05-13 13:38:17] [NOTICE] dnscrypt-proxy is ready - live servers: 60

И так 60 серверов по списку и повтор через  "refresh_delay"

На основании ответов "ms" будет выбран основной - быстрый для работы (в данном случае sth-doh-se = rtt: 46ms)

Рекомендация выбрать три наиболее быстрых по ответу, и включить строку "server_names" и проверить утверждение

Обнаружил у себя аналогичную проблему - огромный исходящий трафик, видимый в странице "Системный монитор" в WEB-интерфейсе.

Edited by vasek00

Share this post


Link to post
Share on other sites
11 минуту назад, vasek00 сказал:

Включил dnscrypt-proxy2 проверку на "счет виновника" и не нашел нечего :


/opt/etc/init.d # netstat -ntulp | grep dnscrypt-proxy
tcp        0      0 192.168.1.1:53          0.0.0.0:*               LISTEN      2355/dnscrypt-proxy
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      2355/dnscrypt-proxy
udp        0      0 192.168.1.1:53          0.0.0.0:*                           2355/dnscrypt-proxy
udp        0      0 127.0.0.1:53            0.0.0.0:*                           2355/dnscrypt-proxy
/opt/etc/init.d # 

 

Да, у меня это выглядело примерно так же, а трафик был.

Важный нюанс я, однако, забыл упомянуть в первом сообщении: у меня роутер с белым адресом в Интернете торчит.

Share this post


Link to post
Share on other sites
5 часов назад, HuduGuru сказал:

Обнаружил у себя аналогичную проблему - огромный исходящий трафик, видимый в странице "Системный монитор" в WEB-интерфейсе.

Эта "дырища" из-за правила в скрипте так в шапке темы и осталась, и не исправлена.

Надо автора темы позвать.

@ankar84 надо бы поправить правило в шапке, либо сделать сноску, о том, чем грозит такое использование.

Share this post


Link to post
Share on other sites
1 час назад, HuduGuru сказал:

Да, у меня это выглядело примерно так же, а трафик был.

Важный нюанс я, однако, забыл упомянуть в первом сообщении: у меня роутер с белым адресом в Интернете торчит.

Я вам привел пример откуда мог появиться трафик, из-за перебора всех серверов по списку *.md (отсутствие строки "server_names", при ее наличие перебора нет, а есть выбранные сервера не более 4) и повтор данной процедуры через "refresh_delay". В данном случае по логу время перебора для выбора быстрого потребовалось 8минут.

Share this post


Link to post
Share on other sites

Хочу запустить его на Extra с прошивкой 3.4.12 - не получается.

В логе пишет [FATAL] listen udp 127.0.0.1:5323: bind: address already in use

Не могу понять почему. Подскажите пожалуйста. На 2.16 с такой конфигурацией работал, а тут что случилось?

 

Share this post


Link to post
Share on other sites

поменял порт на 5555

пишет Dropping privileges и не стартует

Что это? Оно теперь вообще рабочее?

Share this post


Link to post
Share on other sites

 

15 часов назад, rotor сказал:

В логе пишет [FATAL] listen udp 127.0.0.1:5323: bind: address already in use

Так посмотрите кто занял этот порт.

 

11 час назад, rotor сказал:

пишет Dropping privileges и не стартует

Закомментируйте в файле .toml строку user_name = 'username'

  • Thanks 1

Share this post


Link to post
Share on other sites

Спасибо что откликнулись.

1 час назад, Albram сказал:

 

Так посмотрите кто занял этот порт.

 

Закомментируйте в файле .toml строку user_name = 'username'

Сразу было закоментированно.

Всё заработало-просто удалил и заново установил и настроил. Почему сразу не завелось, не понятно.

Но проц экстры, некоторое время, с ним грузится на 100% после перезагрузки.

Share this post


Link to post
Share on other sites

Может кому то это будет интересно. В известной статье на хабре Выборочный обход блокировок приводится иной способ перенаправления запросов к порту 53 "на себя"

Цитата

В этот же файл вы можете добавить (это необязательно) перенаправление всех запросов на внешний порт 53 на себя. Это нужно, чтобы клиенты в локальной сети не использовали сторонние DNS-сервисы. Запросы будут идти через штатный DNS-сервер. Перед последним exit добавьте:

if [ -z "$(iptables-save 2>/dev/null | grep "udp \-\-dport 53 \-j DNAT")" ]; then
	iptables -w -t nat -I PREROUTING -i br0 -p udp --dport 53 -j DNAT --to 192.168.0.1
fi

if [ -z "$(iptables-save 2>/dev/null | grep "tcp \-\-dport 53 \-j DNAT")" ]; then
	iptables -w -t nat -I PREROUTING -i br0 -p tcp --dport 53 -j DNAT --to 192.168.0.1
fi

Share this post


Link to post
Share on other sites

Помогите пожалуйста настроить.

Пришлось сбросить роутер до заводских.

В итоге стал перенастраивать DNSCrypt как тут в шапке. До этого уже много лет пользуюсь этим решением.

Но.

Столкнулся с проблемой обновления списка из-за python

Скрытый текст

~ # opkg install python-base python-urllib3
Unknown package 'python-base'.
Unknown package 'python-urllib3'.

 

Я нашел в депозитарии, что пакет изменился, поставил аналогичные:

Скрытый текст

 # opkg install python3-base
Installing python3-base (3.8.5-2) to root...
Downloading http://bin.entware.net/mipselsf-k3.4/python3-base_3.8.5-2_mipsel-3.4 .ipk
Configuring python3-base.
~ # opkg install python3-urllib3
Installing python3-urllib3 (1.25.10-1) to root...
Downloading http://bin.entware.net/mipselsf-k3.4/python3-urllib3_1.25.10-1_mipse l-3.4.ipk
Installing libbz2 (1.0.8-1) to root...
Downloading http://bin.entware.net/mipselsf-k3.4/libbz2_1.0.8-1_mipsel-3.4.ipk
Installing libtirpc (1.2.6-2) to root...

 

Но скрип обновления, который еще утром отработал ,выдаешь ошибку:

Скрытый текст

root@Keenetic_Ultra:/opt/etc/cron.daily$ ./generate-blacklist
Traceback (most recent call last):
  File "generate-domains-blacklist.py", line 8, in <module>
    import urllib2
ModuleNotFoundError: No module named 'urllib2'

 

Что делать?

 

Скрипт generate-domains-blacklist.py ниже

Скрытый текст

#! /usr/bin/env python

# run with python generate-domains-blacklist.py > list.txt.tmp && mv -f list.txt.tmp list

import argparse
import re
import sys
import urllib2


def parse_list(content, trusted=False):
    rx_comment = re.compile(r'^(#|$)')
    rx_inline_comment = re.compile(r'\s*#\s*[a-z0-9-].*$')
    rx_u = re.compile(r'^@*\|\|([a-z0-9.-]+[.][a-z]{2,})\^?(\$(popup|third-party))?$')
    rx_l = re.compile(r'^([a-z0-9.-]+[.][a-z]{2,})$')
    rx_h = re.compile(r'^[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}\s+([a-z0-9.-]+[.][a-z]{2,})$')
    rx_mdl = re.compile(r'^"[^"]+","([a-z0-9.-]+[.][a-z]{2,})",')
    rx_b = re.compile(r'^([a-z0-9.-]+[.][a-z]{2,}),.+,[0-9: /-]+,')
    rx_dq = re.compile(r'^address=/([a-z0-9.-]+[.][a-z]{2,})/.')
    rx_trusted = re.compile(r'^([*a-z0-9.-]+)$')

    names = set()
    rx_set = [rx_u, rx_l, rx_h, rx_mdl, rx_b, rx_dq]
    if trusted:
        rx_set = [rx_trusted]
    for line in content.splitlines():
        line = str.lower(str.strip(line))
        if rx_comment.match(line):
            continue
        line = rx_inline_comment.sub('', line)
        for rx in rx_set:
            matches = rx.match(line)
            if not matches:
                continue
            name = matches.group(1)
            names.add(name)
    return names


def load_from_url(url):
    sys.stderr.write("Loading data from [{}]\n".format(url))
    req = urllib2.Request(url)
    trusted = False
    if req.get_type() == "file":
        trusted = True
    response = None
    try:
        response = urllib2.urlopen(req, timeout=int(args.timeout))
    except urllib2.URLError as err:
        raise Exception("[{}] could not be loaded: {}\n".format(url, err))
    if trusted is False and response.getcode() != 200:
        raise Exception("[{}] returned HTTP code {}\n".format(url, response.getcode()))
    content = response.read()

    return (content, trusted)


def name_cmp(name):
    parts = name.split(".")
    parts.reverse()
    return str.join(".", parts)


def has_suffix(names, name):
    parts = str.split(name, ".")
    while parts:
        parts = parts[1:]
        if str.join(".", parts) in names:
            return True

    return False


def whitelist_from_url(url):
    if not url:
        return set()
    content, trusted = load_from_url(url)

    return parse_list(content, trusted)


def blacklists_from_config_file(file, whitelist, time_restricted_url, ignore_retrieval_failure):
    blacklists = {}
    whitelisted_names = set()
    all_names = set()
    unique_names = set()

    # Load conf & blacklists
    with open(file) as fd:
        for line in fd:
            line = str.strip(line)
            if str.startswith(line, "#") or line == "":
                continue
            url = line
            try:
                content, trusted = load_from_url(url)
                names = parse_list(content, trusted)
                blacklists[url] = names
                all_names |= names
            except Exception as e:
                sys.stderr.write(e.message)
                if not ignore_retrieval_failure:
                    exit(1)

    # Time-based blacklist
    if time_restricted_url and not re.match(r'^[a-z0-9]+:', time_restricted_url):
        time_restricted_url = "file:" + time_restricted_url

    if time_restricted_url:
        time_restricted_content, trusted = load_from_url(time_restricted_url)
        time_restricted_names = parse_list(time_restricted_content)

        if time_restricted_names:
            print("########## Time-based blacklist ##########\n")
            for name in time_restricted_names:
                print(name)

        # Time restricted names should be whitelisted, or they could be always blocked
        whitelisted_names |= time_restricted_names

    # Whitelist
    if whitelist and not re.match(r'^[a-z0-9]+:', whitelist):
        whitelist = "file:" + whitelist

    whitelisted_names |= whitelist_from_url(whitelist)

    # Process blacklists
    for url, names in blacklists.items():
        print("\n\n########## Blacklist from {} ##########\n".format(url))
        ignored, whitelisted = 0, 0
        list_names = list()
        for name in names:
            if has_suffix(all_names, name) or name in unique_names:
                ignored = ignored + 1
            elif has_suffix(whitelisted_names, name) or name in whitelisted_names:
                whitelisted = whitelisted + 1
            else:
                list_names.append(name)
                unique_names.add(name)

        list_names.sort(key=name_cmp)
        if ignored:
            print("# Ignored duplicates: {}\n".format(ignored))
        if whitelisted:
            print("# Ignored entries due to the whitelist: {}\n".format(whitelisted))
        for name in list_names:
            print(name)


argp = argparse.ArgumentParser(description="Create a unified blacklist from a set of local and remote files")
argp.add_argument("-c", "--config", default="domains-blacklist.conf",
    help="file containing blacklist sources")
argp.add_argument("-w", "--whitelist", default="domains-whitelist.txt",
    help="file containing a set of names to exclude from the blacklist")
argp.add_argument("-r", "--time-restricted", default="domains-time-restricted.txt",
    help="file containing a set of names to be time restricted")
argp.add_argument("-i", "--ignore-retrieval-failure", action='store_true',
    help="generate list even if some urls couldn't be retrieved")
argp.add_argument("-t", "--timeout", default=30,
    help="URL open timeout")
args = argp.parse_args()

conf = args.config
whitelist = args.whitelist
time_restricted = args.time_restricted
ignore_retrieval_failure = args.ignore_retrieval_failure

blacklists_from_config_file(conf, whitelist, time_restricted, ignore_retrieval_failure)

 

 

Share this post


Link to post
Share on other sites
2 часа назад, ykutik сказал:

Помогите пожалуйста настроить.

Пришлось сбросить роутер до заводских.

В итоге стал перенастраивать DNSCrypt как тут в шапке. До этого уже много лет пользуюсь этим решением.

Но.

Столкнулся с проблемой обновления списка из-за python

  Показать содержимое

~ # opkg install python-base python-urllib3
Unknown package 'python-base'.
Unknown package 'python-urllib3'.

 

Я нашел в депозитарии, что пакет изменился, поставил аналогичные:

  Показать содержимое

 # opkg install python3-base
Installing python3-base (3.8.5-2) to root...
Downloading http://bin.entware.net/mipselsf-k3.4/python3-base_3.8.5-2_mipsel-3.4 .ipk
Configuring python3-base.
~ # opkg install python3-urllib3
Installing python3-urllib3 (1.25.10-1) to root...
Downloading http://bin.entware.net/mipselsf-k3.4/python3-urllib3_1.25.10-1_mipse l-3.4.ipk
Installing libbz2 (1.0.8-1) to root...
Downloading http://bin.entware.net/mipselsf-k3.4/libbz2_1.0.8-1_mipsel-3.4.ipk
Installing libtirpc (1.2.6-2) to root...

 

Но скрип обновления, который еще утром отработал ,выдаешь ошибку:

  Показать содержимое

root@Keenetic_Ultra:/opt/etc/cron.daily$ ./generate-blacklist
Traceback (most recent call last):
  File "generate-domains-blacklist.py", line 8, in <module>
    import urllib2
ModuleNotFoundError: No module named 'urllib2'

 

Что делать?

 

Скрипт generate-domains-blacklist.py ниже

  Показать содержимое

#! /usr/bin/env python

# run with python generate-domains-blacklist.py > list.txt.tmp && mv -f list.txt.tmp list

import argparse
import re
import sys
import urllib2


def parse_list(content, trusted=False):
    rx_comment = re.compile(r'^(#|$)')
    rx_inline_comment = re.compile(r'\s*#\s*[a-z0-9-].*$')
    rx_u = re.compile(r'^@*\|\|([a-z0-9.-]+[.][a-z]{2,})\^?(\$(popup|third-party))?$')
    rx_l = re.compile(r'^([a-z0-9.-]+[.][a-z]{2,})$')
    rx_h = re.compile(r'^[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}\s+([a-z0-9.-]+[.][a-z]{2,})$')
    rx_mdl = re.compile(r'^"[^"]+","([a-z0-9.-]+[.][a-z]{2,})",')
    rx_b = re.compile(r'^([a-z0-9.-]+[.][a-z]{2,}),.+,[0-9: /-]+,')
    rx_dq = re.compile(r'^address=/([a-z0-9.-]+[.][a-z]{2,})/.')
    rx_trusted = re.compile(r'^([*a-z0-9.-]+)$')

    names = set()
    rx_set = [rx_u, rx_l, rx_h, rx_mdl, rx_b, rx_dq]
    if trusted:
        rx_set = [rx_trusted]
    for line in content.splitlines():
        line = str.lower(str.strip(line))
        if rx_comment.match(line):
            continue
        line = rx_inline_comment.sub('', line)
        for rx in rx_set:
            matches = rx.match(line)
            if not matches:
                continue
            name = matches.group(1)
            names.add(name)
    return names


def load_from_url(url):
    sys.stderr.write("Loading data from [{}]\n".format(url))
    req = urllib2.Request(url)
    trusted = False
    if req.get_type() == "file":
        trusted = True
    response = None
    try:
        response = urllib2.urlopen(req, timeout=int(args.timeout))
    except urllib2.URLError as err:
        raise Exception("[{}] could not be loaded: {}\n".format(url, err))
    if trusted is False and response.getcode() != 200:
        raise Exception("[{}] returned HTTP code {}\n".format(url, response.getcode()))
    content = response.read()

    return (content, trusted)


def name_cmp(name):
    parts = name.split(".")
    parts.reverse()
    return str.join(".", parts)


def has_suffix(names, name):
    parts = str.split(name, ".")
    while parts:
        parts = parts[1:]
        if str.join(".", parts) in names:
            return True

    return False


def whitelist_from_url(url):
    if not url:
        return set()
    content, trusted = load_from_url(url)

    return parse_list(content, trusted)


def blacklists_from_config_file(file, whitelist, time_restricted_url, ignore_retrieval_failure):
    blacklists = {}
    whitelisted_names = set()
    all_names = set()
    unique_names = set()

    # Load conf & blacklists
    with open(file) as fd:
        for line in fd:
            line = str.strip(line)
            if str.startswith(line, "#") or line == "":
                continue
            url = line
            try:
                content, trusted = load_from_url(url)
                names = parse_list(content, trusted)
                blacklists[url] = names
                all_names |= names
            except Exception as e:
                sys.stderr.write(e.message)
                if not ignore_retrieval_failure:
                    exit(1)

    # Time-based blacklist
    if time_restricted_url and not re.match(r'^[a-z0-9]+:', time_restricted_url):
        time_restricted_url = "file:" + time_restricted_url

    if time_restricted_url:
        time_restricted_content, trusted = load_from_url(time_restricted_url)
        time_restricted_names = parse_list(time_restricted_content)

        if time_restricted_names:
            print("########## Time-based blacklist ##########\n")
            for name in time_restricted_names:
                print(name)

        # Time restricted names should be whitelisted, or they could be always blocked
        whitelisted_names |= time_restricted_names

    # Whitelist
    if whitelist and not re.match(r'^[a-z0-9]+:', whitelist):
        whitelist = "file:" + whitelist

    whitelisted_names |= whitelist_from_url(whitelist)

    # Process blacklists
    for url, names in blacklists.items():
        print("\n\n########## Blacklist from {} ##########\n".format(url))
        ignored, whitelisted = 0, 0
        list_names = list()
        for name in names:
            if has_suffix(all_names, name) or name in unique_names:
                ignored = ignored + 1
            elif has_suffix(whitelisted_names, name) or name in whitelisted_names:
                whitelisted = whitelisted + 1
            else:
                list_names.append(name)
                unique_names.add(name)

        list_names.sort(key=name_cmp)
        if ignored:
            print("# Ignored duplicates: {}\n".format(ignored))
        if whitelisted:
            print("# Ignored entries due to the whitelist: {}\n".format(whitelisted))
        for name in list_names:
            print(name)


argp = argparse.ArgumentParser(description="Create a unified blacklist from a set of local and remote files")
argp.add_argument("-c", "--config", default="domains-blacklist.conf",
    help="file containing blacklist sources")
argp.add_argument("-w", "--whitelist", default="domains-whitelist.txt",
    help="file containing a set of names to exclude from the blacklist")
argp.add_argument("-r", "--time-restricted", default="domains-time-restricted.txt",
    help="file containing a set of names to be time restricted")
argp.add_argument("-i", "--ignore-retrieval-failure", action='store_true',
    help="generate list even if some urls couldn't be retrieved")
argp.add_argument("-t", "--timeout", default=30,
    help="URL open timeout")
args = argp.parse_args()

conf = args.config
whitelist = args.whitelist
time_restricted = args.time_restricted
ignore_retrieval_failure = args.ignore_retrieval_failure

blacklists_from_config_file(conf, whitelist, time_restricted, ignore_retrieval_failure)

 

 

 

 

Вообщем изменил ситакис согласно рекомендациям

import urllib.request
req=urllib.request.Request(api_url,binary_data,header)
f=urllib.request.urlopen(req)

Но теперь совсем скрип не работает

Скрытый текст

#! /usr/bin/env python

# run with python generate-domains-blacklist.py > list.txt.tmp && mv -f list.txt.tmp list

import argparse
import re
import sys
import urllib.request


def parse_list(content, trusted=False):
    rx_comment = re.compile(r'^(#|$)')
    rx_inline_comment = re.compile(r'\s*#\s*[a-z0-9-].*$')
    rx_u = re.compile(r'^@*\|\|([a-z0-9.-]+[.][a-z]{2,})\^?(\$(popup|third-party))?$')
    rx_l = re.compile(r'^([a-z0-9.-]+[.][a-z]{2,})$')
    rx_h = re.compile(r'^[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}\s+([a-z0-9.-]+[.][a-z]{2,})$')
    rx_mdl = re.compile(r'^"[^"]+","([a-z0-9.-]+[.][a-z]{2,})",')
    rx_b = re.compile(r'^([a-z0-9.-]+[.][a-z]{2,}),.+,[0-9: /-]+,')
    rx_dq = re.compile(r'^address=/([a-z0-9.-]+[.][a-z]{2,})/.')
    rx_trusted = re.compile(r'^([*a-z0-9.-]+)$')

    names = set()
    rx_set = [rx_u, rx_l, rx_h, rx_mdl, rx_b, rx_dq]
    if trusted:
        rx_set = [rx_trusted]
    for line in content.splitlines():
        line = str.lower(str.strip(line))
        if rx_comment.match(line):
            continue
        line = rx_inline_comment.sub('', line)
        for rx in rx_set:
            matches = rx.match(line)
            if not matches:
                continue
            name = matches.group(1)
            names.add(name)
    return names


def load_from_url(url):
    sys.stderr.write("Loading data from [{}]\n".format(url))
    req = urllib.request.Request(url)
    trusted = False
    if req.get_type() == "file":
        trusted = True
    response = None
    try:
        response = urllib.request.urlopen(req, timeout=int(args.timeout))
    except urllib.request.URLError as err:
        raise Exception("[{}] could not be loaded: {}\n".format(url, err))
    if trusted is False and response.getcode() != 200:
        raise Exception("[{}] returned HTTP code {}\n".format(url, response.getcode()))
    content = response.read()

    return (content, trusted)


def name_cmp(name):
    parts = name.split(".")
    parts.reverse()
    return str.join(".", parts)


def has_suffix(names, name):
    parts = str.split(name, ".")
    while parts:
        parts = parts[1:]
        if str.join(".", parts) in names:
            return True

    return False


def whitelist_from_url(url):
    if not url:
        return set()
    content, trusted = load_from_url(url)

    return parse_list(content, trusted)


def blacklists_from_config_file(file, whitelist, time_restricted_url, ignore_retrieval_failure):
    blacklists = {}
    whitelisted_names = set()
    all_names = set()
    unique_names = set()

    # Load conf & blacklists
    with open(file) as fd:
        for line in fd:
            line = str.strip(line)
            if str.startswith(line, "#") or line == "":
                continue
            url = line
            try:
                content, trusted = load_from_url(url)
                names = parse_list(content, trusted)
                blacklists[url] = names
                all_names |= names
            except Exception as e:
                sys.stderr.write(e.message)
                if not ignore_retrieval_failure:
                    exit(1)

    # Time-based blacklist
    if time_restricted_url and not re.match(r'^[a-z0-9]+:', time_restricted_url):
        time_restricted_url = "file:" + time_restricted_url

    if time_restricted_url:
        time_restricted_content, trusted = load_from_url(time_restricted_url)
        time_restricted_names = parse_list(time_restricted_content)

        if time_restricted_names:
            print("########## Time-based blacklist ##########\n")
            for name in time_restricted_names:
                print(name)

        # Time restricted names should be whitelisted, or they could be always blocked
        whitelisted_names |= time_restricted_names

    # Whitelist
    if whitelist and not re.match(r'^[a-z0-9]+:', whitelist):
        whitelist = "file:" + whitelist

    whitelisted_names |= whitelist_from_url(whitelist)

    # Process blacklists
    for url, names in blacklists.items():
        print("\n\n########## Blacklist from {} ##########\n".format(url))
        ignored, whitelisted = 0, 0
        list_names = list()
        for name in names:
            if has_suffix(all_names, name) or name in unique_names:
                ignored = ignored + 1
            elif has_suffix(whitelisted_names, name) or name in whitelisted_names:
                whitelisted = whitelisted + 1
            else:
                list_names.append(name)
                unique_names.add(name)

        list_names.sort(key=name_cmp)
        if ignored:
            print("# Ignored duplicates: {}\n".format(ignored))
        if whitelisted:
            print("# Ignored entries due to the whitelist: {}\n".format(whitelisted))
        for name in list_names:
            print(name)


argp = argparse.ArgumentParser(description="Create a unified blacklist from a set of local and remote files")
argp.add_argument("-c", "--config", default="domains-blacklist.conf",
    help="file containing blacklist sources")
argp.add_argument("-w", "--whitelist", default="domains-whitelist.txt",
    help="file containing a set of names to exclude from the blacklist")
argp.add_argument("-r", "--time-restricted", default="domains-time-restricted.txt",
    help="file containing a set of names to be time restricted")
argp.add_argument("-i", "--ignore-retrieval-failure", action='store_true',
    help="generate list even if some urls couldn't be retrieved")
argp.add_argument("-t", "--timeout", default=30,
    help="URL open timeout")
args = argp.parse_args()

conf = args.config
whitelist = args.whitelist
time_restricted = args.time_restricted
ignore_retrieval_failure = args.ignore_retrieval_failure

blacklists_from_config_file(conf, whitelist, time_restricted, ignore_retrieval_failure)

 

Скрытый текст

root@Keenetic_Ultra:/opt/etc/cron.daily$ ./generate-blacklist
Loading data from []
Traceback (most recent call last):
  File "generate-domains-blacklist.py", line 96, in blacklists_from_config_file
    content, trusted = load_from_url(url)
  File "generate-domains-blacklist.py", line 42, in load_from_url
    req = urllib.request.Request(url)
  File "/opt/lib/python3.8/urllib/request.py", line 328, in __init__
  File "/opt/lib/python3.8/urllib/request.py", line 354, in full_url
  File "/opt/lib/python3.8/urllib/request.py", line 383, in _parse
ValueError: unknown url type: '\ufeff'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "generate-domains-blacklist.py", line 168, in <module>
    blacklists_from_config_file(conf, whitelist, time_restricted, ignore_retrieval_failure)
  File "generate-domains-blacklist.py", line 101, in blacklists_from_config_file
    sys.stderr.write(e.message)
AttributeError: 'ValueError' object has no attribute 'message'

 

 

Помогите поправить скрипт под нового Pyton'a?

 

Share this post


Link to post
Share on other sites
31 минуту назад, TheBB сказал:

Спасибо, заработало. Правда пришлось сделать имена файлов "толерантными"

Они решили blacklist  заменить на blocklists....

А whitelist на allowlist....

 

  • Thanks 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.


×
×
  • Create New...