Bạn đã sao chép một OpenVPN jail từ một bài đăng cộng đồng, khởi động lại fail2ban và không địa chỉ nào bị chặn. Nguyên nhân gần như luôn là định dạng nhật ký: Access Server không ghi những dòng xác thực thất bại mà bộ lọc có sẵn mong đợi. Trước khi chạm vào bộ lọc, hãy xác nhận rằng các bản ghi thực sự tồn tại, vì một mẫu không thể khớp với thứ mà dịch vụ chưa từng ghi lại.

Đây là quy trình tôi làm theo trên máy chủ Access Server: xác nhận hình dạng bản ghi, viết một biểu thức neo, thử nó trên nhật ký thật, sau đó tách jail theo bề mặt bị tấn công và kiểm tra rằng lệnh chặn đến được tường lửa.

Xác nhận rằng bản ghi lỗi tồn tại

Access Server ghi các dòng có cấu trúc của riêng nó vào /var/log/openvpnas.log, và địa chỉ máy khách nằm trong trường real_ip trong dấu ngoặc kép chứ không phải ở đầu dòng syslog. Trước khi viết bất kỳ mẫu nào, hãy tìm một lần đăng nhập thất bại mà bạn biết đã xảy ra:

grep -i 'LOG ERR' /var/log/openvpnas.log | tail -20

Nếu không thấy gì, mức nhật ký là nghi phạm tiếp theo. Access Server có công tắc gỡ lỗi cơ sở dữ liệu nhật ký trong /usr/local/openvpn_as/etc/as.conf (DEBUG_LOGDB=1), và dịch vụ phải được khởi động lại sau khi thay đổi nó. Hãy coi công tắc đó là một cài đặt chẩn đoán cần hạ xuống lại khi đã có mẫu, không phải cấu hình vĩnh viễn.

Trong lúc ở trong tệp, hãy để ý những bề mặt nào ghi vào đó. Lỗi của cổng thông tin máy khách, giao diện quản trị và xác thực đường hầm đều rơi vào cùng một tệp với các dấu khác nhau, và chi tiết đó quyết định bố cục jail về sau.

Neo một bộ lọc vào real_ip

Giữ biểu thức hẹp. Một bộ lọc nhận mọi dòng có địa chỉ IP sẽ chặn người ta vì những lần ngắt kết nối thông thường, và trên một máy chủ bận rộn, triệu chứng duy nhất là người dùng phàn nàn bị khóa vì đã đóng máy tính xách tay. Hãy nhận bản ghi lỗi và bắt lấy địa chỉ trong dấu ngoặc kép:

# /etc/fail2ban/filter.d/openvpnaccess.local
[Definition]
failregex = ^ .*LOG ERR.*"real_ip": "<HOST>".*
ignoreregex =

Khoảng trắng đầu dòng không phải để trang trí. Access Server thụt lề các bản ghi của mình, và neo vào đó ngăn mẫu nhận luôn những dòng do các dịch vụ không liên quan ghi vào cùng tệp. Nếu bản ghi của bạn thay vào đó có dấu thời gian ở đầu, hãy khớp tiền tố đó, nhưng hãy neo vào thứ thực sự có mặt trong mọi bản ghi bạn định nhận.

Khi cần độ chính xác theo bề mặt, hãy thu hẹp hơn nữa bằng cách yêu cầu dấu bề mặt (WEB_CLIENT, WEB_ADMIN hoặc VPN) trên cùng dòng. Một bộ lọc với ba mẫu dễ kiểm tra hơn ba bộ lọc chỉ khác nhau một từ.

Thử biểu thức trước khi bật một jail

Đừng bao giờ bật một bộ lọc mà bạn chưa chạy trên nhật ký sản xuất. Bài kiểm tra được ghi trong tài liệu truyền bộ lọc qua hai lần, một lần để nạp và một lần để áp dụng, và báo cáo các dòng bị bỏ sót là phần đáng đọc:

fail2ban-regex --print-all-missed /var/log/openvpnas.log \
  /etc/fail2ban/filter.d/openvpnaccess.local \
  /etc/fail2ban/filter.d/openvpnaccess.local > missed.txt

So sánh số lần khớp với các lỗi bạn đã xác nhận ở bước đầu. Không khớp lần nào nghĩa là mẫu sai; khớp trên những dòng không phải lỗi xác thực nghĩa là nó quá rộng. Đọc missed.txt cho đến khi bạn giải thích được từng dòng mà bạn đã chọn không nhận.

Hãy làm bài kiểm tra này trên một bản sao nếu nhật ký lớn, và lặp lại sau mỗi lần nâng cấp Access Server. Định dạng nhật ký là giao diện bạn khớp vào, và nó không phải một API ổn định.

Tách jail theo bề mặt, không theo daemon

Một Access Server trình bày nhiều bề mặt xác thực: giao diện web cho máy khách và quản trị trên 943/tcp, và đường hầm trên 1194/udp hoặc 443/tcp trong phần lớn triển khai. Một jail bao trùm tất cả cho phép các lần đoán trên đường hầm chặn một địa chỉ cũng là đường quản trị của bạn, và nó giấu đi bề mặt nào thực sự đang bị tấn công. Hãy cho mỗi bề mặt một jail riêng với cổng và ngưỡng riêng:

# /etc/fail2ban/jail.d/openvpnaccess.local
[openvpnas-web-client]
enabled  = true
port     = 943
protocol = tcp
filter   = openvpnaccess
logpath  = /var/log/openvpnas.log
maxretry = 3
findtime = 10m
bantime  = 1h
[openvpnas-tunnel]
enabled  = true
port     = 443
protocol = udp
filter   = openvpnaccess
logpath  = /var/log/openvpnas.log
maxretry = 5
findtime = 10m
bantime  = 1h

Bắt đầu với bộ đếm nhỏ và lệnh chặn ngắn, rồi tăng lên sau khi đã quan sát một tuần lưu lượng thật. Một ngưỡng rộng rãi trên địa chỉ văn phòng dùng chung sẽ phạt mọi người dùng phía sau một NAT, và một lệnh chặn mạnh tay trên bề mặt đường hầm sẽ ngắt những máy khách hợp lệ có thông tin đăng nhập đã lưu hết hạn qua đêm.

Kiểm tra lệnh chặn, backend và thiệt hại kèm theo

Sau khi khởi động lại, đầu ra trạng thái là cách xác nhận nhanh nhất rằng jail tồn tại và đang đếm:

fail2ban-client status
fail2ban-client status openvpnas-tunnel

Sau đó xác nhận rằng lệnh chặn đến được tường lửa mà bạn thực sự vận hành, vì một jail cấu hình cho backend mà không ai thực thi thì không bảo vệ được gì. Với hành động iptables, các địa chỉ xuất hiện trong một chuỗi mang tên jail (f2b-openvpnas-tunnel); với hành động nftables, chúng rơi vào một tập trong bảng riêng của fail2ban. Hãy kiểm tra cái mà máy chủ của bạn dùng thay vì giả định.

Hai kiểm tra kèm theo quan trọng hơn chính lệnh chặn. Thứ nhất, xác nhận rằng real_ip là địa chỉ máy khách chứ không phải bộ cân bằng tải hay proxy ngược; phía sau proxy, mọi lệnh chặn đều rơi vào proxy và kéo cả dịch vụ xuống theo. Thứ hai, hãy ghi lại thủ tục bỏ chặn, vì địa chỉ vượt ngưỡng lúc 02:00 thường thuộc về kỹ sư trực ca: fail2ban-client set openvpnas-tunnel unbanip 203.0.113.24.

Hãy nhớ ranh giới khi tinh chỉnh. Fail2ban là bộ giới hạn tốc độ trên một bề mặt xác thực, không phải một lớp kiểm soát truy cập. Nó không thay thế MFA, các hạn chế theo từng tài khoản hay việc giữ giao diện quản trị ngoài internet công cộng, và Access Server có cài đặt autoban riêng đáng để kiểm tra trước khi bạn chồng hai bộ giới hạn tốc độ lên cùng một cổng.

Bài viết liên quan