openssl heartbleed

有用到openssl 需要注意他的漏洞更新,這邊提到的是大約2014年中的一個重大漏洞,屬於implementation flaw,同年的還有ShellShock和POODLE。作為許多軟體的底層元件,在當時影響的層面相當廣泛(參考: https://en.wikipedia.org/wiki/Heartbleed)

https://blog.cloudflare.com/answering-the-critical-question-can-you-get-private-ssl-keys-using-heartbleed/
這篇主要描述了openssl heartbleed bug(CVE-2014-0160),主要是利用heartbeat會response echo傳來的訊息,而在程式中沒有做message size boundary check

而依賴在protocol中由client提供的16bits length (存在payload變數), hbtype為message type,因為是16bits 所以最多可以echo 64kb的資料,因此可以從response拿到一些存在heap記憶體的資料,透過大量的request一直malloc free,其中可能可以拿到之前request帶的敏感資訊而進一步攻擊

有問題的點在上面的memcpy 將p1的內容複製到bp,共payload個bytes,而payload又是直接讀取content轉出來 n2a(p, payload) 那一行

測試可參考
https://github.com/mpgn/heartbleed-PoC
openssl影響的版本為1.0.1~1.01f,實際拿apache + openssl 1.0.1c來測試就會發現能夠dump server side的記憶體內容

Posted in General | Leave a comment

docker install on CentOS 6.9

在epel-repo有帶1.7的docker

yum -y install epel-release
yum -y install docker-io
#升級成1.9.1 參考 https://www.jianshu.com/p/31248c006c06
curl -sSL -O https://get.docker.com/builds/Linux/x86_64/docker-1.9.1
chmod +x docker-1.9.1
mv /usr/bin/docker /usr/bin/docker-1.7
cp ./docker-1.9.1 /usr/bin/docker

docker pull centos:6.9

有問題 先關掉service

service stop docker

#看起來是必須升級kernel
rpm –import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm 
yum –enablerepo=elrepo-kernel install kernel-lt -y

另外在CentOS 6.5實際測試,docker 1.7不能執行,主要原因是

relocation error: docker-1.7: symbol dm_task_get_info_with_deferred_remove, version Base not defined in file libdevmapper.so.1.02 with link time reference 需要將libdevmapper更新: yum upgrade device-mapper-libs 

修改/etc/grub.conf 更改default

reboot

https://docs.docker.com/engine/breaking_changes/#engine-110

Posted in System Administration | Leave a comment

bash exclamation (!)

在bash處理有帶!的字串要注意他本身有其他功用(history expansion),作為字串夾在double quote時

https://www.gnu.org/software/bash/manual/bashref.html#Double-Quotes

Enclosing characters in double quotes (‘"’) preserves the literal value of all characters within the quotes, with the exception of ‘$’, ‘`’, ‘\’, and, when history expansion is enabled, ‘!’.

要注意的是escape !不可用 \ backslash
\! 會是 \! 而不是!

The backslash preceding the ‘!’ is not removed.

用 single quote ‘!’ 可以解決此問題
echo “123”‘!’

3.1.2.2 Single Quotes
Enclosing characters in single quotes (‘'’) preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.

Posted in System Administration | Leave a comment

semaphore整理

In computer science, a semaphore is a variable or abstract data type used to control access to a common resource by multiple processes in a concurrent system such as a multitasking operating system. (In computer science, a semaphore is a variable or abstract data type used to control access to a common resource by multiple processes in a concurrent system such as a multitasking operating system. (Wikipedia)

semaphore機制主要是用來控制有限個數的resource存取問題,

例如洗手間有3間,可是同時間有十個人要使用,

這時候就會需要synchronization(一間洗手間同一個時間只能有一個人使用,同時最多三個人使用)

大家排隊依序使用-> FIFO

semaphore S本身是一個變數(waiting count/available resource count),只能透過P(wait)和V(signal)來操作,

S <= 0 代表waiting count,全部resource使用中

S > 0 代表閒置的resource count

P: get or wait for resource, decrement S, wait(after decrement, if S<0)
V: 來自Dutch verhogen(increase), release the resource, increment S, notify waiting(before increment, if S<0, 代表increment之前有等待)

binary semaphore (count = 1) 例如一條鐵軌區段只能有一輛火車在上面運行,和mutex非常相似,其中差異在 semaphore不限定同一個thread可以解除資源鎖定,而mutex通常要求lock unlock在同一個thread。

這樣的特性使得semaphore有signaling的功能,有文章分類成locking semaphoresignaling semaphore,locking semaphore加鎖P和釋放V在同一個thread ( http://nuttx.org/doku.php?id=wiki:howtos:signalling-semaphores )。對比的話,locking semaphore – mutex, signaling semaphore – condition variable

另外一個須注意的地方是在priorty-based scheduling下,semaphore可能會造成priority inversion(對於需要鎖定資源的synchronization primitive都會遇到同樣的問題),其中一種解法是priority inheritance(對於mutex, locking semaphore)

semaphore的API在POSIX.1b有定義(sem_ 開頭,不在pthreads中)

其他: 參考 https://en.wikipedia.org/wiki/Semaphore_(programming)

producer-consumer problem:
producer – queue – consumer
需用到三個semaphore
一個用來通知producer queue有位置可以放東西
一個用來通知consumer queue有東西可以取
一個binary semaphore用來鎖定queue的存取

2021.2.20 補充

在linux kernel 2.6.39裡的semaphore實作,他的semaphore count總是 >=0的,跟上面的PV計算方式不同(上面的count < 0代表有等待),linux kernel是用 count + wait_list 來判斷

void down(struct semaphore *sem)
{
  unsigned long flags;

  spin_lock_irqsave(&sem->lock, flags);
  if (likely(sem->count > 0))
    sem->count--;
  else
    __down(sem);
  spin_unlock_irqrestore(&sem->lock, flags);
}
void up(struct semaphore *sem)
{
  unsigned long flags;

  spin_lock_irqsave(&sem->lock, flags);
  if (likely(list_empty(&sem->wait_list)))
    sem->count++;
  else
    __up(sem);
  spin_unlock_irqrestore(&sem->lock, flags);
}
Posted in General | Leave a comment

regex lib

在使用c++11 regex時,需要注意在gcc 4.9.0前 regex的實作是c++0x的
特別是CentOS預設的gcc版本是4.8.5,此時可改用boost::regex
使用以下

#include <regex>
int main()
{
  std::regex reg_decimal("((\\+|-)?[[:digit:]]+)(\\.(([[:digit:]]+)?))?((e|E)((\\+|-)?)[[:digit:]]+)?");
  return 0; 
}

參考: https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions

Posted in C++ Language | Leave a comment

windows elevate UAC

在windows csharp的程式中,如果要一開始限定執行為administrator系統管理權限,可以在manifest檔註記
參考 https://stackoverflow.com/questions/2818179/how-do-i-force-my-net-application-to-run-as-administrator

 <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> 

或是用程式強制重新起始為系統管理權限(放在Main起始處)
參考 https://itneverworksfirsttime.wordpress.com/2012/02/27/using-uac-to-request-administrative-privileges-from-c/

WindowsPrincipal pricipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
bool hasAdministrativeRight = pricipal.IsInRole(WindowsBuiltInRole.Administrator);
if (!hasAdministrativeRight) 
{ // relaunch the application with admin rights 
  string fileName = System.Reflection.Assembly.GetExecutingAssembly().Location;
  ProcessStartInfo processInfo = new ProcessStartInfo();
  processInfo.Verb = "runas";
  processInfo.FileName = fileName;
  try {
     Process.Start(processInfo); 
  }
  catch (System.ComponentModel.Win32Exception) 
  { // This will be thrown if the user cancels the prompt 
  }
  return; 
}

另外實測時,如果是32bit程式,在某些情況會被windows7判定為安裝程式而跳出”This program might not have installed correctly”
https://docs.microsoft.com/en-us/windows/desktop/SbsCs/application-manifests
可用manifest繞過Program Compatibility Assistant(PCA)
https://support.microsoft.com/en-my/help/2545347/excluding-programs-from-the-program-compatibility-assistant-pca

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows Vista and Windows Server 2008 --> 
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Windows 7 and Windows Server 2008 R2 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 and Windows Server 2012 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 8.1 and Windows Server 2012 R2 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
Posted in System Administration | Leave a comment

exit process with delay

在nodejs中處理error發生要結束process時,可使用process.exit,但注意process.exit會立即返回
特別是當要寫error log時,有可能還沒寫完就結束process了。
這種情況可以利用timer來控制
這裡節錄stackoverflow上的一個解法

Exit Node.js process after event loop is empty OR after timeout

以下節錄

function exit() {
  var t = setTimeout(function() {
    process.exit(1);
  }, 10000);
  // allow process to exist naturally before the timer if it is ready to
  t.unref();
}

如果時間到 event loop不為空,仍然會執行process.exit,中斷未完成的task。
當然這邊會有其他的問題,因為通常發生異常必須結束時,會希望取消其他進行中的async task,單純記上error log,但許多async api並沒有取消的方式。

Posted in nodejs | Leave a comment

expressjs send file

在 expressjs傳送檔案可以直接使用res.sendFile或是開啟readable stream再pipe到res

fs.createReadStream(fpath).pipe(res)

但在某些情況(例如video播放)這樣的方式太陽春,沒辦法seek (http byte range request)

特別是例如iOS safari browser在播放mp4影片時,會要求伺服器支援byte range request,不然不會播放。
Safari Web Content Guide#Configuring Your Server

HTTP servers hosting media files for iOS must support byte-range requests, which iOS uses to perform random access in media playback. (Byte-range support is also known as content-range or partial-range support.)

事實上,nodejs有一個send module(被serve-static引用)可以很方便處理這樣的情況。

send(req, fpath).pipe(res)

就能讓檔案傳送支援range request了!

Posted in nodejs | Leave a comment

remote deploy with ssh

遠端佈署時,常常更新完檔案要重新啟動服務,使用ssh execute remote command 可以整合在script方便automation

ssh $HOST COMMAND
ssh $HOST COMMAND1; COMMAND2; …

scp SCRIPT.sh $HOST:
ssh $HOST SCRIPT.sh #將多個command 放在script

以上使用SSH Key-Based Authentication的方式驗證

Posted in System Administration | Leave a comment

moment.js

在js的程式哩,對於時間格式處理解析與驗證可以使用momentjs,
下面簡要整理

  1. 處理不同版本js的Date對於字串解析的不一致 var a = new Date(‘2016-01-01’); ES5(解成UTC), ES2015(解成local time)
  2. mutable: t.add(1, ‘days’) 這樣會直接影響到t,如果要重複操作時 t.clone().add(1, ‘days’), value可為負數
  3. 避免在操作 add傳入小數點
  4. 處理timezone相關問題時要注意DST, daylight saving time
  5. 儘量使用.format(…)顯示描述轉成字串的格式
  6. moment.utc(), moment().utc() 可以理解成目前是UTC timezone
  7. moment距離 x.diff(y) => x減去y 回傳 milliseconds
  8. moment.duration(milliseconds number) 再用 asDays()等的function轉單位

解析時間:

moment()
moment(Date)
moment(unix ms)
moment.unix(unix secs)
moment(字串str) //解析: 檢查ISO 8601 -> 檢查rfc 2822 -> new Date(str)
moment(str, format)
moment(str, format, strict)

產生字串 moment().format(…)

moment.utc().format(‘ddd, DD MMM YYYY HH:mm:ss [GMT]’); //rfc 2822
moment().toISOString() //=> “2018-10-11T03:44:53.612Z”

轉成其他物件或格式

moment().valueOf(); // (get unix ms), moment().unix(); (get unix secs)
moment().toDate(); //(get js Date)
moment().toArray(); // => [2018, 9, 11, 11, 44, 10, 780]
moment().toObject();

{ //moment.toObject()
  date: 11,
  hours: 11,
  milliseconds: 948,
  minutes: 45,
  months: 9,
  seconds: 26,
  years: 2018,
}

format驗證

moment().isValid();

註: 時間有關rfc: rfc 2822, 3339

Posted in nodejs | Leave a comment