How to Configure Windows Server 2012 R2 as a VPN Server with SSTP
Secure Socket Tunneling Protocol (SSTP) is a VPN protocol that encapsulates PPP traffic inside HTTPS, using port 443 for all VPN data. This makes SSTP the most firewall-friendly VPN protocol available — it works through virtually any firewall, NAT device, or web proxy that allows HTTPS traffic, unlike IKEv2 or L2TP which require specific UDP ports and special firewall rules. Windows Server 2012 R2 includes SSTP server support through the Routing and Remote Access Service (RRAS) role, making it straightforward to deploy without additional software. This guide covers deploying a fully functional SSTP VPN server with AD authentication and PKI certificates.
Prerequisites
– Windows Server 2012 R2 with a static public IP or a NAT/reverse proxy mapping port 443
– An SSL certificate for the VPN server’s public FQDN (e.g., vpn.corp.com) from a public CA or internal CA trusted by clients
– Active Directory domain for user authentication
– Network Policy Server (NPS) for centralized RADIUS-based access control
– DNS record for the VPN server FQDN
– One static external IP address for the VPN server (or port-forwarded NAT)
– Windows 7/8.1/10 clients (all support SSTP natively)
Step 1: Install the RRAS Role
# Install Remote Access role with RRAS and NPS
Install-WindowsFeature -Name RemoteAccess, RSAT-RemoteAccess, NPAS `
-IncludeManagementTools
# Install the DirectAccess and VPN role service
Install-WindowsFeature -Name DirectAccess-VPN
# Import required modules
Import-Module RemoteAccess
Import-Module NetworkPolicyServer
# Verify installation
Get-WindowsFeature RemoteAccess, DirectAccess-VPN, NPAS |
Select-Object DisplayName, Installed | Format-Table -AutoSize
Step 2: Install the SSL Certificate
# Import the SSL certificate for vpn.corp.com
# For SSTP, clients validate this certificate — it must be trusted
# Use a public CA certificate if clients are not joined to your domain
# Use an internal CA cert if all clients have your root CA in their trust store
$certPwd = ConvertTo-SecureString "CertP@ss!" -AsPlainText -Force
$cert = Import-PfxCertificate `
-FilePath "C:Certsvpn_corp_com.pfx" `
-CertStoreLocation "Cert:LocalMachineMy" `
-Password $certPwd
Write-Host "VPN certificate imported"
Write-Host "Subject: $($cert.Subject)"
Write-Host "Thumbprint: $($cert.Thumbprint)"
Write-Host "Expires: $($cert.NotAfter)"
# SSTP requires the certificate to be in the machine's Personal store
# Verify
Get-ChildItem Cert:LocalMachineMy |
Where-Object { $_.Subject -like "*vpn.corp.com*" } |
Select-Object Subject, Thumbprint, NotAfter | Format-Table -AutoSize
Step 3: Configure RRAS for SSTP VPN
Import-Module RemoteAccess
$certThumbprint = (Get-ChildItem Cert:LocalMachineMy |
Where-Object { $_.Subject -like "*vpn.corp.com*" } |
Select-Object -First 1).Thumbprint
# Configure RRAS for VPN access
# Use the static IP pool method if DHCP is not available
Install-RemoteAccess `
-VpnType VPN `
-IPAddressRange @("192.168.100.2","192.168.100.254") `
-IPv6Prefix "2001:db8:1::/48"
# Alternatively configure without static IP pool (use DHCP)
# Install-RemoteAccess -VpnType VPN
# Configure SSTP specifically — bind the certificate to SSTP
Set-SstpConfiguration -ServerCertificateHash $certThumbprint
Write-Host "SSTP configured with certificate: $certThumbprint"
# Enable SSTP and disable other less-secure protocols (optional)
# By default, RRAS enables PPTP, L2TP, SSTP, and IKEv2
# For SSTP-only:
# netsh ras set type PPTP disabled
# netsh ras set type L2TP disabled
# Verify RRAS is running
Get-Service RemoteAccess | Select-Object Status, StartType
Get-RemoteAccess | Format-List *
Step 4: Configure Dial-In Permissions and Network Policy
Import-Module NetworkPolicyServer
Import-Module ActiveDirectory
# Create an AD group for VPN users
New-ADGroup -Name "VPN-Users" `
-GroupScope Global -GroupCategory Security `
-Path "OU=Groups,DC=corp,DC=local" `
-Description "Users authorized for VPN access"
# Add users to the VPN group
Add-ADGroupMember -Identity "VPN-Users" -Members "jsmith","acooper","mlevy"
# Configure the user account dial-in permission to "Control access through NPS Network Policy"
# This is the default since Windows Server 2008 and required for NPS-based policy to work
Get-ADGroup "VPN-Users" | Get-ADGroupMember | Get-ADUser -Properties msNPAllowDialin |
ForEach-Object {
# Ensure Control access through NPS policy is set
Set-ADUser $_ -Clear msNPAllowDialin # Clears explicit Allow/Deny, defers to NPS
}
# Configure NPS Network Policy for VPN
New-NpsNetworkPolicy `
-Name "VPN Users Policy" `
-ProcessingOrder 10 `
-Enabled $true
# Configure the NPS policy in nps.msc:
# Conditions:
# - Windows Groups: CORPVPN-Users
# - NAS Port Type: Virtual (VPN)
# Constraints:
# - Authentication Methods: MS-CHAPv2 (for PPTP/L2TP/SSTP with password)
# Or EAP-TLS (certificate-based, strongest)
# Settings:
# - Grant access
# - Framed-Protocol: PPP
# - Service-Type: Framed
Write-Host "Configure VPN network policy in nps.msc with the above settings"
Step 5: Configure Split Tunneling and DNS
Import-Module RemoteAccess
# Configure VPN client IP address pool
Set-VpnServerIPsecConfiguration -TunnelType SSTP `
-EncryptionType Optional # Allow negotiation, prefer encryption
# Set DNS and WINS server addresses pushed to VPN clients
# These are configured via RRAS properties
# Configure DNS suffix to push to VPN clients
netsh ras ip set access mode=clientserver
# Configure VPN server to push internal DNS settings
$rrasConfig = @"
[RRAS]
DNS_SUFFIX_LIST = corp.local
"@
# The DNS configuration is usually pushed via DHCP inform or IPCP options
# For SSTP, configure via RRAS properties in the GUI:
# Routing and Remote Access > Server Properties > IP tab
# Configure DNS server and WINS server for client connections
# Alternatively, configure via registry
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetServicesRemoteAccessParametersIP" `
-Name "InAddr_DnsSuffix" `
-Value "corp.local"
Step 6: Configure Windows Firewall for SSTP
# SSTP uses port 443 — may conflict with IIS on the same server
# If IIS is running on port 443, use a different public IP for SSTP
# Or configure SNI-based routing
# Firewall rules for SSTP VPN server
New-NetFirewallRule -DisplayName "SSTP VPN - HTTPS Inbound" `
-Direction Inbound -Protocol TCP -LocalPort 443 `
-Action Allow -Profile Any `
-Description "SSTP VPN tunnel traffic on port 443"
New-NetFirewallRule -DisplayName "SSTP VPN - RRAS" `
-Direction Inbound -Protocol TCP -LocalPort 1723 `
-Action Allow -Profile Domain `
-Description "PPTP (if enabled)"
# Allow VPN client traffic to access internal resources
New-NetFirewallRule -DisplayName "SSTP VPN Clients - Internal Access" `
-Direction Inbound -Protocol Any `
-RemoteAddress "192.168.100.0/24" `
-Action Allow -Profile Any `
-Description "VPN client IP pool to internal network"
# Enable IP forwarding (required for VPN)
Set-NetIPInterface -InterfaceAlias "Ethernet" -Forwarding Enabled
netsh interface ipv4 set interface "Ethernet" forwarding=enabled
# Configure NAT for VPN clients to access the internet through the VPN server (if needed)
# Add-VpnServerConfiguration -SplitTunnel $false # Full tunnel mode
Write-Host "Firewall rules configured for SSTP VPN"
Step 7: Configure Windows VPN Client
# Script to configure SSTP VPN on Windows 10/8.1 client
# Run on client machines (or push via GPO)
$vpnServer = "vpn.corp.com"
$vpnName = "Corp VPN (SSTP)"
# Create the VPN connection
Add-VpnConnection `
-Name $vpnName `
-ServerAddress $vpnServer `
-TunnelType SSTP `
-EncryptionLevel Required `
-AuthenticationMethod MSChapv2 `
-RememberCredential $false `
-SplitTunneling $true ` # Only route internal traffic through VPN
-DnsSuffix "corp.local" `
-PassThru
# For certificate-based auth (EAP-TLS)
# Add-VpnConnection -Name $vpnName -ServerAddress $vpnServer `
# -TunnelType SSTP -AuthenticationMethod Eap `
# -EapConfigXmlStream (Get-EapConfiguration) `
# Add routes for internal subnets (for split tunneling)
Add-VpnConnectionRoute -ConnectionName $vpnName -DestinationPrefix "10.10.0.0/8"
Add-VpnConnectionRoute -ConnectionName $vpnName -DestinationPrefix "192.168.0.0/16"
Add-VpnConnectionRoute -ConnectionName $vpnName -DestinationPrefix "172.16.0.0/12"
# Configure DNS for the VPN connection
Set-DnsClientNrptRule -Namespace "corp.local" `
-NameServers @("10.10.0.10","10.10.0.11") `
-PassThru
# Connect the VPN
rasdial "Corp VPN (SSTP)" jsmith Password123!
Step 8: Monitor VPN Connections
Import-Module RemoteAccess
# View active VPN connections
Get-RemoteAccessConnectionStatistics |
Select-Object UserName, ClientIpAddress, TransportTunnel,
ConnectionDuration, IncomingBandwidth, OutgoingBandwidth |
Format-Table -AutoSize
# Count active connections
$activeCount = (Get-RemoteAccessConnectionStatistics |
Where-Object { $_.TransportTunnel -eq "SSTP" }).Count
Write-Host "Active SSTP connections: $activeCount"
# Check RRAS accounting log
$logPath = "C:WindowsSystem32LogFiles"
Get-ChildItem $logPath -Filter "IN*.log" | Sort-Object LastWriteTime -Descending |
Select-Object -First 1 | Get-Content | Select-Object -Last 20
# Check NPS audit events (successful logins = Event 6272, failures = 6273)
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = @(6272, 6273)
StartTime = (Get-Date).AddHours(-8)
} | Where-Object { $_.Message -like "*VPN*" } |
Select-Object TimeCreated, Id, Message | Format-Table -Wrap
# Disconnect a specific user
Disconnect-VpnUser -UserName "jsmith"
Verification
Import-Module RemoteAccess
Write-Host "=== SSTP VPN Server Health Check ===" -ForegroundColor Cyan
# Service status
Get-Service RemoteAccess | Select-Object Status, StartType
# SSTP certificate
$vpnCert = Get-ChildItem Cert:LocalMachineMy |
Where-Object { $_.Subject -like "*vpn.corp.com*" }
if ($vpnCert) {
Write-Host "SSTP Certificate: $($vpnCert.Subject)" -ForegroundColor Green
$days = ($vpnCert.NotAfter - (Get-Date)).Days
Write-Host " Expires: $($vpnCert.NotAfter) ($days days)"
} else {
Write-Host "SSTP Certificate: NOT FOUND" -ForegroundColor Red
}
# RRAS configuration
Get-RemoteAccess | Select-Object VpnConfiguration, DAStatus | Format-List
# Active connections
$connections = Get-RemoteAccessConnectionStatistics
Write-Host "Active VPN connections: $($connections.Count)"
# Verify port 443 is listening
netstat -an | findstr ":443"
# Test certificate chain
certutil -verify "C:Certsvpn_corp_com.pfx"
Summary
Configuring Windows Server 2012 R2 as an SSTP VPN server provides a robust remote access solution that works through virtually any network environment due to its use of standard HTTPS port 443. By installing the RRAS role, binding a valid SSL certificate to the SSTP endpoint, configuring NPS network policies to control which AD users have VPN access, creating appropriate firewall rules, and monitoring active connections through PowerShell, you deploy a complete enterprise VPN solution without any third-party software. SSTP’s reliance on TCP/443 eliminates the common firewall and NAT traversal issues that affect PPTP and L2TP, making it the most universally compatible Windows VPN protocol for remote workers connecting from hotels, airports, and home networks.