How to create an IP restrictions whitelist for your IIS FTP Server with Powershell.

When you set up a new public facing FTP server in IIS, it is important to properly secure it. Of course there’s authentication and authorization, but in this post I’ll show you how to configure an IP whitelist for FTP using PowerShell.

FTP IP Security <ipSecurity>

IIS FTP IP Address and Domain Restrictions
IIS FTP IP Address and Domain Restrictions

The <ipSecurity> element defines a list of IP-based security restrictions in IIS FTP. These restrictions can be based on the IP version 4 address, a range of IP version 4 addresses, or a DNS domain name.

The <add> element of the <ipSecurity> collection defines a unique IP security restriction. Each restriction can be based on the IP version 4 address, a range of IP version 4 addresses, or a DNS domain name.

Using PowerShell‘s webadministration module, you can use Set-WebConfigurationProperty to configure these settings. By the way, the iisadministration module is the better alternative. More on that later.

Configure access for unspecified clients

Use FTP IP Address and Domain Restrictions

The purpose of an IP whitelist, is to block everything and only allow a small number of IP’s (clients). Those are whitelisted. You must be able to deny all clients who are not whitelisted in IIS FTP. Luckily, you can use FTP IP Address and Domain Restrictions for just that.

Read this too:   MySQL sleep() attacks

In IIS Manager, set Access for unspecified clients to Allow on your IIS root, and Deny on your FTP Site.

Deny access for unspecified clients
Deny access for unspecified clients

Setting the allowUnlisted attribute to false locks down the server, preventing access to all IP address unless they are listed. If you do not allow access for unspecified clients on your IIS root, then no one may access your FTP server. Unless you add your whitelist in the root node which makes it compulsory configuration for all virtual FTP sites on your server. This may be exactly what you are looking for depending on your needs.

In PowerShell, use Set-WebConfigurationProperty to set allowUnlisted to True and False in different locations:

# Set allowUnlisted to $true (allowed) for IIS FTP root node,
# then deny access for unspecified clients (set to $false) on 
# your virtual FTP Site in IIS.
Set-WebConfigurationProperty -Filter /system.ftpserver/security/ipsecurity -Name allowUnlisted -Value "True" -PSPath 'IIS:'

Set-WebConfigurationProperty -Filter /system.ftpserver/security/ipsecurity -Name allowUnlisted -Value "False" -PSPath 'IIS:' -Location "ftp.example.com"

Doing so ensures all clients may connect to your IIS FTP server, but only allowed IP addresses to your virtual site ftp.example.com. If you set Access for unspecified clients to Deny/False on IIS’ root, only IP addresses that are added as allowed may connect.

Now it’s time to add those IP addresses.

Read this too:   List all SPNs used in your Active Directory

Allow access for the following IP address or domain name

You can easily create an array of IP addresses and loop through it in PowerShell. In the following example, I’m using for documentation reserved IP addresses. FTP IP Address and Domain Restrictions accepts a specific IP address, or a range of IP addresses including a mask.

# single IP addresses from 203.0.113.0/24
$whitelisted_ips = @("203.0.113.5",
	"203.0.113.6",
	"203.0.113.10",
	"203.0.113.36",
	"203.0.113.37",
	"203.0.113.38",
	"203.0.113.66",
	"203.0.113.76",
	"203.0.113.89",
	"203.0.113.90",
	"203.0.113.91")

foreach($ip in $whitelisted_ips) {
	Add-WebConfiguration -Filter /system.ftpserver/security/ipsecurity -PSPath 'IIS:' -Location "ftp.example.com" -Value @{ipAddress="$ip";subnetMask="255.255.255.255";allowed=$true}
}

# entire range 198.51.100.0/24 subnetMask="255.255.255.0":
$whitelisted_ips2 = @(
	"198.51.100.0")

foreach($ip2 in $whitelisted_ips2) {
	Add-WebConfiguration -Filter /system.ftpserver/security/ipsecurity -PSPath 'IIS:' -Location "ftp.example.com" -Value @{ipAddress="$ip2";subnetMask="255.255.255.0";allowed=$true}
}

In the example above, you’ve whitelisted a number of single IP addresses from 203.0.113.0/24 and the complete 198.51.100.0/24 block.

Allowed IP addresses (whitelisted) in IIS FTP
Allowed IP addresses (whitelisted) in IIS FTP

Only these IP’s may connect to your server, it is as easy as that.

IIsadministration equivalent

Yes, I said using the iisadministration module is the better alternative for webadministration. Especially since we’re using IIS 10.0 on Windows Server 2019 (Core edition, right?! 😛 ). So in a nutshell, here are the iisadministration equivalents for Get-WebConfiguration and Add-WebConfiguration:

# Set allowUnlisted to True on your root node
Get-IISConfigSection -SectionPath "system.ftpServer/security/ipSecurity" | Set-IISConfigAttributeValue -AttributeName "allowUnlisted" -AttributeValue True

# Set allowUnlisted to False on your virtual FTP site
Get-IISConfigSection -SectionPath "system.ftpServer/security/ipSecurity" -Location "ftp.example.com" | Set-IISConfigAttributeValue -AttributeName "allowUnlisted" -AttributeValue False

Next you need to loop through your IP address array to add the IP’s to your whitelist. For this, you can create an object ‘$MyFtpSite’. Use Start-IISCommitDelay and Stop-IISCommitDelay to delay the commitment of changes. Failing to do so may result in an error message

New-IISConfigCollectionElement : The configuration object is read only, because it has been committed by a call to
ServerManager.CommitChanges(). If write access is required, use ServerManager to get a new reference.

Start-IISCommitDelay
$MyFtpSite = Get-IISConfigSection "system.ftpServer/security/ipSecurity" -Location "ftp.example.com" |  Get-IISConfigCollection

$whitelisted_ips = @("203.0.113.5",
	"203.0.113.6",
	"203.0.113.10",
	"203.0.113.36",
	"203.0.113.37",
	"203.0.113.38",
	"203.0.113.66",
	"203.0.113.76",
	"203.0.113.89",
	"203.0.113.90",
	"203.0.113.91")

foreach($ip in $whitelisted_ips) {
	New-IISConfigCollectionElement -ConfigCollection $MyFtpSite -ConfigAttribute @{ipAddress="$ip";subnetMask="255.255.255.255";allowed=$true}
}
Stop-IISCommitDelay

HTH!

Read this too:   Target multiple ASP.NET versions with AppCmd.exe