The greatest challenge to any thinker is stating the problem in a way that will allow a solution

Bertrand Russell

By

On 28 Mar 2012

PowerShell

Tags: , , ,


Catchy title, eh?

I make quite extensive use of the NAT’ing functionality of Vyatta routers, and it can be quite a pain in the task to keep track of servers’ real (local) and NAT’ed (remote) IP addresses.

Therefore I have the need to collate all the address translations into a central report, in an easy (aka scripted) fashion.  There are probably other ways of achieving this, but for me its a PowerShell script that SSH’s to each Vyatta router in order to query it…

I’ve used PowerShell as this is what I’m using for other reporting already, which doesn’t support SSH out of the box.  But can do by way of the Renci SSH.Net project, which I’ve detailed before here.

The script below connects to a Vyatta router, runs the show nat rules command, and parses the output into an array.  From here you can do what you like with it.  As you can see the SSH part of the script is very simple, I’ve created a couple of functions that have some simple error control in, and from there connecting and running commands is pretty simple.

You will need to download the SSH.NET DLL file before trying the script below (see my previous post for further info). In my case I have renamed it to Renci.SshNet3.5.dll and placed it in a sub-folder to the script (lib\RenciSSH\).

$VyattaRouter = "router"
$user = "username"
$pass = "password"
 
$SshDll = ".\lib\RenciSSH\Renci.SshNet3.5.dll"        # Path to DLL - Most likely cause of problems
 
# SSH functions ==============================================================================================
 
function New-SshSession ([string]$server, [string]$user, [string]$pass, [int]$port = 22) {
    #Write-Host "Create SSH Client - New-Object Renci.SshNet.SshClient($server, $port, $user, $pass)"
    $Client = New-Object Renci.SshNet.SshClient($server, $port, $user, $pass)
 
    try {
        $Client.Connect()
    } catch {
        throw $_
    }
 
    if ($Client.IsConnected) {
        Return $Client
    } else {
        throw "SSH client connect failed..!"
        Return 0
    }
}
 
function New-SshCommand ([Renci.SshNet.SshClient]$SshClient, [string]$command) {
    if ($SshClient.IsConnected) {
        $SshCommand = $SshClient.RunCommand($command)
    } else {
        throw "SshClient is not connected!"
    }
    Return $SshCommand
}
 
# The script ==================================================================================================
 
# Load the SSH library
try {
    [void][reflection.assembly]::LoadFrom( (Resolve-Path $SshDll) )
} catch {
    Write-Error $_
    throw "Unable to find/load the Ssh.Net DLL"
}
 
# Connect to router and run command
Write-Host "Connecting to $VyattaRouter..."
$SshClient = New-SshSession -server $VyattaRouter -user $user -pass $pass
$SshCommand = New-SshCommand -SshClient $SshClient -Command "exec vbash -i -c 'show nat rules'"
 
# Get result and split into rows
$NatText = $SshCommand.Result.Split("`n")
 
# Close session to router and dump objects
$SshCommand.Dispose()
$SshClient.Disconnect()
$SshClient.Dispose()
 
$nats = @()
 
# Parse router output
Write-Host "Parsing results..."
foreach ($line in $NatText) {
    if (!$line.length) {
        Continue
    }
    # Write-Host ("Parsing line [$line]")
    $text = ([regex]::matches($line, "^\d{2,4}\s+(SRC|DST)\s+eth\d\s+(s|d)addr\s\b((25[0-5]|2[0-4]\d|[01]\d\d|\d?\d)\.){3}(25[0-5]|2[0-4]\d|[01]\d\d|\d?\d)\b\sto\s\b((25[0-5]|2[0-4]\d|[01]\d\d|\d?\d)\.){3}(25[0-5]|2[0-4]\d|[01]\d\d|\d?\d)\b"))[0].Value
    $text = [regex]::replace($text, "\s{2,}", " ")
    if ($text.length) {
        $nat = "" | Select RealIP, NatIP
        $words = $text.split(" ")
        if ($words[1] -eq "DST") {
            $nat.RealIP = $words[6]
            $nat.NatIP = $words[4]
        } elseif ($words[1] -eq "SRC") {
            $nat.RealIP = $words[4]
            $nat.NatIP = $words[6]
        } else {
            Write-Host "Ignored invalid line [$text]"
            Continue
        }
        #Write-Host ("Adding " + $nat.RealIP + " - " + $nat.NatIP)
        $nats += $nat
    }
}
$nats = $nats | Sort-Object -Property RealIP -Unique 
 
$nats

Enjoy!


5 Comments to “SSH to Vyatta Router to Get NAT’ing Using PowerShell”

  1. arenas says:

    hi,

    pls, how i have to do for retrief de PW ? for my router.

    Thanks!
    A.

  2. arenas says:

    Hi,
    Many thanks for your reply!

    my probleme is slightly od. In general, how i have to do to look inside the router?
    Pls, can i send you my probleme by mail? to you?
    My best regrads
    A.

  3. Simon Strutt says:

    You need to SSH to the router on any of its IP’s in order to gain access to it.

    If you have an odd problem I’m probably not the best person to contact. If you’ve read Vyatta’s documentation and are still having problems you might want to post your query on their forum (http://www.vyatta.org/forum/), there will be plenty of more experienced people able to help.

  4. arenas says:

    Hello sir

    Many thanks

    A.

Leave a Reply

XHTML: You can use these tags if you know what they are: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

ERROR: si-captcha.php plugin says GD image support not detected in PHP!

Contact your web host and ask them why GD image support is not enabled for PHP.

ERROR: si-captcha.php plugin says imagepng function not detected in PHP!

Contact your web host and ask them why imagepng function is not enabled for PHP.