Skip to main content

Windows Server 2022 Core迁移记录

分类:  Windows Server 标签:  #Windows #Windows Server Core 发布于: 2023-08-05 0:42:10

最早的时候我将自己的博客部署在Ubuntu 20.04上,采用的架构是nginx + .Net 6 Kerstrel, 为了优化性能,减少从nginxloopback之间的交互,配置nginxKerstrel之间的通讯走UnixSocket, 并将UnixSocket文件存入到/dev/shm中,这套配置经历一段时间, 使用benchmarkdotnet做了一些基准的测试并留下了数据。这之后,决定使用windows server 2019 datacenter作为操作系统,并配置IIS + Asp.net core Module V2直接走了in-process模式,迁移之后发现博客网站在使用同样的测试方案下,windows + IIS的模式居然比之前基于ubuntu + nginx的模式要快上不少,性能好很多。同样的硬件配置,居然有这样的结果,也是自己之前没想到的,完全打破了以前的经验:Linux的方案要比Windows的方案性能好太多,Linux性能比windows好完全就是一个伪命题。

将整个博客网站迁移到基于Windows的方案上之后,一直运行特别稳定,这几天突然想将网站迁移到最新版的Windows Server 2022 Core上,说干就干,这篇文章主要是记录一些在迁移到Windows Server Core上的小技巧,以免自己忘了。

开始之前要了解的是:什么是Windows Server Core,它之前发现的版本有什么不一样。Windows server core不是一个新鲜的东西,早在windows server 2016发布的时候,就已经发布了基于core的版本。Core和完整的发行版主要的区别就是Core拿掉了GUI的部分,但是保留了完整的服务功能,要管理和操作Core,需要使用很多的命令行工具,之前熟悉的几乎全部的在Windows Server上的基于GUI的工具全部没有,这就要求用户必须要熟悉基于Windows的命令行工具以及PowerShellRemote Desktop Service(Terminal Service)还是保留的(通过3389端口连接),另外其他的远程管理工具和接口都是完全具备的,例如WinRM等等。

详细的介绍,请参考微软官方文档:https://learn.microsoft.com/en-us/windows-server/administration/server-core/what-is-server-core

Tips
Windows Server最大的好处就是它的角色和特性,新安装的Windows Server是一个非常干净的系统,具有极少的攻击面,特别是Core的版本,用户只需要根据自己的需求向windows Server上添加必要的服务就可以了。

使用Servier Core主要的技术要点:

  1. 使用Powershell更改防火墙规则。
  2. 更改注册表:修改`Remote Desktop Service(Terminal Service)的监听端口。
  3. 使用Powershell安装IIS必要的组件。
  4. 使用mstsc.exe挂在本地硬盘到远程的Server Core上共享文件。
  5. 使用Powershell修改文件目录的权限。
  6. 使用Powershell或者Inetmgr.exe管理IIS.
  7. 使用sc.exe安装和修改服务。
  8. 使用Powershell启动/停止服务
  9. 使用Powershell查询事件日志。
  10. 使用WebDeploy远程部署。
  11. 使用Azure Pipeline进行部署。

使用Powershell更改防火墙的规则

由于目前Remote Desktop Service(Terminal Service)是监听在常用的端口3389, 为了进一步提高安全度,我们需要将这个端口更改到其他的端口,并且可以限制IP地址访问。
可以使用如下的语句来创建一个防火墙的新规则:

New-NetFirewallRule -DisplayName "Allow Access Local Port 9000" -Direction Inbound -RemoteAddress {Remote IP Address}  -Protocol TCP  -LocalPort 9000 -Action Allow

这个Powershell的命令就是用于给防火墙新增一个规则,让远程固定的IP地址通过访问本地的9000端口,这个端口用于之后的remote desktop service监听。

同时由于我们需要远程管理IIS, 因此预分配9001端口给IIS远程管理,使用如下的命令新增一个防火墙端口:

New-NetFirewallRule -DisplayName "Allow Access Local Port 9001" -Direction Inbound -RemoteAddress {Remote IP Address}  -Protocol TCP  -LocalPort 9001 -Action Allow

同时我们需要关闭本机3389的端口规则,先使用如下的语句找到这些规则:

Get-NetFirewallPortFilter | where {$_.LocalPort -eq '3389' } | Get-NetFirewallRule

这样就可以得到这些规则的名字了, 例如:

PS C:\Users\hongw> Get-NetFirewallPortFilter | where {$_.LocalPort -eq '3389' } | Get-NetFirewallRule

Name                          : RemoteDesktop-UserMode-In-TCP
DisplayName                   : 远程桌面 - 用户模式(TCP-In)
Description                   : 用于远程桌面服务的入站规则,以允许 RDP 通信。[TCP 3389]
DisplayGroup                  : 远程桌面
Group                         : @FirewallAPI.dll,-28752
Enabled                       : True
Profile                       : Any
Platform                      : {}
Direction                     : Inbound
Action                        : Allow
EdgeTraversalPolicy           : Block
LooseSourceMapping            : False
LocalOnlyMapping              : False
Owner                         :
PrimaryStatus                 : OK
Status                        : 已从存储区成功分析规则。 (65536)
EnforcementStatus             : NotApplicable
PolicyStoreSource             : PersistentStore
PolicyStoreSourceType         : Local
RemoteDynamicKeywordAddresses :

然后可以使用如下的语句禁止防火墙:

Set-NetFirewallRule -Name RemoteDesktop-UserMode-In-TCP -Enabled False

这样就关闭了防火墙的这条规则。

如果需要查看更多的防火墙的使用方法,请直接查看get-help

更改注册表,将remote desktop service的监听端口更改到9000

需要注意的是: Server Core仍然带有注册表编辑器,而且是图像化的,只需要在命令行下运行:regedit.exe就可以启动图形化的注册表编辑器了。

启动注册表编辑器之后,查找如下的两个键值,更改PortNumber9000, 重启服务器之后就生效了

Tips
请一定要先更改防火墙,并测试防火墙的相应端口是可以从外部测试通过的,否则如果忘记了更改防火墙,并且先更改了remote desktop service的端口的话,那么这台机器恐怕就丢失了控制权限了,除非呼叫技术支持没有别的好办法了。

  • 键值一: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server \Wds\rdpwd\Tds\Tcp下PortNumber
  • 键值二:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TerminalServer \WinStations\RDP-Tcp下PortNumber

更改好这两个端口之后,重启服务器。

Tips
重启Server Core服务会发现,服务器重启的速度特别快,基本上是这边远程连接关闭,等1,2秒,就可以直接连上了。

使用Powershell安装IIS角色

在管理Windows server的时候,我们有Server Manager可以使用,这个用起来很方便,但是在Server Core上就没有这个工具了,可以使用如下的PowerShell来安装必要的组件:

get-windowsfeature

这个命令会列出可以用于Server安装的所有的角色和组件。

然后使用如下的命令安装就可以了:

install-windowsfeature 组件名1,组件名2......组件名N

这样就可以安装所有的组件。

我们本例中是安装IIS组件,并运行Asp.net core, 因此只选择了如下的组件,同时为了支持http2, 没有选择基于windows的认证。

install-windowsfeature Web-Common-Http,Web-Default-Doc,Web-Http-Errors,Web-Static-Content,Web-Http-Redirect,Web-Http-Logging,Web-Custom-Logging, Web-Log-Libraries, Web-Request-Monitor, Web-Http-Tracing, Web-Stat-Compression,Web-Dyn-Compression,Web-Filtering,Web-Basic-Auth,Web-CertProvider,Web-Digest-Auth,Web-IP-Security,Web-Url-Auth,Web-WebSockets,Web-Mgmt-Console,  Web-Scripting-Tools, Web-Mgmt-Service  

使用mstsc.exe挂在本地硬盘到远程的Server Core

Server Core由于没有GUI的操作界面,因此我们不能使用方便的Copy/Paste了。也就是不能共享剪贴板了。但是我们可以利用mstsc.exe远程桌面客户端(远程桌面连接)将本地的资源临时挂载到远程服务器上。

步骤如下:

  1. 在客户端机器上启动远程桌面连接(mstsc.exe)

  2. 如下图所示:




  3. 登录到Server core之后,通过如下的路径访问挂载的硬盘:\\tsclient\d, 如下图:


小技巧
如果在Server Core上关闭了控制台窗口(cmd或者powershell), 可以快速地使用快捷键Ctrl + shift + ESC 打开任务管理器,然后在任务管理器的菜单File(文件)新运行一个命令,例如cmd或者powershell或者pwsh,这样就可以启动新的命令行窗口了,免得一片黑,不知道该如何操作了。

使用PowerShell给文件目录赋予权限

安装好了系统,需要给即将发布的应用创建目录,并赋予目录权限,由于我们的应用是在IIS上运行的应用,那么我们需要给用户组IIS_IUSR赋予访问某些目录的权限,例如用户文件上传的目录需要赋予读写权限(我们的实例中为了偷懒,直接给需要写入的权限赋予了full control), 至于应用目录仅仅赋予读权限就可以了。

$ACL = Get-Acl -Path .\test\  //取得一个目录的已有的权限。
$ACL.Access | Format-Table    //显示已经有的权限。

$accessRule =  New-Object System.Security.Accesscontrol.FileSystemAccessRule("BUILTIN\IIS_IUSRS", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")
$ACL.AddAccessRule($accessRule)
$ACL | Set-Acl -Path .\test\

这样就给目录test设置了完全的权限了。

管理IIS和开启IIS远程管理

幸运的是:安装完IIS之后,IIS管理器还是可以用的,不过它的路径在:C:\Windows\System32\interv\下。切换命令行到该目录下,运行inetmgr.exe就可以启动IIS管理器了,直接用这个GUI工具来管理就可以了,可以省很多事情,如果想远程管理,只需要启动IIS远程管理服务,并把端口设置在90001这个我们之前已经设置好的端口就好了。

使用sc.exe安装和修改服务

使用如下的命令来安装服务:

sc.exe create "Azure Developer Search Indexes Update" binpath="C:\Users\AzureDeveloperCN\Services\AzureDeveloper.Search.Indexes.exe" DisplayName="Azure Developer Search Indexes Update"
sc description "Azure Developer Search Indexes Update" "Azure Developer 网站索引更新服务"

这样就可以将自行开发的Windows服务添加到系统了。

使用Powershell启动/停止服务

这个就简单了:

start-service -Name 'Service Name'
stop-service -Name 'service Name`

或者用sc.exe也是可以的。

使用Powershell查询事件日志

使用命令:

Get-EventLog -List
Get-EventLog -LogName Application -Newest 20

先列出有哪些日志,然后查看Application日志前20条。

使用WebDeploy远程部署

这没啥好讲的,先去https://www.iis.net上下载web deploy安装上。
然后发布的时候用命令行或者visual studio直接发布就可以了,记得web deploy的端口和IIS远程管理的端口是一样的。

使用Azure Pipeline进行部署

这个主题就内容太多了,之后在学习Azure Pipeline的时候再给大家分享,如下是我通过Azure Pipeline的结果图:


使用Azure提供的代理部署比较慢,可以自定义一个self-host的机器专门用户部署和打包,这样性能会好很多。