Computer >> Hướng Dẫn Máy Tính >  >> Hệ Thống >> Máy Chủ Windows

Cách ký script PowerShell (PS1) bằng chứng chỉ ký mã

Một script hoặc file thực thi có chữ ký số cho phép người dùng đảm bảo rằng file là nguyên bản và mã của nó không bị thay đổi bởi bên thứ ba. Các phiên bản PowerShell hiện tại có công cụ tích hợp để ký mã các file script *.ps1 bằng chứng chỉ số.

Bạn có thể ký script PowerShell bằng một loại chứng chỉ đặc biệt – Code Signing (Ký mã). Chứng chỉ này có thể được lấy từ tổ chức cấp chứng chỉ thương mại (CA) bên ngoài, CA doanh nghiệp nội bộ hoặc bạn có thể sử dụng chứng chỉ tự ký.

Giả sử dịch vụ PKI (Dịch vụ chứng chỉ Active Directory) đã được triển khai trong miền của bạn. Hãy yêu cầu chứng chỉ mới bằng cách truy cập https://CA-server-name/certsrv và yêu cầu chứng chỉ mới với mẫu Code Signing (mẫu này phải được bật trước trong bảng điều khiển Certification Authority).

Người dùng cũng có thể yêu cầu chứng chỉ để ký script PowerShell từ snap-in mmc Certificates -> My Account -> Personal -> All Tasks -> Request a new certificate.

Nếu bạn yêu cầu chứng chỉ thủ công, bạn sẽ có file chứng chỉ x509 với phần mở rộng .cer. Chứng chỉ này phải được cài đặt trong kho chứng chỉ cục bộ của máy tính.

Bạn có thể sử dụng các lệnh PowerShell sau để thêm chứng chỉ vào chứng chỉ gốc tin cậy của máy tính:

$certFile = Export-Certificate -Cert $cert -FilePath C:\ps\certname.cer
Import-Certificate -CertStoreLocation Cert:\LocalMachine\AuthRoot -FilePath $certFile.FullName

Nếu bạn muốn sử dụng chứng chỉ tự ký, hãy dùng cmdlet New-SelfSignedCertificate để tạo chứng chỉ CodeSigning với tên DNS testPC1:

New-SelfSignedCertificate -DnsName testPC1 -Type CodeSigning
$cert = New-SelfSignedCertificate -Subject "Cert for Code Signing" -Type CodeSigningCert -DnsName test1 -CertStoreLocation cert:\LocalMachine\My

Sau khi chứng chỉ được tạo, hãy di chuyển nó từ container Intermediate sang Trusted Root bằng bảng điều khiển Certificate Manager (certmgr.msc).

Sau khi có chứng chỉ, bạn có thể cấu hình Chính sách thực thi script PowerShell để chỉ cho phép chạy script đã ký. Mặc định, Chính sách thực thi PowerShell trên Windows 10/Windows Server 2016 được đặt là Restricted (chặn thực thi mọi script PowerShell).

File C:\ps\script.ps1 cannot be loaded because running scripts is disabled on this system.

Để chỉ cho phép chạy script PS1 đã ký, bạn có thể thay đổi Chính sách thực thi PowerShell thành AllSigned hoặc RemoteSigned (chỉ khác nhau ở chỗ RemoteSigned yêu cầu chữ ký chỉ cho script tải từ Internet):

Set-ExecutionPolicy AllSigned –Force

Trong chế độ này, khi chạy script PowerShell không có chữ ký, sẽ xuất hiện lỗi:

File C:\script.ps1 cannot be loaded. The file script.ps1 is not digitally signed. You cannot run this script on the current system.

Bạn cũng có thể cho phép chạy script PowerShell đã ký bằng cách sử dụng tham số Group Policy Turn on Script Execution tại Computer Configuration -> Policies -> Administrative Templates -> Windows Components -> Windows PowerShell. Thay đổi giá trị tham số thành Allow only signed scripts.

Bây giờ hãy chuyển sang ký file script PowerShell. Trước hết, bạn cần lấy chứng chỉ CodeSign từ kho chứng chỉ cục bộ của người dùng hiện tại. Đầu tiên, hãy liệt kê tất cả chứng chỉ có thể dùng để ký mã:

Get-ChildItem cert:\CurrentUser\my –CodeSigningCert

Trong trường hợp của chúng ta, chúng ta sẽ lấy chứng chỉ đầu tiên từ kho chứng chỉ cá nhân của người dùng và lưu vào biến $cert:

$cert = (Get-ChildItem cert:\CurrentUser\my –CodeSigningCert)[0]

Nếu bạn đã di chuyển chứng chỉ vào kho chứng chỉ gốc tin cậy, hãy dùng lệnh sau:

$cert = (Get-ChildItem Cert:\LocalMachine\AuthRoot –CodeSigningCert)[0]

Sau đó, bạn có thể dùng chứng chỉ này để ký file PS1 với script PowerShell của bạn:

Set-AuthenticodeSignature -Certificate $cert -FilePath C:\PS\testscript.ps1

Bạn cũng có thể dùng lệnh sau (trong trường hợp này, chúng ta chọn chứng chỉ tự ký tạo trước đó theo DnsName):

Set-AuthenticodeSignature C:\PS\test_script.ps1 @(gci Cert:\LocalMachine\AuthRoot -DnsName testPC1 -codesigning)[0]

Mẹo. Cmdlet Set-AuthenticodeSignature có tham số đặc biệt TimestampServer chỉ định URL cho dịch vụ Dấu thời gian. Nếu để trống tham số này, script PS sẽ ngừng chạy sau khi chứng chỉ hết hạn. Ví dụ, bạn có thể đặt máy chủ dấu thời gian như sau: -TimestampServer "https://timestamp.verisign.com/scripts/timstamp.dll"

Nếu bạn cố dùng chứng chỉ SSL/TLS phổ biến để ký script, sẽ xuất hiện lỗi:

Set-AuthenticodeSignature: Cannot sign code. The specified certificate is not suitable for code signing.

Bạn có thể ký tất cả file script PowerShell trong thư mục cùng lúc:

Get-ChildItem c:\ps\*.ps1| Set-AuthenticodeSignature -Certificate $Cert

Bây giờ bạn có thể kiểm tra xem file script PowerShell đã được ký đúng chưa. Bạn có thể dùng cmdlet Get-AuthenticodeSignature hoặc mở thuộc tính file PS1 và chuyển đến tab Digital Signatures.

Get-AuthenticodeSignature c:\ps\test_script.ps1 | ft -AutoSize

Nếu cảnh báo UnknownError xuất hiện khi thực thi lệnh Set-AuthenticodeSignature, chứng chỉ này không được tin cậy vì nằm trong kho chứng chỉ cá nhân của người dùng.

Bạn cần di chuyển nó vào Chứng chỉ gốc tin cậy (đừng quên định kỳ kiểm tra kho chứng chỉ Windows để tìm chứng chỉ đáng ngờ và cập nhật danh sách chứng chỉ gốc tin cậy):

Move-Item -Path $cert.PSPath -Destination "Cert:\LocalMachine\Root"

Bây giờ khi kiểm tra chữ ký file PS1, trạng thái Valid sẽ được trả về.

Khi ký file script PowerShell, cmdlet Set-AuthenticodeSignature thêm khối chữ ký số vào cuối file văn bản PS1:

# SIG # Begin signature block ........... ........... # SIG # End signature block

Khối chữ ký chứa hash của script, được mã hóa bằng khóa riêng tư.

Lần đầu tiên bạn cố chạy script, một cảnh báo sẽ xuất hiện:

Do you want to run software from this untrusted publisher? File C:\PS\script.ps1 is published by CN=testPC1 and is not trusted on your system. Only run scripts from trusted publishers.

Nếu bạn chọn [A] Always run khi chạy script lần đầu, lần sau chạy script được ký bằng chứng chỉ này, cảnh báo sẽ không còn xuất hiện.

Để ngăn cảnh báo này xuất hiện, bạn cần sao chép chứng chỉ vào cơ quan chứng chỉ Trusted Publishers. Sử dụng thao tác Copy-Paste trong bảng điều khiển Certificates để sao chép chứng chỉ vào Trusted Publishers -> Certificates.

Script PowerShell đã ký sẽ chạy mà không hiển thị thông báo nhà phát hành không tin cậy.

Mẹo. Chứng chỉ gốc CA và chứng chỉ dùng để ký script phải được tin cậy (ngược lại script sẽ không chạy). Bạn có thể triển khai trung tâm chứng chỉ đến máy tính trong miền bằng GPO. Chứng chỉ cần đặt trong các mục Public Key sau của GPO: Computer Configuration -> Policies -> Windows Settings -> Security Settings -> Public Key Policies -> Trusted Root Certification Authorities và Trusted Publishers.

Nếu chứng chỉ gốc không được tin cậy, khi chạy script PowerShell sẽ xuất hiện lỗi:

A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.

Điều gì sẽ xảy ra nếu bạn thay đổi mã của file script PowerShell đã ký? Việc chạy nó sẽ bị chặn với thông báo rằng nội dung script đã bị thay đổi.

File xx.ps1 cannot be loaded. The contents of file xx.ps1 might have been changed by an unauthorized user or process, because the hash of the file does not match the hash stored in the digital signature. The script cannot run on the specified system.

Hãy thử xác minh chữ ký của script bằng cmdlet Get-AuthenticodeSignature. Nếu hash tính toán không khớp với hash trong chữ ký, thông báo HashMismatch sẽ xuất hiện.

Vì vậy, bất kỳ sửa đổi nào đối với mã của script PS1 đã ký sẽ yêu cầu ký lại nó.