背景
Microsoft (MS) が嫌いなユーザーではあるものの,業務上の理由でPowerShellを使わなければならくなった.手元にWindowsがないので,常設のWindows 11 Proにsshdを入れてリモートからwindows 11にアクセスしPowerShellを使えるようにした個人的な覚書.sshの操作などbashなどのterminal操作は慣れているものとする.
>
, $
はPowerSell,bashそれぞれのコマンドの接頭を表し入力する必要はない.
windows にssh serverをインストールする
PowerShellのversionが5系の場合は7系に先にupdateしておいた方が良いかもしれません.
Updateの方法は追記に記述しています.
以下は
> $PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
5 1 22621 3958
での作業内容.
windows 11 GUI環境での作業
対象が異なるが公式の Windows server 2022を参照して(windows server 2025はデフォルトでsshdがインストールされているので参考ならない),前提条件の確認 と OpenSSH for Windows Server (PowerShell版)を実行する.記憶が曖昧だが前提条件はWinsows 11 Pro だったら問題なかったはず.
ほぼ,コピペになるが
-
PowerShell を管理者として実行します。
-
OpenSSH が使用可能になっていることを確認するには、次のコマンドレットを実行します。
PowerShell> Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
SSH client と server いずれもインストールされていなければ
PowerShellName : OpenSSH.Client~~~~0.0.1.0 State : NotPresent Name : OpenSSH.Server~~~~0.0.1.0 State : NotPresent
となる.(version 0.0.1.0ってまともにversion管理するつもりないなと嫌な気分になる)
-
今回はSSHクライアントは不要なのでopenssh Serverのみインストールする(5分くらいかかったので気長に待つ).
PowerShell# Install the OpenSSH Server > Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
-
Serviceの起動
PowerShell# Start the sshd service > Start-Service sshd
-
Service自動起動(永続化)
PowerShell> Set-Service -Name sshd -StartupType 'Automatic'
-
Firewallのport 22番の穴あけ
PowerShell# Confirm the Firewall rule is configured. It should be created automatically by setup. Run the following to verify if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue | Select-Object Name, Enabled)) { Write-Output "Firewall Rule 'OpenSSH-Server-In-TCP' does not exist, creating it..." New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 } else { Write-Output "Firewall rule 'OpenSSH-Server-In-TCP' has been created and exists." }
おそらく
TCP -Action Allow -LocalPort 22
の部分を22以外にすれば任意のポートで穴あけできると思われる(未調査)
ssh client -> ssh server
-
ssh server (Windows 11)にssh clientが入っている端末から接続してみる
適当なSSH clientから
bash$ ssh username@ip # or ssh username@hostname.local.
で接続すればいい.fingerprintを確認して接続するとパスワード認証を要求されるので入力する.私の場合はMS Accountだったので,MSアカウントのパスワードを入力する.
後者のホスト名+.local.方法でも同じサブネットにある端末なので接続できたが,パブリックネットーワークの設定であるにも関わらず見えるのは不思議なような気がする.avahi-daemon的なものはネットワークの探索と無関係なんだろうか.ちなみに,ssh server側(Windows)のhostnameやipはPowerShellから
PowerShell> whoami hostname\username > ipconfig # != ifconfig ...(省略)...
などで調べれば良い.
ssh serverの設定ファイル (sshd_conf)
-
ssh_confのPATH
sshd_config 内の Windows 構成 を参照すると,Windows 11 にSSH Serverをinstallすると
Windows では、sshd は既定で、%programdata%\ssh\sshd_config から構成を読み取ります
と記述されているが,PowerShell> cd %programdata%\ssh\sshd_config > cd : パス 'C:\Users\hanaata\%programdata%\ssh\sshd_config' が存在しないため検出できません。
となる.どうやら %programdata% とは root directory 直下に配置されている隠しファイルのよう.GUIからエクスプローラーの表示設定 から隠しファイルを表示させると,
\ProgramData\ssh\sshd_conf
にアクセスできる.注意しなけばならいことは,エクスプローラーから管理者権限でsshd_conf
を編集する権限がない(ro)ので,管理者権限で立ち上げたPowerShellでPowerShell> notepad C:\ProgramData\ssh\sshd_config
としてメモ帳を開き編集する必要がある.設定ファイル自体はOpenSSH serverの設定ファイルそのものなので,ようやく生きた心地がする.
-
公開鍵認証
個人的にパスワード認証は嫌いなので公開鍵認証に制限する.
conf_sshdPubkeyAuthentication yes PasswordAuthentication no #PasswordAuthentication yes
もしかするとデフォルトで
# PubkeyAuthentication yes
となっていたので,OpenSSHの設定ファイルから考えると,デフォルト値で公開鍵認証はyesなので,コメントアウトは不要だったかもしれない. -
謎のwindows 固有のsshdの設定の無効化
conf_sshdの最下部2行に次のような設定がある.
conf_sshdMatch Group administrators AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
linuxのsshd.confには無い設定なので不穏な空気を感じつつ,ChatGPTくんに恐る恐る聞いてみると,管理者権限を持つユーザーの公開鍵のファイルの場所を
__PROGRAMDATA__/ssh/administrators_authorized_keys
に強制するみたい.Windowsのお作法に従っても良いかもしれないが,個人的に公開鍵は
~/.ssh/authorized_keys
に配置したいので上記2行はコメントアウトする. -
sshdの再起動
PowerShell> Restart-Service sshd
-
公開鍵の設置
- で言及したように ssh serverのユーザーホームディレクトに,
~/.ssh/authorized_keys
に公開鍵を置けば,公開鍵認証でリモートにアクセスできる.
- で言及したように ssh serverのユーザーホームディレクトに,
-
ssh接続次にPowerShellを起動する
デフォルトの場合,sshでログインするとコマンドプロンプトが表示されるのでsshで起動後powershellを起動したいので下記設定をsshd_confに追記しsshdを再起動する
conf_sshdForceCommand powershell.exe
(PowerShell v7のがinstallされていたv7を起動する場合は
ForceCommand pwsh.exe
にする必要があります.追記参照)PowerShell> Restart-Service sshd
おそらくこれでsshでログインした際にpowershellが起動するはず.
-
残課題
上記の設定でssh経由でpowershellを起動すると,私のアカウントが管理者権限を持っているせいかログインした直後から管理者モードになっている.
PowerShell> ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") True
linuxユーザからするとpermit root loginを許可しているようで非常に居心地が悪い.ただ,WindowsのGUIでPowerShellを管理者権限で開く場合にroot パスワードを聞かれるわけでも無いのでこれで良いのか?ただ非常に気持ちわくモヤモヤする.
Linux terminalの知識で対応できるものできないもの
とりあえず
> man
トピック
Windows PowerShell のヘルプ システム
(省略)
> Get-Help
コマンドレットのヘルプを表示するには、次のように入力します。
Get-Help <コマンドレット名>
などでヘルプが見られる.出力が違うのでman
はGet-Help
のエイリアスではないかもだが,man <command>
は基本的に Get-Help
を参照していそう.
共通のコマンド
個人的によく使いそうな次のコマンドは
ls,cd, pwd,rm,cp,cat,echo,wget,curl,ping,date,host,history
は使える.但しパラメーターがbash系と異なるので注意が必要かもしれない.
$ cd ~
$ cd ../
などはbashと共通だが, cd -
はNGっぽいし,引数なしで cd
単体でもhome directoryに戻れない.
Windowsのディレクトリは,/
ではなく\
で切られているが,tab補完すれば自動でWindows用のフォーマットに整形してくれるのでそこまで不便ではない(但しWindowsのTab補完は使いずらうえ,Ctrl-aやCtrl-eなどのemacs likeなショートキーが使えないのでクソ不便).
共通でないコマンド
個人的にlinuxでよく使うがPowerShellで使えないコマンドは
touch, chown, where,find,ln,
最も残念なことはcliで動くeditorが見つからないこと.ググってもChatGPTに聞いてもそれらしい記事が出てこない.x11経由でnotepadを起動できない(未調査)のでそのため,wsl経由でemacsなりvimなりnanoなりEditorを起動するしかなさそう. wingetコマンドでvimなどのeditorをinstallしてPowerShell上で動かせそう(後述).
> wlc emacs -nw test.txt
まあ私の環境ではwlcが使えるので,これが一番かな.
パスの表示がlinuxとwindowsで違うので中一が必要である.
例えば,カレントディレクトリに存在しないファイルの中身を
> wsl nano C:\pass\to\somwhere\test.txt
と参照することは,wsl上で
$ nano C:\pass\to\somwhere\test.txt
としているに等しい.
従ってPowerShellからwlcを経由してwindows上のファイルにアクセスするには
> wsl nano /mnt/c/pass/to/somwhere/test.txt
とする必要がある.この場合PathのTab補完が機能しないので,参照したいファイルがあるdirectry まで cd
して(current dirctoryにファイルがあるようにして)開くか,wslにログインしてファイルにアクセスした方が良いであろう.
後述(wingetを使ってみる)
ChatGPTくんにPowerShellでパッケージマネージャが使えないか聞いたところwingetでアプリ系ーションをダウンロードできるみたい
> winget search vim
名前 ID バージョン 一致 ソース
--------------------------------------------------------------------------------------------------
Vim Cheat Sheet 9WZDNCRDMCWR Unknown msstore
Vimar By-me App List Exporter 9PFSSC3DTHK8 Unknown msstore
Vimar VIEW Pro 9NNG9QXL8W3Z Unknown msstore
Vim vim.vim 9.1.0618 winget
Vim vim.vim.nightly 9.1.0703 winget
Helix Helix.Helix 24.07 Tag: vim winget
Vieb Jelmerro.Vieb 12.0.0 Tag: vim winget
Neovim Neovim.Neovim 0.10.1 Tag: vim winget
Neovim Nightly Neovim.Neovim.Nightly 0.11.0 Tag: vim winget
spotify_player aome510.spotify-player 0.19.1 Tag: vim winget
lf gokcehan.lf r32 Tag: vim winget
win-vind pit-ray.win-vind 5.13.2 Tag: vim winget
qutebrowser qutebrowser.qutebrowser 3.2.1 Tag: vim winget
Yazi sxyazi.yazi 0.3.2 Tag: vim winget
neovim-qt equalsraf.neovim-qt 0.2.18 winget
marksman Artempyanykh.Marksman 2023.12.09 Tag: neovim winget
Kaku Chia-Lung.Kaku 2.0.2 Tag: vimeo winget
4K Video Downloader OpenMedia.4KVideoDownloader 4.32.5.0116 Tag: vimeo winget
Replit Replit.Replit 1.0.12 Tag: desenvolvimento winget
お,vimあるじゃんと思いinstall
> PS C:\Users\hanaata> winget install vim
複数のパッケージが入力条件に一致しました。入力内容を修正してください。
名前 ID ソース
---------------------------------------
Vim Cheat Sheet 9WZDNCRDMCWR msstore
Vim vim.vim winget
Vim vim.vim.nightly winget
PS C:\Users\hanaata> winget install vim.vim
見つかりました Vim [vim.vim] バージョン 9.1.0618
このアプリケーションは所有者からライセンス供与されます。
Microsoft はサードパーティのパッケージに対して責任を負わず、ライセンスも付与しません。
ダウンロード中 https://github.com/vim/vim-win32-installer/releases/download/v9.1.0618/gvim_9.1.0618_x64.exe
██████████████████████████████ 10.8 MB / 10.8 MB
インストーラーハッシュが正常に検証されました
パッケージのインストールを開始しています...
インストールが完了しました
> PS C:\Users\hanaata> vim
vim : 用語 'vim' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認し てから、再試行してください。
発生場所 行:1 文字:1
+ vim
+ ~~~
+ CategoryInfo : ObjectNotFound: (vim:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
installはできるけどPATHが通ってないみたいので絶対pathで実行すればPowerShell上でeditorを起動できる.
> C:'\Program Files\Vim\vim91\vim.exe'
ただ,アプリケーション入れる度に環境変数でPATHの設定するのか?めんどくさ過ぎるぞ.emacsもinstallできるけどGUIを開こうとするので
& 'C:\Program Files\Emacs\emacs-29.4\bin\emacs-29.4.exe' -nw
としなきゃならん.これらは使わないかな・・・
wsl
wlsのコマンドヘルプは
> wls --help
で確認できる.
wslにubuntu 20.04が入ってたけど古いので削除して最新のdebianを入れる.
> wsl -l -v
NAME STATE VERSION
* Ubuntu Stopped 2
> # Status runningなら一度terminateした方がお行儀が良いかも
> # wsl -t Ubuntu
> wsl --unregister Ubuntu
ちなみに wsl --shutdown
は仮想マシンをシャットダウンするコマンド.
長年Ubuntuを使っていたけどaptのリポジトリがtestingブランチでアップデートが多いので,Debianのstable版を使う.
> wsl --list --online
インストールできる有効なディストリビューションの一覧を次に示します。
'wsl.exe --install <Distro>' を使用してインストールします。
NAME FRIENDLY NAME
Ubuntu Ubuntu
Debian Debian GNU/Linux
kali-linux Kali Linux Rolling
Ubuntu-18.04 Ubuntu 18.04 LTS
Ubuntu-20.04 Ubuntu 20.04 LTS
Ubuntu-22.04 Ubuntu 22.04 LTS
Ubuntu-24.04 Ubuntu 24.04 LTS
OracleLinux_7_9 Oracle Linux 7.9
OracleLinux_8_7 Oracle Linux 8.7
OracleLinux_9_1 Oracle Linux 9.1
openSUSE-Leap-15.6 openSUSE Leap 15.6
SUSE-Linux-Enterprise-15-SP5 SUSE Linux Enterprise 15 SP5
SUSE-Linux-Enterprise-15-SP6 SUSE Linux Enterprise 15 SP6
openSUSE-Tumbleweed openSUSE Tumbleweed
> wsl --install Debian
仮想マシンのデフォルトがDebianになっていれば,wlcへのログインは
> wlc
でできるのであとは好きなパッケージでも入れればよろしい.昔はVcXsrvを入れてx11を動かしていたが確か,WSLgで不要になった気がする.
設定不要でx11 forwardingできるかと思ったが
> wsl --version
WSL バージョン: 2.2.4.0
カーネル バージョン: 5.15.153.1-2
WSLg バージョン: 1.0.61
MSRDC バージョン: 1.2.5326
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.26091.1-240325-1447.ge-release
Windows バージョン: 10.0.22631.4037
> wsl xeyes
X connection to :0 broken (explicit kill or server shutdown).
となりそのままでは実行できない.多分server側のsshd_configで許可されてない.
ダメもとでssh serverに
X11Forwarding yes
X11DisplayOffset 10
X11UseLocalhost yes
を追記すると,
X connection to :0 broken (explicit kill or server shutdown).
のエラーは出なくなったがx11はforwardingされない.まあ使わないからこれ以上は探らない.
とりあえずリモートからPowerShellを起動できるので,これでよしとする.
追記
PowerShellのupgrade
PowerShellにログインすると
新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows
と表示される.Versionを調べてみると
> $PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
5 1 22621 3958
となり,version 5で現行はvesion 7なので古い様子.ここの記事を参考にコマンドラインからupgradeを試みる.
> Invoke-Expression "& { $(Invoke-RestMethod https://aka.ms/install-powershell.ps1) } -UseMSI"
あ,ssh経由だとGUIが開かないからセットアップに進めない.ChatGPUくんに方法ないか聞いたらCUIで完結できそうではあるものの,RemoteDesktopなどでアクセスしてupdateした方が早いので,リモード経由でPowerShellの7系をインストールする.どうやらPowerShell5とPowerShell7はソフトウェアとして異なるみたいで,Windowsに共存して(やが)る.
> $PSVersionTable.PSVersion
Major Minor Patch PreReleaseLabel BuildLabel
----- ----- ----- --------------- ----------
7 4 5
sshd_configのPowerShell設定だとPowerShell v5 が起動するので
#ForceCommand powershell.exe #v5
ForceCommand pwsh.exe #v7
に変更し,sshdを再起動し,再度sshでログインすればpowershell v7が起動する.
ちなみにコマンドプロンプトでpwshと打てばPowerShell v7が起動する.
ちょっとだけ使ってみた印象として,ls
のディレクトリ名の背景がblueにになっている.
ただ,黒背景だと見えない.Gighub issue に解決策があり
$PSStyle.FileInfo.Directory = "`e[38;2;255;255;255m"
とすれば解決できた.ただ設定はtemporalなので設定ファイルを作成する.
PowerShellの設定ファイルのPATHは
echo $Profile.AllUsersAllHosts
echo $Profile.AllUsersCurrentHost
echo $Profile.CurrentUserAllHosts
echo $Profile.CurrentUserCurrentHost
から調べることができて,実際にPATHを調べてみるとクソみたいな場所にあるようなので,
> echo $Profile.CurrentUserCurrentHost
C:\Users\hanaata\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
該当のPATHに設定ファイルを作成する.
Tab補完がクソなので改善してるかなと思ったが改善していなかったのが残念である.