顯示具有 ssh 標籤的文章。 顯示所有文章
顯示具有 ssh 標籤的文章。 顯示所有文章

2026年5月13日 星期三

[Windows] 設置 OpenSSH 預設使用 PowerShell 7 環境 @ Windows 11

最近在處理 AI 自動化工作,開發了一些 claude skills ,發現最後需要在 Windows 11 運行 Claude Code CLI ,發現不同筆電的環境容易有問題,研究一陣子後,就決定統一都用 PowerShell 7 吧,也可以把 Windows 11 內建的 OpenSSH server 的 shell 也更換過去。

需要先理解 Windows 11 內建有 Powershell 5 ,但他不能拿來當 ssh 登入使用。這是預設採用 cmd 環境,改壞無法 ssh 登入 Windows 11 可以用這段還原,這是在 Powershell 運行:

New-ItemProperty `
  -Path "HKLM:\SOFTWARE\OpenSSH" `
  -Name DefaultShell `
  -Value "C:\Windows\System32\cmd.exe" `
  -PropertyType String `
  -Force

Restart-Service sshd

運行完,可用 Get-ItemProperty HKLM:\SOFTWARE\OpenSSH | Select-Object DefaultShell 查看預設的情況。

連續動作:

```
Windows PowerShell
著作權(C) Microsoft Corporation。保留擁有權利。

安裝最新的 PowerShell 以取得新功能和改進功能!https://aka.ms/PSWindows

PS C:\WINDOWS\system32> New-ItemProperty `
>>   -Path "HKLM:\SOFTWARE\OpenSSH" `
>>   -Name DefaultShell `
>>   -Value "C:\Windows\System32\cmd.exe" `
>>   -PropertyType String `
>>   -Force

DefaultShell : C:\Windows\System32\cmd.exe
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\OpenSSH
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE
PSChildName  : OpenSSH
PSDrive      : HKLM
PSProvider   : Microsoft.PowerShell.Core\Registry

PS C:\WINDOWS\system32>
PS C:\WINDOWS\system32> Restart-Service sshd
PS C:\WINDOWS\system32> Get-ItemProperty HKLM:\SOFTWARE\OpenSSH | Select-Object DefaultShell

DefaultShell
------------
C:\Windows\System32\cmd.exe
```

後續安裝完 Powershell 7 且更正確是要安裝 PowerShell 7 MSI 套件,直接在 MS Store 安裝會是另一個:

winget install --id Microsoft.PowerShell --installer-type wix

這時安裝完路徑會顯示在 `C:\Program Files\PowerShell\7\pwsh.exe` ,這版就可以當 ssh shell 來用了:

```
PS C:\WINDOWS\system32> Get-Command pwsh

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     pwsh.exe                                           7.6.1.0    C:\Program Files\PowerShell\7\pwsh.exe


PS C:\WINDOWS\system32> New-ItemProperty `
>>   -Path "HKLM:\SOFTWARE\OpenSSH" `
>>   -Name DefaultShell `
>>   -Value "C:\Program Files\PowerShell\7\pwsh.exe" `
>>   -PropertyType String `
>>   -Force

DefaultShell : C:\Program Files\PowerShell\7\pwsh.exe
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\OpenSSH
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE
PSChildName  : OpenSSH
PSDrive      : HKLM
PSProvider   : Microsoft.PowerShell.Core\Registry

PS C:\WINDOWS\system32>
PS C:\WINDOWS\system32> Restart-Service sshd
```

如此遠端到 Windows 11 時,登入後會看到版本資訊:

```
PowerShell 7.6.1
PS C:\Users\user> 
```

2025年2月17日 星期一

Docker 開發筆記 - 使用 aws cli 和 Docker Exec 進入 AWS ECS Container @ macOS

這個議題比我想像中麻煩了點,讓我回憶起 2009 年寫的 AWS 筆記,那時同事一開始還只在用 Firefox extension 管理 AWS EC2 呢 XD 我覺得這理論上要能都透過網頁搞定才對,先把目前研究的過程筆記一下。

總之,要能像 ssh 遠端(docker exec -it ContainerID bash)進去 AWS ECS container 的關鍵之處:
  • 使用 awscli 做事
  • AWS ECS 的 Task 定義,基礎設施需求 -> 任務角色,需要指定一下角色,例如 ecsTaskExecutionRole
  • AWS IAM -> ecsTaskExecutionRole -> 添加 AmazonSSMManagedInstanceCore 權限
  • AWS ECS -> Cluster -> Service ,需要用 awscli 啟動 enable-execute-command ,並且重新更新服務,使之生效
  • 使用 aws 指令登入
首先,先下載 awscli 並且版本要夠新:
安裝後檢查版本,版本太低會無法完成任務:

% aws --version
aws-cli/2.24.5 Python/3.12.6 Darwin/24.3.0 exe/x86_64

接著還要安裝 Session Manager plugin,此例紀錄 Mac with Apple silicon 版:
% curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac_arm64/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"
% unzip sessionmanager-bundle.zip
% sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin

基本的環境已準備好了,下一刻是查看自己的 AWS ECS 的任務定義是否有把 任務角色 設定好,這部就維持用網頁吧:



若你的 AWS ECS 上定義的 Task 只有一個,也可以偷懶靠 awscli 操作(在此就不贅述 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION 部分),會用到的指令:

aws ecs list-task-definition-families --status ACTIVE
aws ecs list-task-definitions --family-prefix webapp
aws ecs describe-task-definition --task-definition webapp:3

連續技,快速檢查 taskRoleArn 跟 executionRoleArn:

% NamespaceID=$(aws ecs list-task-definition-families --status ACTIVE | jq -r '.families[0]') ; echo "Namespace: $NamespaceID" ; TaskID=$(aws ecs list-task-definitions --family-prefix "$NamespaceID" | jq -r '.taskDefinitionArns[0]') ; echo "Task: $TaskID" ; aws ecs describe-task-definition --task-definition "$TaskID" | jq ".taskDefinition | { taskRoleArn: .taskRoleArn, executionRoleArn: .executionRoleArn}"
Namespace: myapp-task
Task: arn:aws:ecs:ap-northeast-1:####:task-definition/myapp-task:2
{
  "taskRoleArn": "arn:aws:iam::####:role/ecsTaskExecutionRole",
  "executionRoleArn": "arn:aws:iam::####:role/ecsTaskExecutionRole"
}

接下來,若 AWS ECS Cluster 還沒有建立任何 Service,用指令查:

% aws ecs list-tasks --cluster myapp-cluster  
{
    "taskArns": []
}

接著我們在 AWS ECS 網頁端起了一個 Service 名為 myapp-service ,在創建過程中沒看到啟用 enable-execute-command,這時在網頁上查看也是顯示 "ECS 執行: 關閉"



接下來用 aws cli 查詢:

% aws ecs list-tasks --cluster myapp-cluster   
{
    "taskArns": [
        "arn:aws:ecs:ap-northeast-1:####:task/myapp-cluster/#TASKID#"
    ]
}

% TaskID=$(aws ecs list-tasks --cluster myapp-cluster | jq -r '.taskArns[0]') ; echo "TaskID: $TaskID" ; aws ecs describe-tasks --cluster myapp-cluster --tasks $TaskID | jq '.tasks[0] | { "clusterArn": .clusterArn, "taskArn": .taskArn, "taskDefinitionArn": .taskDefinitionArn, "group": .group, "healthStatus": .healthStatus, "desiredStatus": .desiredStatus, "enableExecuteCommand": .enableExecuteCommand, "containers-name": [.containers |.[] | { "name":.name, "runtimeId": .runtimeId} ] }'
TaskID: arn:aws:ecs:ap-northeast-1:####:task/myapp-cluster/#TASKID#
{
  "clusterArn": "arn:aws:ecs:ap-northeast-1:####:cluster/myapp-cluster",
  "taskArn": "arn:aws:ecs:ap-northeast-1:####:task/myapp-cluster/#TASKID#",
  "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:####:task-definition/myapp-task:2",
  "group": "service:myapp-service",
  "healthStatus": "HEALTHY",
  "desiredStatus": "RUNNING",
  "enableExecuteCommand": false,
  "containers-name": [
    {
      "name": "php-fpm-docker",
      "runtimeId": "#TASKID#-#ContainerID#"
    },
    {
      "name": "web-docker",
      "runtimeId": "#TASKID#-#ContainerID#"
    }
  ]
}

可以看到 enableExecuteCommand 為 false

這時候,如果透過 aws cli 來設法登入到 Container:

% aws ecs execute-command --cluster myapp-cluster --task #TASKID# --container #containers#name# --command "/bin/bash" --interactive


The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.


An error occurred (InvalidParameterException) when calling the ExecuteCommand operation: Unable to start session because the container doesn’t exist. Specify a valid container and try again.

接著,使用 aws cli 來啟動 enableExecuteCommand 吧:

% aws ecs update-service --cluster myapp-cluster --service arn:aws:ecs:ap-northeast-1:####:service/myapp-cluster/myapp-service --enable-execute-command 
{
    "service": {
        ... 
        "enableExecuteCommand": true,
        ...
    }
}

可以看到 enableExecuteCommand 被標記成 true 了,這時還需要重新發布服務,可以重網頁去觸發,或是靠指令觸發:

% aws ecs update-service --cluster myapp-cluster --service arn:aws:ecs:ap-northeast-1:####:service/myapp-cluster/myapp-service --force-new-deployment

當服務發布完畢後,在網頁上就可以看到改變,或是用指令在查一次:

% TaskID=$(aws ecs list-tasks --cluster myapp-cluster | jq -r '.taskArns[0]') ; echo "TaskID: $TaskID" ; aws ecs describe-tasks --cluster myapp-cluster --tasks $TaskID | jq '.tasks[0] | { "clusterArn": .clusterArn, "taskArn": .taskArn, "taskDefinitionArn": .taskDefinitionArn, "group": .group, "healthStatus": .healthStatus, "desiredStatus": .desiredStatus, "enableExecuteCommand": .enableExecuteCommand, "containers-name": [.containers |.[] | { "name":.name, "runtimeId": .runtimeId} ] }'
TaskID: arn:aws:ecs:ap-northeast-1:####:task/myapp-cluster/#TASKID#
{
  "clusterArn": "arn:aws:ecs:ap-northeast-1:####:cluster/myapp-cluster",
  "taskArn": "arn:aws:ecs:ap-northeast-1:####:task/myapp-cluster/#TASKID#",
  "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:####:task-definition/myapp-task:2",
  "group": "service:myapp-service",
  "healthStatus": "HEALTHY",
  "desiredStatus": "RUNNING",
  "enableExecuteCommand": true,
  "containers-name": [
    {
      "name": "php-fpm-docker",
      "runtimeId": "#TASKID#-#CONTAINERID#"
    },
    {
      "name": "web-docker",
      "runtimeId": "#TASKID#-#CONTAINERID#"
    }
  ]
}

如此,就可以正式遠端進去一下:

% aws ecs execute-command --cluster myapp-cluster --task #TASKID# --container web-docker --command "/bin/bash" --interactive

The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.


Starting session with SessionId: ecs-execute-command-################
ip-123-45-6-123:/var/www/html# 

收工

參考資料:

2023年9月20日 星期三

Windows 開發筆記 - 使用 Command Line / CMD / ssh 與 PHP 8.2 / Composer / Git / VIM 開發環境 @ Windows 11

幫同事看了一下 Windows 開發環境,要在此環境使用 PHP8.2 與 PHP Laravel v10 framework,由於之前採用 xampp 管理套件被環境變數卡住。這些問題描述,瞬間拉回到學生時代在那邊設置 Windows %PATH% 環境變數 XD 我也忘了那時在幹嘛?推論是配置 Java 環境吧

目前就把手邊的 Windows 11 筆電拿來遠端,但懶得打開它。並且實際在 command line 測試會碰到幾個問題。

1. 從 https://windows.php.net/download/ 下載 VS16 x64 Non Thread Safe ,並解壓在 C:\php 目錄中,必須在設置 php.ini 。想要知道自己的 php.ini 位置,可以用 php.exe --ini

C:\php>php.exe --ini 
Configuration File (php.ini) Path: 
Loaded Configuration File:         (none)
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)

接著把 C:\php\php.ini-development 複製到 C:\php\php.ini 使用:

C:\php>copy php.ini-development php.ini     
複製了         1 個檔案。

後續就編輯 php.ini 開啟一些項目,在此就靠 C:\cygwin64\bin\vim.exe 當編輯器(若碰到滑鼠圈選文字難複製,記得關掉滑鼠模式 :set mouse-=a),主要打開一些 php.ini 註解:

; Directory in which the loadable extensions (modules) reside.
; https://php.net/extension-dir
;extension_dir = "./"
; On windows:
extension_dir = "ext"
; ...
extension=curl
extension=fileinfo
extension=gd
extension=intl
extension=mbstring
extension=exif
extension=mysqli
extension=openssl
extension=sqlite3

C:\php>php.exe --ini 
Configuration File (php.ini) Path: 
Loaded Configuration File:         C:\php\php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)

2. 下載 composer 後,預設會失敗:

C:\php>php.exe composer.phar self-update

In Factory.php line 648:
                                                                                                                          The openssl extension is required for SSL/TLS protection but is not available. If you can not enable the openssl extension, you can   
   disable this error, at your own risk, by setting the 'disable-tls' option to true.                          

self-update [-r|--rollback] [--clean-backups] [--no-progress] [--update-keys] [--stable] [--preview] [--snapshot] [--1] [--2] [--2.2] [--set-channel-only] [--] [<version>]

設置後:

C:\php>php.exe composer.phar self-update 
You are already using the latest available Composer version 2.6.3 (stable channel).

3. 在管理專案時,透過 C:\php\php.exe composer.phar install 時,會需要 GIT 指令,解法就是去官方安裝一下,安裝完的目錄位置在 C:\Program Files\Git 位置

C:\>"C:\Program Files\Git\bin\git.exe" --version
git version 2.42.0.windows.2

4. 回過頭來,更新環境變數 %PATH% 

C:\>git
'git' 不是內部或外部命令、可執行的程式或批次檔。
C:\>echo %PATH%
C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\Docker\Docker\resources\bin;C:\WINDOWS\system32\config\systemprofile\AppData\Local\Microsoft\WindowsApps;C:\Users\user\AppData\Local\Microsoft\WindowsApps;
C:\>set PATH=%PATH%;C:\Program Files\Git\bin\
C:\>git --version
git version 2.42.0.windows.2

如此在 Windows 的 command line (PowerShell) 環境下,也可以靠純指令做一點事了

2023年9月3日 星期日

Kubernetes/k8s 開發筆記 - 在 macOS 僅安裝 kubectl 、在 Windows 安裝 minikube v1.31.2 和 VirtualBox v7.0.10 @ macOS 13 , Windows 11

雖然 k8s 已夯很久,但工作事務上一直還沒用他,主因是現有的 Jenkins + Ansible 已經可以輕鬆管理數百台機器群,說穿了也滿像實體機房管理機制,有人(Linode/AWS/GCP/Azure)負責把實體機器上架插上電源網路線,接著設法自動化(Ansible)找到他們完成初始化,接著靠 Jenkions 完成 CI/CD。

年初就想要提升同事技能,刻意備好書推動,現在趁個颱風天自己也找點時間走一輪吧!我認為 k8s 的線上資源已經夠多了,已夯了五年,到處都有精美的簡中電子書和鐵人文,如:
整體上,我覺得可以 Kubernetes Handbook (Kubernetes指南)那為基準,先把基礎入門文都看一下,知道 k8s 源自於 Google Borg 的設計理念,往後只要看著 k8s 架構圖即可:


例如操作 k8s 可以透過 kubectl 指令,也可以透過 api 呼叫,更可以透過 Web UI 來操作。如果硬要對比的話,早年 AWS 2009 前後,一開始也是先提供 API 操控方式,接著進展到 Firefox plugin,後續提供 Web UI 並且越來越豐富,對應的還有 Azure / GCP 一推出就有 Web UI 可操作,接著為了自動化操控,我們會使用 API level 的方式,透過基本的權限掌控後,得知機器的 IP 跟默認的登入方式,也可以簡化成單純在 AWS/GCP Web UI 開好機器及設定好標籤後,後續 ansible-playbook 就能全盤接手處理。

至於要認識 k8s ,目前看到 minukube 是最佳的下手,他支援跨平台。實務上只需做一兩件事:
  1. 下載 minukube ,可以架設出本地 k8s cluster (預設是單一節點)
  2. 下載 kubectl 工具(雖然 minukube kubectl 也能呼喚出)
這邊做一點有趣的情境:在 macos 上僅安裝 kubectl 而已,在 windows 11 安裝 minukube v1.31.2 + VirtualBox v7.0.10,讓 Windows 資源拿來運作 k8s 環境,未來 macos 就縮減成 thin client 用來遠端操作。

實作方式 - macOS (也可靠 MacPorts 或 Homebrew 安裝):

% curl -L https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/darwin/amd64/kubectl > /tmp/kubectl
% chmod 700 /tmp/kubectl
% /tmp/kubectl version
Client Version: v1.28.1
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
The connection to the server localhost:8080 was refused - did you specify the right host or port?

這邊就可以看到 kubectl 他本身預設會去跟 localhost:8080 溝通,那代表其可以設定在遠方。

實作方式 - Windows 11: 

PS C:\Users\user\Downloads> .\minikube-windows-amd64.exe start
😄  minikube v1.31.2 on Microsoft Windows 11 Pro 10.0.22621.2215 Build 22621.2215
✨  Using the virtualbox driver based on existing profile
👍  Starting control plane node minikube in cluster minikube
🔄  Restarting existing virtualbox VM for "minikube" ...
❗  This VM is having trouble accessing https://registry.k8s.io
💡  To pull new external images, you may need to configure a proxy: https://minikube.sigs.k8s.io/docs/reference/networking/proxy/
🐳  Preparing Kubernetes v1.27.4 on Docker 24.0.4 ...
🔗  Configuring bridge CNI (Container Networking Interface) ...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
    ▪ Using image docker.io/kubernetesui/dashboard:v2.7.0
    ▪ Using image docker.io/kubernetesui/metrics-scraper:v1.0.8
🔎  Verifying Kubernetes components...
💡  Some dashboard features require the metrics-server addon. To enable all features please run:

        minikube addons enable metrics-server

🌟  Enabled addons: default-storageclass, storage-provisioner, dashboard
💡  kubectl not found. If you need it, try: 'minikube kubectl -- get pods -A'
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

PS C:\Users\user\Downloads> .\minikube-windows-amd64.exe stop
✋  Stopping node "minikube"  ...
🛑  1 node stopped.

PS C:\Users\user\Downloads> .\minikube-windows-amd64.exe delete
🔥  Deleting "minikube" in virtualbox ...
💀  Removed all traces of the "minikube" cluster.

以上就是很粗淺的....我起來了,我停掉,我砍掉了。其中比較麻煩之處應該是 Virutalbox 7 的使用,剛安裝完後要重新啟動電腦,接著運行 minikube-windows-amd64.exe start 時,看能不能順利跑起來,常見卡住的地方是 Host-Only 網路卡等等。

此外,一直切換筆電很煩,就來把 Windows 11 Desktop 安裝 OpenSSH ,讓 macOS 遠端登入:[macOS] 從 Macbook 遠端登入 Windows 筆電並使用 PowerShell 工作環境

接著就回到 macOS 遠端登入 windows minikube 的用法:

% ssh user@windows-minikube-ip

Microsoft Windows [版本 10.0.22621.2215]
(c) Microsoft Corporation. 著作權所有,並保留一切權利。

user@WINDOWS-DESKTOP C:\Users\user>cd Downloads

user@WINDOWS-DESKTOP C:\Users\user\Downloads>minikube-windows-amd64.exe start
😄  minikube v1.31.2 on Microsoft Windows 11 Pro 10.0.22621.2215 Build 22621.2215
✨  Automatically selected the virtualbox driver
👍  Starting control plane node minikube in cluster minikube
🔥  Creating virtualbox VM (CPUs=2, Memory=4000MB, Disk=20000MB) ...
❗  This VM is having trouble accessing https://registry.k8s.io
💡  To pull new external images, you may need to configure a proxy: https://minikube.sigs.k8s.io/docs/reference/networking/proxy/
🐳  Preparing Kubernetes v1.27.4 on Docker 24.0.4 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔗  Configuring bridge CNI (Container Networking Interface) ...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🔎  Verifying Kubernetes components...
🌟  Enabled addons: default-storageclass, storage-provisioner
💡  kubectl not found. If you need it, try: 'minikube kubectl -- get pods -A'
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

user@WINDOWS-DESKTOP C:\Users\user\Downloads>

user@WINDOWS-DESKTOP C:\Users\user\Downloads>minikube-windows-amd64.exe status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

user@WINDOWS-DESKTOP C:\Users\user\Downloads>minikube-windows-amd64.exe kubectl -- config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority: C:\Users\user\.minikube\ca.crt
    extensions:
    - extension:
        provider: minikube.sigs.k8s.io
        version: v1.31.2
      name: cluster_info
    server: https://192.168.59.101:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    extensions:
    - extension:
        provider: minikube.sigs.k8s.io
        version: v1.31.2
      name: context_info
    namespace: default
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate: C:\Users\user\.minikube\profiles\minikube\client.crt
    client-key: C:\Users\user\.minikube\profiles\minikube\client.key

user@WINDOWS-DESKTOP C:\Users\user\Downloads>minikube-windows-amd64.exe kubectl -- version --output=json     
{
  "clientVersion": {
    "major": "1",
    "minor": "27",
    "gitVersion": "v1.27.4",
    "gitCommit": "fa3d7990104d7c1f16943a67f11b154b71f6a132",
    "gitTreeState": "clean",
    "buildDate": "2023-07-19T12:20:54Z",
    "goVersion": "go1.20.6",
    "compiler": "gc",
    "platform": "windows/amd64"
  },
  "kustomizeVersion": "v5.0.1",
  "serverVersion": {
    "major": "1",
    "minor": "27",
    "gitVersion": "v1.27.4",
    "gitCommit": "fa3d7990104d7c1f16943a67f11b154b71f6a132",
    "gitTreeState": "clean",
    "buildDate": "2023-07-19T12:14:49Z",
    "goVersion": "go1.20.6",
    "compiler": "gc",
    "platform": "linux/amd64"
  }
}


user@WINDOWS-DESKTOP C:\Users\user\Downloads>ipconfig

Windows IP 設定


乙太網路卡 乙太網路:

   媒體狀態 . . . . . . . . . . . . .: 媒體已中斷連線
   連線特定 DNS 尾碼 . . . . . . . . :

乙太網路卡 乙太網路 2:

   連線特定 DNS 尾碼 . . . . . . . . :
   IPv4 位址 . . . . . . . . . . . . : 192.168.56.1
   子網路遮罩 . . . . . . . . . . . .: 255.255.255.0
   預設閘道 . . . . . . . . . . . . .:

乙太網路卡 乙太網路 3:

   連線特定 DNS 尾碼 . . . . . . . . :
   IPv4 位址 . . . . . . . . . . . . : 192.168.59.1
   子網路遮罩 . . . . . . . . . . . .: 255.255.255.0
   預設閘道 . . . . . . . . . . . . .:

...

如此,若要用 macOS kubectl 去控制 Windows 11 上的 minikube ,先挑個土法煉鋼模式:

1. 把 minikube-windows-amd64.exe kubectl -- config view 存起來(可以透 ssh remote command)

% ssh user@windows-minikube-ip '%HOME%\Downloads\minikube-windows-amd64.exe kubectl -- config view' > /tmp/kubectl.config.yaml

2. 將上面列到的 certificate-authority, client-certificate 和 client-key 也都靠 scp 下載回來

% scp user@windows-minikube-ip:"/C:/Users/user/.minikube/ca.crt" /tmp/kubectl.ca.crt
% scp user@windows-minikube-ip:"/C:/Users/user/.minikube/profiles/minikube/client.crt" /tmp/kubectl.client.crt
% scp user@windows-minikube-ip:"/C:/Users/user/.minikube/profiles/minikube/client.key" /tmp/kubectl.client.key

3. 修改 /tmp/kubectl.config.yaml 上 certificate-authority, client-certificate 和 client-key 對應位置

% /tmp/kubectl --kubeconfig ./kubectl.config.yaml config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority: kubectl.ca.crt
    extensions:
    - extension:
        provider: minikube.sigs.k8s.io
        version: v1.31.2
      name: cluster_info
    server: https://127.0.0.1:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    extensions:
    - extension:
        provider: minikube.sigs.k8s.io
        version: v1.31.2
      name: context_info
    namespace: default
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate: kubectl.client.crt
    client-key: kubectl.client.key

其中上述的 clusters.cluster.server 數值我已換成 https://127.0.0.1:8443 ,這是為了彈性自行靠 ssh tunnel 

4. 最後,我再透過 SSH tunnel 自建一條連到 192.168.56.101:8443 (Windows 11 上的 minikube api 入口點)

% ssh -N -L 8443:192.168.59.101:8443 user@windows-minikube-ip

5. 如此,未來想從 macOS 的 kubectl 遠端連去控制 Windows 11 上的 minikube 時,就是先建立一條 SSH tunnel ,接著運行 kubectl 要指定 config 位置,就能黑皮遠端操控

% ./kubectl --kubeconfig ./kubectl.config.yaml version
Client Version: v1.28.1
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.27.4

最後一提,其實 Windows 11 Desktop 安裝完 OpenSSH server 後,已經可以自行遠端進去用 minikube-windows-amd64.exe kubectl 做事,只剩熟不熟悉 PowerShell 指令環境,所以,上述有點脫褲子放屁 XD 好處是練一輪後,未來有很多 k8s cluster 可以用 --kubeconfig 切換吧!

其他資訊:

2023年8月31日 星期四

[macOS] 從 Macbook 遠端登入 Windows 筆電並使用 PowerShell 工作環境 @ macOS 13.2.1

由於想善用 Windows 筆電的資源(算力),先來試試看能不能打通 macOS command line 遠端登入進 Windows 11 筆電。查了一下資料,看來真的也有人有這種需求 XD

原理:
  1. Windows 11 安裝 OpenSSH Server
  2. macOS 安裝 PowerShell Core 資源 (非必要)
其中一還滿常見,二就有點怕怕,所幸資源算是微軟提供(?),有興趣可以裝 pkg 檔案,裝完在 macos command line 用 pwsh 指令就切換到 PowerShell 工作環境,目前只需做 (1) 就能完成需求,以下是在 Windows 11 筆電下運行指令,建議在上述微軟官方文件上複製使用,在此純做筆記:

PS C:\Users\user> Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'

Name  : OpenSSH.Client~~~~0.0.1.0
State : Installed

Name  : OpenSSH.Server~~~~0.0.1.0
State : NotPresent

PS C:\Users\user> ssh -V
OpenSSH_for_Windows_8.6p1, LibreSSL 3.4.3

PS C:\Users\user> Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

Path          :
Online        : True
RestartNeeded : False

PS C:\Users\user> Start-Service sshd
PS C:\Users\user> Set-Service -Name sshd -StartupType 'Automatic'
PS C:\Users\user> 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."
>> }
Firewall rule 'OpenSSH-Server-In-TCP' has been created and exists.

PS C:\Users\user> ssh localhost
user@localhost's password:

如此筆電重啟後,也會自動啟動 OpenSSH Server 。而 macOS 要遠端進去一樣把它當成 linux server 即可,靠 ssh 加上帳密遠端登入。

另外,常會使用 ping 來查看機器健康情況,而 Windows 11 默認關閉(也是滿好的資安規劃),在此要人工開啟:

系統 -> 隱私權與安全性 -> Windows 安全性 -> 防火牆與網路保護 -> 進階設定 -> 輸入規則 ->  核心網路診斷 - ICMP 回應要求 -> 啟動


可以自行依照需求開啟全部 ICMP 回應或部分情境。 

最後,莫忘筆電的電源節源設計,預設應該是 5分鐘就會進入休眠,可以把它調整成插電就永不進入休眠,以及要衝刺算力也可以調整電源策略。

2017年2月3日 星期五

Ansible 筆記 - 透過 Reverse SSH Tunnel 維護機器

有時候就是這樣,某些機器本身連不進去,這時要測試發佈流程時,就適合從中間機器建立 SSH Tunnel 啦。例如 A <-> B <-> C 關係中,B 可以分別連到 A 跟 C ,但 A 跟 C 彼此無法連上。這時就從 B 的角色建立個 Reverse SSH Tunnel 了

@B:

$ ssh -NR 2266:C_HOST_IP:22 user@A_HOST_IP


如此一來,在 A 機器中,就可以自連 ssh 127.0.0.1:2266 就可以直達 C 機器囉!

接著,若在 A 機器發動 ansible deploy 任務,就會有需要指定 ansible-playbook 運作時,那個 ssh port 要換一下,所幸的,用 ansible-playbook -h 就有教學啦 XD 其中 sftp 跟 scp/ssh 的參數名不一樣,所以得個別設定,完整的範例:

@A:

$ HOST=tag_Ansible_MY_Task DATA="['127.0.0.1']" ansible-playbook -i bin/echo.sh MY_Task.yml --private-key=ssh-private-key.pem --sftp-extra-args="-oPORT=2266" --scp-extra-args="-p 2266" --ssh-extra-args="-p 2266"


此例 bin/echo.sh 只是一個讓我組出 ansible-playbook 所需的格式:

$ cat bin/echo.sh
#!/bin/bash
echo "{\"$HOST\":$DATA}"
$ HOST=tag_Ansible_MY_Task DATA="['127.0.0.1']" bin/echo.sh
{"tag_Ansible_MY_Task":['127.0.0.1']}
$ head -n 7 MY_Task.yml
---
- hosts: tag_Ansible_MY_Task
  remote_user: ubuntu
  become: true
  become_user: root
  become_method: sudo

2014年4月10日 星期四

[Linux] 更新 OpenSSH Server Key @ Ubuntu 12.04

由於熱門議題 OpenSSL Security Advisory [07 Apr 2014] / CVE-2014-0160 的影響,只好重新處理一下 OpenSSH Server key 了:

$ lsb_release -a
Distributor ID: Ubuntu
Description: Ubuntu 12.04.4 LTS
Release: 12.04
Codename: precise
$ sudo rm /etc/ssh/ssh_host_*
$ sudo dpkg-reconfigure openssh-server

2014年3月26日 星期三

[Linux] 限制使用者只能用 public key 登入 @ Ubuntu 12.04

原先是要用在 mysql 之 rsync 的備份方式,雖然最後不用了,也順便記一下:

$ sudo vim /etc/ssh/sshd_config
#PasswordAuthentication yes # default
RSAAuthentication yes
PubkeyAuthentication yes

Match User user1,user2
PasswordAuthentication no


$ sudo service ssh reload