
Предыстория
Недавно я взялся переводить межсетевой экран на своей РС с проверенных временем iptables на новенькие nftables. Для более углублённого изучения таблиц nf я поставил себе задачу: настроить прозрачный прокси-сервер (Squid) с разбором шифрованных соединений (HTTPS) для раздачи доступа в Интернет виртуальным машинам, РС «Raspberry Pi», а также своему смартфону (работающему с ОС «Android» 6-го выпуска) по беспроводному соединению (с помощью приложения hostapd).
Обозначения
| Буквы равной ширины | Приказы оболочки и содержимое конфигурационных файлов. |
| Полужирные буквы | Настройки, строго необходимые для прозрачного посредничества. |
| Наклонные буквы | Настройки, специфичные для моей установки (номера выпусков ПО, адреса канального и сетевого уровня, названия сетевых интерфейсов и т. п.). В вашем случае значения, как правило, будут другими. |
| Подчёркнутые буквы | Настройки, необходимые для работы разбора шифрованных соединений |
Дано
| Операционная система | «Gentoo Linux» со службой запуска служб «OpenRC». Все дальнейшие настройки будут применимы к этой поставке |
| Ядро | sys-kernel/gentoo-sources-5.3.1 USE="" Здесь и далее снятые USE-флаги не показаны |
| Прокси-сервер | net-proxy/squid-4.8 USE="caps ssl ssl-crtd" |
| Библиотека шифрования | dev-libs/openssl-1.1.1c-r1 USE=«asm test zlib» |
| Приложение nft | net-firewall/nftables-0.9.2 USE=«doc gmp modern_kernel» |
| Приложение ip | sys-apps/iproute2-5.2.0-r1 USE=«caps minimal» |
| Служба записи в журнал | app-admin/ulogd-2.0.7-r1 USE=«nfct nflog» |
Настройка ядра

Тоже самое, но текстом
[*] Networking support --->
Networking options --->
[*] TCP/IP networking
[*] IP: advanced router
[*] IP: policy routing
[*] Network packet filtering framework (Netfilter) --->
[*] Advanced netfilter configuration
Core Netfilter Configuration --->
# не обязательно, но пригодится для фильтрации пакетов на входе сетевых интерфейсов
[*] Netfilter ingress support
# не обязательно, но пригодится для отладки
<*> Netfilter LOG over NFNETLINK interface
<*> Netfilter connection tracking support
<*> Netfilter nf_tables support
<*> Netfilter nf_tables set infrastructure
# не обязательно, но пригодится для фильтрации пакетов на входе сетевых интерфейсов
[*] Netfilter nf_tables netdev tables support
<*> Netfilter nf_tables conntrack module
# не обязательно, но пригодится для отладки
<*> Netfilter nf_tables counter module
# не обязательно, но пригодится для отладки
<*> Netfilter nf_tables log module
<*> Netfilter nf_tables masquerade support
<*> Netfilter nf_tables nat module
<*> Netfilter nf_tables socket match support
<*> Netfilter nf_tables tproxy support
IP: Netfilter Configuration --->
[*] IPv4 nf_tables support
# не обязательно, но пригодится для фильтрации пакетов на канальном уровне
<*> Ethernet Bridge nf_tables support --->
Для справки привожу выдержку из /usr/src/linux/.config:
CONFIG_NET=y CONFIG_INET=y <b>CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y</b> CONFIG_NETFILTER=y CONFIG_NETFILTER_ADVANCED=y CONFIG_NETFILTER_INGRESS=y CONFIG_NETFILTER_NETLINK=y CONFIG_NETFILTER_NETLINK_LOG=y CONFIG_NF_CONNTRACK=y CONFIG_NF_TABLES=y CONFIG_NF_TABLES_SET=y CONFIG_NF_TABLES_NETDEV=y CONFIG_NFT_CT=y CONFIG_NFT_COUNTER=y CONFIG_NFT_LOG=y CONFIG_NFT_MASQ=y CONFIG_NFT_NAT=y <b>CONFIG_NFT_SOCKET=y CONFIG_NFT_TPROXY=y</b> CONFIG_NF_TABLES_BRIDGE=y
Настройка сети
Если служба net.lo не добавлена в уровень выполнения «boot», то её следует туда добавить:
rc-config add net.lo boot
Подобным же образом созданы и настроены на запуск для уровня выполнения «default» службы net.br0 (мост для виртуальных машин и смартфона), net.enp0s25 (проводной интерфейс) и net.wlp3s0 (беспроводной интерфейс), например:
ln -s net.lo /etc/init.d/net.br0 rc-config add net.br0 default
Итоговый конфигурационный файл /etc/conf.d/net в нашем примере выглядит так (за вычетом не относящихся к нашей задаче настроек):

Тоже самое, но текстом
# TProxy routes_lo='local default dev lo table 3128' # Qemu bridge bridge_force_br0='' mac_br0='XX:XX:XX:XX:XX:XX' config_br0='192.168.120.1/24' # Ethernet config_enp0s25='dhcp' modules_enp0s25='udhcpc' dhcp_enp0s25='release nontp' udhcpc_enp0s25='--retries 8 --timeout 10' fallback_enp0s25='10.a.b.c/16' fallback_routes_enp0s25='default via 10.a.0.1' # Wi-Fi if [[ -f /var/lib/misc/hostapd ]]; then modules_wlp3s0="!ifconfig !iwconfig !wpa_supplicant" config_wlp3s0='null' else config_wlp3s0='dhcp' modules_wlp3s0='udhcpc' wpa_supplicant_wlp3s0='-Dnl80211' fi postup() { if [ "${IFACE}" == lo ]; then ip rule add fwmark 3128 lookup 3128 fi return 0 }
Выделенные строки добавляют новую таблицу маршрутизации, в данном примере под номером 3128, и ворота — по умолчанию для неё (интерфейс «loopback»), и правило — по которому пакеты, помеченные межсетевым экраном меткой номер 3128 (десятичные числа в обоих случаях), будут обслуживаться этим расписанием.
Чтобы направляемые пакеты не были отброшены из-за несоответствия адресов сетевого уровня (при прозрачном проксировании пакеты сохраняются в первозданном виде!) необходимо добавить в /etc/sysctl.conf следующие строки (или изменить уже имеющиеся):

Если нужно применить эти настройки до перезагрузки, то следует дополнительно задать их для обоих сетевых интерфейсов с доступом в Интернет:
sysctl net.ipv4.conf.enp0s25.rp_filter=0 sysctl net.ipv4.conf.wlp3s0.rp_filter=0
Настройка прокси-сервера
Поскольку обычный (непрозрачный) порт прокси-сервера у нас будет закреплён на адресе моста (192.168.120.1), добавим следующую строку в /etc/rc.conf:
rc_squid_need="net.br0"
Следующие настройки прокси-сервера в рамках этой статьи рассмотрены не будут:
- Проверка личности пользователей на обычном (непрозрачном) порту;
- ICAP для объединения с устройством предотвращения утечек данных (например, InfoWatch Traffic Monitor);
- Выработка ключей шифрования и создание сертификата.
Конфигурационный файл /etc/squid/squid.conf в итоге выглядит так (на всякий случай привожу полностью):


Тоже самое, но текстом
# Задаём перечень виртуальных машин 1 acl virtual_machines src 192.168.120.0/24 2 acl SSL_ports port 443 # Пример добавления необычного для соединений HTTPS порта 3 acl SSL_ports port 1012 # для badssl.com # Пример добавления необычного для соединений HTTPS порта 4 acl SSL_ports port 33443 # getcourse.ru для artlinerschool.ru 5 acl Safe_ports port 21 # ftp 6 acl Safe_ports port 80 # http 7 acl Safe_ports port 443 # https # Пример добавления необычного привилегированного порта 8 acl Safe_ports port 1012 # для badssl.com 9 acl Safe_ports port 1025-65535 # непривилегированные порты 10 acl CONNECT method CONNECT 11 http_access deny !Safe_ports 12 http_access deny CONNECT !SSL_ports 13 http_access allow localhost manager 14 http_access deny manager 15 http_access allow localhost # Разрешаем подключение виртуальных машин к прокси-серверу 16 http_access allow virtual_machines 17 http_access deny all # Настраиваем обычный (непрозрачный) порт. Используем адрес моста, на случай прямого подключения виртуальных машин (например, как к прокси-серверу FTP) 18 http_port 192.168.120.1:3128 ssl-bump options=ALL:NO_SSLv3:NO_TLSv1 cert=/etc/squid/squid.pem # Настраиваем прозрачный порт для нешифрованных соединений. Тут используем адрес интерфейса «loopback», поскольку на него указывает таблица маршрутизации под номером 3128, настроенное ранее, и на него же будут указывать правила межсетевого экрана 19 http_port 127.0.0.1:3129 tproxy # Настраиваем прозрачный порты для шифрованных соединений. Тут используем адрес интерфейса «loopback», поскольку на него указывает таблица маршрутизации под номером 3128, настроенное ранее, и на него же будут указывать правила межсетевого экрана 20 https_port 127.0.0.1:3130 tproxy ssl-bump options=ALL:NO_SSLv3:NO_TLSv1 cert=/etc/squid/squid.pem # прокси-сервер выходит в сеть напрямую, без других прокси-серверов 21 always_direct allow all # Задаём перечень проверенных страниц, имеющим самоподписанный сертификат 22 acl BrokenButTrustedServers dstdomain "/etc/squid/selfsigned.txt" # Разрешаем подключение только к проверенным страницам, имеющим самоподписанный сертификат 23 sslproxy_cert_error allow BrokenButTrustedServers 24 sslproxy_cert_error deny all # Для безопасности разрешаем только свежайшие выпуски TLS 25 tls_outgoing_options min-version=1.2 # Задаём перечень непотребных страниц 26 acl blocked ssl::server_name "/etc/squid/blocked_domains.txt" # Задаём перечень страниц, которые перестают работать из-за подмены сертификата (в первую очередь это касается виртуальных частных сетей на основе SSL) 27 acl fragile dstdomain "/etc/squid/fragile_domains.txt" 28 acl step1 at_step SslBump1 29 ssl_bump peek step1 # Запрещаем подключения к непотребным страницам 30 ssl_bump terminate blocked # Делаем исключения из разбора шифрования для страниц, которые перестают работать из-за подмены сертификата 31 ssl_bump splice fragile # Все остальные шифрованные соединения разбираем, подменяя сертификата 32 ssl_bump bump all # Настраиваем хранилище подменных сертификатов 33 sslcrtd_program /usr/libexec/squid/security_file_certgen -s /var/lib/squid/ssl -M 4MB 34 cache_dir rock /var/cache/squid-r 512 max-size=32768 35 cache_dir aufs /var/cache/squid 512 64 1024 min-size=32768 36 coredump_dir /var/tmp/squid 37 refresh_pattern ^ftp: 1440 20% 10080 38 refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 39 refresh_pattern . 0 20% 4320 40 memory_replacement_policy heap GDSF 41 cache_replacement_policy LFUDA 42 maximum_object_size 32 MB 43 logfile_rotate 3 44 debug_options ALL,1,rotate=3 45 cache_mem 512 MB 46 visible_hostname host.shadow.amn 47 udp_incoming_address 127.0.0.1 48 pinger_enable off
Настройка межсетевого экрана
Настроим запуск на уровне выполнения «default» служб nftables и ulogd (последняя нужна для уведомления о пакетах):
rc-config add nftables default rc-config add ulogd default
Поскольку в настройках межсетевого экрана будет присутствовать мост, добавим следующую строку в /etc/rc.conf:
rc_nftables_need="net.br0"
Для работы уведомления в /etc/sysctl.conf необходимо добавить следующую строку:
net.netfilter.nf_log.2 = nfnetlink_log
Чтобы конфигурационный файл находился в папке /etc/nftables, внесём такое изменение в /etc/conf.d/nftables:
NFTABLES_SAVE="/etc/nftables/rules-save"
Чтобы временные изменения не сохранялись в конфигурационном файле, внесём ещё одно изменение в /etc/conf.d/nftables:
SAVE_ON_STOP="no"
Опишу задачи, поставленные перед межсетевым экраном:
- Правила по умолчанию во всех цепочках таблицы ip filter должны пакеты удалять (даже в цепочке output!). Аналогично для таблиц netdev filter;
- Обмен любого вида, кроме IPv4 и относящегося к нему служебного обмена (например, ARP), пресекается насколько возможно раньше (ни IPv4, ни IPSec не используются);
- Многоадресные пакеты IPv4 также удаляются насколько возможно раньше;
- Для защиты Android-смартфона (при подключении к мосту с помощью приложения hostapd) широковещательный обмен, производимый виртуальными машинами работающими под управлением ОС «Microsoft Windows», не должен передаваться на беспроводной интерфейс.
- Пользоваться нашим Wi-Fi можно только устройствами с известными MAC-адресами.
Конфигурационный файл /etc/nftables/rules-save в итоге выглядит так (за вычетом большинства пояснений):






Тоже самое, но текстом
1 #!/sbin/nft -f # Задаём переменные, которые будут использоваться в правилах 2 define icmp_types = { destination-unreachable, time-exceeded, parameter-problem, echo-request, echo-reply } 3 define host = 192.168.120.1 4 define br = br0 5 define my_br_mac = XX:XX:XX:XX:XX:XX 6 define eth = enp0s25 7 define my_eth_mac = YY:YY:YY:YY:YY:YY 8 define wifi = wlp3s0 9 define my_wifi_mac = WW:WW:WW:WW:WW:WW 10 define my_phone = TT:TT:TT:TT:TT:TT 11 define virtual_machines = 192.168.120.0/24 12 define privileged_vm = { 192.168.120.22, 192.168.120.129 } 13 define dhcp_client = 192.168.120.224/27 14 define transmission_port = 51413 15 define no_track = { microsoft-ds, ms-wbt-server } 16 define vm_ssh = 192.168.120.70 17 define infowatch_pc = { 10.a.0.0/16, 10.h.0.0/16 } 18 define infowatch_my = 10.a.b.c 19 define squid_normal = 3128 20 define squid_transp = 3129 21 define squid_trassl = 3130 22 define sslvpn.infowatch.com = 46.148.194.86 23 define files.infowatch.ru = 178.16.25.15 24 define iwprint.infowatch.ru = 10.d.e.f 25 define s163.getcourses.ru = 95.213.153.163 26 define tls-v1-2.badssl.com = 104.154.89.105 27 flush ruleset 28 table ip raw { 29 chain prerouting { 30 type filter hook prerouting priority -300; # Пытаемся облегчить работу межсетевого экрана тем, что соединения с самым большим объёмом пакетов отслеживаться не будут 31 meta l4proto { tcp, udp } th dport $transmission_port notrack 32 tcp sport $no_track ip saddr != $iwprint.infowatch.ru notrack 33 ip saddr { $sslvpn.infowatch.com, $files.infowatch.ru } tcp sport https notrack 34 } 35 } 36 table ip filter { 37 chain input { 38 type filter hook input priority 0; policy drop; # Поскольку в этой цепочке правило по умолчанию удаляет пакеты, то необходимо разрешить все пакеты на интерфейс «loopback» 39 iif lo accept # Разрешаем пакеты ICMP только необходимых видов для обхода возможных уязвимостей, связанных с редкими и неиспользуемыми видами ICMP 40 icmp type $icmp_types accept # Удаляем битые пакеты 41 ct state invalid counter drop # Обход падения ядра, связанного с избирательным подтверждением (SACK) пакетов TCP. Падения эти уже устранены в свежих выпусках ядра, но данное правило оставлено на всякий случай 42 tcp flags syn tcp option maxseg size < 999 counter drop # Полностью разрешаем Bittorrent, поскольку мы исключили его из отслеживания в строке 31 43 iif $eth meta l4proto { tcp, udp } th dport $transmission_port accept # Удаляем пакеты, начинающие соединение, и заносим о них запись в дннвник, если они пришли с неотслеживаемых соединений 44 tcp flags & (syn | ack) == syn ct state untracked log prefix "Untracked:" group 2 counter counter drop # Разрешаем пакеты с портов, которые мы исключили из отслеживания в строке 32 45 tcp sport $no_track accept # Разрешаем пакеты с адресов, которые мы исключили из отслеживания в строке 33 46 ip saddr { $sslvpn.infowatch.com, $files.infowatch.ru } tcp sport https accept # Разрешаем пакеты от виртуальных машин, помеченные меткой 3128 (десятичное число) 47 iif $br ip saddr $virtual_machines mark set 3128 counter accept # Разрешаем виртуальным машинам подключаться к некоторым службам, в том числе к обычному (непрозрачному) порту прокси-сервера 48 iif $br ip daddr $host ip saddr $virtual_machines tcp dport { domain, http, microsoft-ds, nfs, $squid_normal } accept # Разрешаем все законные отслеженные соединения 49 ct state { established, related } accept # Разрешаем виртуальным машинам подключаться к некоторым службам, подразумевающим широковещательный обмен 50 iif $br udp dport { domain, bootps, tftp, 4011 } counter accept # Производим подсчёт удалённых пакетов, так как следующим правилом будет правило по умолчанию, удаляющее пакеты (см. строку 38) 51 counter comment "Считаем выброшенные пакеты" 52 } 53 chain output { 54 type filter hook output priority 100; policy drop; # Поскольку в этой цепочке правило по умолчанию удаляет пакеты, то необходимо разрешить все пакеты со интерфейса «loopback» 55 oif lo accept # Разрешаем пакеты ICMP только необходимых видов для обхода возможных уязвимостей, связанных с редкими и неиспользуемыми видами ICMP 56 icmp type $icmp_types counter accept # Разрешаем службам отправлять пакеты виртуальным машинам с привилегированных портов (сравните со строками 48 и 50) 57 oif { $eth, $wifi } udp dport . udp sport { bootps . bootpc } counter accept 58 oif $br ip saddr $host ip daddr { $dhcp_client, 255.255.255.255 } udp sport . udp dport { bootps . bootpc } counter accept 59 oif $br ip saddr $host ip daddr $virtual_machines udp sport { domain, tftp } counter accept 60 oif $br ip saddr $host ip daddr $virtual_machines tcp sport { domain, http, microsoft-ds } accept # Разрешаем прокси-серверу отправлять пакеты потребителям от имени страниц всемирной паутины с привилегированных портов. Если используется необычный порт для HTTPS вне привилегированного промежутка, то он подпадёт под следующее правило и его указывать здесь не нужно 61 oif $br ip daddr $virtual_machines tcp sport { http, https, 1012 } counter accept # Разрешаем отправку любых пакетов с портов, имеющих номера вне привилегированного промежутка, то есть выше 1024 62 meta l4proto { tcp, udp } th sport >= 1025 accept # Производим подсчёт удалённых пакетов, так как следующим правилом будет правило по умолчанию, удаляющее пакеты (см. строку 54) 63 counter comment "Считаем выброшенные пакеты" 64 } 65 chain forward { 66 type filter hook forward priority 0; policy drop; # Помогаем виртуальным машинам с настройкой размера пакетов (MTU) 67 tcp flags syn tcp option maxseg size set rt mtu counter # Запрещаем виртуальным машинам обращаться к чужим службам разрешения имён 68 iif $br ip daddr != $host meta l4proto { tcp, udp } th dport domain drop # Разрешаем обмен с внешним миром (помимо прокси-сервера) только некоторым виртуальным машинам и всем, получившим временный адрес сетевого уровня, как правило, это будет смартфон. Эти правила не означают, что подключение ко всемирной паутине (порты 80 и 443) произойдёт для них без прокси-сервера, так как цепочка divert имеет более высокое первенство по сравнению с цепочкой forward (сравните строки 66 и 81). Кроме того, в строке 96 мы не преобразуем адрес сетевого уровня, если номер порта назначения равен 80 или 443 69 iif $br ip saddr { $privileged_vm, $dhcp_client } accept 70 oif $br ip daddr { $privileged_vm, $dhcp_client } accept # Производим подсчёт удалённых пакетов, так как следующим правилом будет правило по умолчанию, удаляющее пакеты (см. строку 66) 71 counter comment "Считаем выброшенные пакеты" 72 } # Создаём набор пар «адрес канального уровня • порт» для случаев использования соединениями HTTPS номеров портов, отличающихся от 443 73 set nonstandard_https { 74 type ipv4_addr . inet_service; 75 elements = { 76 $s163.getcourses.ru . 33443, # для страницы artlinerschool.ru 77 $tls-v1-2.badssl.com . 1012, # для страницы badssl.com 78 } 79 } 80 chain divert { 81 type filter hook prerouting priority -150; policy accept; # Помечаем меткой 3128 (дес. ч.) все пакеты TCP, отправляющиеся из сокета, имеющего свойство прозрачности (свойство задаётся прокси-сервером) 82 meta l4proto tcp socket transparent 1 mark set 3128 accept # Помечаем меткой 3128 (дес. ч.) все пакеты TCP с портом назначения, имеющим номер 80. Одновременно заворачиваем их на прозрачного прокси-сервера 83 ip daddr != { 127.0.0.1, $host } tcp dport http tproxy to 127.0.0.1:$squid_transp mark set 3128 counter accept # Помечаем меткой 3128 (дес. ч.) все пакеты TCP с портом назначения, имеющим номер 443. Одновременно заворачиваем их на прозрачного прокси-сервера 84 ip daddr != { 127.0.0.1, $host } tcp dport https tproxy to 127.0.0.1:$squid_trassl mark set 3128 counter accept # Помечаем меткой 3128 (дес. ч.) все пакеты TCP с адресами и портами назначения из набора nonstandard_https (см. строки 76 и 77 для примера). Одновременно заворачиваем их на прозрачного прокси-сервера 85 ip daddr . tcp dport @nonstandard_https tproxy to 127.0.0.1:$squid_trassl mark set 3128 counter accept 86 } 87 } 88 table ip nat { 89 chain prerouting { 90 type nat hook prerouting priority 0; policy accept; # Разрешаем другим РС из рабочей сети подключаться к одной из виртуальных машин с помощью SSH 91 iif $eth ip daddr $infowatch_my ip saddr $infowatch_pc tcp dport ssh counter dnat $vm_ssh 92 } 93 chain postrouting { 94 type nat hook postrouting priority 100; policy accept; # Преобразуем адреса сетевого уровня в пакетах, отправляемых вовне прокси-сервером, так как он отправляет их от лица виртуальных машин. Принадлежность прокси-серверу определяем с помощью свойств UID и GID сокета 95 oif { $eth, $wifi } ip saddr $virtual_machines skuid . skgid { squid . squid } counter masquerade # Преобразуем адреса сетевого уровня в пакетах, отправляемых вовне некоторыми виртуальными машинами, и всеми, получившими временный адрес сетевого уровня, (сравните со строками 69 и 70). При этом ведём им учёт, занося в общий журнал, с целью выявления необычных для соединений HTTPS портов. После выявления таковых заносим их вместе с адресами в набор nonstandard_https (см. строки 76 и 77 для примера). 96 oif { $eth, $wifi } ip saddr { $privileged_vm, $dhcp_client } tcp dport != { http, https } log prefix "NAT:" group 2 counter masquerade 97 } 98 } 99 table bridge filter { # Решаем задачу №5: Разрешаем передавать данные нашему Wi-Fi только известным устройствам 100 chain input { type filter hook input priority -200; policy accept; iif $wifi ether saddr != $my_phone counter drop } # Решаем задачу №4: защита смартфона от всего, не связанного с IPv4, и от ненужных ему широковещательных рассылок chain forward { 101 type filter hook forward priority -200; policy accept; 102 oif $wifi ether type arp accept 103 oif $wifi ip protocol { icmp, tcp, udp } ip daddr != 192.168.120.255 accept 104 oif $wifi drop 105 } # Решаем задачу №5: Разрешаем нашему Wi-Fi отдавать данные только известным устройствам 106 chain output { type filter hook input priority 200; policy accept; oif $wifi ether daddr != $my_phone counter drop } } # Решаем задачу №2: удаление на входах интерфейсов всего, не связанного с IPv4 107 table netdev filter { 108 chain enp0s25 { 109 type filter hook ingress device enp0s25 priority 0; policy drop; 110 ether type arp accept 111 ether daddr $my_eth_mac ip protocol { icmp, tcp, udp, gre } accept 112 } 113 chain wlp3s0 { 114 type filter hook ingress device wlp3s0 priority 0; policy drop; # Разрешаем ARP и EAPOL на случай, когда подключение к Интернету происходит через беспроводной интерфейс 115 ether type { arp, 0x888e } accept # Поскольку беспроводный интерфейс будет подключаться к мосту, здесь необходимо указать адреса канального уровня как самого интерфейса, так и моста 116 ether daddr { $my_br_mac, $my_wifi_mac, ff:ff:ff:ff:ff:ff } ip protocol { icmp, tcp, udp, gre } accept 117 } 118 }
Настройка потребителей
На самой РС
Для более основательных испытаний прозрачного прокси-сервера я решил использовать его и для всех приложений (за некоторыми исключениями, о чём дальше) на самой РС.
Добавим сертификат прокси-сервера в общее хранилище:
mkdir -p /usr/local/share/ca-certificates cp /etc/squid/squid.pem /usr/local/share/ca-certificates/squid.crt
Обновим хранилище:
update-ca-certificates
Приложения — веб-браузеры «Firefox» и «Chromium» не используют общее хранилище сертификатов, поэтому его следует добавлять в соответствующие хранилища этих приложений.
Создадим конфигурационный файл /etc/env.d/38proxy с такими строками:
http_proxy=http://192.168.120.1:3128 https_proxy=http://192.168.120.1:3128 ftp_proxy=http://192.168.120.1:3128
Обновим переменные окружения:
env-update
После повторного входа настройки будут применены для всех приложений.
Об исключениях:
- На всякий случай оставим веб-браузер «Chromium», он будет всегда подключаться к сети напрямую, без прокси-сервера, для этого конфигурационный файл /etc/chromium/default изменим таким образом:
CHROMIUM_FLAGS="--enable-seccomp-sandbox —no-proxy-server" - Приложение xfreerdp при наличии переменной окружения https_proxy пытается подключаться через прокси-сервера, поэтому в конфигурационный файл оболочки добавим следующую строку:
alias xfreerdp='https_proxy= xfreerdp' - Приложение youtube-dl не может проверить сертификат, вероятно, из-за особенностей хранилища сертификатов языка Python. Постоянное решение пока не найдено, поэтому в конфигурационный файл оболочки добавим следующую строку:
alias youtube-dl='youtube-dl --no-check-certificate'
На виртуальных машинах с ОС «Red Hat Enterprise Linux» 6-го и 7-го выпуска
На виртуальной машине включаем работу с сертификатами PEM:
update-ca-trust force-enable
Переписываем с РС сертификат прокси-сервера на виртуальную машину:
scp squid.crt root@192.168.120.66:/etc/pki/ca-trust/source/anchors/
На виртуальной машине обновляем сертификата:
update-ca-trust extract
На виртуальных машинах с ОС «Microsoft Windows» разных выпусков
Сертификат загружается в общее хранилище сертификатов машины (не пользователя!) в раздел «Доверенные корневые...». Веб-браузер «Firefox» не использует общее хранилище сертификатов, поэтому сертификат следует добавлять в соответствующее хранилище этого приложения.
На РС «Raspberry Pi» с ОС «Raspbian»
Обновление приложений прошло успешно без установки сертификата.
На смартфонах с ОС «Android»
Сертификат предварительно загружается на устройство, затем устанавливается с помощью приложения по управлению сертификатами. После этого у пользователя будет запрошено усиление безопасности входа в устройство (если это ещё не сделано) с помощью графического ключа или пароля.
Вывод
Новый брандмауэр в линуксе (nft) представляет собой прекрасный образчик свободного ПО, хорошо сочетающийся со Squid’ом, де-факто стандартом свободного прокси-сервера.
Первоисточники
1. http://wiki.squid-cache.org/Features/Tproxy4
2. /usr/src/linux/Documentation/networking/tproxy.txt
3. http://wiki.nftables.org
4. nft(8)
5. https://www.bounca.org/tutorials/install_root_certificate.html
Автор: Шамиль Саитов Nikodim_Tychoblin
