Dịch vụ iptables không thành công với systemd vì bind9 chưa thực sự sẵn sàng


1

Tôi đang cố gắng gọi iptables-restore trong tập lệnh systemd.service. Tôi có một số quy tắc yêu cầu tra cứu DNS. Tôi đã bao gồm After = bind9.service trong phần Đơn vị cho tường lửa. Tuy nhiên, systemd nghĩ rằng bind9 được bắt đầu khi nó rẽ nhánh chứ không phải khi được đặt tên sẵn sàng phục vụ các yêu cầu. Nó khởi động iptables-restore trước khi có thể giải quyết tên máy chủ và do đó không thành công. Đây là phần thích hợp của syslog:

Ngày 13 tháng 12 21:29:02 fw systemd [1]: Bắt đầu BIND Máy chủ tên miền.
Ngày 13 tháng 12 21:29:02 fw systemd [1]: Đạt mục tiêu Tra cứu tên máy chủ và mạng.
Ngày 13 tháng 12 21:29:02 fw systemd [1]: Bắt đầu tải quy tắc iptables ...
Ngày 13 tháng 12 21:29:02 fw systemd [1]: Bắt đầu cầu Homebridge HomeKit.
Ngày 13 tháng 12 21:29:02 fw systemd [1]: Bắt đầu máy chủ OpenBSD Secure Shell ...
Ngày 13 tháng 12 21:29:02 fw sh [1841]: iptables-restore v1.6.0: không tìm thấy máy chủ / mạng `example.com '
Ngày 13 tháng 12 21:29:02 fw sh [1841]: Xảy ra lỗi tại dòng: 24
Ngày 13 tháng 12 21:29:02 fw sh [1841]: Hãy thử `iptables-restore -h 'hoặc' iptables-restore --help 'để biết thêm thông tin.
Ngày 13 tháng 12 21:29:02 fw có tên [1838]: bắt đầu BIND 9.10.3-P4-Ubuntu <id: ebd72b3> -f -4 -u bind

Đây là tập tin dịch vụ:

[Đơn vị]
Mô tả = Tải quy tắc iptables
Sau = bind9.service

[Tải về]
WantedBy = multi-user.target
WantedBy = network-online.target

[Dịch vụ]
Loại = oneshot
RemainAfterExit = có
ExecStart = / bin / sh -c "/ sbin / iptables-restore </etc/iptables.up.rules"

Cách tốt nhất để lệnh iptables-restore thực thi khi khởi động, nhưng đợi tên được kích hoạt là gì?

Câu trả lời:


2

Tuy nhiên, systemd nghĩ rằng bind9 được bắt đầu khi nó rẽ nhánh chứ không phải khi được đặt tên sẵn sàng phục vụ các yêu cầu

Systemd không có cách nào khác để biết khi được đặt tên là "sẵn sàng phục vụ các yêu cầu". Giao thức thường được chấp nhận, quay trở lại SysVinit ngày, là một trình tiện ích, thiết lập mọi thứ và một khi đã sẵn sàng nói với cha mẹ của nó rằng bây giờ nó có thể thoát (thường thông qua một đường ống hoặc tín hiệu). Điều này rất đơn giản và thậm chí nó hoạt động nếu "init" của bạn chỉ là shell-script:named; echo Ready!

(Nói cách khác, systemd không quan tâm chút nào về quá trình ban đầu forking con của nó, nhưng khi nó thoát ra .)

Ngoài ra còn có các giao thức có thể khác - ví dụ: nếu Type = notify được sử dụng, thì daemon dự kiến ​​sẽ gửi một tin nhắn READY = 1; với Type = dbus, nó phải xác nhận tên trên bus hệ thống; Vân vân.

Nhưng nếu được đặt tên không thực hiện đúng giao thức này - nghĩa là, nếu quy trình ban đầu của nó xuất hiện quá sớm sau khi giả mạo - thì không có gì init có thể làm về điều đó. Đó không phải là công việc của init để đối phó với daemon đang nói dối với nó (thông qua sự bất tài hay nói cách khác).

Đã nói rằng, điều đầu tiên cần làm là kiểm tra xem bind9.servicethực sự hoạt động như thế nào . Vẫn có thể là nó không chạy được đặt tên trực tiếp mà thông qua các lớp script init.d, có xu hướng gây ra các vấn đề tương tự. (Mặc dù các nhật ký không hiển thị tiền tố "LSB: Hoài" điển hình tôi vẫn sẽ kiểm tra.)

Nó có thể cũng được mà bind9.service đã được đổi thành Type = đơn giản, mà không hỗ trợ bất kỳ loại 'sẵn sàng' thông báo ở tất cả! Điều này cũng thường xuyên xảy ra khi một người bảo trì chọn một cách mù quáng "systemd nói rằng việc giả mạo là xấu xa" từ một số trang web.

Vì vậy, hãy đảm bảo bind9.service thực sự Type = forking (không phải Type = Simple) và nó chạy được đặt tên trực tiếp (và với các tùy chọn "vui lòng daemonize" cần thiết).

Nếu điều đó không hoạt động (nghĩa là vẫn còn quá sớm), thì lựa chọn duy nhất khác của bạn là có dịch vụ thứ hai tiếp tục kiểm tra tính khả dụng của DNS.


Cuối cùng, Type = notify đã khiến bind9.service hết thời gian chờ. Để trả lời câu hỏi, trên hệ thống Ubuntu 16.04 của tôi, không có loại nào được chỉ định để nó mặc định là đơn giản. Cuối cùng, tôi đã tạo ra một dịch vụ đơn giản chỉ định After = bind9 và sau đó lặp cho đến khi lệnh máy chủ trả về giá trị mong đợi. Sau đó tôi đã thực hiện dịch vụ tường lửa của mình phụ thuộc vào điều đó. Ngoài ra, để giải quyết vấn đề iptables.service của Marius phụ thuộc vào mạng-pre.target, phân phối ubfox dường như không đi kèm với dịch vụ cho iptables. Nhưng tôi đánh giá cao đề nghị đặt một tường lửa tạm thời.
user2102964

@ user2102964: Với tên, tùy chọn tốt nhất của bạn là Loại truyền thống = forking. Bạn không nên sử dụng Loại = thông báo trừ khi dịch vụ cung cấp tài liệu rõ ràng là được hỗ trợ (trong trường hợp không rõ ràng từ bài đăng).
grawity

@ user2102964: Đối với iptables, Ubuntu có dưới netfilter-persistent+ iptables-persistent.
grawity
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.