<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>未分類 &#8211; acm&#039;s blog</title>
	<atom:link href="https://blog.acm.idv.tw/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.acm.idv.tw</link>
	<description>技術與生活隨筆</description>
	<lastBuildDate>Wed, 01 May 2024 12:25:29 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8</generator>

<image>
	<url>https://blog.acm.idv.tw/wp-content/uploads/2022/06/cropped-logo_kaffa9-3-32x32.png</url>
	<title>未分類 &#8211; acm&#039;s blog</title>
	<link>https://blog.acm.idv.tw</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>老電腦續命──AMD Ryzen 3 3200G上陣！</title>
		<link>https://blog.acm.idv.tw/2024/05/01/%e8%80%81%e9%9b%bb%e8%85%a6%e7%ba%8c%e5%91%bd%e2%94%80%e2%94%80amd-ryzen-3-3200g%e4%b8%8a%e9%99%a3%ef%bc%81/</link>
					<comments>https://blog.acm.idv.tw/2024/05/01/%e8%80%81%e9%9b%bb%e8%85%a6%e7%ba%8c%e5%91%bd%e2%94%80%e2%94%80amd-ryzen-3-3200g%e4%b8%8a%e9%99%a3%ef%bc%81/#respond</comments>
		
		<dc:creator><![CDATA[kaffa9]]></dc:creator>
		<pubDate>Wed, 01 May 2024 11:12:20 +0000</pubDate>
				<category><![CDATA[技術]]></category>
		<category><![CDATA[未分類]]></category>
		<category><![CDATA[硬體]]></category>
		<category><![CDATA[3200G]]></category>
		<category><![CDATA[AMD]]></category>
		<category><![CDATA[B450]]></category>
		<category><![CDATA[CPU-Z]]></category>
		<category><![CDATA[Gigabyte]]></category>
		<category><![CDATA[Intel]]></category>
		<category><![CDATA[LGA775]]></category>
		<category><![CDATA[Passmark]]></category>
		<category><![CDATA[Ryzen]]></category>
		<guid isPermaLink="false">https://blog.kaffa9.com/?p=822</guid>

					<description><![CDATA[家裡仍有幾部年齡十年以上的PC在服役中，其中一台是2008年自組的Intel 775平台，核心零組件是： CPU Intel Pentium Dual-Core...<p class="read-more"><a class="btn btn-default" href="https://blog.acm.idv.tw/2024/05/01/%e8%80%81%e9%9b%bb%e8%85%a6%e7%ba%8c%e5%91%bd%e2%94%80%e2%94%80amd-ryzen-3-3200g%e4%b8%8a%e9%99%a3%ef%bc%81/"> Read More<span class="screen-reader-text">  Read More</span></a></p>]]></description>
										<content:encoded><![CDATA[
<p>家裡仍有幾部年齡十年以上的PC在服役中，其中一台是2008年自組的Intel 775平台，核心零組件是：</p>



<figure class="wp-block-table"><table><tbody><tr><td>CPU</td><td>Intel Pentium Dual-Core E5200</td></tr><tr><td>Motherboard</td><td>ASUS P5QL-EM</td></tr><tr><td>Memory</td><td>G.Skill F2-6400CL4D-4GBHK (DDR2-800 2G*2)</td></tr><tr><td>VGA</td><td>MSI R4770 Cyclone</td></tr><tr><td>HDD</td><td>WD WD6400AAKS (640G Blue)</td></tr><tr><td>PSU</td><td>Seasonic S12 II 430W Bronze</td></tr></tbody></table><figcaption class="wp-element-caption">配備第1版</figcaption></figure>



<p>後來因為愈來愈跟不上時代，或是零件故障，也陸陸續續換過幾次零組件，但都沒有脫離Intel 775平台（P5QL-EM真能撐啊！）。</p>



<span id="more-822"></span>



<p>在本次換心手術前的規格是：</p>



<figure class="wp-block-table"><table><tbody><tr><td>CPU</td><td>Intel Core 2 Quad Q9400 (蝦皮二手零件)</td></tr><tr><td>Motherboard</td><td>ASUS P5QL-EM (耐用程度我給120分了！)</td></tr><tr><td>Memory</td><td>不知名品牌 DDR2-800 4G * 2 (原芝奇移到家人的舊PC上使用)</td></tr><tr><td>VGA</td><td>ASUS PH-GTX1050TI-4G NVIDIA 1050Ti (原4770疑似陣亡，三不五時就黑屏或無法開機)</td></tr><tr><td>SSD</td><td>Lite-On MU3 PH6L 240G SATA (系統碟由SSD取代)</td></tr><tr><td>HDD</td><td>#1: WD WD6400AAKS (640G Blue)<br>#2: Toshiba DT02 ABA400 (4TB)</td></tr><tr><td>PSU</td><td>全漢聖武士450W (原供應器曾一度被懷疑故障、供電輸出不足瓦，因此更換)</td></tr></tbody></table><figcaption class="wp-element-caption">配備第2版</figcaption></figure>



<p>雖然上述配備在2024年的今日，做做基本文書處理、看看影片都還過得去，但是其實效能（笑能？）也已經是捉襟見肘，所以一直醞釀著更換的想法。正巧上週末去台北順發時，發現順發AMD AM4的CPU和主機板都在打折（感覺是想出清，以Intel為主力了，光看款式與數量就輸Intel陣營一大截），最終用3,780元的價格帶走了技嘉B450M-K和Ryzen 3 3200G這個組合。</p>



<p>從Passmark跑分比較來看，兩次的換血，應該是非常有感，若從E5200跳到3200G來看，將近提升了8倍！</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="903" height="736" src="https://blog.kaffa9.com/wp-content/uploads/2024/05/passmark_3200G.png" alt="" class="wp-image-817" srcset="https://blog.acm.idv.tw/wp-content/uploads/2024/05/passmark_3200G.png 903w, https://blog.acm.idv.tw/wp-content/uploads/2024/05/passmark_3200G-300x245.png 300w, https://blog.acm.idv.tw/wp-content/uploads/2024/05/passmark_3200G-768x626.png 768w, https://blog.acm.idv.tw/wp-content/uploads/2024/05/passmark_3200G-331x270.png 331w" sizes="(max-width: 903px) 100vw, 903px" /></figure>



<p>下班後花了一點時間，完成換血。</p>



<figure class="wp-block-image size-large"><img decoding="async" width="577" height="1024" src="https://blog.kaffa9.com/wp-content/uploads/2024/05/1557353-577x1024.jpg" alt="" class="wp-image-819" srcset="https://blog.acm.idv.tw/wp-content/uploads/2024/05/1557353-577x1024.jpg 577w, https://blog.acm.idv.tw/wp-content/uploads/2024/05/1557353-169x300.jpg 169w, https://blog.acm.idv.tw/wp-content/uploads/2024/05/1557353-768x1363.jpg 768w, https://blog.acm.idv.tw/wp-content/uploads/2024/05/1557353-865x1536.jpg 865w, https://blog.acm.idv.tw/wp-content/uploads/2024/05/1557353-152x270.jpg 152w, https://blog.acm.idv.tw/wp-content/uploads/2024/05/1557353.jpg 960w" sizes="(max-width: 577px) 100vw, 577px" /></figure>



<p>最新配備清單：</p>



<figure class="wp-block-table"><table><tbody><tr><td>CPU</td><td>AMD Ryzen 3 3200G 4C4T</td></tr><tr><td>Motherboard</td><td>Gigabyte B450M-K</td></tr><tr><td>Memory</td><td>#1: Team ELITE DDR4-3200 16G 美光顆粒<br>#2: Team ELITE DDR3-3200 16G SpecTek顆粒</td></tr><tr><td>VGA</td><td>使用內顯 Radeon Vega 8</td></tr><tr><td>SSD</td><td>Lite-On MU3 PH6L 240G SATA</td></tr><tr><td>HDD</td><td>#1: WD WD6400AAKS (640G Blue)<br>#2: Toshiba DT02 ABA400 (4TB)</td></tr><tr><td>PSU</td><td>全漢聖武士450W</td></tr></tbody></table><figcaption class="wp-element-caption">配備最終版</figcaption></figure>



<p>原本執行EndeavourOS (Arch Linux系)，試用了下沒問題，也不用額外安裝驅動，為了做完整測試，重新安裝成Windows 11專業版，以下是工作管理員和CPU-Z執行畫面。</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img decoding="async" width="1025" height="698" data-id="815" src="https://blog.kaffa9.com/wp-content/uploads/2024/05/工作管理員.png" alt="" class="wp-image-815" srcset="https://blog.acm.idv.tw/wp-content/uploads/2024/05/工作管理員.png 1025w, https://blog.acm.idv.tw/wp-content/uploads/2024/05/工作管理員-300x204.png 300w, https://blog.acm.idv.tw/wp-content/uploads/2024/05/工作管理員-768x523.png 768w, https://blog.acm.idv.tw/wp-content/uploads/2024/05/工作管理員-396x270.png 396w" sizes="(max-width: 1025px) 100vw, 1025px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="419" height="402" data-id="816" src="https://blog.kaffa9.com/wp-content/uploads/2024/05/CPUZ.png" alt="" class="wp-image-816" srcset="https://blog.acm.idv.tw/wp-content/uploads/2024/05/CPUZ.png 419w, https://blog.acm.idv.tw/wp-content/uploads/2024/05/CPUZ-300x288.png 300w, https://blog.acm.idv.tw/wp-content/uploads/2024/05/CPUZ-281x270.png 281w" sizes="auto, (max-width: 419px) 100vw, 419px" /></figure>
</figure>



<p>做了許多日常操作測試，觀看YouTube、Netflix、巴哈姆特動畫瘋影片都沒有什麼大問題，大概只有遊戲沒有測過了，也許再找機會跑個原神試試？<img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.acm.idv.tw/2024/05/01/%e8%80%81%e9%9b%bb%e8%85%a6%e7%ba%8c%e5%91%bd%e2%94%80%e2%94%80amd-ryzen-3-3200g%e4%b8%8a%e9%99%a3%ef%bc%81/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>mosquitto-go-auth編譯與使用</title>
		<link>https://blog.acm.idv.tw/2022/08/14/mosquitto-go-auth%e7%b7%a8%e8%ad%af%e8%88%87%e4%bd%bf%e7%94%a8/</link>
					<comments>https://blog.acm.idv.tw/2022/08/14/mosquitto-go-auth%e7%b7%a8%e8%ad%af%e8%88%87%e4%bd%bf%e7%94%a8/#respond</comments>
		
		<dc:creator><![CDATA[kaffa9]]></dc:creator>
		<pubDate>Sun, 14 Aug 2022 03:11:35 +0000</pubDate>
				<category><![CDATA[技術]]></category>
		<category><![CDATA[未分類]]></category>
		<category><![CDATA[go]]></category>
		<category><![CDATA[mosquitto]]></category>
		<category><![CDATA[mqtt]]></category>
		<guid isPermaLink="false">https://kaffa9.com/?p=606</guid>

					<description><![CDATA[mosquitto是一個受歡迎的輕量MQTT broker，雖然本身具備了pwfile、aclfile等使用者驗證機制，但使用者數增加、或是使用情境較複雜一點的...<p class="read-more"><a class="btn btn-default" href="https://blog.acm.idv.tw/2022/08/14/mosquitto-go-auth%e7%b7%a8%e8%ad%af%e8%88%87%e4%bd%bf%e7%94%a8/"> Read More<span class="screen-reader-text">  Read More</span></a></p>]]></description>
										<content:encoded><![CDATA[
<p>mosquitto是一個受歡迎的輕量MQTT broker，雖然本身具備了pwfile、aclfile等使用者驗證機制，但使用者數增加、或是使用情境較複雜一點的時候，用起來就沒有那麼彈性了，而且修改完pwfile、aclfile還需要重啟服務，如果服務不適合中斷，那可就尷尬了。</p>



<p>為了做更有彈性的使用者驗證管理，有些人會考慮自行修改mosquitto原始碼（畢竟mosquitto是開源軟體），或者是另外撰寫mosquitto plug-in來處理驗證這一塊（是的！mosquitto有plug-in interface），例如jpmens的mosquitto-auth-plugin，就是一個廣受觀迎的mosquitto驗證plug-in，在Github上的fork數甚至達到487！不過這有一部份原因應該是原作者在2018年底就不再繼續維護此專案，大家有issue或是新需求就fork出來各自努力。<img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f625.png" alt="😥" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>不過別難過得太早，早在2017年開始，iegomez便開始了一個新的mosquitto驗證plug-in專案，稱為mosquitto-go-auth，也就是本文要介紹的軟體。</p>



<span id="more-606"></span>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">簡介</h2>



<p>根據mosquitto-go-auth專案的README.md所述，這個專案主要是受到jpmens的mosquitto-auth-plug專案啟發，採用Go語言開發，並利用cgo曝露出符合mosquitto plug-in規範的連結介面，供mosquitto與此plug-in動態連結。</p>



<p>mosquitto-go-auth主要具備以下幾個優點（個人看法）：</p>



<ul class="wp-block-list"><li>使用Go開發，擴充、改寫、編譯皆比原本以C撰寫來得方便</li><li>原mosquitto-auth-plug支援的backend皆有支援（如：Redis、MySQL、JWT、HTTP、……等），甚至更完善</li><li>與最新版的Mosquitto 2.0相容</li><li>持續維護中！</li></ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">編譯</h2>



<p>要編譯mosquitto-go-auth專案，需準備以下項目：</p>



<ul class="wp-block-list"><li>Go工具包（建議直接用最新版，本文撰寫之時為1.19）</li><li>mosquitto原始碼</li><li>mosquitto-go-auth原始碼</li></ul>



<p>工作目錄如下：</p>



<ul class="wp-block-list"><li>Go: /home/kaffa9/ws/go1.19</li><li>mosquitto: /home/kaffa9/ws/mosquitto</li><li>mosquitto-go-auth: /home/kaffa9/ws/mosquitto-go-auth</li><li>測試目錄: /home/kaffa9/ws/mosquitto-test</li></ul>



<p>在mosquitto-go-auth工作目錄下，先以編輯器開啟Makefile：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">CFLAGS := -I/usr/local/include -fPIC
LDFLAGS := -shared

UNAME_S := $(shell uname -s)

ifeq ($(UNAME_S),Darwin)
	LDFLAGS += -undefined dynamic_lookup
endif

all:
	@echo "Bulding for $(UNAME_S)"
	env CGO_CFLAGS="$(CFLAGS)" go build -buildmode=c-archive go-auth.go
	env CGO_LDFLAGS="$(LDFLAGS)" go build -buildmode=c-shared -o go-auth.so
	go build pw-gen/pw.go

test:
	cd plugin &amp;&amp; make
	go test ./backends ./cache ./hashing -v -count=1
	rm plugin/*.so

test-backends:
	cd plugin &amp;&amp; make
	go test ./backends -v -failfast -count=1
	rm plugin/*.so

test-cache:
	go test ./cache -v -failfast -count=1

test-hashing:
	go test ./hashing -v -failfast -count=1

service:
	@echo "Generating gRPC code from .proto files"
	@go generate grpc/grpc.go

clean:
	rm -f go-auth.h
	rm -f go-auth.so
	rm -f pw</pre>



<p>進行以下修改：</p>



<ul class="wp-block-list"><li>在第1行加上mosquitto標頭檔的路徑：-I../mosquitto/src -I../mosquitto/lib</li><li>在第12行加上CGO_LDFLAGS=&#8221;$(LDFLAGS)&#8221;</li><li>在第13行加上CGO_CFLAGS=&#8221;$(CFLAGS)&#8221;</li></ul>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">CFLAGS := -I/usr/local/include -I../mosquitto/src -I../mosquitto/lib -fPIC
LDFLAGS := -shared

UNAME_S := $(shell uname -s)

ifeq ($(UNAME_S),Darwin)
	LDFLAGS += -undefined dynamic_lookup
endif

all:
	@echo "Bulding for $(UNAME_S)"
	env CGO_CFLAGS="$(CFLAGS)" CGO_LDFLAGS="$(LDFLAGS)" go build -buildmode=c-archive go-auth.go
	env CGO_CFLAGS="$(CFLAGS)" CGO_LDFLAGS="$(LDFLAGS)" go build -buildmode=c-shared -o go-auth.so
	go build pw-gen/pw.go

test:
	cd plugin &amp;&amp; make
	go test ./backends ./cache ./hashing -v -count=1
	rm plugin/*.so

test-backends:
	cd plugin &amp;&amp; make
	go test ./backends -v -failfast -count=1
	rm plugin/*.so

test-cache:
	go test ./cache -v -failfast -count=1

test-hashing:
	go test ./hashing -v -failfast -count=1

service:
	@echo "Generating gRPC code from .proto files"
	@go generate grpc/grpc.go

clean:
	rm -f go-auth.h
	rm -f go-auth.so
	rm -f pw</pre>



<p>如此一下，Go編譯時才找得到相依的mosquitto標頭檔。</p>



<p>設定一下Go工具路徑：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">export PATH=/home/kaffa9/ws/go1.19/bin:$PATH</pre>



<p>就可以開始編譯囉！</p>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">make</pre>



<p>編譯完成後，可得以下檔案：</p>



<ul class="wp-block-list"><li>go-auth.so : plug-in</li><li>pw : 密碼工具</li></ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">設定與運行（以Redis為例）</h2>



<p>首先將mosquitto執行檔以及go-auth.so複製到測試目錄（/home/kaffa9/ws/mosquitto-test）中。</p>



<p>要讓plug-in順利運行，必須在mosquitto.conf中進行設定，以下為參考設定值：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">listener 1883

auth_plugin /home/kaffa9/ws/mosquitto-test/go-auth.so
auth_opt_backends redis
auth_opt_hasher pbkdf2                 # password hashing type
auth_opt_hasher_salt_size 16           # salt bytes length
auth_opt_hasher_iterations 100000      # number of iterations
auth_opt_hasher_keylen 64              # key length
auth_opt_hasher_algorithm sha512       # hashing algorithm, either sha512 (default) or sha256
auth_opt_hasher_salt_encoding base64   # salt encoding, either base64 (default) or utf-8
auth_opt_redis_host localhost
auth_opt_redis_port 6379
auth_opt_redis_db 1
auth_opt_redis_password myPa55w0rd
auth_opt_redis_disable_superuser true</pre>



<p>我們將mosquitto運行在port 1883，指定驗證plug-in路徑，並額外進行以下設定：</p>



<ul class="wp-block-list"><li>auth_opt_backends : 指定使用redis</li><li>auth_opt_hasher : 指定密碼採用pbkdf2格式</li><li>auth_opt_hasher_salt_size : 指定salt長度為16</li><li>auth_opt_hasher_iterations : 指定PBKDF2迭代次數為100000</li><li>auth_opt_hasher_keylen : 指定金鑰長度為64</li><li>auth_opt_hasher_algorithm : 指定HMAC雜湊演算法為sha512</li><li>auth_opt_hasher_salt_encoding : 指定salt儲存格式為base64</li><li>auth_opt_redis_host : Redis連線位址</li><li>auth_opt_redis_port : Redis連線port</li><li>auth_opt_redis_db : Redis資料庫編號</li><li>auth_opt_redis_password : Redis密碼</li><li>auth_opt_redis_disable_superuser : 是否停用superuser功能</li></ul>



<p>接下來可以使用pw工具為使用者，依照mosquitto.conf裡設定的條件（salt_size、iterations、keylen、……）產生密碼，這裡我們產生foo123和bar123，共2組密碼，待會兒給foo和bar這2個帳號使用：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">$ ./pw -a sha512 -e base64 -h pbkdf2 -i 100000 -l 64 -s 16 -p foo123
PBKDF2$sha512$100000$9Ey+5BSIyYJCTnNFJm7NPA==$S7BZ8loLtIergIybLQbOf45iJsubksB10VHAnBkZ93/FyfS9nXuYH34Rv2mIhC8sVg24jzjs+fwg9IayGNSr7g==
$ ./pw -a sha512 -e base64 -h pbkdf2 -i 100000 -l 64 -s 16 -p bar123
PBKDF2$sha512$100000$Yd+W79o4NRrvl+c5uiYceA==$Op/YJbn0xs7nd9tFZ9Eumstj/HBn4A+nJydYEsScucko1rdDXJOIy83lV2CbiZNXfTWPFgtG2gv1ju0M/TI0TQ==</pre>



<p>然後將帳號密碼的對應關係寫入Redis中（以下在redis-cli中操作）：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">選擇使用資料庫1
127.0.0.1:6379> SELECT 1

新增foo
127.0.0.1:6379[1]> SET foo PBKDF2$sha512$100000$9Ey+5BSIyYJCTnNFJm7NPA==$S7BZ8loLtIergIybLQbOf45iJsubksB10VHAnBkZ93/FyfS9nXuYH34Rv2mIhC8sVg24jzjs+fwg9IayGNSr7g==
OK

新增bar
127.0.01:6379[1]> SET bar PBKDF2$sha512$100000$Yd+W79o4NRrvl+c5uiYceA==$Op/YJbn0xs7nd9tFZ9Eumstj/HBn4A+nJydYEsScucko1rdDXJOIy83lV2CbiZNXfTWPFgtG2gv1ju0M/TI0TQ==
OK</pre>



<p>接著設定ACL：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">設定ACL (subscribe)
127.0.0.1:6379[1]> SADD foo:sacls "mailbox/foo/#"
OK

設定ACL (read)
127.0.0.1:6379[1]> SADD foo:racls "mailbox/foo/#"
OK

設定ACL (write)
127.0.0.1:6379[1]> SADD foo:wacls "mailbox/foo/#"
OK

設定ACL (readwrite)
127.0.0.1:6379[1]> SADD foo:rwacls "mailbox/foo/#"
OK

//bar的部份如法泡製</pre>



<p>接著讓mosquitto正式上場：</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">./mosquitto -c ./mosquitto.conf
1660441737: mosquitto version 2.0.14 starting
1660441737: Config loaded from ./mosquitto.conf.
1660441737: Loading plugin: /home/kaffa9/ws/mosquitto-test/go-auth.so
1660441737:  ├── Username/password checking enabled.
1660441737:  ├── TLS-PSK checking enabled.
1660441737:  └── Extended authentication not enabled.
INFO[2022-08-14T01:48:57Z] Backend registered: Redis
INFO[2022-08-14T01:48:57Z] registered acl checker: redis
INFO[2022-08-14T01:48:57Z] registered user checker: redis
INFO[2022-08-14T01:48:57Z] registered superuser checker: redis
INFO[2022-08-14T01:48:57Z] No cache set.
1660441737: Opening ipv4 listen socket on port 1883.
1660441737: Opening ipv6 listen socket on port 1883.
1660441737: mosquitto version 2.0.14 running</pre>



<p>之後就可以使用MQTT client來測試看看啦！</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">給「原mosquitto-auth-plug使用者」注意事項</h2>



<p>原mosquitto-auth-plug密碼格式只支援PBKDF2，但使用時不需特別指定salt和key長度，mosquitto-auth-plug驗證時會檢查interation數以及salt、key長度，自動往回推算（如下列C程式碼，第11行tokenize取出PDFBK2密碼hash的各部位，第19行計算key長度、第39行計算salt長度）。</p>



<pre class="EnlighterJSRAW" data-enlighter-language="c" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">int pbkdf2_check(char *password, char *hash)
{
	char *sha, *salt, *h_pw;
	int iterations, saltlen, blen;
	char *b64, *keybuf;
	unsigned char *out;
	int match = FALSE;
	const EVP_MD *evpmd;
	int keylen, rc;

	if (detoken(hash, &amp;sha, &amp;iterations, &amp;salt, &amp;h_pw) != 0)
		return match;

	/* Determine key length by decoding base64 */
	if ((keybuf = malloc(strlen(h_pw) + 1)) == NULL) {
		fprintf(stderr, "Out of memory\n");
		return FALSE;
	}
	keylen = base64_decode(h_pw, keybuf);
	if (keylen &lt; 1) {
		free(keybuf);
		return (FALSE);
	}
	free(keybuf);

	if ((out = malloc(keylen)) == NULL) {
		fprintf(stderr, "Cannot allocate out; out of memory\n");
		return (FALSE);
	}

#ifdef RAW_SALT
	char *rawSalt;

	if ((rawSalt = malloc(strlen(salt) + 1)) == NULL) {
		fprintf(stderr, "Out of memory\n");
		return FALSE;
	}

	saltlen = base64_decode(salt, rawSalt);
	if (saltlen &lt; 1) {
		return (FALSE);
	}

	free(salt);
	salt = rawSalt;
	rawSalt = NULL;
#else
	saltlen = strlen((char *)salt);
#endif

#ifdef PWDEBUG
	fprintf(stderr, "sha        =[%s]\n", sha);
	fprintf(stderr, "iterations =%d\n", iterations);
	fprintf(stderr, "salt       =[%s]\n", salt);
	fprintf(stderr, "salt len   =[%d]\n", saltlen);
	fprintf(stderr, "h_pw       =[%s]\n", h_pw);
	fprintf(stderr, "kenlen     =[%d]\n", keylen);
#endif


	evpmd = EVP_sha256();
	if (strcmp(sha, "sha1") == 0) {
		evpmd = EVP_sha1();
	} else if (strcmp(sha, "sha512") == 0) {
		evpmd = EVP_sha512();
	}

	rc = PKCS5_PBKDF2_HMAC(password, strlen(password),
		(unsigned char *)salt, saltlen,
		iterations,
		evpmd, keylen, out);
	if (rc != 1) {
		goto out;
	}

	blen = base64_encode(out, keylen, &amp;b64);
	if (blen > 0) {
		int i, diff = 0, hlen = strlen(h_pw);
#ifdef PWDEBUG
		fprintf(stderr, "HMAC b64   =[%s]\n", b64);
#endif

		/* "manual" strcmp() to ensure constant time */
		for (i = 0; (i &lt; blen) &amp;&amp; (i &lt; hlen); i++) {
			diff |= h_pw[i] ^ b64[i];
		}

		match = diff == 0;
		if (hlen != blen)
			match = 0;

		free(b64);
	}

  out:
	free(sha);
	free(salt);
	free(h_pw);
	free(out);

	return match;
}</pre>



<p>然而<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">在mosquitto-go-auth中，會發現雖然要求在mosquitto.conf中指定hmac演算法、iteration、salt len、keylen</mark>，但經過trace原始碼發現，目前仍是仿照mosquitto-auth-plug，由取得的hash做tokenize，分別得到HMAC演算法、iteration、salt len、keylen等值後，再將客戶端的明文密碼進行PBKDF2計算。至於日後會不會改變？（也許不會吧）這是要特別注意的地方。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">參考資源</h2>



<ol class="wp-block-list"><li>Eclipsea Mosquitto &#8211; <a rel="noreferrer noopener" href="https://github.com/eclipse/mosquitto" target="_blank">https://github.com/eclipse/mosquitto</a></li><li>mosquitto-auth-plugin &#8211; <a rel="noreferrer noopener" href="https://github.com/jpmens/mosquitto-auth-plug" target="_blank">https://github.com/jpmens/mosquitto-auth-plug</a></li><li>mosquitto-go-auth &#8211; <a href="https://github.com/iegomez/mosquitto-go-auth" target="_blank" rel="noreferrer noopener">https://github.com/iegomez/mosquitto-go-auth</a></li></ol>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.acm.idv.tw/2022/08/14/mosquitto-go-auth%e7%b7%a8%e8%ad%af%e8%88%87%e4%bd%bf%e7%94%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
