[ 安裝心得 ] 如何設定 VPN ﹖


作者﹕網中人 <netman@study-area.org>
-------------- 前言﹕ 一直以來﹐接到過不少朋友來問我關於 vpn 的設定﹐但一直都懶於整理﹐ 以至辜負了不少期望。但願這篇文章能稍作補償吧。 事實上﹐在 linux 的 vpn 方案非常多﹐不少朋友會參考 VPN-mini-HOWTO 來設定﹐見 http://www.linux.org.tw/CLDP/mini/VPN.html 但我覺得這份文件‘讀起來容易、做起來難’~~ :) 下面的文章﹐則是針對該文修改而成的。 -------------- 測試環境﹕ remote 端 (rh7.1): real: 1.2.3.4 (杜撰) vpn: 10.0.3.1 (隨便) local 端 (rh7.2): real: 4.3.2.1 (亂掰) vpn:10.0.1.1 (自定) -------------- 設定步驟﹕ 一﹐ 設定 SSH 1) 在 remote 端建立一個 vpn1 的帳號﹕ mkdir /etc/skel/.ssh useradd -m vpn1 2) 在 local 端用 root 身份執行 ssh-keygen 並完成設定 * 假如您打算以非 root 身份執行 vpn 的話﹐請用該帳號執行 ssh-keygen。 * 假如在 rh7.3 上面﹐執行 ssh-keygen 的時候要用 -t rsa 來指定類別。 3) 每次執行以上命令之後﹐必須將 ~/.ssh/identity.pub 這個檔案的內容﹐ (假如在 rh7.3 上面﹐檔案名稱則為 id_rsa.pub﹐參考下面的內容時請替換掉。) 增加到 remote 端之 ~vpn1/.ssh/authorized.keys 檔案中﹐例如﹕ 用 floopy 或 ftp 將檔案 upload 至 remote 端的 /tmp 目錄中﹐ 再於其上執行﹕cat /tmp/indetify.pub >> ~vpn1/.ssh/authorized_keys 4) 完成後 '千萬' 要記得檢查檔案權限﹕ chown -R vpn1.vpn1 ~vpn1/.ssh chmod 711 ~vpn1/.ssh chmod 644 ~vpn1/.ssh/authorized_keys 5) 測試 ssh 連線﹐確定能夠用 ssh1 的帳號而無需密碼能夠連上 remote 端﹕ ssh -1 -l vpn1 1.2.3.4 * 注意﹐我不知道如何在 ssh version 2 上面使用 RAS 驗證﹐ 所以用 -1 來指定 version 1 。 後來在 rh7.3 上測試的時候﹐執行 ssh-keygen -t rsa 的話﹐ 則可以直接使用 v2 版本﹐無需使用 -1 參數。 * 因為使用 non-root 帳號的關係﹐我修改了 remote 端的 /etc/ssh/sshd_config 檔﹐ 將 StrictModes yes 改為 StrictModes no ﹐ 您或許可以在後面的測試中來決定是否需要如此修改。 二﹐設定 remote 端 1) 修改 /etc/sudoers ﹐增加如下數行﹕ User_Alias VPNUSER=root,vpn1 Cmnd_Alias VPN=/usr/sbin/pppd,/sbin/route VPNUSER ALL=(ALL) NOPASSWD: VPN 2) 在 /usr/local/sbin 裡面建立一個可執行的 script ﹐取名為 vpn-ppp ﹕ #!/bin/bash exec sudo /usr/sbin/pppd (請記得 chmod +x /usr/local/sbin/vpn-ppp) 3) 修改 vpn1 的 shell ﹕ usermod -s /usr/local/sbin/vpn-ppp vpn1 三﹐設定 local 端 1) 下載 pty-redir-0.1.tgz (可從這裡﹕http://www.study-area.org/linux/src/pty-redir-0.1.tgz) 2) 將檔案解至 /usr/local 內﹕ tar zxvf pty-redir-0.1.tgz mv pty-redir-0.1 /usr/local cd /usr/local/pty-redir-0.1 make cp pty-redir /usr/local/sbin 3) 在 /etc/rc.d/init.d 目錄內建立一個叫 vpnd 的可執行 script ﹐內容如下﹕ (假如您是從上面路徑下載 pty-redir-0.1.tgz 的話﹐我已經將這個 script 包在裡面了) #! /bin/sh # skeleton example file to build /etc/init.d/ scripts. # This file should be used to construct scripts for /etc/init.d. # # Written by Miquel van Smoorenburg <miquels@cistron.nl>. # Modified for Debian GNU/Linux # by Ian Murdock <imurdock@gnu.ai.mit.edu>. # # Version: @(#)skeleton 1.6 11-Nov-1996 miquels@cistron.nl # # Modification: by netman<netman@study-area.org> on 2002/03/24 # Ext. Version: -0.9 # # chkconfig: 2345 99 01 # description: Connects to VPN # PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/bin/X11/: FUNCTIONS=/etc/rc.d/init.d/functions PPPD=/usr/sbin/pppd REDIR=/usr/local/sbin/pty-redir DEVNAME=/tmp/vpn_device SSH=/usr/bin/ssh LOCALIP=10.0.1.1 LOCALNET=10.0.1.0/24 REMOTEIP=10.0.3.1 REMOTENET=10.0.3.0/24 SSHSERVER=1.2.3.4 SSHACC=vpn1 test -r $FUNCTIONS && . $FUNCTIONS test -x $PPPD || exit 0 set -e case "$1" in start) echo "Setting up vpn, please wait..." $REDIR $SSH -1 -q -t -l $SSHACC $SSHSERVER > $DEVNAME TTYNAME=$(cat $DEVNAME) sleep 5s if [ ! -z $TTYNAME ] then sudo $PPPD $TTYNAME ${LOCALIP}:${REMOTEIP} else echo FAILED! logger "vpn setup failed" fi sleep 2s sudo /sbin/route add -net $REMOTENET gw $REMOTEIP ;; stop) ps -ax | grep "ssh -1 -q -t -l $SSHACC " | grep -v grep \ | awk '{print $1}' | xargs kill ;; *) echo "Usage: $0 {start|stop}" exit 1 ;; esac rm -f $DEVNAME exit 0 # -- end of script --# (記得執行 chmod +x) (如果使用 ssh v2 版本之 RSA 連線﹐請將 ssh 命令之 -1 參數拿掉。共兩行。) 4) 如果需要開機就啟動 vpnd 的話﹐請執行如下命令﹐否則略﹕ chkconfig --add vpnd chkconfig vpnd on 5) 假如您是以 non-root 身份執行這個 script 的話﹐ 那就參照 remote 端那樣修改 /etc/sudoers 吧。 四﹐建立 vpn 連線 1) 在 local 端執行如下命令進行連線﹕ /etc/rc.d/init.d/vpnd start 2) 如果結束連線﹐可執行﹕ /etc/rc.d/init.d/vpnd stop 3) 執行 ifconfig 和 route 以檢查連線是否正確。 -------------- 注意之處﹕ 1) 確定 ssh 能支援 RSA 驗證功能而無需使用密碼。 2) 確定 sudo 設定以允許 non-root 權限執行必要的程式。 3) 確定 script 有執行權限。 4) 確定所有檔案名稱和路徑的正確性。 5) 確定路由的正確性﹐這需要您具備非常清晰的 IP subnet 基礎。 例如在本例子中﹐remote 端必並沒有回來 local network 的路由﹐ 請自行建立(不管用 script 還是手工設定)。 6) 如果遇到 pppd 的設定問題﹐請參考其他文件﹐如﹕ http://www.study-area.org/linux/servers/linux_ppp.htm 7) 請自行解決 firewall 和 NAT 的問題。(建議測試的時候取消 firewall ) -------------- 其他替代方案﹕ * SWAN/ipsec 因為需要修改核心﹐比較麻煩~~ 等日後再整理出來和大家分享。 * vpnd ( http://sunsite.dk/vpnd/) 相對而已比較容易﹐按如下步驟進行即可﹕ 前提條件是﹕kernel 必須設定為支援 SLIP 功能。 否則﹐請自行編譯核心﹐或載入 slip 模組: <M> SLIP (serial line) support [*] CSLIP compressed headers [*] Keepalive and linefill [ ] Six bit SLIP encapsulationn 1) 下載 vpnd-1.1.0.tar.gz (可以從這裡﹕http://www.study-area.org/linux/src/vpnd-1.1.0.tar.gz) 2) 解至 /usr/local 中﹐並進行安裝﹕ tar zxvf vpnd-1.1.0.tar.gz mv vpnd /usr/local cd /usr/local/vpnd ./configure make cp vpnd /usr/loca/sbin chmod +x /usr/local/sbin/vpnd cp vpnd.conf vpnd.chat /etc chmod 644 /etc/vpnd.conf /etc/vpnd.chat chown root.root /etc/vpnd.conf /etc/vpnd.chat ./vpnd -m * 最後的 vpnd -m 是要產生 /etc/vpnd.key 檔﹐ 它必須只能被 root.root 擁有﹐而且只有 400 權限。 3) 編輯 /etc/vpnd.conf ﹐將所有內容全部換為如下句子﹕ mode server client 4.3.2.1 10001 server 1.2.3.4 10001 local 10.0.3.1 remote 10.0.1.1 keyfile /etc/vpnd.key route1 10.0.1.0 255.255.255.0 10.0.1.1 nocompress autoroute 4) 將如下檔案打包﹕ mkdir vpnd_client cp -a /etc/vpnd.* vpnd_client cp -a /usr/local/sbin/vpnd vpnd_client tar zcvf vpnd_client.tgz vpnd_client 5) 將打包檔案轉移到 VPN 的另外一端的機器上﹐並將檔案複製到合適的位置﹕ tar zxvf vpnd_client.tgz cp -a vpnd_client/* /etc mv /etc/vpnd /usr/local/sbin 6) 修改 /etc/vpnd.conf ﹐使之設定與另外一端相對應﹕ mode client client 4.3.2.1 10001 server 1.2.3.4 10001 local 10.0.1.1 remote 10.0.3.1 keyfile /etc/vpnd.key route1 10.0.3.0 255.255.255.0 10.0.3.1 nocompress autoroute 7) 在 server 端執行執行如下命令﹕ /usr/local/sbin/vpnd -f /etc/vpnd.conf (測試成功後可以寫到 rc.local 中) 8) 在 client 端執行執行如下命令﹕ /usr/local/sbin/vpnd -f /etc/vpnd.conf (測試成功後可以寫到 rc.local 中) 9) 測試結果 10) 結束連線請執行﹕ killall vpnd -------------- 結語﹕ vpn 的確為許多跨地域企業提供了便宜且便利的網路方案﹐ 其難點往往在於 ip schem 的規劃﹐而不是 vpn 技術本身。 假如在一些複雜的環境中﹐例如 NAT 和 NT domain 等﹐ 更是要求設定者具備堅實的網路基礎和慎密的測試能力。 至於將來的 IPv6 版本是否能提供更佳的 VPN 方案﹐ 則等日後我們慢慢發掘了。 -------------- 最後修改日期﹕ 2002/07/03