Jan 12

Ausnahmsweise mal keine (Über-)Lebenshilfe, sondern ein Hilferuf!

Da hier zwei Kids rumlaufen, hab ich gern die Kontrolle wann und wie das Netz benutzt wird. Bisher (zu v4-Zeiten) hat der Squid gute Dienste geleistet. Mit ipv6 ist das nicht mehr so. Da beisse ich mir nämlich die Zähne aus.

Doch von vorn: Hier im Netz läuft ein radvd (Router Advertising Daemon), der ein sixxs-Prefix im LAN Announced. Der (zwangs-)proxy biegt alle ausgehenden ipv4-Port-80 Anfragen transparent auf den Squid-Port um, und handlet den Kram dann per ACL. v4 gibt es statisch über einen DHCP, und für Gäste ist eine Range vergeben.

Seit v6 schnappen sich die Endgeräte irgendeine v6-Adresse (bei ios7 kann man ja bekanntlich die privacy-extensions nicht mehr ausschalten) und vorbei ist es mit der Kontrolle (vom DNS mal ganz abgesehen). Eine Lösung muss her. Bisher ausprobiert habe ich folgendes:

  • auth_param im Squid angeknipst. Resultat erschütternd:
    • Android und Proxys … Hahaha (wenn, nur “gerooted”) !!! Android und Proxy-Auth – HEUL! Tut überhaupt nicht.
    • ios und Proxys – Nett / ios und Proxy-Auth – Neee, da taktet ein Autoblinker stabiler. Geht nicht 🙁
    • OSX: Siehe ios.
  • acl based on arp (acl arp)
    • Bei v4 schick – bei v6 gibts Neighbourdiscovery und kein arp mehr. Dummerweise scheint noch niemand ND in irgendeiner Squid-Version als acl implementiert zu haben 🙁
  • ACLs auf V6-IP-Basis
    • Aufgrund der Privacy-Extensions unbenutzbar

Noch nicht ausprobiert (weil so demotiviert von den o.g. zwei Punkten – und tlw. auch zu aufwendig):

  • Getrennte “Netze” mit getrennten IPv6-Prefixen um die ACLs auf Netzebene auszurollen:
    • Aufwändig !! Trennbar nur über VLANs, extra SSIDs an jedem WLAN-AP … und überhaupt
  • DHCPv6
    • will man sowas?
  • RADIUS
    • Kanonen / Spatzen und so. Neee
  • 802.1X
    • Interessanter Ansatz. Aber da fliegen auch wieder die IOS-Devices raus. Ferner gilt das selbe wie bei radius.

Vorschläge sind mehr als willkommen. Derzeit hab ich auf der LAN-Seite des Proxies v6 wieder ausgeschaltet und arbeite mit den o.g. ARP-Filtern. Tut zumindest einigermassen. An so einem iphone lässt sich die macaddy nicht so einfach ändern. 

Tagged with:
Jun 23

Die Konfig hier zu Haus sagt, gehe über den Proxy – egal was passiert. Per iptables ist es den Workstations verboten, direkte HTTP-Requests nach draussen abzusetzen. Die werden einfach gedroppt. Damit man jedoch nicht bei jedem neuen Client erst den Proxy eintragen muss, gibt es so schöne Erfindungen wie wpad.dat (aka proxy.pac).

Der DHCP Server im Netz announced also, bei Vergabe einer ip, gleich die URL fuer die Proxy-Autoconf mit. In der Regel klappt das auch alles super. Hätte nicht jeder Browserhersteller wieder seinen eigenen Kram gebastelt. So interpretiert der Safari auf dem Mac diverse Dinge anders als der Chrome oder der IE. Eine schöne Matrix, mit dem was geht, und was nicht geht, gibt es bspw. bei pacwpad.com.

Die Herausforderung bestand/besteht am Ende darin, den Browsern zu sagen: Hey, du willst was im LAN, dann brauchst Du den Proxy nicht zu fragen. Ansonsten bitte Proxy nehmen. Mit ipv4 kein Thema. Bei ipv6 verschluckt sich der Safari jedoch massivst.

In der folgenden Config bin ich nun soweit, dass Chrome brav das macht was er soll, Safari jedoch bei jeglichen (auch LAN) ipv6-only Websites immer über den Proxy geht. Das liegt daran, dass der Safari scheinbar die javascript-Funktion “dnsResolveEx” nicht kennt. Ohne try/exception macht der immer einen auf “direct” bei ipv6. Mit diesem Konstrukt geht er zumindest immer auf den Proxy. Bin mal gespannt, wie lange es dauert bis sich die Browserhersteller da geeinigt haben…

Hier also die Config:

  • LANv4 ist 10.0.0.0/24
  • LANv6 ist 2001:999:999:8888/64

function FindProxyForURL(url, host)
{
        if (isInNet(host, "10.0.0.0", "255.255.255.0")) { // ipv4 im LAN ? Dann direct
                return "DIRECT";
        }
        if (host.substring(0, 4) == "127.") { // Localhost ? dann DIRECT
                return "DIRECT";
        }
        if (host.substring(0,16) == "2001:999:999:8888") { // IPv6 Adresse in den Browser eingegeben, und die ist im LAN ? Dann DIRECT
                return "DIRECT";
        }
        try {
            var resolved_ip = dnsResolveEx(host);
            if (resolved_ip.indexOf("2001:999:999:8888")>-1 ) { // Hostname löst auf eine IPv6 auf, die im LAN ist ? Dann DIRECT
                    return "DIRECT";
            }
        } catch(e) { // Funktion "dnsResolveEx" nicht vorhanden ? Dann Fallback proxy
            return "PROXY 10.0.0.2:3128";
        } 
        return "PROXY 10.0.0.2:3128"; // Default: Proxy
}

									

Update: Es empfiehlt sich anstelle der IP (10.0.0.2:3128) den FQDN des Proxies einzutragen. Einige Geräte machen scheinbar einen lookup bevor sie den Proxy fragen. Wenn beim lookup eine V6 Adresse herauskommt, dann läuft die wpad.dat ins leere, da kein V6-Proxy gefunden wird. Wichtig: der FQDN des Proxies sollte sowohl über einen V4-Eintrag (A), als auch über einen V6-Eintrag (AAAA) verfügen, und auch zusätzlich auf dem V6-Port lauschen…

Tagged with:
Dez 29

Aufmerksam geworden durch diesen Artikel, mit dem ueber den Proxy geholte Webseiten (genauer gesagt werden alle Images einmal um 180 Grad gedreht) on the Fly manipuliert werden habe ich mir das ganze mal näher angesehen und optimiert.

Vorweg schonmal das Ergebnis (funktioniert TRANSPARENT mit allen JPGs, GIFs und PNGs). Transparent bedeutet in diesem Falle, dass der Anwender in keinerlei Weise mitbekommt, dass es sich hier um ein manipliertes Bild handelt. Die Requests werden quasi 1:1 durchgeleitet.

Wor moechten also alle Bilder, die aus dem LAN via Proxy angefordert werden, einmal um 180 Grad drehen. Folgende Ausgangssituation:

  • Transparenter Squid auf einem Router
  • Webserver auf einem etwas dickeren Rechner im LAN

in /etc/squid/squid.conf folgende Zeile einfügen:

url_rewrite_program /usr/bin/updwn.pl
url_rewrite_children 5

Das File /usr/bin/updwn.pl sollte wie folgt aussehen:

#!/usr/bin/perl
# Runs as proxy:proxy
# input - siehe unten (Array params)
# output - URL - transparent *invisble to Enduser :-) *
$|=1;
while (<>) {
chomp $_;
@params=split(/ /,$_);
# 0 = Request URL
# 1 = Requesting IP/-
# 2 = -
# 3 = Request Method
# 4 = myip= ?
# 5 = myport = ?
$url=$params[0];
if (!($params[1]=~/192\.168\.60\.200/)) { # Nicht rekursiv aufrufen (Boese !!)
$url='http://192.168.60.200/ppics/updwn.pl?u='.$url if ( ($url=~/gif/i) || ($url=~/jpg/i) || ($url=~/jpeg/i) || ($url=~/png/i));
}
print $url."\n";
$count++;
}

Wobei die 192.168.60.200 durch die IP des eigenen Webserver zu ersetzen waere. Die eigentliche “Magie” findet naemlich jetzt im updwn.pl auf dem Webserver statt. Das Ding benutzt, im gegensatz zu dem File, welches in dem Artikel beschrieben wurde, direkt die GD-Library und ruft keinerlei Executables mehr auf. Damit ist das Script ein wenig performanter

Hier der Inhalt von /var/www/ppics/updwn.pl:

use CGI qw/:standard/;
use LWP::UserAgent;
use GD;
binmode STDOUT;

$|=1;
my $url=param(“u”);

chomp $url;
my $ctype=”;
my $content=”;
get_content($url,\$ctype,\$content);
rotate(\$content,\$ctype) if ($ctype=~/image/i);
print “Content-Type: “.$ctype.”\n\n”;
print $content;
print “\n–magicalboundarystring\n” if ($ctype=~m/image/);

sub get_content {
my ($url,$ref_ctype,$ref_content)=@_;
my $ua = LWP::UserAgent->new;
$ua->agent(“MyApp/0.1 “);
my $req = HTTP::Request->new(GET => $url);
my $res = $ua->request($req);
$$ref_ctype=$res->content_type;
$$ref_content=$res->content;
}

sub rotate {
my ($ref_content,$ref_header)=@_;
my $image=undef;
$image=newFromPngData GD::Image($$ref_content) if ($$ref_header=~/png/i);
$image=newFromJpegData GD::Image($$ref_content) if ($$ref_header=~/jpeg/i);
$image=newFromGifData GD::Image($$ref_content) if ($$ref_header=~/gif/i);
$image->rotate180();
$$ref_header=’image/png’;
$$ref_content=$image->png();
}
Wichtig: Die URL sollte nicht aus dem Internet erreichbar sein. Ansonsten hat man einen selbstgebastelten offenen Proxy…

Mithilfe der Parameter des Files /usr/bin/updwn.pl kann man sich jetzt sogar lustige ACLs bauen. (Rotiere nur fuer bestimmte IP’s oder fuer bestimmte URLs, etc…) Der Phantasie sind da keine Grenzen gesetzt.

Tagged with:
preload preload preload