-C
Tùy chọn mới là không thỏa đáng, bởi vì nó mở cho điều kiện cuộc đua thời gian kiểm tra thời gian sử dụng (TOCTTOU). Nếu hai quy trình cố gắng thêm cùng một quy tắc cùng một lúc, -C
sẽ không bảo vệ chúng khỏi việc thêm hai lần.
Vì vậy, nó thực sự không tốt hơn grep
giải pháp. Một công việc xử lý văn bản chính xác trên đầu ra của iptables-save
có thể hoạt động một cách đáng tin cậy -C
, vì đầu ra đó là một ảnh chụp nhanh đáng tin cậy về trạng thái của các bảng.
Điều cần thiết là một --ensure
tùy chọn kiểm tra nguyên tử và thêm quy tắc chỉ khi nó không tồn tại. Hơn nữa, thật tuyệt nếu quy tắc được chuyển đến đúng vị trí nơi quy tắc mới sẽ được chèn nếu nó chưa tồn tại ( --ensure-move
). Chẳng hạn, nếu iptables -I 1
được sử dụng để tạo quy tắc ở đầu chuỗi, nhưng quy tắc đó đã tồn tại ở vị trí thứ bảy, thì quy tắc hiện tại sẽ chuyển sang vị trí đầu tiên.
Không có các tính năng này, tôi nghĩ một cách giải quyết khả thi là viết một vòng lặp shell shell dựa trên mã giả này:
while true ; do
# delete all copies of the rule first
while copies_of_rule_exist ; do
iptables -D $RULE
done
# now try to add the rule
iptables -A $RULE # or -I
# At this point there may be duplicates due to races.
# Bail out of loop if there is exactly one, otherwise
# start again.
if exactly_one_copy_of_rule_exists ; then
break;
fi
done
Mã này có thể quay xung quanh; nó không đảm bảo rằng hai hoặc nhiều tay đua sẽ bị loại trong một số lần lặp cố định. Một số giấc ngủ ngược theo cấp số nhân ngẫu nhiên có thể được thêm vào để giúp với điều đó.