เชื่อมต่อ VPN ระหว่าง Linux กับ Windows/macOS ด้วย strongSwan

Work from Home

เพื่อเป็นอีกแนวทางหนึ่งที่จะช่วยให้พนักงานสามารถทำงานจากบ้านได้ แต่ต้องการเรียกดูข้อมูลจากเซิร์ฟเวอร์ที่ติดตั้งไว้ภายในบริษัท

ขอแชร์วิธีการติดตั้งและคอนฟิก strongSwan เพื่อทำหน้าที่เป็น VPN Server แบบ IPSec IKEv2 เพื่อรองรับการเชื่อมต่อจากเครื่องคอมพิวเตอร์ทั้ง Windows และ macOS ผ่านทางอินเทอร์เน็ต โดยจะมีความปลอดภัยในระดับหนึ่ง ด้วยการตรวจสอบสิทธิ์ก่อนการใช้งานด้วย Username/Password และมีการเข้ารหัสข้อมูลที่ส่งระหว่างเครื่องเซิร์ฟเวอร์และเครื่องคอมพิวเตอร์ด้วย IPSec

คอนฟิกเบื้องต้นของเซิร์ฟเวอร์ที่ใช้ทดสอบ

  • ติดตั้ง Ubuntu 18.04 พร้อมอัพเดทล่าสุด
  • มี Internet Public IP เพื่อรองรับการเชื่อมต่อผ่านอินเทอร์เน็ต
  • ชื่อเครื่อง (DNS name) ของเซิรฟ์เวอร์ที่ใช้ทดสอบ ในที่นี้ขอใช้เป็นชื่อ my-vpn.example.com
  • แก้ไข rule ของ Firewall เพื่ออนุญาตให้เครื่องอื่นสามารถเข้าใช้งานพอร์ต UDP 500, 4500

ติดตั้ง strongSwan

รันคำสั่ง apt install ติดตั้งแพ็คเกจ strongswan

sudo apt install strongswan strongswan-pki libstrongswan-extra-plugins

สร้าง Certificate Authority

ในที่นี้เราจะคอนฟิก VPN แบบ IKEv2 โดยใช้ Server Certificate เพื่อยืนยันตัวตนของฝั่งเซิร์ฟเวอร์ (left) แต่ขั้นแรกเราต้องสร้าง Certificate Authority หรือเรียกสั้นๆ ว่า CA ขึ้นมาก่อน

มาดูวิธีการสร้าง CA กัน

สร้างโฟลเดอร์สำหรับเก็บไฟล์ Key, Certificate

mkdir -p ~/pki/{cacerts,certs,private}

chmod 700 ~/pki

ใช้คำสั่ง ipsec เพื่อสร้างไฟล์ Key สำหรับ CA

ipsec pki --gen --type rsa --size 4096 --outform pem > ~/pki/private/ca-key.pem

ใช้คำสั่ง ipsec เพื่อสร้างไฟล์ Certificate จากไฟล์ Key ที่ได้จากคำสั่งที่แล้ว

คำแนะนำ แนะนำให้เปลี่ยนค่าในออปชัน --dn เพื่อแยกความแตกต่างกับชื่อ CA อื่นๆ ที่เราจะ import เข้าไปในเครื่อง Windows หรือ macOS เช่นในที่นี้ขอตั้งชื่อเป็น "CN=MyIKE VPN CA"

sudo ipsec pki --self --ca --lifetime 3650 \
    --in ~/pki/private/ca-key.pem \
    --type rsa --dn "CN=MyIKE VPN CA" \
    --outform pem > ~/pki/cacerts/ca-cert.pem

ตอนนี้เราก็มี CA หรือ Certificate Authority แล้ว โดยเก็บไว้ในรูปแบบไฟล์ ca-key.pem, ca-cert.pem ซึ่งเราจะใช้ในการสร้าง Server Certificate ในขั้นตอนต่อไป

สร้าง Server Certificate

ใช้คำสั่ง ipsec เพื่อสร้างไฟล์ key สำหรับ Server

sudo ipsec pki --gen --type rsa --size 4096 --outform pem > ~/pki/private/server-key.pem

ใช้คำสั่ง ipsec โดยระบุไฟล์ key ของ Server server-key.pem และระบุไฟล์ key กับไฟล์​ certificate ของ CA เพื่อใช้ issue ไฟล์ Server Certificate

อย่าลืมเปลี่ยนชื่อเครื่องที่ระบุในออปชัน --dn และ --san ให้ตรงกับชื่อเครื่องที่คุณคอนฟิกอยู่ ไม่อย่างนั้นจะมีปัญหาเรื่องการตรวจสอบความถูกต้องของ ServerCertificate

sudo ipsec pki --pub --in ~/pki/private/server-key.pem --type rsa \
    | ipsec pki --issue --lifetime 1825 \
        --cacert ~/pki/cacerts/ca-cert.pem \
        --cakey ~/pki/private/ca-key.pem \
        --dn "CN=my-vpn.example.com" \
        --san "my-vpn.example.com" \
        --flag serverAuth --flag ikeIntermediate --outform pem \
    >  ~/pki/certs/server-cert.pem

คัดลอกไฟล์ทั้งหมดในโฟลเดอร์ ~/pki/ ไปไว้ในโฟลเดอร์ /etc/ipsec.d/

sudo cp -r ~/pki/* /etc/ipsec.d/

คอนฟิก strongSwan

ขั้นต่อไป มาแก้ไขไฟล์คอนฟิกของ strongSwan กัน โดยไฟล์คอนฟิกหลักจะอยู่ที่ /etc/ipsec.conf

ตัวอย่างไฟล์คอนฟิก /etc/ipsec.conf

# /etc/ipsec.conf
config setup
    charondebug="ike 1, knl 1, cfg 1"
    uniqueids=yes

conn %default
    auto = add
    compress = no
    dpdaction = clear
    dpddelay = 300s
    dpdtimeout = 60s
    forceencaps = yes
    fragmentation = no
    rekey = yes
    type = tunnel

    left = %any
    leftid = @my-vpn.example.com
    leftcert=server-cert.pem
    leftsendcert=always
    leftsubnet=172.31.1.0/24

    right = %any
    rightid = %any
    rightsendcert=never
    rightsourceip = 10.1.1.0/24
    rightdns=8.8.8.8,8.8.4.4

conn my-ikev2-eap
    keyexchange = ikev2
    rightauth = eap-mschapv2
    eap_identity=%any

ขออธิบายบางส่วนของไฟล์คอนฟิก ipsec.conf

  • leftid แก้ไขให้ตรงกับชื่อเครื่องเซิร์ฟเวอร์ โดยมีเครื่องหมาย @ นำหน้า
  • leftsubnet แก้ไขค่าให้ครงกับ subnet ที่เซิร์ฟเวอร์เชื่อมต่อ แล้วต้องการให้ VPN Client ที่เชื่อมต่อเข้ามาแล้ว สามารถเข้าใช้งาน subnet นี้ได้
  • rightsourceip คือชุด IP Address ที่จะแจกให้กับ VPN Client ที่เชื่อมต่อเข้ามา
  • rightauth เลือกวิธีการตรวจสอบสิทธิ์ (authentication) ของเครื่อง Client ที่ต้องการเชื่อมต่อเข้ามา

VPN Authentication

ก่อนที่เครื่อง Client จะสามารถเชื่อมต่อได้ ต้องทำการพิสูจน์สิทธิ์การใช้งาน โดยในที่นี้จะเลือกคอนฟิกแบบ eap-mschapv2 คือให้เครื่อง Client ระบุ Username, Password ให้ถูกต้องก่อนจะเชื่อมต่อได้

strongSwan จะใช้ไฟล์ /etc/ipsec.secrets เพื่อเก็บรายชื่อ Username, Password

ตัวอย่างไฟล์ /etc/ipsec.secrets เพื่อเก็บข้อมูลการพิสูจน์สิทธิ์ โดยบรรทัด RSA จะเป็นการตรวจสอบฝั่งเซิร์ฟเวอร์ ซึ่งเราระบุเป็น server-key.pem เพื่อตรวจสอบโดยใช้ Server Certificate ส่วนบรรทัด EAP จะระบุรายชื่อ Username เช่น alice ต้องระบุ Password เป็น alice-secret เพื่อเชื่อมต่อ VPN

# /etc/ipsec.secrets
: RSA "server-key.pem"

alice : EAP "alice-secret"
bob : EAP "bob-secret"

สตาร์ตเซอร์วิส strongSwan

หลังการแก้ไขไฟล์คอนฟิก รันคำสั่ง systemctl เพื่อรีสตาร์ตเซอร์วิส

sudo systemctl restart strongswan

คอนฟิก Windows 10 เพื่อเชื่อมต่อ VPN

ติดตั้ง CA Certificate บนเครื่อง Windows 10

เนื่องจาก CA Certificate เป็นไฟล์ที่เราสร้างขึ้นเอง ทำให้ไม่ได้รับความน่าเชื่อถือจากเครื่อง Windows 10 ดังนั้น เราจะต้องติดตั้ง CA Certifcate เพิ่มเติม

คัดลอกไฟล์ /etc/ipsec.d/cacerts/ca-cert.pem ไปไว้บนเครื่อง Windows 10

รันคำสั่ง mmc เพื่อเปิดโปรแกรม Microsoft Management Console

คลิกที่ File -> Add/Remove Snap-in

ฝั่ง Available snap-in คลิกเลือก Certificates แล้วกดปุ่ม Add

เลือกเพิ่มแบบ Computer Account

ในหน้า Certificates คลิกเลือก Trusted Root Certification Authorities แล้วเลือก Certificates อีกที

ด้านขวามือ ภายใต้ Action เลือกเมนู Import คลิกไปเรื่อยๆ จนถึงหน้า File to Import เลือกไฟล์ ca-cert.pem

คลิกไปเรื่อยๆ จนถึงหน้า Certifaction Store เลือกให้เก็บไว้ใน Trusted Root Certifaction Authorities

ตัวอย่าง CA ที่ import เรียบร้อยแล่้ว

macOS Keychain Access

แก้ไข Registry เพื่อเปิดการใช้งาน DH2048/AES256

เปิดโปรแกรม Registry Editor แล้วคลิกเข้าไปที่

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Rasman\Parameters

เพิ่มชื่อ NegotiateDH2048_AES256 โดยกำหนดให้มีค่า 1

macOS Keychain Access

สร้าง VPN Interface บน Windows 10

ในช่องค้นหา ใส่ VPN Settings

คลิก Add a VPN connection โดยระบุค่าคอนฟิก

  • VPN provider : Windows (built-in)
  • Connection name : MyVPN
  • Server name or address : my-vpn.example.com
  • VPN type : IKEv2
  • Type of sign-in info: User name and password
  • User name : bob
  • Password : bob-secret

แล้วกดปุ่ม Save

macOS Keychain Access

คลิกที่ไอคอน MyVPN แล้วกดปุ่ม Connect

ตัวอย่างหน้าจอแสดงสถานะการเชื่อมต่อแล้ว (Connected)

macOS Keychain Access

คอนฟิก macOS เพื่อเชื่อมต่อ VPN

ติดตั้ง CA Certificate บนเครื่อง macOS

เนื่องจาก CA Certificate เป็นไฟล์ที่เราสร้างขึ้นเอง ทำให้ไม่ได้รับความน่าเชื่อถือจากเครื่อง macOS ดังนั้น เราจะต้องติดตั้ง CA Certifcate เพิ่มเติม

คัดลอกไฟล์ /etc/ipsec.d/cacerts/ca-cert.pem ไปไว้บนเครื่อง macOS

คลิกสองครั้ง (double-click) ที่ไฟล์ ca-cert.pem เพื่อติดตั้ง CA Certificate

หน้าจอจะแสดง Keychain Access ถ้าเราคลิกที่ชื่อ CA ที่เราเพิ่งติดตั้ง จะมีข้อความแสดงว่า This root certificate is not trusted.

macOS Keychain Access

คลิกสองครั้งที่ชื่อ CA หน้าจอจะแสดงรายละเอียด คลิกที่ Trust เพื่อขยายรายละเอียดในส่วน Trust

เปลี่ยนค่าคอนฟิกของ When using this certificate ให้เป็น Always Trust

macOS Keychain Access

กดปุ่ม (x) เพื่อปิดหน้าต่างนี้ จะมีหน้าจอให้ระบุ User Name, Password ของเครื่อง macOS ก่อนที่จะกด Update Settings ได้

หลังจากเปลี่ยนค่าคอนฟิกแล้ว ถ้าคลิกเข้าไปดูรายละเอียดของ CA Certificate นี้อีกที จะแสดงข้อความ This certificate is marked as trusted for this account

สร้าง VPN Interface บน macOS

ในหน้า System Preferences คลิกที่ Network

คลิกปุ่ม + เพื่อสร้าง interface ใหม่ โดยระบุค่า

  • Interface: VPN
  • VPN Type: IKEv2
  • Server Name: My VPN (IKEv2)

แล้วคลิกปุ่ม Create

ในหน้าคอนฟิก Interface ระบุ

  • Server Address: my-vpn.example.com
  • Remote ID: my-vpn.example.com
  • Local ID:

แล้วคลิกปุ่ม Authentication Settings

เลือก Authentication Settings เป็นแบบ Username และระบุ Username, Password ที่คอนฟิกไว้ในไฟล์ ipsec.secrets เช่น

Usernama: alice Password: alice-secret

เสร็จแล้ว ลองกด Connect ดู

ตัวอย่างหน้าจอแสดงสถานะเชื่อมต่อได้ (Connected)

macOS Keychain Access

การตรวจสอบสถานะการเชื่อมต่อบนเซิร์ฟเวอร์

สามารถใช้คำสั่ง ipsec ระบุออปชัน status เพื่อแสดง client ที่เชื่อมต่ออยู่ได้

$ sudo ipsec status
Security Associations (2 up, 0 connecting):
my-ikev2-eap[3]: ESTABLISHED 21 seconds ago, 18.140.x.x[my-vpn.example.com]...223.204.x.x[192.168.1.23]
my-ikev2-eap{3}:  INSTALLED, TUNNEL, reqid 3, ESP in UDP SPIs: c95a...
my-ikev2-eap{3}:   172.31.1.0/24 === 10.1.1.1/32
my-ikev2-eap[2]: ESTABLISHED 28 seconds ago, 18.140.x.x[my-vpn.example.com]...223.204.x.x[192.168.1.22]
my-ikev2-eap{2}:  INSTALLED, TUNNEL, reqid 2, ESP in UDP SPIs: c285d47e_i 02303805_o
my-ikev2-eap{2}:   172.31.1.0/24 === 10.1.1.2/32

ข้อมูลเพิ่มเติม