• Welcome to Hurricane Electric's IPv6 Tunnel Broker Forums.

Windows bat file to set up tunnel and Routable prefix.

Started by ravenstar, March 05, 2014, 12:07:44 PM

Previous topic - Next topic

ravenstar

Hi I've just created a .bat file to automate the creation of a he.net tunnel and set up the Routable prefix on a Windows 8 based machine.  (Should also work for Windows 7 and Vista AFAIK.)

You enter the tunnel details from the tunnelbroker.net page when asked.  It does require you to enter the Routable 64 in the form 2001:470:xxxx:xxxx::/64.
It also requires the bat file to be run in administrator mode.

REM tunnelsetup.bat (c) Timothy Dutton 2014

@echo off
echo This script will automate setting up an IPv6 tunnel from Hurricane Electric
echo Note this needs to be run with administrator privileges to work.
echo Login in to your tunnelbroker.net account and go to the tunnel details and enter the following details
echo Note that if you are running behind a NAT router then you should use the LAN IP instead of the Client address on the Tunnel details page
set /p clientv4=Enter client IPv4 address:
set /p serverv4=Enter server IPv4 address:
set/p clientv6=Enter client IPv6 address:
set/p serverv6=Enter server IPv6 address:
set/p routed64=Enter routed 64 (Please include the /64):
set firstadd=%routed64:/64=%1
set/p lanname=Enter name of LAN interface:
set lanname="%lanname%"

netsh interface ipv6 add v6v4tunnel IP6Tunnel %clientv4% %serverv4%
netsh interface ipv6 add address IP6Tunnel %clientv6%
netsh interface ipv6 add route ::/0 IP6Tunnel %serverv6% publish=yes
netsh interface ipv6 set interface IP6Tunnel forwarding=enabled

netsh interface ipv6 set interface %lanname% forwarding=enabled advertise=enabled
netsh interface ipv6 add address %lanname% %firstadd%
timeout /T 2 /NOBREAK
netsh int ipv6 set route %routed64% %lanname% publish=yes


I did have to put a timeout in otherwise the last line of code was executed before the route was properly set up after adding the address, resulting in an element not found error.

If anyone can suggest any improvements I would be grateful.

Ravenstar

chrisjmartini

This looks like a great help, thanks. However, what is meant by "client IPv4 address" in my case? I am connected on a laptop via wifi to a modem/router supplied by my isp (Time Warner Cable). Would it be the internal LAN ip4 address assigned to my laptop by the router?

kasperd

Quote from: chrisjmartini on March 12, 2014, 04:04:57 PMHowever, what is meant by "client IPv4 address" in my case? I am connected on a laptop via wifi to a modem/router supplied by my isp (Time Warner Cable). Would it be the internal LAN ip4 address assigned to my laptop by the router?
Looks like it expects the internal IPv4 address of the machine you run the script on. Configuration of NAT (if needed), and update of the tunnel server (in case your extern IP is dynamic) does not appear to be done by this script.

chrisjmartini

Ok, it is not connecting. I don't think I am entering correct info since I am behind a modem/router. I managed to take a screenshot of the cmd window before it closed and also a screenshot of my tunnel details (attached). Any help would be appreciated as I need to get this up and running for work.

* I entered my machine's ip4 address for "client ipv4 address".

kasperd

Looks like the input you gave the script is not in the expected format. What does the output look like, if you omit the /64 from client and server address?

chrisjmartini

Tried again, leaving off '/64' from client and server ipv6 addresses. Output attached.

kasperd

Quote from: chrisjmartini on March 13, 2014, 02:31:44 PMTried again, leaving off '/64' from client and server ipv6 addresses. Output attached.
Output looks better. I think that is the format, which the script expects. But the error messages sounds like cleanup after the previous run was needed. That means either you need to figure out the sequence of commands needed to clean up after the previous run, or you need to reboot the machine and then run the script again.

If it still doesn't work, there are two likely explainations. Either the client IP on the server does not match the external IP of your NAT, in which case you just need to update the setting on the tunnel server. Or the NAT cannot pass protocol 41 in its current configuration, in which case you need to figure out, if the NAT need to be reconfigured.

ravenstar

Hi

Apologies

From your output I see you already have an existing 6in1 tunnel set up (either manually or by previously running the bat file)
Before re running the bat file you need to delete the existing tunnel manually

Open up an Elevated command prompt. And enter the following 2 lines
netsh int ipv6 del int ip6tunnel
netsh int ipv6 reset

After this reboot the machine and try running the bat again.

I am currently using a Virginmedia Superhub 2 which passes protocol 41 packets, as has already been said, not all routers do this (I could never get a tunnel working on my Netgear WNDR3400 for example).

Ravenstar68

PS I am working on a Powershell variant that takes even less user input.  It uses the tunnelbroker API to fetch the tunnel details.  I have the main functionality working.  I just need to deal with a couple of issues that break it prior to posting.  (in fact I'll add a check for IP6Tunnel at the start of the script).

ravenstar

#8
I've now created 3 Powershell scripts.
The first is used to extract the tunnel info automatically from tunnelbroker.net using the API

<#
   GetTunnelInfo.ps1  (c) 2014 Timothy Dutton

   Function to retreive the info of the first tunnel interface found on
   a users account.
   Many thanks to Hurricane Electric who provided the API that is used
   to make this script work.
#>

function Get-TunnelInfo
{
# Prompt for Tunnelbroker user details
Param(
   [Parameter(Mandatory=$true, Position=0, Helpmessage="Tunnelbroker Username: ")]
   $Username,
   [Parameter(Mandatory=$true, Position=0, Helpmessage="Enter Password: ")]
   [SecureString]$Password
   )
# Password was obtained using a secure string so now we decode it
$pw=[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.Interopservices.Marshal]::SecureStringToBSTR($Password))
$ErrorActionPreference="Stop"
# Now obtain the Tunnel info
$url="https://tunnelbroker.net/tunnelInfo.php"
$webClient = New-Object System.Net.WebClient
$credCache = New-Object System.Net.CredentialCache
$creds = New-Object System.Net.NetworkCredential($Username, $pw)
$credCache.Add($url, "Basic", $creds)
$webClient.Credentials = $credCache
$webpage = $webClient.DownloadString($url)

# Now we have the XML page downloaded parse it using Powershell's XML parser
$tunnelinfo = [xml]$webpage
# Check to see how many tunnels we have
$tcount = $tunnelinfo.tunnels.ChildNodes.Count
   if ($tcount -eq 1) #Only one tunnel so return it
   {
       return $tunnelinfo.tunnels.tunnel
   }
   else
   {
       $count = 0
       do
       {
           $tunnel = $tunnelinfo.tunnels.tunnel[$count]
           Write-Host($count + 1) '  ' $tunnel.id      
           $count = $count +1
       }
       while ($count -lt $tcount)
       do
       {
           $num = Read-Host "Enter Tunnel number to use"
       }


The second is simply used to Elevate the script is is called from. this means that you don't have to explicitly start in an elevated powershell session for the final script to work.

# Elevate.ps1

Function Elevate
{
   $myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
   $myWindowsPrincipal=New-Object System.Security.Principal.WindowsPrincipal($myWindowsID)
   $adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
   if (-not $myWindowsPrincipal.IsInRole($adminRole))
   {
       $newProcess = New-Object System.Diagnostics.ProcessStartInfo "Powershell"
       $newProcess.Arguments = $Script:MyInvocation.MyCommand.Definition
       $newProcess.Verb = "runas"
       [System.Diagnostics.Process]::Start($newProcess)
       exit
   }
}


The final Script takes the other two and sets up the tunnel

<#
   Pwershell Script to automate setting up a HE.net IPv6 Tunnel
   Copyright (C) 2014 Timothy Dutton
#>

cd $PSScriptRoot

# Script needs administrator priviledges to run the Netsh commands correctly
# So check to see if we are already running as such
. .\Elevate.ps1
. .\GetTunnelInfo.ps1
Elevate

# Have already created a function GetTunnelInfo which prompts for a username and password
# And then connects to Tunnelbroker.net and gets the first tunnel found using their API
$ErrorActionPreference = "Stop"
$tunnel = Get-TunnelInfo

# Strip out the info we need to create the tunnel.  While not necessary it makes the
# netsh commands further down easier to read
$serverv4=$tunnel.serverv4
$clientv6=$tunnel.clientv6
$serverv6=$tunnel.serverv6
$routed64=$tunnel.routed64

# First Locate Which device is the Ethernet Adapter
$wiredAdapter = Get-NetAdapter | Where-Object {$_.PhysicalMediaType -eq '802.3'}

# Now Get the IPv4 address of the wired adapter
$ipAddress=Get-NetIPAddress -AddressFamily IPv4 -InterfaceIndex $wiredAdapter.ifIndex
$ipAddress=$ipAddress[0]
$clientv4=$ipAddress.IPAddress
# We also get the interface name and add quotes to the string so that if there are spaces
# The whole name is used in the netsh commands
$interface=$wiredAdapter.Name
$interface='"'+$interface+'"'

# Finally do a simple replace to get the first IP address of the Routed /64
$firstAdress = $routed64.Replace("/64","1")

# Before setting up the Tunnel Display the Values
Write-Host "Client IPv4 Address is $($clientv4)"
Write-Host "Server IPv4 Address is $($serverv4)"
Write-Host "Client IPv6 Address is $($clientv6)"
Write-Host "Server IPv6 Address is $($serverv6)"
Write-Host "Routed /64 Prefix is   $($routed64)"
Write-Host "Network adapter used   $($interface)"
# Now we wait for user to press enter
Read-Host "Press Enter to set up tunnel or CTRL-C to abort"

# Now set up the basic tunnel
netsh int ipv6 add v6v4tunnel IP6Tunnel $clientv4 $serverv4
netsh int ipv6 add address IP6Tunnel $clientv6
netsh int ipv6 add route ::/0 IP6Tunnel $serverv6 publish=yes

# And enable forwarding on this and the LAN interface which will advertise the
# IPv6 Prefix
netsh int ipv6 set interface IP6Tunnel forwarding=enabled
netsh int ipv6 set interface $interface forwarding=enabled advertise=enabled

# Add the first address of the routed prefix to the LAN interface and publish the route
netsh int ipv6 add address $interface $firstAdress
# Sleep for 2 seconds else last command does not sleep successfully
sleep -s 2
netsh int ipv6 set route $routed64 $interface publish=yes


To use the scripts they need to be copied and pasted into the following filenames - all in the same directory.

GetTunnelInfo.ps1
Elevate.ps1
SetupTunnel.ps1

To allow execution of the scripts you need to go into Powershell and enter Set-ExecutionPolicy -Scope CurrentUser Unrestricted

GetTunnelInfo is a stand alone script - it does require you to enter your tunnelbroker.net username and password in order to fetch the tunnel details.  If you have more than one tunnel it will enumerate them by tunnelid.  If only one tunnel it will return that.

SetupTunnel calls Elevate and GetTunnelInfo for that reason if it is not in the same folder as the other two functions it will not work.

When called it will open up an elevated Powershell session (If not already in one).  You will be prompted for your tunnelbroker username and password.
It will then display the parameters it will use to set up the tunnel.  At this point Press enter to proceed or Ctrl-C to quit the program.


On a final note - If you already have a tunnel set up using IP6Tunnel this will need to be deleted prior to running the script bey entering an elevated command prompt
and typing

netsh int ipv6 del int ip6tunnel
netsh int ipv6 reset


This code was developed on PowerShell 4.1 in windows 8.1 However AFAIK it should work on Windows 7 and Vista machines.

The scripts have been zipped up here
http://shadowraven.webspace.virginmedia.com/powershell/pstunnel.zip

Any feedback from users would be welcome

Ravenstar68

chrisjmartini

I have tried your set of PowerShell scripts but they don't seem to be working. When I run SetupTunnel.ps1, a power shell window appears, then closes, then a UAC prompt appears. I click 'ok' and then the power shell window reappears, with text all in red (see attached). It then closes so fast, there's no time to check what happened. I managed to capture a screenshot just before it closed.

???

ravenstar

#10
My apologies

I'd added the previous 2 to my Powershell Profile.  I deleted my profile to test running the scripts from the folder and got the same result as you. :(

I've added a line at the start of Setuptunnel.ps1

cd $PSScriptRoot  

Note this is specific to Powershell 3.0 and above.

Provided the files are all in the same folder it now works as intended

Edit - Have now modified the script above to include the same line.

I have amended the file in the zip I linked in earlier.

chrisjmartini

#11
Quote from: ravenstar on March 17, 2014, 05:51:20 AM
My apologies

I'd added the previous 2 to my Powershell Profile.  I deleted my profile to test running the scripts from the folder and got the same result as you. :(

I've added a line at the start of Setuptunnel.ps1

$PSScriptRoot  

Note this is specific to Powershell 3.0 and above.

Provided the files are all in the same folder it now works as intended

Edit - Have now modified the script above to include the same line.

I have amended the file in the zip I linked in earlier.

Ah ok, though now when I try to run the new version (right click on SetupTunnel.ps1 and select run with power shell), a power shell window appears for a second, and then closes. I have followed your instructions above. Perhaps I am doing something incorrectly?

UPDATE: I have now run PowerShell separately from this as admin. I then manually cd into the directory and have run the script. It did finally start correctly after some errors, but did not end up creating the tunnel. Screenshot attached.

ravenstar


chrisjmartini


ravenstar

Can you run the following commands in an interactive powershell
$wiredAdapter = Get-NetAdapter | Where-Object {$_.PhysicalMediaType -eq '802.3'}
$wiredAdapter


Line 29 relies on the outcome of these 2 lines.