пятница, 30 октября 2015 г.

Squid на Windows: мобильная экономия

Вы сколько угодно можете выпендриваться, говоря, "У нас в Москве безлимит стоит 400 рублей в месяц и мне западло даже думать о кэшировании! И вообще, сквид умер и нафиг не нужен!", но это ровно до тех пор, как вам взбрендится воспользоваться LTE/3G/GPRS - не всем повезло жить в Нерезиновой. :) (Но даже и в этом случае - в кризис да и обычно выживают чаще жлобы, чем транжиры).

Не знаю и знать не хочу, как там у вас, в Монстрополисе в Нерезиновой, но повсюду в мире интернет дорогой. Особенно не пиринговый. Особенно мобильный - безлимитные тарифы есть в считанных странах (по пальчикам одной руки черепашки-мутанта).

В остальных странах так называемый безлимит - это курнадцать гигабайт на полной скорости, обычно только облизнуться, а потом - 64/128 кбит. Сосать тырмыз. Да.

Обычные пользователи лезут за бумажником, скорбно вздохнув и матюкнув жлобство ОТПСОСов, но интеллигентные люди чешут репу и припоминают Polipo или, вообще, кэширование всуе.

Мы, однако, не настолько мазохисты и вкрации вкратце, ёпто, вкратце! (Учите родной язык, мать вашу так за ногу, дышлом крещеную!) напишем РУКОВОДСТВО ДЛЯ ЖЛОБОВ.

Как сэкономить на трафике мобильного девайса - общие положения

В случае ноутбука, оснащенного свистком для мобилиздеца, у вас есть два основных пожирателя трафика. Это DNS (описано ранее, как его нужно кэшировать) и HTTP/HTTPS (вот тут вам всякие шибздики типа Polipo нифига не в помощь, HTTPS кэшировать - это вам не хрен сосать в сырую погоду).

Соответственно, у вас, красноглазого, две задачи:
  1. Закэшировать DNS (Unbound вам в помощь)
  2. Закэшировать HTTP/HTTPS
Расточители могут дальше не читать, дочеря и сыновья Рокфеллеров - тоже, а те, которые с красными глазками - добро пожаловать дальше.

В случае мобильного устройства (ноутбука) себя, любимого - кэширование антивирусных баз и обновлений Шиндошс не имеет смысла. Все остальное - по мере возможности по максимуму.

Как это сделать конкретно?

Обычные пользователи на этом месте валят смотреть "Звездные Войны". Дружно. Колонной по четыре. Идите дальше к остальным киборгам и платите 1,85. Боливару не снести двоих.

Красноглазым СЮДА.

Да. Сквид. Который - дабы он годился нам к употреблению - на Шиндошс x64 надо хитро настроить, чтобы: 

а) все летало
б) не улетало бабло
в) чтобы HTTPS тоже кэшить - ну, в большинстве случаев.

Предварительно устанавливаем и настраиваем DNS-кэш. И убеждаемся, что он у нас работает,

Особо продвинутые могут также снабдить свое мобильное устройство Torом и Privoxy, дабы вертеть на детородном органе всяческих запрещаторов и регуляторов - пшли бы они в трещину к ишаку. Видали мы их в гробу, в белых тапках. Мы сами решим, что нам вредно, а что полезно, без санитаров. :)

Вернемся, однако, к нашим баранАм.

Итак, мы тут упоминали HTTPS. Соответственно, понадобится корневой серт, которому мы будем верить.

Создадим его:

 # Создадим ключ, без шифрования и пароля  
 # Его, ежу понятно, надо оберегать  
 openssl genrsa -out rootCA.key 2048  
   
 # Подпишем его  
 openssl req -x509 -sha256 -new -nodes -config D:\OpenSSL-Win64\bin\openssl.cfg -key rootCA.key -days 10950 -out rootCA.crt  
   
 # Конвертируем в DER и установим на свою машину - везде, где он нужен  
 # Файлы ключа и сертификата отложим в сторону, для кэша  
 openssl x509 -in rootCA.crt -inform PEM -out rootCA.der -outform DER  
   

Установим Squid, который ранее скачали. Он будет установлен, добавлен в автоматический запуск сервисов, и запущен с умолчательной конфигурацией. Можно его сразу же остановить - это не то, что нам нужно:

 net stop squidsrv  

Положим сгенерированные сертификаты в директорию:


Не забудем сгенерировать DH-параметры:

 openssl dhparam -outform PEM -out dhparam.pem 2048  

и положим их туда же.

Теперь напишем в точности вот такой squid.conf и поместим в ту же директорию:
 # -------------------------------------  
 # ACL's  
 # -------------------------------------  
 acl localnet src 10.0.0.0/8     # RFC1918 possible internal network  
 acl localnet src 172.16.0.0/12     # RFC1918 possible internal network  
 acl localnet src 192.168.0.0/16     # RFC1918 possible internal network  
 #acl localnet src fc00::/7    # RFC 4193 local private network range  
 #acl localnet src fe80::/10   # RFC 4291 link-local (directly plugged) machines  
   
 acl SSL_ports port 443  
 acl SSL_ports port 8443  
 acl Safe_ports port 80          # http  
 acl Safe_ports port 21          # ftp  
 acl Safe_ports port 443          # https  
 acl Safe_ports port 70          # gopher  
 acl Safe_ports port 210          # wais  
 acl Safe_ports port 1025-65535     # unregistered ports  
 acl Safe_ports port 280          # http-mgmt  
 acl Safe_ports port 488          # gss-http  
 acl Safe_ports port 591          # filemaker  
 acl Safe_ports port 777          # multiling http  
 acl CONNECT method CONNECT  
   
 # No-cache ACLs  
 acl dont_cache dstdomain rulesofwargame.com imgur.com  
   
 # Privoxy+Tor acl  
 acl tor_url dstdom_regex "C:/Squid/etc/squid/url.tor"  
   
 # -------------------------------------  
 # Access parameters  
 # -------------------------------------  
 # Deny requests to unknown ports  
 http_access deny !Safe_ports  
   
 # Deny CONNECT to other than SSL ports  
 http_access deny CONNECT !SSL_ports  
   
 # Only allow cachemgr access from localhost  
 http_access allow localhost manager  
 http_access deny manager  
 http_access deny to_localhost  
   
 # Rule allowing access from your local networks.  
 # Adapt localnet in the ACL section to list your (internal) IP networks  
 # from where browsing should be allowed  
 http_access allow localnet  
 http_access allow localhost  
   
 # Cache directives  
 cache deny dont_cache  
   
 # Disable alternate protocols  
 reply_header_access Alternate-Protocol deny all  
 # Disable HSTS  
 reply_header_access Strict-Transport-Security deny all  
 reply_header_replace Strict-Transport-Security max-age=0; includeSubDomains  
 # Normalize Vary to reduce duplicates  
 reply_header_access Vary deny all  
 reply_header_replace Vary Accept-Encoding  
   
 # SSL bump rules  
 sslproxy_cert_error allow all  
 acl DiscoverSNIHost at_step SslBump1  
 ssl_bump peek DiscoverSNIHost  
 acl NoSSLIntercept ssl::server_name_regex -i "C:/Squid/etc/squid/url.nobump"  
 acl NoSSLIntercept ssl::server_name_regex -i "C:/Squid/etc/squid/url.tor"  
 ssl_bump splice NoSSLIntercept  
 ssl_bump bump all  
   
 # Privoxy+Tor access rules  
 never_direct allow tor_url  
   
 # And finally deny all other access to this proxy  
 http_access deny all  
   
 # -------------------------------------  
 # HTTP parameters  
 # -------------------------------------  
   
 # Local Privoxy is cache parent  
 cache_peer 127.0.0.1 parent 8118 0 no-query no-digest default  
   
 cache_peer_access 127.0.0.1 allow tor_url  
 cache_peer_access 127.0.0.1 deny all  
   
 # Don't cache 404 long time  
 negative_ttl 5 minutes  
   
 # -------------------------------------  
 # Cache parameters  
 # -------------------------------------  
 # Squid normally listens to port 3128  
 #       dhparams=     File containing DH parameters for temporary/ephemeral  
 #               DH key exchanges. See OpenSSL documentation for details  
 #               on how to create this file.  
 #               WARNING: EDH ciphers will be silently disabled if this  
 #                     option is not set.  
 http_port 3128 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/etc/squid/rootCA.crt key=/etc/squid/rootCA.key options=NO_SSLv3 dhparams=/etc/squid/dhparam.pem  
 sslproxy_cafile /etc/ssl/certs/ca-bundle.trust.crt  
 sslproxy_options NO_SSLv3,SINGLE_DH_USE  
 sslproxy_cipher EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:HIGH:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS  
 sslcrtd_program /lib/squid/ssl_crtd -s /var/cache/squid_ssldb -M 4MB  
   
 # Turn off collect per-client statistics  
 client_db off  
   
 # Hide internal networks details outside  
 via off  
 forwarded_for delete  
   
 pipeline_prefetch 4  
 reload_into_ims on  
   
 # Do not show Squid version  
 httpd_suppress_version_string on  
   
 # Specify local DNS cache  
 dns_nameservers 127.0.0.1  
   
 visible_hostname cthulhu_jr  
   
 dns_v4_first on  
   
 # -------------------------------------  
 # Store parameters  
 # -------------------------------------  
 # Uncomment and adjust the following to add a disk cache directory  
 cache_dir ufs C:/squid/var/cache 8192 16 256  
   
 # -------------------------------------  
 # Memory parameters  
 # -------------------------------------  
 cache_mem 256 Mb  
 maximum_object_size_in_memory 2 Mb  
 maximum_object_size 4 Gb  
   
 # -------------------------------------  
 # Tuning parameters  
 # -------------------------------------  
 memory_replacement_policy heap GDSF  
 cache_replacement_policy heap LFUDA  
   
 # Default is 20  
 store_objects_per_bucket 128  
   
 # Shutdown delay before terminate connections  
 shutdown_lifetime 1 second  
   
 # -------------------------------------  
 # Process/log parameters  
 # -------------------------------------  
 # Access log  
 access_log daemon:C:/squid/var/logs/access.log squid  
   
 logfile_rotate 0  
   
 # Cache log  
 cache_log C:/squid/var/logs/cache.log  
   
 # Store log  
 cache_store_log none  
   
 # Leave coredumps in the first cache dir  
 coredump_dir /var/cache/squid  
   
 # Buffered logs. Default is off  
 buffered_logs on  
   
 strip_query_terms off  
   
 # -------------------------------------  
 # Content parameters  
 # -------------------------------------  
 quick_abort_min 100 KB  
 quick_abort_max 1 MB  
 quick_abort_pct 80  
   
 # Keep swf in cache  
 refresh_pattern -i \.swf$     10080     100%     43200     override-expire reload-into-ims ignore-private  
 # .NET cache  
 refresh_pattern -i \.((a|m)s(h|p)x?)$          10080     100%     43200     reload-into-ims ignore-private  
 # Other long-lived items  
 refresh_pattern -i \.(jp(e?g|e|2)|gif|png|tiff?|bmp|ico|svg|webp|flv|f4f|mp4|ttf|eot|woff)(\?.*)?$     14400     99%     518400      override-expire ignore-reload reload-into-ims ignore-private ignore-must-revalidate  
 refresh_pattern -i \.((cs|d?|m?|p?|r?|s?|w?|x?|z?)h?t?m?(l?)|(c|x|j)ss|js(t?|px)|php(3?|5?)|rss|atom|vr(t|ml))(\?.*)?$     10080     90%     86400     override-expire override-lastmod reload-into-ims ignore-private ignore-must-revalidate  
 # Default patterns  
 refresh_pattern -i (/cgi-bin/|\?)     0     0%     0  
 refresh_pattern     .     0     20%     10080     override-lastmod reload-into-ims ignore-private  
 ##  
 #nonhierarchical_direct off  
 #debug_options ALL,0 44,2 11,2  
 ##  

Файл url.tor:

 torproject.*  
 archive\.org.*  
 livejournal\.com.*  
 #wordpress\.com.*  
 #youtube.*  
 #ytimg.*  
 #googlevideo.*  
 #google.*  
 #googleapis.*  
 #googleusercontent.*  
 #gstatic.*  
 #gmodules.*  
 #blogger.*  
 #blogspot.*  
 #facebook.*  
 #fb.*  
   
и файл url.nobump:
 localhost  
 # ICQ  
 icq\.com  
 icq\.net  
 mrim\.mail\.ru  
 # Docs/Clouds  
 e\.mail\.ru  
 docs\.mail\.ru  
 cloud\.mail\.ru  
 drive\.google\.com  
 disk\.yandex\.ru  
 # Banking  
 # WU (Squid 3.5.x and above with SSL Bump)  
 # Only this three sites must be spliced.  
 fe1\.update\.microsoft\.com\.akadns\.net  
 fe2\.update\.microsoft\.com\.akadns\.net  
 fe2\.update\.microsoft\.com  
 # Mozilla services  
 services\.mozilla\.com  

и запустим наш Squid с новыми конфигурациями:
 net start squidsrv  

Осталась мелочь. Настроить нашу машину на использование прокси:


Если вы все сделали правильно, то в логах, разумеется, после прогрева кэша, будет примерно следующее:


а ваш провайдер недополучит примерно 30-40% (в среднем) денег за тот же самый объем трафика (по моей личной статистике - до 50-60%).

И если у вас установлен правильно настроенный Tor Bundle и Privoxy, то в access.log будут вот такие записи при обращении:

 1446552738.421  8015 127.0.0.1 TCP_TUNNEL/200 68644 CONNECT www.torproject.org:443 - FIRSTUP_PARENT/127.0.0.1 -  
 1446552738.647 10617 127.0.0.1 TCP_TUNNEL/200 136911 CONNECT www.torproject.org:443 - FIRSTUP_PARENT/127.0.0.1 -  
 1446552738.808  8401 127.0.0.1 TCP_TUNNEL/200 23501 CONNECT www.torproject.org:443 - FIRSTUP_PARENT/127.0.0.1 -  
 1446552738.969  8605 127.0.0.1 TCP_TUNNEL/200 30266 CONNECT www.torproject.org:443 - FIRSTUP_PARENT/127.0.0.1 -  
 1446552739.131  8687 127.0.0.1 TCP_TUNNEL/200 2796 CONNECT www.torproject.org:443 - FIRSTUP_PARENT/127.0.0.1 -  
 1446552740.910  8015 127.0.0.1 TCP_TUNNEL/200 7841 CONNECT www.torproject.org:443 - FIRSTUP_PARENT/127.0.0.1 -  
   

И - да, вы имеете полноценный HTTPS-прокси с бампом, который должен показывать для всех сайтов (кроме списка url.nobump) примерно следующее:


Да, в качестве корневого сертификата должен быть корневой сертификат вашего прокси, который вы ранее сгенерировали и установили. Сечете, о чем я? 

PS. Продвинутым красноглазым хочу напомнить - кэш не только экономит ваши деньги, но и защищает. Если вы удосужились настроить ваш локальный кэш DNS с DNSSEC. получаете для него данные через DNSCrypt, и ваш локальный кэширующий прокси снабжен Tor - то вы весьма нешуточно усиливаете вашу защиту от всяких нехороших парней.

PPS. А теперь приняли таблетки и марш в палату! Параноики живут дольше - мы бережем себе подобных! :)

вторник, 27 октября 2015 г.

Squid: SSL Bump и Windows Update

Администраторы новых версий Squid - 3.5.x и 4.x.x - неожиданно для себя выяснили, что Windows Update с использованием SSL Bump не работают.

Для Squid 3.4.x проблема решалась относительно просто. Достаточно было вычислить все IP-диапазоны авторизационных серверов MS, добавить их в ACL no-bump, и порядок. Ну, и время от времени, обновлять эти диапазоны по необходимости. В какой-то момент обеспечивалось достаточное перекрытие сетей MS и бОльшая часть обновлений кэшировалась, а проблем у клиентов не возникало.

С новыми версиями Squid, однако, картинка не настолько радостная. no-bump по dst уже не работает, так как используется принципиально иная алгортимтическая схема peek-n-splice.

И, для того, чтобы выполнить no-bump, а, точнее, splice, нужно указывать не IP, а имя сервера/серверов.

Допустим, что вы - умная маша, сделали sniffing сессии WU, и увидели некоторые адреса авторизационных серверов до получения ошибки WindowsUpdate_80072F8F или чего-то подобного. Вы видите IP, скажем, 191.234.72.190. Делаете реверсивный запрос - обана! - и получаете примерно вот это:


Чешете репу и пытаетесь запихнуть адрес в no-bump. Опа! - не работает.

Все просто, мальчики и девочки. Вам нужно добавить в ACL splice всего три сервера:
 fe1.update.microsoft.com.akadns.net  
 fe2.update.microsoft.com.akadns.net  
 fe2.update.microsoft.com  

Сделайте так. Напишите файл url.nobump:

 # WU (Squid 3.5.x and above with SSL Bump)  
 # Only this three sites must be spliced.  
 fe1\.update\.microsoft\.com\.akadns\.net  
 fe2\.update\.microsoft\.com\.akadns\.net  
 fe2\.update\.microsoft\.com  

Добавьте его в свой squid.conf в группу правил SSL Bump:

 acl DiscoverSNIHost at_step SslBump1  
 acl NoSSLIntercept ssl::server_name_regex -i "/usr/local/squid/etc/url.nobump"  
 ssl_bump splice NoSSLIntercept  
 ssl_bump peek DiscoverSNIHost
 ssl_bump bump all  

Все. Ошибка ушла навсегда. Вам больше не надо вылавливать сети MS, используя сниффер и tcpiputils.com

Одно предупреждение напоследок: Часть обновлений Windows может не кэшироваться ввиду попадания CDN на адреса диапазонов данных серверов. Я вас предупредил.

UPDATE

Не совсем все. Как оказалось, WU в некоторых случаях все еще использует в стартовых соединениях HTTPS с сайферами, использующими RC4 и 3DES. Если вы сконфигурировали свой набор сайферов на прокси по рекомендациям Мозиллы, вы рискуете получить ошибку  WindowsUpdate_80072F8F снова и сразу в момент начала процесса обновления. Чтобы избежать этого, вам необходимо модифицировать список используемых сайферов прокси сделующим образом:

 sslproxy_cipher HIGH:MEDIUM:RC4:3DES:!aNULL:!eNULL:!LOW:!MD5:!EXP:!PSK:!SRP:!DSS  

Такой же набор надо выбрать и на стороне прокси, обращенной к клиенту:

 http_port 3128 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/usr/local/squid/etc/rootCA2.crt key=/usr/local/squid/etc/rootCA2.key cafile=/usr/local/squid/etc/rootCA12.crt options=SINGLE_ECDH_USE tls-dh=prime256v1:/usr/local/squid/etc/dhparam.pem cipher=HIGH:MEDIUM:RC4:3DES:!aNULL:!eNULL:!LOW:!MD5:!EXP:!PSK:!SRP:!DSS  

среда, 14 октября 2015 г.

Solaris: DNSCrypt High Availability

Хотя возможность использования DNSCrypt в отказоустойчивой конфигурации (в сочетании с кэширующим DNS), в общем, известна, большинство пользователей, не умея писать скрипты, с нетерпением ждут окошечной гуёвой версии отказоустойчивого DNSCrypt.

Между тем, все достаточно просто.

Честно говоря, мне было лениво писать для Solaris настоящий отказоустойчивый SMF, с non-default instances, поэтому я поступил немного проще.

Так как dnscrypt-proxy демонстрирует завидную стабильность как сервис, то я просто тупо и цинично написал SMF из трех файлов, позволяющий запустить перед Unbound любое произвольное число пиров dnscrypt, на разных прослушивающих портах.

Предварительно соберем dnscrypt-proxy из исходников в 64 битах (напоминаю, что пререквизитами являются libsodium и libevent):

 После сборки libsodium в /usr/local/lib и ПЕРЕД сборкой dnscrypt необходимо (Solaris):  
   
 # 32 bit  
 crle -u -l /usr/local/lib  
 crle -u -l /opt/csw/lib  
 crle -c /var/ld/ld.config -l /lib:/usr/lib:/usr/local/lib:/opt/csw/lib  
   
 # 64 bit  
 crle -64 -u -l /usr/local/lib  
 crle -64 -u -l /opt/csw/lib/64  
 crle -64 -c /var/ld/64/ld.config -l /lib/64:/usr/lib/64:/usr/local/lib:/opt/csw/lib/64:/usr/sfw/lib/64  
   
 и лишь затем делать ./configure && gmake && gmake install-strip  
   
 Также может потребоваться установка libevent (если ее еще нет в системе).  
   
 # 32 bit GCC  
 ./configure 'CFLAGS=-O3 -m32'  
   
 # 64 bit GCC  
 ./configure 'CFLAGS=-O3 -m64'  
   
 gmake && gmake install-strip  


Затем напишем три файла.



  • /etc/dnscrypt.conf
 # Base dnscrypt installation directory  
 BASE_DIR="/usr/local"  
   
 # Local address  
 LOCAL_ADDRESS="127.0.0.1"  
   
 # Active requests  
 # Default 250  
 ACTIVE_REQUESTS=4096  
   
 # Specify resolvers names from list.  
 # HA option. List element: <resolver_name>:<local_peer_port>  
 RESOLVERS="4armed:5551 cloudns-can:5552 cloudns-syd:5553 soltysiak:5554 dnsmachine.net-de:5555"  
   
 # Change full path to resolvers CSV if it in non-standard location or name  
 RESOLVERS_LIST="$BASE_DIR/share/dnscrypt-proxy/dnscrypt-resolvers.csv"  
   
 # TCP only flag. Leave empty if not set.  
 # Set to 1 for turn on (if UDP blocking).  
 # Beware, tcp only is SLOWER.  
 USE_TCP_ONLY=""  
   
 # A value below or equal to 512 will disable this mechanism,   
 # unless a client sends a packet with an OPT section providing a payload size.  
 EDNS_PAYLOAD_SIZE="4096"  
   
 # Ephemeral public keys for every query (1.5.x and above)  
 # Default is -E (enabled) or --ephemeral-keys  
 # Leave blank to disable  
 EPHEMERAL_KEYS="--ephemeral-keys"  
   
 # Log level.  
 # 0 - disable  
 LOG_LEVEL="0"  
 #####  

В переменной RESOLVERS задаются ресолверы из списка dnscrypt-resolvers.csv, в виде пары "имя:порт", где "порт" - значение локально прослушиваемого порта, куда будут смотреть настройки форвардинга локального кэширующего DNS. Сколько ресолверов зададите - такая степень отказоустойчивости и будет.
  • /var/svc/manifest/network/dnscrypt-ha.xml
 <?xml version="1.0"?>  
 <!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">  
 <!--  Manifest-file for dnscrypt-ha, put this file in  
     /var/svc/manifest/network/dnscrypt-ha.xml   
     and run #svccfg import /var/svc/manifest/network/dnscrypt-ha.xml  
     Fixed by Yuri Voinov (C) 2007,2015  
 -->  
 <service_bundle type='manifest' name='dnscrypt-ha'>  
   
 <service  
     name='network/dnscrypt-ha'  
     type='service'  
     version='1'>  
   
     <create_default_instance enabled='false' />  
   
     <single_instance />  
   
     <dependency name='fs-local'  
         grouping='require_all'  
         restart_on='none'  
         type='service'>  
         <service_fmri  
             value='svc:/system/filesystem/local' />  
     </dependency>  
   
     <dependency name='net-loopback'  
         grouping='require_all'  
         restart_on='none'  
         type='service'>  
         <service_fmri value='svc:/network/loopback' />  
     </dependency>  
   
     <dependency name='net-physical'  
         grouping='require_all'  
         restart_on='none'  
         type='service'>  
         <service_fmri value='svc:/network/physical' />  
     </dependency>  
   
     <dependency name='utmp'  
         grouping='require_all'  
         restart_on='none'  
         type='service'>  
         <service_fmri value='svc:/system/utmp' />  
     </dependency>  
   
     <dependency name='dnscrypt-ha-config'  
         grouping='require_all'  
         restart_on='refresh'  
         type='path'>  
         <service_fmri value='file://localhost/etc/dnscrypt-ha.conf' />  
     </dependency>  
   
     <exec_method  
         type='method'  
         name='start'  
         exec='/lib/svc/method/init.dnscrypt-ha %m'  
         timeout_seconds='60'/>  
   
     <exec_method  
         type='method'  
         name='stop'  
         exec=':kill'  
         timeout_seconds='60' />  
   
     <exec_method  
         type='method'  
         name='restart'  
         exec='/lib/svc/method/init.dnscrypt-ha %m'  
         timeout_seconds='60' />  
   
     <property_group name='startd'  
         type='framework'>  
         <!-- sub-process core dumps shouldn't restart session -->  
         <propval name='ignore_error'  
           type='astring' value='core,signal' />  
     </property_group>  
   
     <property_group name='general' type='framework'>  
         <!-- to start stop squid -->  
         <propval name='action_authorization' type='astring'  
             value='solaris.smf.manage' />  
     </property_group>  
   
     <stability value='Unstable' />  
   
     <template>  
         <common_name>  
             <loctext xml:lang='C'>  
             dnscrypt HA service  
             </loctext>  
         </common_name>  
     </template>  
   
 </service>  
   
 </service_bundle>  

  • /lib/svc/method/init.dnscrypt-ha

И затем сам управляющий метод:

 #!/sbin/sh  
   
 #  
 # Control Method for dnscrypt-ha (/lib/svc/method/init.dnscrypt-ha)  
 # Written by Yuri Voinov (C) 2007,2015  
 #  
 # ident "@(#)dnscrypt-ha.sh  2.4  11/10/15 YV"  
 #  
   
 . /lib/svc/share/smf_include.sh  
 . /lib/svc/share/net_include.sh  
   
 #############  
 # Variables #  
 #############  
   
 # Config file, by default,  
 # finds in /etc. Lines, commented with #  
 # in config file, will be skipped  
 config_file="/etc/dnscrypt-ha.conf"  
   
 pid_base="/tmp"  
   
 #  
 # OS Commands location variables  
 #  
 CAT=`which cat`  
 CUT=`which cut`  
 ECHO=`which echo`  
 KILL=`which kill`  
 RM=`which rm`  
 UNAME=`which uname`  
   
 # OS release  
 OS_VER=`$UNAME -r|$CUT -f2 -d"."`  
 OS_NAME=`$UNAME -s|$CUT -f1 -d" "`  
   
 ###############  
 # Subroutines #  
 ###############  
   
 check_os ()  
 {  
  # Check OS version  
  if [ ! "$OS_NAME" = "SunOS" -a ! "$OS_VER" -lt "10" ]; then  
  $ECHO "ERROR: Unsupported OS $OS_NAME $OS_VER"  
  $ECHO "Exiting..."  
  exit 1  
  fi  
 }  
   
 startproc()  
 {  
 # Start dnscrypt daemons  
  program=$1  
  LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH  
  export LD_LIBRARY_PATH  
  for R in $RESOLVERS; do  
  port=`$ECHO $R|$CUT -f2 -d":"`  
  resolver=`$ECHO $R|$CUT -f1 -d":"`  
  pid_file=$pid_base/dnscrypt_ha_$port.pid  
  $DNSCRYPT_PATH/$program --daemonize --pidfile=$pid_file --local-address=$LOCAL_ADDRESS:$port --max-active-requests=$ACTIVE_REQUESTS $USE_TCP $RLIST --resolver-name=$resolver $EDNS $EPHEMERAL_KEYS --loglevel=$LOG_LEVEL  
  done  
 }  
   
 stopproc()  
 {  
 # Stop dnscrypt daemons  
  for R in $RESOLVERS; do  
  port=`echo $R|cut -f2 -d":"`  
  pid_file=$pid_base/dnscrypt_ha_$port.pid  
  $KILL -9 `$CAT $pid_file` && $RM $pid_file  
  done  
 }  
   
 ##############  
 # Main block #  
 ##############  
   
 # Check OS version  
 check_os  
   
 ##########################################################  
 # Check config file exists  
 if [ ! -f "$config_file" -o ! -s "$config_file" ]; then  
  $ECHO "ERROR: Config file not found or is empty."  
  $ECHO "Exiting..."  
  exit 1  
 else  
  # Source config file  
  . $config_file  
 fi  
 #### Check config contents  
 if [ -z "$LOCAL_ADDRESS" ]; then  
  # If local address is not specified, then set it to 127.0.0.1  
  LOCAL_ADDRESS="127.0.0.1"  
 fi  
 if [ ! -z "$USE_TCP_ONLY" ]; then  
  # If TCP flag specified, set option  
  USE_TCP="--tcp-only"  
 fi  
 if [ ! -z "$RESOLVERS_LIST" ]; then  
  # If non-standard location or list name is given, set option  
  RLIST="--resolvers-list=$RESOLVERS_LIST"  
 fi  
 if [ ! -z "$EDNS_PAYLOAD_SIZE" ]; then  
  # If EDNS payload size specified, set option  
  EDNS="--edns-payload-size=$EDNS_PAYLOAD_SIZE"  
 fi  
 # Set other variables  
 # dnscrypt files paths  
 DNSCRYPT_PATH="$BASE_DIR""/sbin"  
 # dnscrypt files  
 DNSCRYPT_BIN_FILE="dnscrypt-proxy"  
 # Check daemon installed  
 if [ ! -f "$DNSCRYPT_PATH/$DNSCRYPT_BIN_FILE" -a ! -x "$DNSCRYPT_PATH/$DNSCRYPT_BIN_FILE" ]; then  
  $ECHO "ERROR: DNSCrypt not found!"  
  $ECHO "Exiting..."  
  exit 1  
 fi  
 ##########################################################  
   
 case "$1" in  
 "restart")  
  stopproc $DNSCRYPT_BIN_FILE  
  startproc $DNSCRYPT_BIN_FILE  
  ;;  
 "start")  
  startproc $DNSCRYPT_BIN_FILE  
  ;;  
 "stop")  
  stopproc $DNSCRYPT_BIN_FILE  
  ;;  
 *)  
  $ECHO "Usage: $0 { start | stop | restart }"  
  exit 1  
 esac  
   
 exit 0  
 ####  

Осталось немного. Загрузить сервисный манифест командой:

 svccfg import /var/svc/manifest/network/dnscrypt-ha.xml  

и запустить сервис:

 svcadm enable dnscrypt-ha  

Убедимся, что пиры запущены:



Осталось лишь добавить записи о них в unbound.conf:

 forward-zone:  
  name: "."  
  forward-addr: 127.0.0.1@5551  
  forward-addr: 127.0.0.1@5552  
  forward-addr: 127.0.0.1@5553  
  forward-addr: 127.0.0.1@5554
  forward-addr: 127.0.0.1@5555

и перезапустить Unbound.

Для совсем ленивых есть полностью готовое решение с ленивчиками установки и удаления сервиса. :)

Замечание

DNSLeakTest будет вам показывать при тестировании сервера dnscrypt, через которые вы ходите, последовательно - так как Unbound обходит пиры форвардеров по round-robin:


так что не паникуйте, так и должно быть.

вторник, 13 октября 2015 г.

DNSSEC: Unbound + DNSCrypt proxy

Большинство из тех, кто использует связку Unbound+dnscrypt, обычно отключает валидацию DNSSEC в Unbound, так как считают, что она не будет работать через dnscrypt.

Это не совсем так. Вообще говоря, это совсем не так.

Если внимательно посмотреть на список ресолверов dnscrypt, то можно увидеть, что некоторое количество из них поддерживает DNSSEC. 

Следовательно, никто не мешает нам использовать DNSSEC. Что, в сочетании с встроенными в Unbound возможностями харденинга, несколько повышает защищенность нашей DNS-системы и опять-таки уменьшает вероятность намеренного отравления нашего DNS.

Итак, как мы это сделаем?

Всегда правой!

Конфигурирование dnscrypt

В настройках dnscrypt нужно выбрать те ресолверы, которые, во-первых, чаще находятся в онлайне (иначе получите непредсказуемые отказы вашей системы DNS), во-вторых, находятся ближе к вам по пингу и быстрее отвечают, и, в-третьих, те, которые поддерживают DNSSEC.

Например, dnsmachine.net-decloudns-cancloudns-syd или 4armed. Чуть позже мы рассмотрим вопрос отказоустойчивой конфигурации dnssec-пиров.

Учтите при выборе один факт. Ваша инфраструктура должна пропускать 443/UDP наружу с сервера, на котором выполняется dnscrypt. По данному порту происходит периодический запрос публичных ключей DNSSEC, во всяком случае у большинства серверов dnscrypt.

После изменения ресолвера (ресолверов) перезапустите ваш dnscrypt-proxy.

Конфигурирование Unbound

Для активации поддержки DNSSEC в Unbound необходимо раскомментировать (или убедиться, что они раскомментированы) следующие параметры:

      # module configuration of the server. A string with identifiers  
      # separated by spaces. "iterator" or "validator iterator"  
      module-config: "validator iterator"  
      # module-config: "iterator"  
   
      # File with trusted keys, kept uptodate using RFC5011 probes,  
      # initial file like trust-anchor-file, then it stores metadata.  
      # Use several entries, one per domain name, to track multiple zones.  
      #  
      # If you want to perform DNSSEC validation, run unbound-anchor before  
      # you start unbound (i.e. in the system boot scripts). And enable:  
      # Please note usage of unbound-anchor root anchor is at your own risk  
      # and under the terms of our LICENSE (see that file in the source).  
      auto-trust-anchor-file: "/usr/local/etc/unbound/root.key"  
   

Учтите одну вещь: auth-trust-anchor-file будет обновляться автоматически. Для того, чтобы этот процесс мог вообще происходить, необходимо разрешить пользователю, от которого исполняется Unbound, запись в директорию конфигурации Unbound.

Для этого нужно, чтобы владельцем всей директории рекурсивно был этот пользователь (включая root.key):


Если вы этого не сделаете, ключ не сможет автоматически обновляться Unbound'ом и, более того, ваш Unbound не сможет работать в режиме DNSSEC validation. Он будет просто падать с первым же запросом.

После завершения конфигурирования перезапустите Unbound.

Для тестирования конфигурации выполните команду:


      dig com. SOA +dnssec  

Вы должны увидеть следующее:


Чтобы окончательно убедиться, что все в порядке, можно найти в Гугле онлайновые тестировщики клиентского ресолвера:

http://dnssec.vs.uni-due.de/

https://dnssectest.sidnlabs.nl/test.php
Если последний тест показывает вам "Permissive mode", задайте в конфигурационном файле Unbound явно значение:

 val-permissive-mode: no  

Должно быть вот так:


That's all, folks!

пятница, 2 октября 2015 г.

Squid: Tor + Privoxy + transparent DNS redirect. Часть III

Ранее я уже писал, как организовать в рамках прокси-сервера торифицированный туннель для контролируемого пробивания разного рода блокировок:
В них, однако, совершенно не рассматривается вопрос (и многие это уже обнаружили) туннелирования HTTPS - соединений.

Суть в том, что для Squid версии 3.4.x это, к сожалению, невозможно. 

Говоря простым языком - HTTPS нельзя наравне с HTTP отправить в кэш-пир, в нашем случае - в туннель.

Совсем нельзя?

В настоящее время - уже можно. С некоторыми оговорками, однако - можно.

Введение


Проблема возникла в тот момент, когда повсюду стали переходить на HSTS. Я, возможно, еще скажу, почему я не считаю волосы на лобке значительной защитой против изнасилования. Хотя это и так очевидно любому, оборудованному головным мозгом.

Итак, два вопроса.

Через описанную ранее конфигурацию невозможно попасть на:

  • https://archive.org
  • https://torproject.org
в рамках нашего, отдельно взятого Мордора.

Может, это все же возможно?


Безусловно.

Два пререквизита.
  1. Вам потребуется Squid версии от 3.5.6 и выше (для версий ниже я не тестировал, ничего сказать не могу)
  2. SSL Bump придется отключить для всех HTTPS-сайтов (т.е. использовать splice), которые надо загонять в туннель (re-crypting, как сказал Амос, не поддерживается в текущих версиях)
Конфигурацию Squid следует скорректировать следующим образом (предполагается, что вы имеете настроенную конфигурацию с отлаженным SSL Bump):

 # Privoxy+Tor acl  
 acl tor_url dstdom_regex "C:/Squid/etc/squid/url.tor"  
   
 # SSL bump rules  
 sslproxy_cert_error allow all  
 acl DiscoverSNIHost at_step SslBump1  
 ssl_bump peek DiscoverSNIHost  
 acl NoSSLIntercept ssl::server_name_regex -i "C:/Squid/etc/squid/url.nobump"  
 acl NoSSLIntercept ssl::server_name_regex -i "C:/Squid/etc/squid/url.tor"  
 ssl_bump splice NoSSLIntercept  
 ssl_bump bump all  
   
 # Privoxy+Tor access rules  
 never_direct allow tor_url  
      
 # Local Privoxy is cache parent  
 cache_peer 127.0.0.1 parent 8118 0 no-query no-digest default  
   
 cache_peer_access 127.0.0.1 allow tor_url  
 cache_peer_access 127.0.0.1 deny all  
   

Замечание
Файлы utl.tor и url.nobump имеют одинаковый формат dstdom_regex. Обратите внимание, что url.tor имеет совпадающий формат с url.nobump и добавлен в ACL для splice.

Если все правильно, в access.log вы увидите следующее:

 1446552738.421  8015 127.0.0.1 TCP_TUNNEL/200 68644 CONNECT www.torproject.org:443 - FIRSTUP_PARENT/127.0.0.1 -  
 1446552738.647 10617 127.0.0.1 TCP_TUNNEL/200 136911 CONNECT www.torproject.org:443 - FIRSTUP_PARENT/127.0.0.1 -  
 1446552738.808  8401 127.0.0.1 TCP_TUNNEL/200 23501 CONNECT www.torproject.org:443 - FIRSTUP_PARENT/127.0.0.1 -  
 1446552738.969  8605 127.0.0.1 TCP_TUNNEL/200 30266 CONNECT www.torproject.org:443 - FIRSTUP_PARENT/127.0.0.1 -  
 1446552739.131  8687 127.0.0.1 TCP_TUNNEL/200 2796 CONNECT www.torproject.org:443 - FIRSTUP_PARENT/127.0.0.1 -  
 1446552740.910  8015 127.0.0.1 TCP_TUNNEL/200 7841 CONNECT www.torproject.org:443 - FIRSTUP_PARENT/127.0.0.1 -  
   

Вуаля:



Имел я господ цензоров противоестественным образом.

Заключение


До тех пор, пока в МарсТелеКомах нанимают на работу недоумков (по какому угодно признаку, кроме IQ и профессионализма) - нам не страшны никакие DPI. Привет анацефалам от сапиенсов!