Thursday, July 30, 2015

configuring IPsec VPN betweeen a fortigate and Microsoft Azure

I tried to set up a vpn connection between my network which is behind a Fortigate 60C firewall and a Microsoft Azure network.  I followed the instructions in this cookbook article published by Fortinet cookbook.fortinet.com/download/3127/ and this video video.fortinet.com/video/120/ipsec-vpn-to-microsoft-azure
Unfortunately it didn't work.  (Kind of like the cook who gives out a recipe without the secret ingredient that gives them the correct texture.

With the help of the fortigate support we finally got it working and its working well.  Here are the steps that need to be taken.
1.  Create an Azure viritual Network.  This is the same as the cookbook so I'll do this briefly.
  • use the custom create method
  • choose configure a site to site VPN
  • Enter the public IP of the fortigate unit and the private address space on your internal network
  • Configure a NAT address space on the Virtual network.  I used one differeant from the NAT on my local network
  • Add gateway subnet (this is done automatically and it takes a few minutes)
  • You will get a Gateway IP address (public)
2.  Configure the Fortigate tunnel (used fortinet version 5.2)
  • Go to VPN IPsec Wizard and select Custom VPN Tunnel.  Enter a name a next
  • For Remote gateway enter the public IP of the Azure network you created in 1
  • Local interface should be your wan interface
  • For the preshared key go to the azure management site.  Click on manage keys, copy the key and paste it into the Pre shared key textbox in the fortigate wizard.
  • Phase 1 - delete any encryptions with DES on either side of the encryption.
  • Select IKE version 2, Diffe -0Hellman Group 2, Key Lifetime 566200 (as in cookbook)
  • Phase 2 Enter your local NAT address space and the for the remote address space the NAT address of the Azure network
  • Disable any encryptions with DES in it
  • Disable Replay Detection and disable Perfect Forward Secrecy (unlike some of the cookbooks)
  • Enable local Port, Remote Port and protocol
  • Disable Autokey keep alive and Auto-negotiate
  • Set Key lifetime for 7200 seconds
3.  configure policies
  • Set up addresses for your local NAT network addresses and the Azure network addresses (we'll use azure-internal and azure-external respectively for this example)
  • Go to Policy & Objects->Policy->IP4  create new policy
  • Incoming interface:  internal, source address azure-internal, outgoing interface Azure (Name of interface you created in 2), Destination address azure-external, schedule to always and service all.  NAT is on, enable Use outgoing Interface Address, enable policy.
  • Create new policy for azure-internal network the opposite of the previous policy
  • Incoming interface Azure, source address azure-external, outgoing interface internal, destination address  azure-internal, rest as the previous policy.
4.  Set up a virtual machine on Azure
  • Go to Azure portal click on virtural machines.  Find the New button, Click on From Gallery
  • select your image.  Fill out the information on the next schreen
  • Choose the cloud service that was created for your virtual network.  It will then automatically choose your virtual network you created previously in Region/Affinity group/virtual network. as well as assign it an IP in the nat space you configured for your azure network.
  • finish the wizard.
5.  Go back to the fotigate portal and select vpn->Monitor->IPsec monitor.
  • The tunnel created in step 2 should show up there.  Make sure the status is on up.  IF its down, right click and click on bring up.
6.  Go back to Azure portal and your virtual network and see if the gateway is connected.  if it is not than click on the connect button.  the graphics should change after a few minutes and you will see connected.  There also should be numbers greater than 0 in data in and data out.
7.  If everything is working you can set up some file shares on the virtual machine you created and access them from your local network and vice versa. 
8.  Buy me a beer.




Monday, July 27, 2015

using jquery autocomplete

In an old web form application I had a combobox with a growing unmanageable number of entries.  I decided to enter the 21'th century and replace it with a client side autocomplete box.  With jquery ui it was supposed to be easy and after 4 days of pain and agony I got it to work.  The basic functionality is this.  The user selects a country and then types in his institution in the autocomplete box and the code finds her institution.   The autocomplete uses a webapi that I built just for this box.  This was done with MVC webapi and was very easy. 
Getting the javascript to work was not.
Here are the main problems I had:
1)  The autocomplete list does not show up while in debug mode of the javascript.  You can debug to see what happens, but the drop down list will not show up until all the breakpoints are removed. 
2)  When I finally got it working using the  localhost api via visual studio, it stopped working when I deployed the webapi to the server, in spite of it the webapi working on the server and serving the correct json to the script (which I was able to detect in fiddler).  The problem was that the url I used was the full website and for some reason it generated an error.  (http://www.bard-isus.com/BS/api/inst).  Though the server was contacted and it returned proper json, the error message was hit.  Only when I changed it to /BS/api/Inst, did the error message go away.



here is the code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script type="text/javascript" >
var mymessage = "Try again with any part of your institution name.";
$(document).ready(function () {
$("#Institution").autocomplete({
source: function (req, res) {
$.ajax({
 
url: '/BS/api/Inst/' + req.term + "?cty=" + $("#Country")[0].value,

type: "GET",

dataType: "json",

success: function (data) {

res($.map(data, function (item) {

return {
label: item.InstLongName,
Instcode: item.instcode,
value: item.InstShortName
};
}));
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(mymessage);
}
});
},
minLength: 4,
delay: 500,
 
 
select: function (event, ui) {
$("#cbIsInst").val(ui.item.Instcode);

}
});
});
 
</script>

Here are the relevant controls:
<asp:label id="Label11" runat="server"  Width="72px" Height="24px">Country</asp:label>
<asp:dropdownlist id="Country" runat="server" Width="160px" AutoPostBack="True">

<asp:ListItem Value="NoChoice">Please Choose</asp:ListItem>
<asp:ListItem Value="Israel">Israel</asp:ListItem>
<asp:ListItem Value="USA">USA</asp:ListItem>
</asp:dropdownlist>
<div class="ui-widget">
<asp:TextBox id="Institution"
tabIndex="8" runat="server" Width="216px" Visible="True"/>
<asp:TextBox ID="cbIsInst" runat="server" CssClass="instclass" visible="false"></asp:TextBox>
</div>