Skip to main content

Squid proxy

Squid cache je cachovací proxy server který slouží primárně pro optimalizaci doručení http/https/ftp dat.

My jej zde použijeme pro omezení provozu na určité vybrané domény v HA režimu hot-standby pomocí keepalived.

Pro rychlé nasazení zde nabízím svůj projekt který mám v GitLabu a nasazuji pomocí něj konfiguraci automaticky: uproxy-main.zip

⚠️ Mysli na to, že je potřeba vytvořit ještě SSH klíče které nahraješ do proměnných GitLabu a v .gitlab-ci.yml je použiješ. Tento projekt je tedy ještě drobně poupravit 😉

Instalace

APT

  • Nainstalovat potřebné balíčky:
    • Debian/Ubuntu:
      apt update
      apt install squid keepalived
      

NFT (firewall)

  • Za předpokladu že používáme nftables, vytvořit pravidla pro protokol VRRP (112) a příchozí pravidla pro proxy pro porty na kterých má poslouchat.

    ⚠️ Pravidlo pro IPv6 na výstupu je nutné pro inicializaci squid proxy!

    1. 12-ha.nft
      #!/usr/sbin/nft -f
       table inet filter {
         chain INPUT {
                 meta l4proto 112 ip saddr IP4_ADDRESS accept comment "Allow VRRP from BACKUP - IPv4 IN"
         }
         chain OUTPUT {
                 meta l4proto 112 ip daddr IP4_ADDRESS accept comment "Allow VRRP to BACKUP - IPv4 OUT"
         }
       }
      
    2. 11-proxy.nft
      #!/usr/sbin/nft -f
       table inet filter {
         chain INPUT {
                 tcp dport 10000-10006 accept comment "Allow Squid proxy - IN"
         }
         chain OUTPUT {
                 ip6 saddr ::1 ip6 daddr ::1 accept comment "Allow IPv6 for localhost - OUT"
         }
       }
      
  • Reloadnout službu systemctl restart ntables.

Keepalived

  • Vytvořit si skripty které nám budou kontrolovat, jestli síťový adapter žije, a jestli squid proxy běží:

    • /usr/local/bin/check_nic_carrier
      #!/bin/sh
      # This scrips checks if ethernet specified as first script arg has carrier
      NIC="$1"
      if grep -qx 1 /sys/class/net/${NIC}/carrier 2>/dev/null; then
        # interface is up
        exit 0
      else
        # interface is down
        exit 1
      fi
      
    • /usr/local/bin/check_squid_status
      #!/bin/sh
      if [ -z $(pidof squid) ]; then
        # squid not running
        exit 1
      else
        # squid running
        exit 0
      fi
      

      ⚠️ Nezapomeň je učinit spustitelnými: chmod 755 /usr/local/bin/check_{nic_carrier,squid_status}

  • Nastavit si konfigurační soubor /etc/keepalived/keepalived.conf kde doplníme adresy a jména síťových adapterů

    • Oba nody:
      • NIC: síťový adaptér po kterém se má komunikovat, třeba eth0

        🗒️ Pokud jsou servery rozdílné, nevyplňovat samozřejmě to stejné 😄

      • VIP_IP4: Plovoucí adresa mezi hlavní a záložním serverem.
      • VIP_IP4_MASK: Maska sítě za použití CIDR Prefix formátu, např.: 24
      • VIP_IP4_GW: Výchozí brána pro adresu.

        💡 Příklad:

        • 10.0.1.10 (adresa která cestuje a žije vždy jen na aktivním/živém serveru)
        • 24 (klasická síť 255.255.255.0)
        • 10.0.1.1 (router)
    • MASTER:
      • HOST_IP4: < adresa serveru >
      • REMOTE_IP4: < adresa backup serveru >
      • NODE_STATE: MASTER
      • NODE_PRIO: 200
    • BACKUP
      • HOST_IP4: < adresa serveru >
      • REMOTE_IP4: < adresa master serveru >
      • NODE_STATE: BACKUP
      • NODE_PRIO: 100
    # Global definitions configuration block.
    global_defs {
            enable_script_security
            script_user nobody
            vrrp_version 3
    }
    # Periodically check if nginx process is running.
    vrrp_script check_squid_status {
          # Path of the script to execute.
          script "/usr/local/bin/check_squid_status"
          # Number of seconds between script invocations.
          interval 4
          # Number of seconds after which script is considered to have failed.
          timeout 2
          # Requires 2 failures for KO.
          fall 2
    }
    # Periodically check ethernet carrier status.
    vrrp_script check_nic_carrier {
          # Path of the script to execute.
          script "/usr/local/bin/check_nic_carrier NIC"
          # Number of seconds between script invocations.
          interval 2
          # Requires 2 failures for KO.
          fall 2
          # Require 2 successes for OK.
          rise 2
    }
    # Sync instances
    vrrp_sync_group sg {
          group {
                  vi_ipv4
          }
          track_script {
                  check_squid_status
                  check_nic_status
          }
    }
    # IPv4 + IPv6 instances
    vrrp_instance vi_ipv4 {
          state NODE_STATE
          interface NIC
          priority NODE_PRIO
          advert_int 1
          virtual_router_id 66
          unicast_src_ip HOST_IP4
          unicast_peer {
                  REMOTE_IP4
          }
          virtual_ipaddress {
                  VIP_IP4/VIP_IP4_MASK
          }
          virtual_routes {
                  default via VIP_IP4_GW dev NIC
          }
    }
    
  • Reloadnout službu systemctl restart keepalived.

Squid

  • V Debianu se konfigurace nachází v /etc/squid/conf.d/.
  • V této konfiguraci tvořím obecný whitelist a následně pravidla (ACL) pro přístup.
  • Soubory pojmenovávám dle portů od 10000, konfigurace jsou < 10000 ale pořadí.
  1. 00010-dom-rwhitelist - Whitelist na základě REGEX výrazu domény. Povoluje mi CDN na které potřebují přístup systémy které používáme a povoluje přihlášení pomocí Entra ID ČVUT.

     ## Microsoft
     ### https://learn.microsoft.com/en-us/microsoft-365/enterprise/urls-and-ip-address-ranges?view=o365-worldwide#microsoft-365-common-and-office-online
     ### n56+n64 selected domains
     acl acl_drw dstdom_regex .*.events.data.microsoft.com$
     acl acl_drw dstdom_regex .*.auth.microsoft.com$
     acl acl_drw dstdom_regex .*.msftidentity.com$
     acl acl_drw dstdom_regex .*.msidentity.com$
     acl acl_drw dstdom_regex ^login.microsoft.com$
     acl acl_drw dstdom_regex ^login.microsoftonline.com$
     acl acl_drw dstdom_regex ^aadcdn.msftauth.net$
     acl acl_drw dstdom_regex ^aadcdn.msauth.net$
     acl acl_drw dstdom_regex ^aadcdn.msftauthimages.net$
     acl acl_drw dstdom_regex ^aadcdn.msauthimages.net$
     acl acl_drw dstdom_regex ^logincdn.msftauth.net$
     acl acl_drw dstdom_regex ^logincdn.msauth.net$
     acl acl_drw dstdom_regex ^login.live.com$
     acl acl_drw dstdom_regex ^logon.ms.cvut.cz$
     acl acl_drw dstdom_regex ^security.microsoft.com$
    
     # CDN's
     ## Gstatic + GoogleAPIs
     acl acl_drw dstdom_regex ^gstatic.com$
     acl acl_drw dstdom_regex ^www.gstatic.com$
     acl acl_drw dstdom_regex ^fonts.gstatic.com$
     acl acl_drw dstdom_regex ^ssl.gstatic.com$
     acl acl_drw dstdom_regex ^fonts.googleapis.com$
     acl acl_drw dstdom_regex ^ajax.googleapis.com$
    
     ## Cloudflare
     acl acl_drw dstdom_regex ^cdnjs.cloudflare.com$
    
     ## jsdelivr
     acl acl_drw dstdom_regex ^cdn.jsdelivr.net$
    
     ## mathjax
     acl acl_drw dstdom_regex ^cdn.mathjax.org$
    
  2. 10000-bi-dbs.conf - Konfigurační soubor pro systém DBS portál. Povoluje přístup na portál, jeho závislost u digicertu a obecný whitelist. To celé vystavuje na portu 10000 a ten si poté nastavujeme v prohlížeči cíleného systému.

     acl p10000 myport 10000
     acl acl_dbs dstdomain dbsportal.cz
     acl acl_dbs dstdomain ocsp.digicert.com
    
     http_access allow p10000 acl_dbs
     http_access allow p10000 acl_drw
     http_access deny  p10000 all
    
     http_port 10000
    
  • Tohle docela stačí, restartovat službu: systemctl restart squid.

Vlastní chybové stránky

V adresáři files/usr/share/squid/errors lze definovat vlastní formát stránek ukazující na konkrétní chybu.

⚠️ Toto funguje pouze s http, s https ne.

Nastavení v prohlížeči

Firefox

Na Linuxu pro přednastavení ve Firefoxu musíme spustit prohlížeč s parametrem --profile ~/.mozilla/firefox/firefox.default, kdy adresář ~/.mozilla/firefox/firefox.default obsahuje soubor user.js, jehož obsahem je sada nastavení jako na následujícím příkladu nastavujícím připojení k proxy na portu 10000:

user_pref("network.proxy.backup.ssl", "");
user_pref("network.proxy.backup.ssl_port", 0);
user_pref("network.proxy.http", "uproxy.cvut.it");                                                                                                          
user_pref("network.proxy.http_port", 10000);
user_pref("network.proxy.share_proxy_settings", true);
user_pref("network.proxy.ssl", "uproxy.cvut.it");
user_pref("network.proxy.ssl_port", 10000);
user_pref("network.proxy.type", 1);

💡U již vytvořených profilů lze tyto údaje zapsat/změnit v prefs.js.