VPN của bạn trả lời các kết nối lúc 3 giờ sáng trong khi chiếc máy ký chứng chỉ của nó nằm tắt trong ngăn kéo. Máy khách kiểm tra chứng chỉ máy chủ không bao giờ liên hệ với CA của bạn, vì vậy CA không cần phải truy cập được cho bất kỳ kết nối nào. Phần cần lập kế hoạch là ngày một chứng chỉ phải được phát hành, gia hạn hoặc thu hồi trong khi khóa gốc vẫn bị khóa.

Một kết nối thực sự xác thực điều gì

Khi máy khách OpenVPN kết nối, nó đi theo chuỗi chữ ký từ chứng chỉ lá của máy chủ lên đến chứng chỉ CA mà nó đã tin cậy, kiểm tra cửa sổ hiệu lực và, nếu hồ sơ nói vậy, tra cứu danh sách thu hồi. Nó không bao giờ tìm CA gốc của bạn. Máy chủ làm điều tương tự như hình ảnh phản chiếu cho chứng chỉ máy khách. Tại thời điểm kết nối chỉ có chứng chỉ lá, chứng chỉ trung gian và gói tin cậy bạn đã phân phối trước đó.

Điều thực sự thất bại là một trong ba thứ: khóa ký không có sẵn khi phát hành, danh sách thu hồi đã cũ, hoặc gói tin cậy của máy khách cũ hơn chuỗi mà máy chủ trình bày. Thứ nhất là vấn đề quy trình; hai thứ còn lại là vấn đề phân phối. Không thứ nào yêu cầu khóa gốc phải trực tuyến, và dịch vụ VPN được quản lý đòi chứng chỉ riêng cho xác thực đường hầm chỉ chuyển quyền ký sang nhà cung cấp. Azure điểm-đến-trang làm ngược lại: bạn tải lên chứng chỉ gốc và các chứng chỉ được ký bên dưới nó được coi là đáng tin cậy, vì vậy hãy hỏi ai ký, ai xác thực và làm sao thu hồi chứng chỉ sớm.

Xây dựng gốc trên một máy chủ không bao giờ nhận địa chỉ

Gốc ngoại tuyến ít khi được dùng: để ký chứng chỉ CA trung gian và sau đó để gia hạn hoặc thu hồi nó. Mọi thứ khác diễn ra ở một cấp thấp hơn. Làm công việc gốc trên một máy được giữ ngoài mạng, nếu có thể từ hệ thống đang chạy, và ghi lại ai đã ở trong phòng. Các lệnh giả định OpenSSL 1.1.1 hoặc mới hơn, vì -addext không có trong các bản dựng cũ.

openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out root.key
openssl req -x509 -new -key root.key -sha256 -days 7300 \
  -subj "/CN=Example VPN Root CA" -out root.crt \
  -addext "basicConstraints=critical,CA:TRUE" \
  -addext "keyUsage=critical,keyCertSign,cRLSign"

Tạo chứng chỉ trung gian trên máy chủ ký và chỉ mang yêu cầu của nó đến máy ngoại tuyến. Gốc ký yêu cầu đó với độ dài đường dẫn bằng không, nên CA trung gian có thể ký chứng chỉ điểm cuối nhưng không thể tạo CA khác bên dưới nó. Phần mở rộng duy nhất đó ngăn máy chủ ký bị xâm phạm tạo ra thẩm quyền ngang với gốc. Chỉ dùng ECDSA nếu mọi máy khách chạy OpenVPN 2.4 hoặc mới hơn; nếu không, tạo khóa RSA và giữ nguyên luồng.

openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out intermediate.key
openssl req -new -key intermediate.key -subj "/CN=Example VPN Intermediate CA" -out intermediate.csr
openssl x509 -req -in intermediate.csr -CA root.crt -CAkey root.key \
  -CAcreateserial -days 3650 -sha256 -extfile intermediate.ext -out intermediate.crt

intermediate.ext chứa basicConstraints=critical,CA:TRUE,pathlen:0, keyUsage=critical,keyCertSign,cRLSign và authorityKeyIdentifier=keyid:always. Đưa khóa gốc trở lại két trước khi kết nối lại máy chủ ký. Nếu gốc phải có thể thu hồi chứng chỉ trung gian, hãy ký nó bằng openssl ca -config root.cnf -extensions intermediate_ca với index.txt cấp gốc thay vì openssl x509 -req, để số sê-ri được ghi lại; sau đó gửi danh sách gốc thu được trong hồ sơ máy khách, nơi một crl-verify dựa trên tệp đọc nó khi khởi động. Gửi cho máy khách một gói có cả hai chứng chỉ CA; chỉ một lá sẽ không xác thực được với gốc.

Phát hành lá từ CA trung gian, với cơ sở dữ liệu

Ký bằng openssl x509 -req hoạt động cho đến khi bạn cần thu hồi, vì không có gì ghi lại số sê-ri. Dùng openssl ca từ chứng chỉ đầu tiên để số sê-ri, ngày hết hạn và trạng thái thu hồi sống trong một cơ sở dữ liệu. Tạo các tệp cơ sở dữ liệu một lần, rồi trỏ cấu hình vào chúng:

mkdir -p /etc/vpn-ca/intermediate/newcerts
touch /etc/vpn-ca/intermediate/index.txt
echo 1000 > /etc/vpn-ca/intermediate/serial
echo 1000 > /etc/vpn-ca/intermediate/crlnumber
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = /etc/vpn-ca/intermediate
database = $dir/index.txt
new_certs_dir = $dir/newcerts
serial = $dir/serial
crlnumber = $dir/crlnumber
certificate = $dir/intermediate.crt
private_key = $dir/intermediate.key
default_md = sha256
default_days = 365
default_crl_days = 30
unique_subject = no
policy = policy_any
[ policy_any ]
commonName = supplied
[ server_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = serverAuth
subjectAltName = @server_names
[ client_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = clientAuth
[ server_names ]
DNS.1 = vpn.example.com

Dòng sử dụng khóa giả định khóa ECDSA; thêm keyEncipherment cho RSA. Cho mỗi máy khách tên chung riêng, vì OpenVPN nhận diện kết nối bằng trường đó, và hai máy tính xách tay dùng chung CN=vpn-client không thể phân biệt trong nhật ký, trong quy tắc client-config-dir hay trong bất kỳ lần đẩy nào cho người dùng, và bạn mất đi sự quy gán khiến quyết định thu hồi có thể bảo vệ được. Phát hành và xác thực lá như sau:

openssl req -new -key alice.key -subj "/CN=alice-laptop" -out alice.csr
openssl ca -config intermediate.cnf -extensions client_cert -in alice.csr -out alice.crt -batch
openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt alice.crt

Giữ khóa ký sau ranh giới chính sách thay vì sao chép nó lên máy chủ VPN: một dịch vụ nhỏ xác thực yêu cầu, kiểm tra tên chung với danh sách cho phép và chỉ trả về chứng chỉ. Ghi lại mọi số sê-ri; nhật ký là mối liên kết duy nhất giữa một chứng chỉ và người đã yêu cầu nó.

Xuất bản việc thu hồi mà không đánh thức gốc

Chứng chỉ máy khách do CA trung gian thu hồi, không bao giờ do gốc. Danh sách gốc chỉ quan trọng khi một CA trung gian bị đốt. Trỏ máy chủ đến danh sách trung gian bằng crl-verify. CRL dựa trên tệp được nạp khi dịch vụ khởi động, nên nạp lại sau mỗi lần tạo lại; dạng thư mục đọc trạng thái tại thời điểm kết nối và tốn một tệp cho mỗi số sê-ri.

Thu hồi và tạo lại bằng hai lệnh từ cùng cơ sở dữ liệu:

openssl ca -config intermediate.cnf -revoke /etc/vpn-ca/intermediate/newcerts/1001.pem
openssl ca -config intermediate.cnf -gencrl -out /etc/openvpn/crl.pem

Sau đó theo dõi đồng hồ. CRL mang trường cập nhật tiếp theo, và khi ngày đó qua đi, đối tác xác thực từ chối danh sách thay vì bỏ qua nó. Tạo lại hàng tháng bằng default_crl_days = 30 để lại khoảng dư; hàng năm thì không. Tuổi thọ lá ngắn hơn là biện pháp kiểm soát đáng tin cậy hơn, vì việc thu hồi chỉ áp dụng ở nơi danh sách được tra cứu.

Kiểm tra chuỗi, rồi ghi lại nghi lễ

Tái tạo bốn lỗi trước khi tin vào thiết kế. Xác thực chuỗi bằng openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt server.crt. Kết nối bằng chứng chỉ máy khách đã hết hạn và xác nhận máy chủ từ chối nó. Thu hồi một máy khách thử nghiệm, nạp lại và xác nhận danh sách có hiệu lực. Đẩy đồng hồ của một máy chủ lên một ngày, vì đồng hồ sai có thể phát hành và từ chối những chứng chỉ trông hợp lệ ở nơi khác.

Gốc ngoại tuyến chỉ là biện pháp kiểm soát nếu có giấy tờ: hai người được nêu tên cho nghi lễ, hồ sơ mọi số sê-ri đã ký, bản sao lưu mã hóa được lưu riêng khỏi máy, và kiểm tra khôi phục trên máy chủ cách ly. Ký một CA trung gian dự phòng trong cùng nghi lễ để máy chủ ký chết không buộc bạn mở khóa gốc lúc nửa đêm.

Trước khi gọi là xong, xác nhận năm điều: khóa gốc không ở trên máy chủ có mạng, khóa trung gian chỉ sống trên máy chủ ký, gói máy khách mang cả hai chứng chỉ CA, CRL có lần cập nhật tiếp theo trong tương lai, và có người sở hữu mục lịch cho mọi ngày hết hạn trong chuỗi. Nếu thiếu một, cấu hình trông ngoại tuyến chỉ là chưa được ghi chép.

Bài viết liên quan