{"id":7420,"date":"2017-06-02T16:25:34","date_gmt":"2017-06-02T14:25:34","guid":{"rendered":"https:\/\/blog.redbaronofazure.com\/?p=7420"},"modified":"2017-06-03T11:54:14","modified_gmt":"2017-06-03T09:54:14","slug":"keeping-your-nsg-updated","status":"publish","type":"post","link":"https:\/\/blog.redbaronofazure.com\/?p=7420","title":{"rendered":"Keeping your NSG updated"},"content":{"rendered":"<p>If you are\u00a0working from different places over time, keeping the Network Security Group (NSG) updated will be a task that you quickly want to automate. I have an inbound rule on my NSGs that I always call &#8220;allow-all-from-temp-ip&#8221; that controls access to my resources which\u00a0I constantly change when I&#8217;m out travelling.<\/p>\n<p>In this post, I will show you how to write a small powershell script to update the NSG rule. In the github sources you will also find a bash script that does the same on Mac\/Linux.<\/p>\n<h2>Network Security Groups<\/h2>\n<p>If you don&#8217;t know what an NSG is in Azure, you can think of it as a list of Allow\/Deny rules of what network traffic can flow inbound and outbound.\u00a0You can think of it as a firewall protecting the resources you can put in an Azure Virtual Network.<\/p>\n<p>An NSG can be applied to a subnet in an Azure Virtual Network or directly onto a VMs NIC (network interface card). If you have them on both, the network traffic must be allowed by both NSGs.<\/p>\n<p>A normal configuration of mine when working with an Azure VM is like below. I have two Inbound security rules, where the first is called &#8220;allow-all-from-home&#8221; and the second &#8220;allow-all-from-temp-ip&#8221;. Both rules allow all inbound traffic from one single ip address, which means I don&#8217;t have to think about ports being blocked when I test stuff.<a href=\"https:\/\/blog.redbaronofazure.com\/wp-content\/uploads\/2017\/06\/nsg-script-01.png\"><img loading=\"lazy\" class=\"alignnone size-full wp-image-7421\" src=\"https:\/\/blog.redbaronofazure.com\/wp-content\/uploads\/2017\/06\/nsg-script-01.png\" alt=\"\" width=\"1124\" height=\"564\" srcset=\"https:\/\/blog.redbaronofazure.com\/wp-content\/uploads\/2017\/06\/nsg-script-01.png 1124w, https:\/\/blog.redbaronofazure.com\/wp-content\/uploads\/2017\/06\/nsg-script-01-300x151.png 300w, https:\/\/blog.redbaronofazure.com\/wp-content\/uploads\/2017\/06\/nsg-script-01-768x385.png 768w, https:\/\/blog.redbaronofazure.com\/wp-content\/uploads\/2017\/06\/nsg-script-01-1024x514.png 1024w\" sizes=\"(max-width: 1124px) 100vw, 1124px\" \/><\/a><\/p>\n<h2>Public ip address<\/h2>\n<p>Whenever I come to a new location, I modify the &#8220;allow-all-from-temp-ip&#8221; rule to reflect the current public ip address I&#8217;m using. Going to webpage <a href=\"http:\/\/ipinfo.io\">http:\/\/ipinfo.io<\/a>\u00a0you can find your ip address. If you want to manually update your NSG rules, grab the ip address from ipinfo and use the Azure portal to update your inbound rule(s).<\/p>\n<p>But if you want to automate, ipinfo.io supports REST API calls which means\u00a0you can call the API and get the result back as a JSON structure. In powershell, this might look like this:<\/p>\n<pre class=\"theme:powershell-ise lang:ps decode:true \">$acct = Get-AzureRmContext\r\n$user = $acct.Account.Id\r\n\r\n$resp = Invoke-RestMethod \"http:\/\/ipinfo.io\"\r\nWrite-Host \"Current ip addr $($resp.ip) via provider $($resp.org)\"\r\n\r\n$sourceAddrPrefix = \"$($resp.ip)\/32\"\r\n$description = \"allow all inbound from temp ip $($resp.ip), provider $($resp.org). Set by $user at $(Get-Date -format 's')\"<\/pre>\n<p>The NSG rules work with something known as CIDR notation when it comes to specifying ip addresses. The \/32 means 32 bits of the ip address\u00a0are the mask bits and for an IPv4 address this means all the bits so\u00a0using \/32 basically means 1 ip address.\u00a0You can play with CIDR online calculaters, like\u00a0<a href=\"http:\/\/www.subnet-calculator.com\/cidr.php\">http:\/\/www.subnet-calculator.com\/cidr.php<\/a>, where you can see that 10.4.3.0\/24 gives you 10.4.3.0 &#8211; 10.4.3.255 since 24 mask bits means 255.255.255.0, etc.<\/p>\n<p>The call to Get-AzureRmAccount is there just so I can add it to the description which user I was running as when I made the change.<\/p>\n<h2>Updating the NSG<\/h2>\n<p>Updating the NSG is quite simple. It is just a matter of retrieving the NSG, finding the specific NSG inbound rule and updating it. If the rule isn&#8217;t already defined we need to add it with the next available priority.<\/p>\n<pre class=\"theme:powershell-ise lang:ps decode:true \">$rule = ($nsg | Get-AzureRmNetworkSecurityRuleConfig -Name $SecurityRuleName -ErrorAction SilentlyContinue)\r\nif ($rule -eq $null) {\r\n $prio = [int]($nsg.SecurityRules[$nsg.SecurityRules.Count-1].Priority)\r\n $prio += 10\r\n Write-Host \"Adding $SecurityRuleName rule to allow $sourceAddrPrefix with priority $prio\"\r\n $ret = ($nsg | Add-AzureRmNetworkSecurityRuleConfig -Name $SecurityRuleName `\r\n                -SourceAddressPrefix $sourceAddrPrefix  -SourcePortRange \"*\" `\r\n                -DestinationAddressPrefix \"*\" -DestinationPortRange \"*\" `\r\n                -Protocol \"*\" -Direction \"Inbound\" -Access \"Allow\" `\r\n                -Priority $prio -Description $description)\r\n} else {\r\n Write-Host \"Updating $SecurityRuleName rule to allow $sourceAddrPrefix\"\r\n $ret = ($nsg | Set-AzureRmNetworkSecurityRuleConfig -Name $SecurityRuleName `\r\n                -SourceAddressPrefix $sourceAddrPrefix  -SourcePortRange \"*\" `\r\n                -DestinationAddressPrefix \"*\" -DestinationPortRange \"*\" `\r\n                -Protocol \"*\" -Direction \"Inbound\" -Access \"Allow\" `\r\n                -Priority $rule.Priority -Description $description)\r\n}\r\nWrite-Host \"Saving to Azure...\"\r\n$ret = ($nsg | Set-AzureRmNetworkSecurityGroup)\r\n<\/pre>\n<h2>Running the script<\/h2>\n<p>So whenever I enter a new location, I just run the script to update the NSG rule of whatever work I was doing. It is especially usefull if I know I&#8217;m going to be showing something on a projector to a group of people, because troubleshooting network ports being blocked is a sure thing to loose time and interrest of the people around you.<\/p>\n<p><a href=\"https:\/\/blog.redbaronofazure.com\/wp-content\/uploads\/2017\/06\/nsg-script-02.png\"><img loading=\"lazy\" class=\"alignnone size-full wp-image-7422\" src=\"https:\/\/blog.redbaronofazure.com\/wp-content\/uploads\/2017\/06\/nsg-script-02.png\" alt=\"\" width=\"1461\" height=\"196\" srcset=\"https:\/\/blog.redbaronofazure.com\/wp-content\/uploads\/2017\/06\/nsg-script-02.png 1461w, https:\/\/blog.redbaronofazure.com\/wp-content\/uploads\/2017\/06\/nsg-script-02-300x40.png 300w, https:\/\/blog.redbaronofazure.com\/wp-content\/uploads\/2017\/06\/nsg-script-02-768x103.png 768w, https:\/\/blog.redbaronofazure.com\/wp-content\/uploads\/2017\/06\/nsg-script-02-1024x137.png 1024w\" sizes=\"(max-width: 1461px) 100vw, 1461px\" \/><\/a><\/p>\n<h2>A word of warning<\/h2>\n<p>My script opens ALL ports for TCP\/UDP from a single ip address, which is basically disabling the firewall for it. I do it just during dev\/test so I can work productively. In a real world case, where you do hybrid cloud networking, you should of course specify a list of known ports and source addresses instead of making it wide open.<\/p>\n<h2>Sources<\/h2>\n<p>The powershell script can be found on github<br \/>\n<a href=\"https:\/\/github.com\/cljung\/azps\/blob\/master\/change-nsg-ipaddr.ps1\">https:\/\/github.com\/cljung\/azps\/blob\/master\/change-nsg-ipaddr.ps1<\/a><\/p>\n<p>Bash script that does the same<br \/>\n<a href=\"https:\/\/github.com\/cljung\/azps\/blob\/master\/change-nsg-ipaddr.sh\">https:\/\/github.com\/cljung\/azps\/blob\/master\/change-nsg-ipaddr.sh<\/a><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you are\u00a0working from different places over time, keeping the Network Security Group (NSG) updated will be a task that you quickly want to automate. I have an inbound rule on my NSGs that I always call &#8220;allow-all-from-temp-ip&#8221; that controls access to my resources which\u00a0I constantly change when I&#8217;m out travelling. In this post, I [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[131,141,410],"tags":[423,422],"_links":{"self":[{"href":"https:\/\/blog.redbaronofazure.com\/index.php?rest_route=\/wp\/v2\/posts\/7420"}],"collection":[{"href":"https:\/\/blog.redbaronofazure.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.redbaronofazure.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.redbaronofazure.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.redbaronofazure.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7420"}],"version-history":[{"count":8,"href":"https:\/\/blog.redbaronofazure.com\/index.php?rest_route=\/wp\/v2\/posts\/7420\/revisions"}],"predecessor-version":[{"id":7430,"href":"https:\/\/blog.redbaronofazure.com\/index.php?rest_route=\/wp\/v2\/posts\/7420\/revisions\/7430"}],"wp:attachment":[{"href":"https:\/\/blog.redbaronofazure.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7420"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.redbaronofazure.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7420"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.redbaronofazure.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7420"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}