瀏覽標籤:

SSL

[IIS][GitLab] 利用 IIS Reverse Proxy 將 GitLab 加上 Https

最近工作上有個需求要將 GitLab 掛上 SSL 憑證,原本就有一台 Windows Server 在管理所有的 SSL 憑證,於是乎就想到可以利用 IIS Reverse Proxy 的方式將憑證集中管理在這台,這樣管理起來也比較方便。

前置作業

首先需要安裝兩個模組

  1. URL Rewrite
  2. Application Request Routing

安裝 URL Rewrite 的時候有踩到一個地雷,詳情請見 [IIS] Windows Server 2016 安裝 URL Rewrite 憑證失效

開始設定

  1. 建立一個新站台並設定好 SSL 憑證 (由於這邊我只是測試用,所以我自己簽一個自我憑證)

  2. 選擇 URL Rewrite

  3. 選擇 新增規則 -> 反向 Proxy

  4. 選擇 確定 啟用 Proxy

  5. 1 的地方輸入 GitLab 的位置,2 的位置輸入欲對外的 Domain

  6. 當我以為簡單就完成開啟網頁試試時卻噴錯誤給我看

HTTP 錯誤 500.52 - URL Rewrite Module Error.
當 HTTP 回應的內容經過編碼 ("gzip") 時,無法套用輸出重寫規則。


原因是因為 GitLab 有開啟壓縮,但使用了反向 Proxy 無法將已壓縮的檔案進行修改,所以就噴了這個錯誤

  1. 解決方法是在 伺服器變數 做調整

  2. 新增兩個變數分別是 HTTP_ACCEPT_ENCODINGHTTP_X_ORIGINAL_ACCEPT_ENCODING

  3. 編輯輸入規則

  4. 新增兩個伺服器變數,伺服器變數名稱選擇剛剛加入的 HTTP_X_ORIGINAL_ACCEPT_ENCODING,值輸入 {HTTP_ACCEPT_ENCODING}

  5. 我們已經將 HTTP_ACCEPT_ENCODING 放到 HTTP_X_ORIGINAL_ACCEPT_ENCODING 裡面,原本的值就可以清空清空,但因為 UI 不允許輸入空值,所以這邊我就隨便打個值

    如果跟我一樣很在意的話可以去站台底下的 web.config 清空剛剛的值

  6. 終於可以開起來囉 ~

顯示調整

雖然已經可以正常開啟網頁了,但網址還是會顯示錯誤

  1. 新增兩個伺服器變數 HTTP_X_FORWARDED_HOSTHTTP_X_FORWARDED_PROTO
  2. HTTP_X_FORWARDED_HOST 輸入 Domain,HTTP_X_FORWARDED_PROTO 輸入 https
  3. 修改 /etc/gitlab/gitlab.rb 加上這段
external_url 'https://gitlab.exfast.me'
nginx['listen_port'] = 80
nginx['listen_https'] = false

 

這樣頁面顯示的網址就正常囉,不過 https://gitlab.exfast.me/profile/active_sessions 這邊顯示的 IP會是 IIS 那台的位址,所以還必須調整 /etc/gitlab/gitlab.rb 加上這段

# Each address is added to the the NGINX config as 'set_real_ip_from <address>;'
nginx['real_ip_trusted_addresses'] = [ '127.0.0.1', '192.168.56.106' ]
# other real_ip config options
nginx['real_ip_header'] = 'X-Forwarded-For'
nginx['real_ip_recursive'] = 'on'

 

參考資料

  1. How to Configure IIS as a Reverse Proxy for Sonatype Products
  2. IIS with URL Rewrite as a reverse proxy – part 2 – dealing with 500.52 status codes
  3. 如何讓在 Reverse Proxy 之後的網站正常運行 (URL Rewrite)
  4. 如何利用 IIS7 的 ARR 模組實做 Reverse Proxy 機制
  5. Configuring GitLab trusted_proxies and the NGINX real_ip module
       

IIS 網站強制使用 https 加密連線

在這篇 IIS 使用 Let’s Encrypt 的 SSL 免費憑證 – 多站台申請 提到了免費SSL憑證申請,現在我們要申請完後要限制每個網站都只能用https瀏覽的話,就必須用web.config來將使用者自動轉移到https的網址上,廢話不多說教學如下。

  • 在要移轉的網域資料夾下新增檔案web.config,內容如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    	<system.webServer>
    		<rewrite>
    			<rules>
    				<rule name="HTTP to HTTPS redirect from:https://blog.exfast.me" stopProcessing="true">
    					<match url="(.*)" />
    					<conditions>
    					  <add input="{HTTPS}" pattern="off" ignoreCase="true" />
    					</conditions>
    					<action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
    				</rule>
    			</rules>
    		</rewrite>
    	</system.webServer>
    </configuration>

新增完畢後無須重啟立即生效,現在輸入http網址看看會不會轉跳到https吧!

       

IIS 使用 Let’s Encrypt 的 SSL 免費憑證

  1. 首先在你的IIS伺服器上新增一個web.config檔案,這樣他才可以識別等等要新增的驗證檔案,加以確認這個網域是你的。
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <system.webServer>
            <staticContent>
                <mimeMap fileExtension="." mimeType="text/plain" />
            </staticContent>
        </system.webServer>
    </configuration>
  2. 接著到這個下載letsencrypt-win-simple.v1.9.0.zip,解壓縮到你的Server上面,對著解壓縮後的資料夾按著Shift+右鍵選擇在此處開啟命令視窗(W)
    圖一
  3. 輸入指令如圖二(Help)
    letsencrypt.exe --accepttos --manualhost 網域名稱 --webroot wwwroot路徑
    

    圖二

  4. 結果如圖三,這裡顯示是否替換現有的憑證,我選擇Y (沒出現這段沒關係,可能是我已經安裝過)
    圖三
  5. 這裡詢問是否要指定使用者,選擇N
    圖四
  6. 看到圖五這裡就表示憑證已經自動放入你的IIS裡面了
    圖五
  7. 開啟IIS管理介面繫結->新增->類型(https)->連接埠(443)->主機名稱(剛剛申請的網域名稱)->SSL(剛剛產生的新憑證)
    圖六
  8. 測試一下SSL是否正常顯示吧!
    圖七

延伸閱讀:IIS 使用 Let’s Encrypt 的 SSL 免費憑證 – 多站台申請

       

Apache 使用 Let’s Encrypt 的 SSL 免費憑證

SSL憑證服務,用於建立瀏覽器和網站伺服器之間的安全通道,提供伺服器身分鑑別及資料傳輸加密。 透過SSL機制建立一個安全通道,保護網路使用者所傳輸的個人資料(如信用卡號、帳號、密碼等)在傳輸過程中不被駭客截取或竄改,保護網站用戶個人資料,強化網路使用者對於網路交易信心。

  1. 下載官方自動安裝憑證程式
    sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
  2. 進入剛剛下載的資料夾
    cd letsencrypt
  3. 將網域輸入(如有多網址則輸入多次,批量會出錯)
    ./letsencrypt-auto --apache -d example.com
  4. 程式會幫你自動加載SSL資料進conf,所以無需做任何設定

 

若無則手動加入:

<IfModule mod_ssl.c>
    <VirtualHost www.example.com:443>	
	#管理者郵箱 
	ServerAdmin [email protected]
	#網站名稱 
	ServerName abc
	#網站別名
	ServerAlias www.example.com
	#網站的根目錄
	DocumentRoot /var/www/example.com/public_html/
	#網站的錯誤日誌檔存放的位置與檔名
	ErrorLog /var/www/example.com/logs/error.log
	#網站日誌檔存放的位置與檔名
	CustomLog /var/www/example.com/logs/access.log combined
	SSLEngine on
	# Let's encrypt
        SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
        SSLCACertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    </VirtualHost>
</IfModule>
       

寶寶Echo Line ChatBot api 教學 (php)

寶寶Echo:

yqx0407i

  1. Echo
    01
  2. 空氣品質查詢
    messageImage_1462620227535
  3. 無線熱點查詢
    messageImage_1462620227535

 

昨晚看到有人在玩FB ChatBot感覺好好玩
影片支援:https://www.facebook.com/D.Weizhe/videos/10208034398169797/

他好像是用node.js在玩的,不過我完全沒有碰過那個東西…
所以只好轉換個跑道,去找找看有沒有之前接觸過一點點的php範例
找了一個晚上後,終於在一個日本網站找到了一篇教學文
網址:https://www.panzee.biz/archives/9115

雖然看不懂日文,但是看看圖看看Code還是可以了解一點點點的!
Line ChatBot的部分就不多說了,請看這裡
好了開始本篇的教學吧!

1. 在伺服器上安裝SSL憑證
本來這個部份我是想用cloudflare的Flexible來解決的,
但後來發現這樣的話Server IP無法加入到Line的白名單裡面,
最後在這篇文章看到作者推薦Let's Encrypt這家免費SSL商,
安裝了一下發現,這家使用的安裝方法無法套用在Windows Server上面阿阿阿阿啊!
沒關係,我幫你們找好了這個解決方案,
我簡單的整理了一下:

2. 在 Line Developers Channels裡面輸入Server本身的IP
01

3. 寫一個callback.php,這裡我是參考剛剛上面提到的這篇,以下是我的Code。

/* 輸入申請的Line Developers 資料  */
$channel_id = "Channel ID";
$channel_secret = "Channel Secret";
$mid = "MID";
 
/* 將收到的資料整理至變數 */
$receive = json_decode(file_get_contents("php://input"));
$text = $receive->result{0}->content->text;
$from = $receive->result[0]->content->from;
$content_type = $receive->result[0]->content->contentType;
 
/* 準備Post回Line伺服器的資料 */
$header = ["Content-Type: application/json; charser=UTF-8", "X-Line-ChannelID:" . $channel_id, "X-Line-ChannelSecret:" . $channel_secret, "X-Line-Trusted-User-With-ACL:" . $mid];
$message = getBoubouMessage($text);
sendMessage($header, $from, $message);

 
/* 發送訊息 */
function sendMessage($header, $to, $message) {
 
	$url = "https://trialbot-api.line.me/v1/events";
	$data = ["to" => [$to], "toChannel" => 1383378250, "eventType" => "138311608800106203", "content" => ["contentType" => 1, "toType" => 1, "text" => $message]];
	$context = stream_context_create(array(
	"http" => array("method" => "POST", "header" => implode(PHP_EOL, $header), "content" => json_encode($data), "ignore_errors" => true)
	));
	file_get_contents($url, false, $context);
}
 
function getBoubouMessage($value){		
	return "寶寶" . $value .",只是寶寶不說";
}

4. 修改Callback URL改為你的php檔案
02

5. 完成!
01

其實我最初是想用ASP.NET寫的,
已經可以取得使用者輸入的文字,
但是後面發現如果要回傳訊息的話必須要POST回去,
有點麻煩…
就乾脆選擇簡單的PHP解決了。

Sample Code From GitHub