I've already discussed how to establish an IPsec VPN between two hosts in a Microsoft Windows environment using a PSK. For more details, see here. Now, let's enhance security by replacing the PSK with x509 certificates. In this guide, we'll explore how to set up a secure IPsec VPN between Microsoft Windows hosts within the same LAN to significantly improve network security. With this configuration, all communications between machines will be encrypted without exception.
For the purposes of this article, we will maintain a simple architecture. We will establish a secure connection using an IPsec VPN with x509 authentication between a computer running Windows 11 and a server running Windows Server 2022. Both computers will be on the same local network.
As discussed previously, we will use X.509 certificates to establish an IPsec connection between our server and client. To do this, we need to create a PKI: a Root CA which will sign the certificates, and two certificates, one for each of our two hosts.
All the commands below will be executed from a PowerShell console with administrator rights.
PS C:\> $rootCert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName RootCA -KeyUsage CertSign,CRLSign,DigitalSignature -NotAfter (Get-Date).AddYears(10)
PS C:\> $serverCert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName ServerName -Signer $rootCert -NotAfter (Get-Date).AddYears(5)
PS C:\> $serverCert = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Subject -eq "CN=ServerName" }
PS C:\> $cert = New-SelfSignedCertificate -DnsName "W11" -CertStoreLocation "cert:\LocalMachine\My" -Signer $rootCert -KeyExportPolicy Exportable -NotAfter (Get-Date).AddYears(5)
PS C:\> $password = ConvertTo-SecureString -String "PassPass" -Force -AsPlainText
PS C:\> Export-PfxCertificate -Cert $cert -FilePath "C:\W11.pfx" -Password $password
PS C:\> $cert1Proposal = New-NetIPsecAuthProposal -Machine -Cert -Authority "CN=RootCA" -AuthorityType Root
PS C:\> $certAuthSet = New-NetIPsecPhase1AuthSet -DisplayName "Computer Certificate Auth Set" -Proposal $cert1Proposal
PS C:\> New-NetIPsecRule -DisplayName "IPsec" -Name "IPsec" -Mode Transport -InboundSecurity Require -OutboundSecurity Require -LocalAddress 192.168.1.200 -RemoteAddress 192.168.1.30 -Enable True -Phase1AuthSet $certAuthSet.Name
We will create a Firewall rule to allow encrypted flows.
PS C:\> New-NetFirewallRule -DisplayName "IPsec ALLOW" -Direction Inbound -Enabled True -Action Allow -LocalAddress 192.168.1.200 -RemoteAddress 192.168.1.0/24 -Protocol Any -Encryption Dynamic -Authentication Required
We've now finished configuring the server. Now it's time to move on to client configuration.
I'm going to describe them all, but the steps are pretty much the same as those we followed for the server.
From here, everything should work and connections are already encrypted. Here, we'll look at how to further enhance security by choosing more robust IPsec protocols thant those offered by default. All command listed below must be entered on both client and server.
PS C:\> Set-NetIPsecRule -DisplayName "IPsec" -KeyModule IKEv2 -ForwardPathLifetime 120
PS C:\> $proposal1 = (New-NetIPsecQuickModeCryptoProposal -Encapsulation ESP -Encryption AES256 -ESPHash SHA256)
PS C:\> $mMCryptoSet=(New-NetIPsecQuickModeCryptoSet -DisplayName "Quick Mode Rule" -Proposal $proposal1)
PS C:\> Set-NetIPsecRule -DisplayName IPsec -QuickModeCryptoSet $mMCryptoSet.Name
PS C:\> Get-NetIPsecRule -DisplayName IPsec
PS C:\> Remove-NetIPsecRule -DisplayName IPsec
PS C:\> Get-NetIPsecMainModeRule -DisplayName IPsecMain
PS C:\> Remove-NetIPsecMainModeRule -Name "{XXX-XXX-XXX}"
PS C:\> Get-NetIPsecMainModeSA
PS C:\> Get-NetIPsecQuickModeSA
Contact :