2023年8月21日 星期一

禁止RDP(遠端桌面)用戶連上VM時複製、貼上或掛載本機硬碟

圖片

最近開課,為了讓學員有最好的上課體驗,我們都大手筆、大成本的為每位學員準備一台雲端虛擬機,當作上課環境。這樣學員就不需要自己安裝上課所需的軟體了,也不用弄亂自己原本的電腦環境,只要以遠端桌面連上即可。

不料近期,碰到某企業客戶的資安同仁認為,這虛擬機…不安全。
因為,同仁有可能在公司上課時把公司檔案偷偷複製到虛擬機,然後回家後,再下載到回家裡電腦!!! (呃…) 要求我們設法處理。
好唷,沒問題,就來處理處理~

怎麼強制讓用戶連上虛擬機時,不能複製貼上也不能掛載本機硬碟呢? 其實,只需要開啟…
群組原則 --> 電腦設定 --> 系統管理範本 --> windows 元件 --> 遠端桌面服務 --> 遠端桌面工作階段主機 --> 裝置及資源重新導向

然後把剪貼簿和磁碟重新導向關閉即可,很容易吧。

後記:
我突然想到,我有一個在高收入產業上班的朋友(業務單位,非資訊人員),有次他因為電腦使用上的問題向我求救,我請他擷圖用賴傳給我,他說電腦沒法擷圖,我不解。搞了半天,他最後用手機拍了螢幕的照片傳給我,被我嫌怎麼歪歪斜斜解析度那麼差,他才說: 『不錯了,這還是偷拍的』。
他說:公司不能拍照,不能擷圖,不能下載檔案,不能OOXXOOXX。
我說:『哇,你們控管這麼嚴格啊!?』
他說:『你才知道? 公司基本上就把我們都當作是 “賊” 來看待。』
我大笑:『哈哈哈,很好、很好』
心想,這就是所謂的『零信任』吧😛。

使用CLI發送免費的LINE Notify通知

Overview

這個 Lab 介紹如何透過Command Line來免費發送的LINE Notify通知

Prerequisites

  1. 下載安裝 .net core sdk 3.1 以上版本 here
  2. 安裝 LINE CLI 工具1.0.19以上版本 here

Steps

  1. 在command line輸入 dotnet --version,確定您的執行環境具備 .net core 3.x 以上版本
PS C:\> dotnet --version

系統會出現類似底下畫面…

PS C:\> dotnet --version
5.0.202

2.接著執行底下指令, 安裝 LINE CLI 工具…

PS C:\> dotnet tool install --global line.cli 

如果成功,系統會出現類似底下畫面…

工具 'line.cli' 已安裝。
  1. 申請 LINE Notify Token
    前往LINE Notify,以個人帳號登入,至個人頁面的最下方『發行權杖』:
    圖片

  2. 選擇訊息要發送到哪一個群組(亦可發送給自己一人):
    圖片

  3. 按下『發行』後,可取得類似底下的 Notify Token:
    圖片

  4. 如果是發送給群組,記得將 LINE Notify帳號加入該群組中。

  5. 未來,只需要透過底下Command Line指令,即可免費發送LINE訊息給特定群組:

PS C:\> line notify -n [NotifyToken] -m 要發送的訊息 

你會發現訊息就會出現在LINE通知中:
圖片

CLI本質上也是透過 LINE官方的Rest API來完成的:

POST /api/notify HTTP/1.1
Host: notify-api.line.me
Authorization: Bearer ___Notify_token___
Content-Length: 135
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="message"

測試訊息
------WebKitFormBoundary7MA4YWxkTrZu0gW--

透過這樣的方式,即可免費的發送通知訊息給系統管理人員、維運人員,做為企業內的一般通知使用,非常經濟方便。

相關參考資料

LineBotSDK:https://www.nuget.org/packages/LineBotSDK
LINE Notify Document: https://notify-bot.line.me/doc/en/

如果需要即時取得更多相關訊息,可按這裡加入FB專頁。若這篇文章對您有所幫助,請幫我們分享出去,謝謝您的支持。

2023年7月23日 星期日

Azure DevOps - 在Job之間傳遞變數值

圖片

學員來信問到了,如何在 Azure DevOps Pipeline 的多個 Job 之間,傳遞變數值。這有一些知識背景。

首先,Azure DevOps 的一條 Pipeline 中可以有多個Job,每個Job可以獨立運行,或是相依運行(例如Job A完成後再運行 Job B),每一個Job裡面才是多個Tasks(或是Steps),類似底下這樣:

圖片

假設,上面兩個 Job 之間有相依性,如何在第一個 Job 完成之後,把特定的資訊,傳遞到第二個 Job 之中呢?

一般來說我們會想到 Pipeline Variable。底下這樣的輸出,可以建立出一個 Pipeline Variable,基本的設計是在 tasks 之間傳遞資訊:

- powershell: |
    Write-Host "##vso[task.setvariable variable=myVar;]foo"

- bash: |
    echo "##vso[task.setvariable variable=myVar;]foo"

上面這樣的指令可以定義一個名稱為 myVar 的變數,然後設定其值為 foo。

要使用其值,就可以採用 $(變數名稱) 這樣的指令:

- powershell: |
    Write-Host "變數值: $(myVar)"

- bash: |
    echo "變數值: $(myVar)"

問題是,上述的變數預設狀況下只能在單一的job之間使用,如果要pass到另一個job,得做些設定。首先,變數設定得多加一個 isOutput=true,表明要在下一個job中使用:
圖片

接著,要在第二個Job中,設定一個環境變數(例如下圖的B1StagePara),來承接第一個output變數myPara1:
圖片

這樣在第二個job中才可以使用。ok, 確實有點迂迴。

不過如此一般,你就可以順利的把第一個job產出的資訊,pass給第二個job了:

圖片

整段 Yaml 檔案如下:

trigger:
- main
pool:
  vmImage: ubuntu-latest
stages:
- stage: A
  jobs:
  - job: A1
    steps:
     - bash: echo "##vso[task.setvariable variable=myPara1;isOutput=true]這是JobA1中的Step傳遞過來給JobB1的參數"
       name: A1Step1
- stage: B
  dependsOn: A
  jobs:
  - job: B1
    variables:
      B1StagePara: $[stageDependencies.A.A1.outputs['A1Step1.myPara1']]
    steps:
      - bash: echo B1StagePara ==> $(B1StagePara)

hope it helps. 😁


敏捷開發與Azure DevOps實戰』課程,我們最近要開課囉,如果你需要預先保留席次,請點選這裡登記唷。

若您要詢問問題,或是需要即時取得更多相關訊息,可按這裡加入FB專頁。
若這篇文章對您有所幫助,請幫我們分享出去,謝謝您的支持。

2023年6月25日 星期日

敏捷導入流程 - ADAPT

圖片

端午節前,上課的時候,又有學員說到: 『老師,你說的這些都很對,但在公司裡面,老闆(PM/主管)就是沒法接受我花額外的時間來做這些(單元測試、重構…etc.)。而且同仁也不覺得這些東西(測試左移、敏捷開發、頻繁交付…etc.)有那麼重要…』

相信我,敏捷轉型和DevOps導入做久了,我常常碰到這個事情。

上周五我才在 Agile Summit 2023 分享這張圖,幾十分鐘演講我無法把心裡的感受 100% 講清楚,但我得說,組織數位轉型,如果只是技能(Ability)的教導,是很難很難很難達到推動的效果的。

因為同仁(或老闆)根本不認為自己有改變的需要。

因此,在培養同仁的能力(Ability)之前,先得營造團隊對於改變的渴望(Desire),而這必須從讓同仁和團隊意識(Awareness)到自己需要改變開始。(上圖)

過去很多公司把教育訓練(Ability)當作Awareness來使,不是不行,只是成效很勉強。上週五分享時,我們同仁有說過,Awareness的建立,很像是持續的在靜止的湖面一直丟一顆一顆的小石子,讓漣漪可以一波一波的傳遞出去。為了達成這件事,同仁用了很多策略,包含在企業內定期舉辦內部社群聚會、持續帶狀的發送電子報、持續舉辦的分享會和教育訓練、安排技能陪跑指導…這些都只是開始,經過了不斷的努力,成果才會慢慢開始看到。

這還有一個前提,就是大老闆對數位轉型在觀念上是支持的,因此不會挑戰你為何要做這些、那些…。然後,我們才有機會在企業內,依照這個循環,把一種技術、或一種方法逐漸落地、紮根,然後開始改變同仁的習慣,最後才能實踐轉型。

否則要不了多久,你帶入的所有新做法,都會被組織的慣性所掩蓋,同仁會逐漸回到原本那個樣子,船過水無痕。

數位轉型,說起來感覺很容易,得做過才知道箇中難處在哪裡。

『如果老闆就是不支持呢?』學員問。

我說:『那你做你的,不要跟老闆說。』我特別補充:『這不是我說的,這是Martin Fowler說的。』(圖二)
圖片

記得,你的關注範圍不要大於你的影響範圍,否則,你自己會很痛苦。(屈原就是這樣)

如果你的影響範圍目前就只有你自己的團隊,那就從你的團隊安安靜靜地開始做起。如果你做的事情是對的,要不了多久,你的成果就會被大家看到,你的影響範圍就有機會逐漸擴大,這時你的關注範圍(在組織內可進行轉型的影響半徑),就可以被放大。

如果你的影響範圍只有自己一個人呢? 那…你就好好做好自己。還記得漁父說的嗎? 『滄浪之水清兮,可以濯吾纓;滄浪之水濁兮,可以濯吾足』獨善其身,苟存於亂世之中,也並無不可。

否則,你硬是想要在大環境不允許的狀況下,去用一己之力改變整個世界,恐怕最後的結果,只會比屈原好不了多少…而且可能還連顆紀念你的粽子都沒有…

2023年5月23日 星期二

出一張嘴寫程式的時代真的會來嗎?

古時候,有個字叫做人機介面,也就是人和機器溝通的通道。一直以來,人和機器的溝通是不直接的。

操作電腦,你得透過滑鼠、鍵盤、或觸控螢幕,而不是像你跟身邊其他人溝通時,可以透過對話和語言來進行。

這是一種阻礙,即便由來已久,即便你已經習慣,這仍是一種阻礙。
然而阻礙帶來了限制,但也帶來了機會。

所以開始有程式設計師這個行業,程式設計師把人們的需要,翻譯成電腦可以看得懂的程式碼,操控電腦來進行人們想實現的功能。自從電腦誕生以來,這個活兒就沒消失過。

上週,我去集英信誠和百敬老師聊天(其實是錄影),從ChatGPT談到哲學和宗教,中間有一個話題,我們談到了人機介面即將改變。在過去,開發人員必須得把輸入(input)變成結構化的資料,例如表單、欄位、這樣電腦才有機會能夠理解,從而進行處理和運算。

先不管ChatGPT輸出的正確性如何(如果你上完我們的課就知道,現階段根本不該期待一個生成式AI所產出的東西是正確的,它只是依照格式產生看起來像樣的內容,而非正確的內容,內容的正確性得靠你的加工),但這一波ChatGPT會造成轟動的潛在原因是,它似乎聽得懂你說的話,而這才是重點

Chat Bot幾年前早過炒過一波了,結果如何? 成功了嗎?
別問我,你自己說說你對現在哪一家銀行的AI助理或是聊天機器人滿意的? 幾乎沒有。而過去Siri能夠回應你的,也總是那麼幾個簡單的指令,複雜一點的對談,整個就不行了。

但這一波ChatGPT帶來的第一個驚訝,是你發現,它似乎還真聽得懂你說的話。
沒錯,ChatGPT從去年11月底問世到今天才半年,你跟它的溝通大致上不會讓你失望,對吧?

也就是說,ChatGPT對於自然語言的理解(NLU),好過市面上可以見到的大部分ChatBot。它能夠清楚地抓到你的intent和entities,並且對前後文的理解有很高的掌握度。

這也是我上周六在彰化小聚的時候,分享的重點之一。
ChatGPT對於ChatBot最大的價值是,這是有史以來第一次,NLU開始讓社會大眾滿意(相當高比例的可以接受),並且API成本還算是負擔的起。

ChatBot開發人員,終於有機會突破過去的制約,讓你的ChatBot有機會真的理解用戶在說些什麼(至少讓用戶這樣覺得),而且是透過自然語言,不用再去管傳統的表單輸入或結構化資料輸入了,這是人機介面上的一個突破。

知道用戶說的是什麼之後,接著就是與企業內部資訊系統做整合,這時,開發人員可以輕易地透過API,依照用戶的口語命令,查找或分析資料、請假或是建立表單、操控資訊系統、建立試算表、產生圖表、文件、投影片,甚至最後把資料摘要輸出給用戶(有必要時還可以再用ChatGPT的API來潤飾一下,讓輸出更像是人話。

我們在科幻片中看到的,人類透過自然語言命令電腦工作的場景,已經不會太遠了。

現在的GitHub Copilot、Office Copilot,說不定將會成為一個時代的里程碑,傳統的人機介面輸入方式,過去這幾十年間並不是沒有被挑戰過,從鍵盤、滑鼠、觸控螢幕,手勢操作…都曾經帶來機會和改變。而如今,真正的語音操控時代是否會來臨?

我充滿期待。

2023年5月8日 星期一

微服務(或API)的用戶身分驗證

最近不只一次被問到這個問題。

在應用程式(或前端展示層App)呼叫API(或微服務)的時候, 雖然都會有攜帶API KEY來驗證呼叫者(App)的身分,但若是要知道用戶的身分(就是誰操作這個App來呼叫API的?),又該怎麼辦呢?

一般來說,當我們討論微服務開發時,大多不一定會包含UI(套句Uncle Bob說的,UI是細節)。因此,在實作用戶端(End-User)的身分驗證時,往往只會做到UI(展示層)為止。但實務上,不管是多層式架構或是微服務架構,UI(展示層)又會需要呼叫微服務(或應用層API)來實現系統功能。

像是底下這樣:
圖片

但在UI呼叫微服務(應用層API)時,被呼叫端需要確認呼叫端(UI/展示層)具有呼叫微服務(或API)的權限,這一段,大多只會採用API KEY來驗證。

例如:

POST /APIName HTTP/1.1
Host: domain.com
Content-Type: application/json
ApiKey: 3126616e-c14b-4ba8-8617-d7349541ce40
Content-Length: 23

{"data" : "infomation"}

然而,若某些微服務(或API)運作時還需要得知用戶端身分,又會怎麼做呢?

簡單一點的作法,是直接透過JSON Body告知API當前用戶是誰(前提當然是API信任這個呼叫端),這樣既暴力又簡單,如果想更嚴謹一點,可以在Header攜帶先前用戶已經驗證過的Access Token/JWT Token來實現:

UserWeb App (UI)Microservices(API)登入(Cookies/JWT/OAuth)登入成功(保留User Token)...若不須用戶身分資訊...發送請求呼叫API (帶上API Key)(API確認呼叫者是哪個App)返回結果顯示結果...當需要用戶身分資訊...發送請求(帶上User Token)呼叫API (帶上API Key, User Token)(API確認呼叫者是哪個App, 哪位User)返回結果顯示結果UserWeb App (UI)Microservices(API)

但如此一來,微服務(或API)就必須具備解析Token的能力,或是再拿Token去問身分查驗的服務)。這樣不僅僅可以知道是哪個APP呼叫自己,也能得知是哪一個用戶操作這個APP來呼叫自己(上圖最底下的部分)。

總的來說,API KEY和User Token是兩個不同的機制(別搞混了),API KEY只用做用戶端對伺服器端的驗證,也就是呼叫者(這個APP或UI)的驗證,而OAuth Access Token或JWT Token則用作用戶端身分的驗證,兩者的目的並不相同。


相關教育訓練:
https://www.studyhost.tw/NewCourses/Architecture
https://www.studyhost.tw/NewCourses/aspnetcoreauth

若這篇文章對您有所幫助,請點選這裡加入FaceBook專頁按讚並追蹤,也歡迎您幫我們分享出去,謝謝您的支持。

單體式系統與微服務

最近重讀 Sam Newman的『建構微服務』,覺得實在精彩。真心以為,想作微服務系統的開發人員,都值得花點時間讀一下第一章,絕對值回票價。

我把讀完的感想和摘要寫在下面,希望能夠幫助大家釐清什麼是微服務(以及什麼不是)。

傳統來說,古典的單體式應用(Monolith)大多意指在同一個行程內運行的應用系統,底下是典型的單體式應用程式與其變形。

圖片

古典的單體應用程式

一個應用程式,後面搭配一套DB,但上面這樣的系統已經愈來愈少了,只剩下像是手機app或是極端傳統的desktop app。

如今大部分的單體式應用系統(不管是desktop或web),大多會是底下這樣:
圖片

模組化單體式應用程式
  1. 模組採用同樣(或近乎類似)的開發技術。
  2. 模組間有共用的基礎設施(infrastructure),像是log, security…etc.
  3. 即便模組可以獨立運行,但依舊必須一起佈署。

單體式應用系統的優點

相較於微服務,單體式應用系統其實有很多優點:

  1. 簡化開發人員工作流程
  2. 簡化監控、故障排除、與測試

這是事實,但Sam Newman強調『最近人們開始將單體式系統視為「時代遺產」的同義詞,仿佛這種系統有著什麼本質上的問題,是一個需要避免的東西…』

但其實,單體式架構只是一種選擇,甚至是一種有效的選擇。Sam Newman認為:『這是一個作為架構風格合理的預設選項(我欣賞這句話)』,換句話說,我也認為,面對架構選擇,人們應該尋找一個能被說服使用微服務的理由…

微服務架構

圖片

我們很久以前就談過微服務,但到底什麼是微服務?

Sam Newman在書中,對微服務的核心概念做了說明,我覺得包含幾個重點:

  • 可獨立佈署:微服務的每一個單元應該能夠單獨部署,而不需要依賴其他服務。這種可抽換性使得應用程式更加靈活,可以更快地部署和更容易地維護。這也意味著,當你抽換一個微服務、另一個微服務不該受到影響。
  • 圍繞著Business Domain塑模:每個微服務都應該圍繞一個具體的Business Domain來設計,而不是根據技術或企業組織架構來劃分。這種業務驅動的作法使得應用程序更加緊密地與業務相關,並能夠更好地支撐業務需求的變化。(這一點很多公司其實先天就無法做到,參考底下『架構和組織的調整』)
  • 大小:微服務應該要足夠小,以便能夠單獨佈署和管理。這也意味著每個微服務應該只關注一個特定的Business Domain,而不是試圖做太多的事情。
  • 擁有自己的狀態:每個微服務都應該擁有自己的狀態,包括自己的資料庫、Configration和State。這種狀態的獨立性使得微服務更加可靠,並能夠更好地處理高併發流量和分散式操作。這也表示,多個微服務不該共用同一個資料庫或資料表。如同物件導向程式設計的封裝概念,微服務應當可以自己決定如何與其他服務共享資料、或是隱藏資料。如此才能夠自由的變更修改服務內部的行為(而不影響其他單元)。
  • 架構和組織的調整(這一點很殺,幾乎沒收了台灣大部分有規模的企業進入微服務的入場券):傳統的三層式架構之所以會出現,除了它本身容易理解與簡單之外,還應驗了康威定律(Conway’s Law),也就是,系統的架構會自然相似於組織架構。請看這個傳統的架構:
    圖片

有沒有發現,上面每一層剛好是由不同的團隊負責的。這導致在許多大公司內,一個系統需要多個部門一起負責。

但在上面這個架構底下,當我們想要變更(或增加)一個功能時,就得動用到三個部門的人,而部門的設計所造成的Silo(穀倉效應),使得三個部門的人多半有著彼此不同的立場和目標,導致新功能的實現曠日廢時。

隨著敏捷開發與自組織概念的發展,現在軟體開發團隊逐漸採用混合型組織來設計。意即,每一個團隊直接對應到一個客戶的商業需求或服務,而非對應到一項企業內員工的專業技能:
圖片

DB、後端、前端、UIUX設計、業務商業人員…都被打散重組在一個團隊中(所謂的團隊,是擁有著共同的目標,或說的通俗一點,有共同KPI和考績的一群人)。這樣的一個混合型團隊中,會有各種不同技能的人員,以便於能夠好好地滿足客戶的一種服務需求。而我們的系統架構,也從傳統(以職能為區分)的三層式的架構,轉換成(以Business Domain為導向)的微服務系統設計。請注意這也意味著若微服務如前述的以Business Domain塑模,那企業的團隊結構就很可能會被打散重新調整,這樣的微服務才更有意義。

以上這些就是微服務的本質,也是切分服務邊界的重要思路。有沒有發現很多人卡關在哪裡?很多公司常常想要在不動組織架構和既定思維的狀況下,實踐敏捷或微服務,若是這樣,又何苦找自己麻煩呢?

微服務並不意味著比單體式應用程式更優秀,相反的,為了得到微服務所可能帶來的好處(像是獨立佈署、獨立運行、資訊隱藏、高延展性、技術異質性、企業組織對齊…等),必須附上許多代價,像是應用程式開發的複雜度就大大提升。

因此開發團隊必須認真找到你使用微服務的理由,正如同 Sam Newman說的:『…面對架構選擇,人們應該尋找一個能被說服使用微服務的理由,而非尋找一個不使用的理由。


相關教育訓練:
https://www.studyhost.tw/NewCourses/Architecture
https://www.studyhost.tw/NewCourses/aspnetcoreauth

若這篇文章對您有所幫助,請點選這裡加入FaceBook專頁按讚並追蹤,也歡迎您幫我們分享出去,謝謝您的支持。

熱門文章