Windows Server 2022 Core迁移记录
分类: Windows Server ◆ 标签: #Windows #Windows Server Core ◆ 发布于: 2023-08-05 0:42:10

最早的时候我将自己的博客部署在Ubuntu 20.04
上,采用的架构是nginx + .Net 6 Kerstrel
, 为了优化性能,减少从nginx
到loopback
之间的交互,配置nginx
和Kerstrel
之间的通讯走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
的命令行工具以及PowerShell
。Remote 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
主要的技术要点:
- 使用
Powershell
更改防火墙规则。 - 更改注册表:修改`Remote Desktop Service(Terminal Service)的监听端口。
- 使用
Powershell
安装IIS
必要的组件。 - 使用
mstsc.exe
挂在本地硬盘到远程的Server Core
上共享文件。 - 使用
Powershell
修改文件目录的权限。 - 使用
Powershell
或者Inetmgr.exe
管理IIS
. - 使用
sc.exe
安装和修改服务。 - 使用
Powershell
启动/停止服务 - 使用
Powershell
查询事件日志。 - 使用
WebDeploy
远程部署。 - 使用
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
就可以启动图形化的注册表编辑器了。
启动注册表编辑器之后,查找如下的两个键值,更改PortNumber
到9000
, 重启服务器之后就生效了
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
远程桌面客户端(远程桌面连接
)将本地的资源临时挂载到远程服务器上。
步骤如下:
在客户端机器上启动
远程桌面连接
(mstsc.exe
)如下图所示:
登录到
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
的机器专门用户部署和打包,这样性能会好很多。