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

2018年1月20日 星期六

AWS 筆記 - 使用 Ubuntu server 更換 Windows server 2012 帳號狀態

AWS Windows server

公司在三年前在 AWS Beijing 開了一台 Windows server 2012 運行一些套裝軟體,然而,負責的 IT 在整理系統帳號時,把 guest 關閉了。接著發生很多奇妙事件,最恐怖的是機器無法遠端登入了 Orz

一開始想朝更換 Administrator 密碼試試,結果一看過程步驟也不少:
使用 EC2Config 重置 Windows 管理员密码 -
https://docs.aws.amazon.com/zh_cn/AWSEC2/latest/WindowsGuide/ResettingAdminPassword_EC2Config.html
接著,反而朝惡搞的方式進去研究,例如:如何修改機碼啟用 guest 帳號


最後,使用了前一份(一年前版本)的全系統備份,開了一台機器,把他的 C:/Windows/System32/config/SAM 複製出來,覆蓋掉無法登入的機器上,如此一來就搞定了!

情況簡介:
A server: 壞掉的 Windows server 2012
B server: 從 A server 現狀建置 AMI 而開啟的機器
C server: 前一版次備份的 Windows server
D server: Ubuntu 14.04 server
A 計畫:
將 B server 的 C 槽卸下,並掛到 C server 上進行 B server 的 C槽 資料修改,改完後再卸下,重裝到 B server,把 B server 重新啟動,看看是否正常

然而,A 計劃失敗了,在 AWS console 可以看到系統無法正常通過檢驗,於是啟動了 B 計畫

B 計畫:
再次建置乾淨的 B server,將 B server 的 C 槽卸下,也把 C server - C 槽卸下,並一起掛到 D server 上,拿著 C server - C 槽關鍵資訊,直接覆蓋掉 B server - C 槽 資料,修改完後再卸下,重裝到 B server,再把 B server 重新啟動
果真 B 計劃成功了 :p 猜測 A方案 可能因為修改的是 Windows OS level 資訊,修改完可能也改變了 B server - C 槽狀態,以至於重新啟用時反而資訊對不上而無法開機。

AWS Windows server

其他筆記:

  1. Windows 需要 stop 機器,才能卸下指定硬碟,請開啟 “終止保護“ 避免不小心做錯事
  2. Windows 的系統碟(C:)根设备用 /dev/sda1 資訊,卸下後要重新裝上時,記得要用原本的 /dev/sda1 才行
  3. 在 EC2 - EBS 管理介面要卸下某硬碟時,建議把 Name 帶點原本的機器資訊,方便找尋
  4. 在 Ubuntu 要 mount NTFS 都還算簡單,sudo mount /dev/xsgf1 /mnt/Win2012CDisk 
  5. Windows 的帳號資訊擺在 C:\Windows\System32\config\SAM 檔案,可以單純做 cp /mnt/C_server_c_diskt/Windows/System32/config/SAM /mnt/B_server_c_diskt/Windows/System32/config/SAM 
  6. 驗證完畢後,就可以安心地把 A server 先暫停 -> 把系統槽卸下 -> 掛到 Ubuntu server -> mount 起來 -> 覆蓋掉 SAM -> 卸下 -> 掛回 A server -> A server 重新開機

2016年8月4日 星期四

Microsoft Azure 管理筆記 - 使用 Image (Resource Manage - template.json) 快速建構、搬遷 Data Center

這個概念是這樣,為了服務世界各地的朋友們,可能一開始在日本服務,過了一陣子想要在美西服務,這時在 AWS 上可以很便利地將 AMI 複製到其他 Region ,而對 Azure 咧?概念是一樣,但在 Azure Resource Manage 的思維下,做法多了很多步。

參考資料:
步驟如下(在此有做 storage account 的切換,若是要沿用同一個 storage account 可以不用做第三步):
  1. 建立新的 Resource:US,歸屬定 West US
  2. 建立 Virtual Network、Subnet
  3. 建立 Storage account,此乃資料儲存帳號
  4. 將原本所在的 Image (vhd) 複製到新的 Storage account
  5. 建立 Network Interface Controller
  6. 將原本的 template.json 修改,把storage account更新至新的區域
  7. 即可建置新機器
細部流程,大多以 Azure cli 運行:

建立位於 West US 的 Resource Group: US

$ azure group create US westus --subscription MySubscription
info:    Executing command group create
+ Getting resource group US                                                  
+ Creating resource group US                                                
info:    Created resource group US
data:    Id:                  /subscriptions/MySubscription/resourceGroups/US
data:    Name:                US
data:    Location:            westus
data:    Provisioning State:  Succeeded
data:    Tags: null
data:  
info:    group create command OK


建立 Virtual Network (也可多用 -a 10.1.0.0/16 來限制 address prefix)

$ azure network vnet create US USVirtualNetwork westus  --subscription MySubscription
info:    Executing command network vnet create
warn:    Using default address prefix: 10.0.0.0/8
+ Looking up the virtual network "USVirtualNetwork"                          
+ Creating virtual network "USVirtualNetwork"                                
data:    Id                              : /subscriptions/MySubscription/resourceGroups/US/providers/Microsoft.Network/virtualNetworks/USVirtualNetwork
data:    Name                            : USVirtualNetwork
data:    Type                            : Microsoft.Network/virtualNetworks
data:    Location                        : westus
data:    Provisioning state              : Succeeded
data:    Address prefixes:
data:      10.0.0.0/8
info:    network vnet create command OK


建立 Subnet

$ azure network vnet subnet create US USVirtualNetwork default -a 10.1.0.0/16 --subscription MySubscription
info:    Executing command network vnet subnet create
+ Looking up the virtual network "USVirtualNetwork"                          
+ Looking up the subnet "default"                                            
+ Creating subnet "default"                                                  
data:    Id                              : /subscriptions/MySubscription/resourceGroups/US/providers/Microsoft.Network/virtualNetworks/USVirtualNetwork/subnets/default
data:    Name                            : default
data:    Provisioning state              : Succeeded
data:    Address prefix                  : 10.1.0.0/16
info:    network vnet subnet create command OK


接著建議從 Azure Portal Web UI 建立 storage account ,大多採預設即可,需留意區域位置以及採用的 resource group,此例帳號名稱為 myusstorageaccount,而使用 azure 操作 storage 行為時,必須使用 storage access key,於是就 azure cli 先列出一下(也可以在 Azure Portal 找到)

$ azure storage account keys list myusstorageaccount --resource-group US --subscription MySubscription
info:    Executing command storage account keys list
+ Getting storage account keys                                              
data:    Name  Key             Permissions
data:    ----  --------------  -----------
data:    key1  111111111111==  Full    
data:    key2  222222222222==  Full    
info:    storage account keys list command OK


建立 system container(後續 AZURE_STORAGE_ACCOUNT 跟 AZURE_STORAGE_ACCESS_KEY 都會接在指令前面,方便 debug 用途)

$ AZURE_STORAGE_ACCOUNT=myusstorageaccount AZURE_STORAGE_ACCESS_KEY=111111111111== azure storage container create system
info:    Executing command storage container create
+ Creating storage container system                                          
+ Getting storage container information                                      
data:    {
data:        name: 'system',
data:        metadata: {},
data:        etag: '"################"',
data:        lastModified: 'Thu, 04 Aug 2016 12:01:14 GMT',
data:        lease: { status: 'unlocked', state: 'available' },
data:        requestId: '############################',
data:        publicAccessLevel: 'Off'
data:    }
info:    storage container create command OK


接著,要把 Image copy 過來,這邊有些小細節要留意的,第一存取權限,第二這是非同步複製的。對於存取權限部分,請先將來源的 storage account 裡的 system container 的存取權限更新為 Blob 模式(此模式是必須知道完整的 URL 才能下載),預設是 private 模式(需搭配AZURE_STORAGE_ACCOUNT/AZURE_STORAGE_ACCESS_KEY才能),還有另一個是 Container 模式(這也是公開的,比 Blob 模式多了 listing 功能)。由於 azure storage blob 指令操作,對於 source 是 private 權限一直沒有成功 orz 且範例都是 Blob 的,只好忍痛跟著用了 Orz

以下是 source 為 private 權限,但 copy 一直沒成功(狀態會顯示success),但找不到資料的:

$ AZURE_STORAGE_ACCOUNT=myusstorageaccount AZURE_STORAGE_ACCESS_KEY=111111111111== azure storage blob copy start https://sourceaccount.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/my-vm-osDisk.12345-23456-34567-45678.vhd system -a sourceaccount -k sourceaccount_KEY
info:    Executing command storage blob copy start
- Start copying blob https://sourceaccount.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/my-vm-osDisk.12345-23456-34567-45678.vhd
data:    Copy ID                               Status
data:    ------------------------------------  -------
data:    ####################################  success
info:    storage blob copy start command OK


而將 source 更新為 Blob 存取權限後,就可以看到 Status 會顯示 pending 且約2~3分鐘,連 Azure Portal Web UI / Azure cli 都會找到!

$ AZURE_STORAGE_ACCOUNT=myusstorageaccount AZURE_STORAGE_ACCESS_KEY=111111111111== azure storage blob copy start https://sourceaccount.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/my-vm-osDisk.12345-23456-34567-45678.vhd system
info:    Executing command storage blob copy start
- Start copying blob https://sourceaccount.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/my-vm-osDisk.12345-23456-34567-45678.vhd
data:    Copy ID                               Status
data:    ------------------------------------  -------
data:    ####################################  pending
info:    storage blob copy start command OK

$ AZURE_STORAGE_ACCOUNT=myusstorageaccount AZURE_STORAGE_ACCESS_KEY=111111111111== azure storage blob show
info:    Executing command storage blob show
Container name:  system
Blob name:  Microsoft.Compute/Images/vhds/my-vm-osDisk.12345-23456-34567-45678.vhd
+ Getting storage blob information                                          
data:    Property       Value                                                                                            
data:    -------------  ----------------------------------------------------------------------------------------------------
data:    container      system                                                                                            
data:    name           Microsoft.Compute/Images/vhds/my-vm-osDisk.12345-23456-34567-45678.vhd
data:    blobType       PageBlob                                                                                          
data:    contentLength  1234567890                                                                                      
data:    contentType    application/octet-stream                                                                          
data:    contentMD5     ############==                                                                          
info:    storage blob show command OK


當複製完畢後(其實我也看不懂 azure storage blob show 的回報,也沒寫複製進度...),剩下就是建構一台機器的流程,包含建立 public ip、網路卡(NIC)、使用 template.json 發布。

如果你沒有把 Image 搬過來,直接用原本 template.json 開機器,會看到以下訊息(若同一個 storage account 則沒有問題):

error:   Deployment provisioning state was not successful
error:   Source and destination storage accounts for disk my-vm-osDisk.12345-23456-34567-45678.vhd are different.


若資料還沒搬完,會看到:

error:   Deployment provisioning state was not successful
error:   The resource operation completed with terminal provisioning state 'Failed'.
error:   Disk image https://myusstorageaccount.blob.core.windows.net/system/Microsoft.Compute/Images/vhds/my-vm-osDisk.12345-23456-34567-45678.vhd is in Pending state. Please retry when image is ready.


建立 IP:

$ azure network public-ip create US ip-my-server -l westus --subscription MySubscription

建立網卡:

$ azure network nic create US nic-my-server -k default -m USVirtualNetwork -l westus --subscription MySubscription

或給予 public ip:

$ azure network nic create US nic-my-server -k default -m USVirtualNetwork -l westus --subscription MySubscription -p ip-my-server

建立機器:

$ azure group deployment create US -f my-servier-template.json --subscription MySubscription -p '{"vmName":{"value":"my-server"},"networkInterfaceId":{"value":"/subscriptions/MySubscription/resourceGroups/US/providers/Microsoft.Network/networkInterfaces/nic-my-server"}}'

2015年6月29日 星期一

phpBB3 - 使用 OAuth 登入時,自動添加 phpBB3 系統使用者帳號

phpBB3 提供 OAuth 登入的功能,預設有 Bitly、Facebook 跟 Google+ 服務可作為登入系統。只需在外頭管理介面將帳號認證方式從預設的 Db 改成 oauth,接著只要有填寫 api_key, secret_key 後,網頁端在 login 介面下,就會顯示出額外的 OAuth 登入了!

然而,phpBB3 這邊的規劃:凡事透過 OAuth 登入者,完成登入後還要綁定到 PHPBB3 內部帳號才可以。看得出來可能的影響問題,包含資安等等的。而比較重要的一點是 PHPBB3 帳號底層用 Email 帳號當作獨一無二的 key。

因此,如果想要自動建立帳號,需確保 Email 是獨一無二的資料,這邊就簡單的做個小動作:

1.當使用者完成 OAuth 認證後,使用該服務資訊做出一個 unique email address,例如是 facebook.com 登入的,就拿 fb graph id 再加 graph.facebook.com 拼湊一個 email address:uid@graph.facebook.com  而非拿使用者的資料。
2.建立帳號還需要 username 資訊、phpBB3 group id
3.進行 oauth 帳號與 phpBB3 綁定 (link_account_perform_link)

主體上需改變:phpbb/auth/provider/oauth/oauth.php ,我這邊再埋個小東西,當 oauth provider 有提供 get_user_info 時,才進行自動綁定。

對 phpbb/auth/provider/oauth/oauth.php 的操作:

在 public function login($username, $password) 添加東西即可:

if ($this->request->is_set('code', \phpbb\request\request_interface::GET))
{
$this->service_providers[$service_name]->set_external_service_provider($service);
$unique_id = $this->service_providers[$service_name]->perform_auth_login();

// Check to see if this provider is already assosciated with an account
$data = array(
'provider' => $service_name_original,
'oauth_provider_id' => $unique_id
);
$sql = 'SELECT user_id FROM ' . $this->auth_provider_oauth_token_account_assoc . '
WHERE ' . $this->db->sql_build_array('SELECT', $data);
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);

// 添加自動建立帳號流程 -- begin
if (!$row && method_exists($this->service_providers[$service_name], 'get_user_info') && ($user_info = $this->service_providers[$service_name]->get_user_info()))
{
$new_user_data = $this->user_row($user_info['username'], $user_info['user_email']);
// create user automatic
if (!function_exists('user_add'))
{
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
}
$user_id = user_add($new_user_data);

$data = array(
'user_id' => $user_id,
'provider' => $service_name_original,
'oauth_provider_id' => $unique_id,
);
$this->link_account_perform_link($data);

// Update token storage to store the user_id
$storage->set_user_id($user_id);

$sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type, user_login_attempts
FROM ' . $this->users_table . '
WHERE user_id = ' . (int) $user_id;
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);

if (!$row)
{
throw new \Exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_ENTRY');
}

// The user is now authenticated and can be logged in
return array(
'status' => LOGIN_SUCCESS,
'error_msg' => false,
'user_row' => $row,
);
}
// 添加自動建立帳號流程 -- end

...


新增一個函數 user_row ,此參考 phpbb/auth/provider/apache.php - private function user_row($username, $password):

private function user_row($username, $user_email)
{
// first retrieve default group id
$sql = 'SELECT group_id
FROM ' . GROUPS_TABLE . "
WHERE group_name = '" . $this->db->sql_escape('REGISTERED') . "'
AND group_type = " . GROUP_SPECIAL;
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);

if (!$row)
{
trigger_error('NO_GROUP');
}

// generate user account data
return array(
'username' => $username,
'user_password' => $user_email,
'user_email' => $user_email,
'group_id' => (int) $row['group_id'],
'user_type' => USER_NORMAL,
'user_ip' => $this->user->ip,
'user_new' => ($this->config['new_member_post_limit']) ? 1 : 0,
);
}


如此一來,當使用者透過 oauth 登入時,第一時間若發現沒有系統對應帳號時,會自動建立一組帳號跟 oauth 帳號綁定,而下次再登入時就會因為已經有帳號綁定而登入動作。而 oauth provider 需要添加一個 get_user_info 的函數,以 facebook 來看就是修改 phpbb/auth/provider/oauth/service/facebook.php 檔案:

public function get_user_info()
{
if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Facebook))
{
throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
// This was a callback request, get the token
$this->service_provider->requestAccessToken($this->request->variable('code', ''));
// Send a request with it
$result = json_decode($this->service_provider->request('/me'), true);
if (isset($result['id']) && isset($result['name']))
return array( 'username' => $result['name'] , 'user_email' => $result['id'].'@graph.facebook.com' );
// Return the unique identifier
return NULL;

}

2014年9月2日 星期二

[Linux] 透過 alias 與 virtual 機制建立 no-reply @ hostname 帳號 @ Postfix 2.9.6, Ubuntu 12.04

新增一筆 alias 用來導向 /dev/null

$ grep alias_maps /etc/postfix/main.cf
alias_maps = hash:/etc/aliase
$ sudo vim /etc/aliases
...
devnull: /dev/null
...


採用 virtual account 新增 no-reply 帳號:

$ grep virtual_alias_maps /etc/postfix/main.cf
$ sudo vim /etc/postfix/main.cf
virtual_alias_maps = hash:/etc/postfix/virtual

$ sudo vim /etc/postfix/virtual
no-reply@hostname devnull

$ sudo newaliases
$ sudo postmap /etc/postfix/virtual
$ sudo postfix reload
postfix/postfix-script: refreshing the Postfix mail system


至於測試方式,就直接連他寄信看看:

$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 hostname ESMTP Postfix (Ubuntu)
HELO localhost
250 hostname
mail from:<root@localhost>
250 2.1.0 Ok
rcpt to:<no-reply@hostname>
250 2.1.0 Ok
quit
221 2.0.0 Bye
Connection closed by foreign host.


如果出現 451 4.3.0 <no-reply@hostname>: Temporary lookup failure ,請記得翻一下 /var/log/mail.err ,若是單純 error: open database /etc/postfix/virtual.db: No such file or directory 問題,記得跑一下 sudo postmap /etc/postfix/virtual 即可。