October 17, 2005

[備忘] OpenVPN on CentOS 4 (part 3)

時光飛逝(時光總是飛逝:Q),上次寫[備忘] OpenVPN on CentOS 4(part 2)已經是三週前的事了。。。

有件事提一下好了,這段期間,Red Hat發佈Red Hat Enterprise Linux 4 Update 2,我們的主角CentOS也跟著發佈相對應的CentOS-4.2。當然,我們不需要重灌,只需要更新套件即可。

======岔題談談screen======岔題談談screen======
因為擔心更新套件遇到網路塞車,我先安裝screen這個程式(內心的吶喊:早該裝了,竟然撐到現在>_<)
#yum -y install screen
成功之後,執行screen
# screen
再執行yum來更新套件:
# yun -y update
(過程中隨時可以按 ctrl a d ,也就是detach,然後要登出都可以。下次(以一般使用者)登入再切換成root,然後再執行
# screen -r
就可以resume之前的session,檢查套件更新是否順利。
(人家程咬金都有三斧頭,可是screen這麼強的工具我只會screen -r還有按ctrl a d跳離,兩招^^;)
果然在套件更新的途中常常遇到伺服器中斷連線的情況,所以我只要在有網路的地方,就用ssh遠端登入,檢查一下是不是要再次執行`yum -y update`。

這邊再多嘴提一下,我覺得比較好的ssh+screen使用習慣。請依照底下的順序操作:
1./ 以一般使用者身份執行遠端登入 `ssh 1.2.3.4 -l myaccount` (限制root無法從遠端登入,請參考本系列首篇)。
2./ 切換為root `su -`
3./使用screen指令 `screen -r`

其中1./是針對「遠端猛踹(try)root密碼之惡意ssh機器人程式」,但是這些機器人也會亂踹一些「可能存在」的帳號名稱,例如guest, student, teacher...萬一某個一般使用者的密碼被猜出來,她又剛好有執行步驟2./和3./,更糟的是2./ 和 3./ 順序又顛倒,那麼侵入者只要執行`screen -r`就可以resume那個切換到root帳號的session,後果真是不堪設想。
======岔題結束分隔線======岔題結束分隔線======

回題回題,今天(10/17)終於設定成功了,有興趣的朋友請看下去吧!

# 基本需求及規劃:
目標:
「OpenVPN用戶端透過internet登入OpenVPN伺服器後,可以執行VNC viewer登入內部網路之目標伺服器,進行操作。」

機器:
OpenVPN用戶端(Microsoft Windows 2000 Professional)
ip不固定,透過internet來建立VPN tunnel(可以直接連接,也可以透過HTTP proxy唷),取得OpenVPN伺服器配發的10.8.0.0/24網段virtual ip

目標伺服器(Microsoft Windows)
在內部10.66.0.0/24網段,ip 10.66.0.4,執行VNC server,用戶端登入OpenVPN伺服器後,可以執行VNC viewer來連結。

OpenVPN伺服器(CentOS 4, updated to 4.2)
網卡eth0直接連上internet,ip 1.2.3.4,以防火牆保護(額外開啟1194:tcp給OpenVPN用戶端,開啟5900:tcp讓用戶端能夠連接目標伺服器的VNC server),定期更新套件。
網卡eth1連到內部網段,ip 10.66.0.1。

OpenVPN使用預設的Routing而非Bridging,使用tcp而非預設的udp,virtual ip 10.8.0.1。

設定
[OpenVPN伺服器]
這台機器本來只有一張網卡,今天我又加了一張網卡。
在主機前面設定的時候,我會執行底下兩個指令,讓訊息不亂跑,並以英文顯示:
export LANG=C
export TERM=vt100

# 設定兩張網卡的ip
setup
選Network configuration(但是發現只能輸入Primary DNS,沒有要我輸入Secondary DNS)
(上面此法好像只能設定eth0,我用底下的指令設定eth1,有好方法歡迎告知)
netconfig -d eth1

(接下來大量引用了netman的文件:OpenVPN 建置方案,感謝他的經驗分享。)(我的用戶端是Microsoft Windows 2000 Professional,他的是XP)

[OpenVPN伺服器]
# 複製設定範例
cp -r /usr/share/doc/openvpn-2.0.2/easy-rsa/ /etc/openvpn/
cp /usr/share/doc/openvpn-2.0.2/sample-config-files/server.conf /etc/openvpn/

# 設定 CA 環境
cd /etc/openvpn/easy-rsa/
vi vars
export KEY_COUNTRY=TW
export KEY_PROVINCE=Taiwan
export KEY_CITY=Taipei
export KEY_ORG="TOSSUG"
export KEY_EMAIL="ystuan@gmail.com"
. ./vars
./clean-all

# 建置 root CA
./build-ca

# 建置 server key 及 crt
./build-key-server ovpnsrv1

# 建置 Diffie Hellman 參數
./build-dh

# 安裝 server 所需的 CA 文件
cp keys/ca.crt ../
cp keys/dh1024.pem ../
cp keys/ovpnsrv1.key ../
cp keys/ovpnsrv1.crt ../

# 配置 server 設定檔(沒提及的請保持原樣)
因為我希望用戶端就算不是直接連上internet,還是可以透過HTTP proxy連上來,所以改用"proto tcp"。另外我用Routing,所以維持"dev tun"。還有內部網路在10.66.0.0/24,所以加一行push的設定,將這個路由"餵"給每個連上來的客戶端。

cd ../
vi server.conf
proto tcp
;proto udp

;dev tap
dev tun
ca ca.crt
cert ovpnsrv1.crt
key ovpnsrv1.key # This file should be kept secret
push "route 10.66.0.0 255.255.255.0"

# 啟動 server
service openvpn restart
chkconfig openvpn on

# 防火牆設定修改
system-config-securitylevel-tui
Security Level: Enabled
Customize
Other ports填上 1194:tcp 5900:tcp
(前者是讓OpenVPN用戶端可以連接,後者是讓用戶端可以連到目標伺服器的VNC server)

[OpenVPN用戶端設定](以Microsoft Windows 2000 Professional為例)

# 下載並安裝 openvpn (GUI 版本)
http://openvpn.se/files/install_packages/openvpn-2.0.2-gui-1.0.3-install.exe

# 設定環境
cmd.exe
cd "c:\Program Files\OpenVPN\easy-rsa"
init-config.bat
(上面這個.bat檔裡面其實只是兩次「從範例複製一份設定檔」的動作)
edit vars.bat
(也可以用其他的編輯器,例如notepad vars.bat,編輯檔案時,內容必需與 server 一致, 尤其 KEY_ORG 項目。)

# 建置 CA環境
vars

# 建置 client key 與 CSR (Certificate Signing Request)
mkdir keys
(我的機器上不會自動新增 keys 這個目錄,因此手動建立)
build-key ovpnclt1
(會有下列錯誤訊息,是跟CA有關的,可以忽略)
Loading 'screen' into random state - done
Error opening CA private key keys/ca.key
2292:error:02001002:system library:fopen:No such file or directory:crypto/bio/bs
s_file.c:278:fopen('keys/ca.key','rb')
2292:error:20074002:BIO routines:FILE_CTRL:system lib:crypto/bio/bss_file.c:280:

unable to load CA private key
Could Not Find C:\Program Files\OpenVPN\easy-rsa\keys\*.old

# 提交 CSR(請使用安全方式,netman用了pscp.exe,我當時因為就在伺服器旁邊,所以直接mount usbdisk。因為伺服器有開ssh,其實也可以用Filezilla,Servertype記得選"SFTP using SSH2"。)
usb disk插到客戶端,將檔案C:\Program Files\OpenVPN\easy-rsa\keys\ovpnclt1.csr複製過來。然後停止這個usb disk,取下。

[OpenVPN伺服器]
接著usb disk插到伺服器,執行底下指令來掛載,複製檔案,以及卸載(假設在/dev/sdb1):
mount /dev/sdb1 /media/usbdisk/
cp /media/usbdisk/ovpnclt1.csr /etc/openvpn/easy-rsa/keys/
rm /media/usbdisk/ovpnclt1.csr (不要留一份在usb disk上)

# 在伺服器端,簽署 client 提交的CSR,產生crt
------------------------
cd /etc/openvpn/easy-rsa/
./sign-req ovpnclt1
cp ovpnclt1.crt /media/usbdisk/
cp ca.crt /media/usbdisk/
rm ovpnclt1.crt ovpnclt1.csr (不該把這些檔案留在CA server上)
umount /dev/sdb1

[OpenVPN用戶端]
# 安裝 CA 文件
將下列檔案放到"C:\Program Files\OpenVPN\config"
ovpnclt1.key
ca.crt
ovpnclt1.crt
第一個請由"C:\Program Files\OpenVPN\easy-rsa\keys"複製過來,後面兩個在usb disk上面,將usb disk插到客戶端機器,複製檔案(建議不要把這兩個檔案留在usb disk上面,請記得刪除)然後停止這個usb disk,取下。
(安全起見,請把"C:\Program Files\OpenVPN\easy-rsa\keys"底下的ovpnclt1.csr和ovpnclt1.key都刪除)

# 複製 sample 設定檔:
請將範例檔案"client.ovpn"從"C:\Program Files\OpenVPN\sample-config"複製一份到"C:\Program Files\OpenVPN\config"

# 配置 client 端設定檔
右下角工作列(OpenVPN GUI)
右鍵--> Edit Config(沒提及的, 請保持原貌)
;dev tap
dev tun
dev-node OpenVPN_Tap
proto tcp
;proto udp
remote 1.2.3.4 1194
ca ca.crt
cert ovpnclt1.crt
key ovpnclt1.key
ns-cert-type server

# 設定 openvpn TAP 界面
控制台-->網路連線-->TAP-Win32#(#)
(找出哪個介面用的是TAP-Win32,我這邊的"區域連線 4"滑鼠移上去會顯示TAP-Win32 Adapter V8,要把"區域連線 4"這個名字改成剛才"dev-node"取的名字)
右鍵-->重新命名-->OpenVPN_Tap

# 啟動 openvpn用戶端
右下角工作列(OpenVPN GUI)
(如果用戶端要透過HTTP proxy連接OpenVPN伺服器的話,請先 右鍵 --> Proxy Settings加以設定)
右鍵--> Connect

# 測試能否ping到伺服器
ping 10.8.0.1

恭喜!到這邊可以算是完成了點對點的VPN,不過別忘了我們的目標伺服器放在內部網路的10.66.0.0網段,我們要讓OpenVPN用戶端的封包「過的去,回的來」,要確定兩件事:
a./打開IP Forwarding功能,讓OpenVPN伺服器能夠幫我們把封包送過去。
b./確定目標伺服器它的路由設定,能夠讓來自10.8.0.0/24網段的封包回到OpenVPN伺服器對內網卡eth1的ip 10.66.0.1。

[OpenVPN伺服器]
a./關於打開IP Forwarding,請執行底下指令,立即生效:
echo 1 > /proc/sys/net/ipv4/ip_forward
並且修改檔案,即使伺服器重新開機也不怕:
vi /etc/sysctl.conf
net.ipv4.ip_forward = 1

[內部網路目標伺服器]
b./關於目標伺服器的路由設定,最好由它的default route那顆router把10.8.0.0/24都指向OpenVPN伺服器的對內網卡ip 10.66.0.1。
不過因為本例目標伺服器和OpenVPN伺服器的對內網卡都在10.66.0.0/24網段,所以直接在目標伺服器上面增加路由,讓封包回的來:
(目標伺服器是Microsoft Windows,其他作業系統的路由指令不一樣)
route -p add 10.8.0.0 mask 255.255.255.0 10.66.0.1

[OpenVPN用戶端]
好了,從用戶端機器執行VNC viewer,輸入目標伺服器ip 10.66.0.4,再輸入VNC Server密碼,稍候片刻,應該就會看到目標伺服器的桌面環境囉!

檔案安全控管
收工之前,提醒一下自己,哪些檔案要好好保存:
# CA 文件分佈(我們CentOS同時扮演OpenVPN和CA server的角色):
OpenVPN server:
ca.crt
dh1024.pem
ovpnsrv1.crt
ovpnsrv1.key # 必須保密
OpenVPN client:
ca.crt
ovpnclt1.crt
ovpnclt1.key # 必須保密
CA server:
ca.crt
ca.key # 必須保密

關於檔案該(或不該)放在哪台機器上,這邊就要提到Arne Götje於2005/6/14在TOSSUG做過的心得分享PDF檔案雖然是以Debian作業系統為例,但是page 6提到了一些重要的安全觀念:
1./ca.key是整個安全架構中最重要的檔案,它只應該出現在CA server上,請小心保密。
2./妳可以在CA server上產生各台機器的key和certificate,然後用安全的方式轉移到該機器上。或者,妳可以在各台機器上面產生key及certificate request(.csr),然後用安全的方式把.csr轉移到CA server,加以簽署產生.crt,再將.crt安全地轉移回到該機器。
3./不要把上一步驟,別的機器的key或certificate或certificate request留在CA Server上!!
4./每台機器都應該有ca.crt,可不是ca.key唷!!
5./如果有專屬的CA server,其實它可以不連上網路,只要負責產生key和certificate(再安全地派送),或者簽署別台機器送來的certificate request(再安全地派送)即可。

Bridging模式
(這個模式我只能連上OpenVPN伺服器,連不到目標伺服器,歡迎告知妳的成功經驗!)
如果要使用Bridging模式,請安裝 bridge-utils 套件
yum -y -install bridge-utils
(會把相依性套件 sysfsutils 也裝上去)。
因為我沒有成功經驗可供分享,就不多說了,建議妳參考官方網站的Ethernet Bridging吧!

感謝
最後,感謝James Yonan及相關人員開發出OpenVPN這麼棒的VPN解決方案!也感謝netman和Arne Götje的文件!

收工啦,謝謝收看!

Posted by ystuan at October 17, 2005 11:17 PM
Pings
Comments

強調一下,在 "# 設定 CA 環境" 所提到的指令
. ./vars
兩個點之間,是有一個空格的。
(這個指令的作用是要引入檔案vars裡面所設定的環境變數,包括KEY_DIR等等)
上面指令跟下面三個任一個,應該都有同樣效果:
. vars
source ./vars
source vars

如果妳遇到 "you must define KEY_DIR" 這樣的錯誤訊息,多半都是因為這個指令下錯啦。

============
在Win32環境,則是執行vars.bat來設定環境變數。因為.bat可以不打,所以文件裡面是執行vars

Posted by: PowerOp at October 27, 2005 12:06 AM