Proxy per accesso a router TIM Technicolor AG COMBO

In breve, sto cambiando casa, ho preso una linea TIM/Interbusiness cosiddetta “a pacchetti” (non mi chiedete perchè la chiamino così in TIM, sembra lapalissiano anche a me: forse i pacchetti x loro non sono la stessa cosa dei pacchetti per me) e come ampiamente prevedibile mi hanno portato il router/firewall/switch/ap/nas, insomma il “coso” in oggetto.

Risultati immagini per "technicolor-ag-combo.png"

Sono un po’ titubante, ma per il momento lo lascio lì. A un certo punto mi serviva accedere un attimo all’interfaccia amministrativa dall’esterno per farmi un’inoltro. Disponendo di un raspberry collegato all’interno con la SSH inoltrata, mi sono semplicemente intunnellato una porta (821) redirigendola verso il router (192.168.1.254:80) ma la cosa produce un 404. Breve verifica, il router controlla l’host header.

Per ovviare al volo ho pigliato un proxy tcp in perl da qui http://www.catonmat.net/blog/perl-tcp-proxy/ (grazie!!), l’ho modificato brutalmente per cambiare la volo l’header. Vedo che il server manda anche dei redirect HTTP, che ovviamente risultano pure loro spuntati. Cambiati anche quelli, funziona. Logicamente è un lavoro molto migliorabile (ad esempio, si potrebbe almeno controllare di fare le due sostituzioni solo nell’header; mentre invece già controllo di farle solo nella direzione giusta, questo era facile) ma funziona ed essendo solo una cosa da lanciare al volo quando serve, mi basta così. Il listato:

#!/usr/bin/perl
#
# Uso: 
# Inoltra in SSH la porta 821 sulla 821 del presente rPI
# Poi
# tcp-proxyTechnicolor.pl  821 192.168.1.254:80 
#
# Preso da:
#
# http://catonmat.net/blog/perl-tcp-proxy
#
# Peteris Krumins (peter@catonmat.net)
# http://www.catonmat.net  --  good coders code, great reuse
#
#
# Written for the article "A TCP Proxy in Perl":
#
# http://catonmat.net/blog/perl-tcp-proxy
#

use warnings;
use strict;

use IO::Socket::INET;
use IO::Select;
use Data::Dumper;

my @allowed_ips = ('all', '10.10.10.5');
my $ioset = IO::Select->new;
my %socket_map;

my $debug = 1;

sub new_conn {
    my ($host, $port) = @_;
    return IO::Socket::INET->new(
        PeerAddr => $host,
        PeerPort => $port
    ) || die "Unable to connect to $host:$port: $!";
}

sub new_server {
    my ($host, $port) = @_;
    my $server = IO::Socket::INET->new(
        LocalAddr => $host,
        LocalPort => $port,
        ReuseAddr => 1,
        Listen    => 100
    ) || die "Unable to listen on $host:$port: $!";
}

sub new_connection {
    my $server = shift;
    my $remote_host = shift;
    my $remote_port = shift;

    my $client = $server->accept;
    my $client_ip = client_ip($client);

    unless (client_allowed($client)) {
        print "Connection from $client_ip denied.\n" if $debug;
        $client->close;
        return;
    }
    print "Connection from $client_ip accepted.\n" if $debug;

    my $remote = new_conn($remote_host, $remote_port);
    $ioset->add($client);
    $ioset->add($remote);

    $socket_map{$client} = $remote;
    $socket_map{$remote} = $client;
}

sub close_connection {
    my $client = shift;
    my $client_ip = client_ip($client);
    my $remote = $socket_map{$client};
    
    $ioset->remove($client);
    $ioset->remove($remote);

    delete $socket_map{$client};
    delete $socket_map{$remote};

    $client->close;
    $remote->close;

    print "Connection from $client_ip closed.\n" if $debug;
}

sub client_ip {
    my $client = shift;
    return inet_ntoa($client->sockaddr);
}

sub client_allowed {
    my $client = shift;
    my $client_ip = client_ip($client);
    return grep { $_ eq $client_ip || $_ eq 'all' } @allowed_ips;
}

die "Usage: $0  " unless @ARGV == 2;

my $local_port = shift;
my ($remote_host, $remote_port) = split ':', shift();


print "Starting a server on 0.0.0.0:$local_port\n";
my $server = new_server('0.0.0.0', $local_port);
$ioset->add($server);

while (1) {
    for my $socket ($ioset->can_read) {
        if ($socket == $server) {
            new_connection($server, $remote_host, $remote_port);
        }
        else {
            next unless exists $socket_map{$socket};
            my $remote = $socket_map{$socket};
            my $buffer;
            my $read = $socket->sysread($buffer, 4096);
            if ($read) {
		# http://localhost:821
		inet_ntoa($remote->sockaddr) ne '127.0.0.1' and $buffer =~ s/^Host: localhost:$local_port\b/Host: $remote_host/m;
		inet_ntoa($remote->sockaddr) eq '127.0.0.1' and $buffer =~ s|^Location: http://$remote_host\b|Location: http://localhost:$local_port|m;
		#print STDERR "== " . inet_ntoa($remote->sockaddr) . "\n";
		#print STDERR Dumper($buffer) . "\n\n";
                $remote->syswrite($buffer);
            }
            else {
                close_connection($socket);
            }
        }
    }
}



Comments are closed.